Вообщем написал функцию gets. Её задача - считывать строки из файлового меппинга (проще говоря - прямо из памяти). Хочу её оптимизировать (если это вообще возможно), но из-за недостатка опыта и знаний пока даже не знаю что тут можно применить. Подскажите пожалуйста в какую сторону копать. Вот код: Код (Text): gets proc uses esi edi lpString:DWORD,len:DWORD mov al, 0Ah ; mov "0Ah" to al (LF) mov esi, pos mov edi, lpString mov ecx, len cld next: cmp al, byte ptr [esi] ; compare data with al (LF symbol) je exit ; if equal, then exit movsb loop next exit: mov eax, 0 ;mov eax 0 (string terminator) stosb ;replase CR symbol to 0 (terminate lpString) inc esi ;change file pointer to next symbol after LF mov pos, esi ;save file pointer ret gets endp MMX, SSE и др. технологии мне не нужны, т.к. пишу под такие компы, в которых их может и не быть
ASMatik ты чё рихнулся? ты знаеш что у компов есть ресурс выроботки? года 4 назад в госучереждениях жизнь компа ровнялась 3 года и дальше он списывался!!! не знаю как сейчас, но где нет MMX - им минимум 8 лет!! ты что хочеш расхлёбывать железячные ошибки выробатывшихся компом одумайся!! (пиво помогает)
Пиво не помогло))) Вот сижу сейчас с пивного бодуна. Хз. Ок, тогда буду юзать MMX или SSE. Но как с помощью них можно это оптимизировать? Может быть для моей задачи MMX не очень то и нужен. Мне с помощью этой функции только конфиг и считывать. Причем не огромный а малюсенький
wsd Не знаю - не знаю. Контора, для которой пишется мною аська, испокон веку сидит на четыреставосьмидесятниках и Офисе97. Хотя в принципе у нас здесь провинция... ЗЫ: щас будет б/м оптимизированный код
Компы работают вечно! ASMatik а нафига воабще что то оптимизировать если малый объём данных проходит? MMX и SSE это уже тяжелая артелерия, и у каждой набор инструкций если не больше обычного процессорново то не меньше точно.
Вот. Не тестировалось, но работать должно. Если попрут баги, выложите, плиз, екзешник - погоняю под отладчиком, а то самому тестирующую прогу писать лень Код (Text): ; <---- На вход также подаётся ESI как указатель на строку StoreString proc uses esi edi _s:DWORD; MOV EDX, 0F5F5F5F5h; <---- NOT 0A0A0A0Ah MOV ECX, -4; @loop: ADD ECX, 4; MOV EDI, DWORD PTR [ESI+ECX]; ; <---- Здесь ищем терминирующий нуль ; <---- Если этого не нужно - уберите ; <---- этот блок и смените константу ; <---- 0F5F5F5F5h снова на 0A0A0A0Ah LEA EAX, [EDI-01010101h]; NOT EDI; AND EAX, EDI; AND EAX, 80808080h; JNE @copy; <---- Найден нуль! XOR EDI, EDX; LEA EAX, [EDI-01010101h]; NOT EDI; AND EAX, EDI; AND EAX, 80808080h; JE @loop; <---- LF не найден. Идём дальше XOR EDX, EDX; @copy: BSF EAX, EAX; SHR EAX, 3; LEA EDI, [EAX+ECX]; MOV BYTE PTR [ESI+EDI], 0; SHR ECX, 2; ADD ECX, 1; MOV EDI, _s; REP MOVSD; LEA ESI, [ESI+EAX-3]; <---- Ставим на следующий за найденным символ MOV EAX, EDX; <---- EAX != 0 - достигнут завершающий нуль! RET; StoreString endp; [+]: принцип работы таков: сканируется строчка из ESI, блоками по 4 байта, и проверяется на наличие символа 00h или 0Ah - что раньше встретится. Если встретился символ 0Ah - он заменяется на 00h, строка копируется в EDI блоками по 4 байта (поэтому возможны от 1 до 4 "лишних" символов после терминирующего нуля). Если найден 0 - то строка тоже копируется, но функция возвращает ненулевой результат.
Ок, спасибо огромное. Попробую поковыряю еще. Там просто еще проблема в том, что все виндосские строки в файлах кончаются CR LF, т.е. 0Dh 0Ah. Мой код работает, он считывает строку до символа 0Dh и переводит указатель на следующий символ после 0Ah, а 0Dh заменяет на 0. Я просто хотел узнать стоит ли его еще оптимизировать и нет ли в нем каких либо ошибок или "скользких" мест