Реализация функции gets (как в C)

Тема в разделе "WASM.ASSEMBLER", создана пользователем ASMatik, 17 июл 2008.

  1. ASMatik

    ASMatik New Member

    Публикаций:
    0
    Регистрация:
    3 июл 2008
    Сообщения:
    27
    Вообщем написал функцию gets. Её задача - считывать строки из файлового меппинга (проще говоря - прямо из памяти). Хочу её оптимизировать (если это вообще возможно), но из-за недостатка опыта и знаний пока даже не знаю что тут можно применить. Подскажите пожалуйста в какую сторону копать. Вот код:
    Код (Text):
    1. gets proc uses esi edi lpString:DWORD,len:DWORD
    2.     mov al, 0Ah         ; mov "0Ah" to al (LF)
    3.     mov esi, pos
    4.     mov edi, lpString
    5.     mov ecx, len
    6.     cld
    7.     next:
    8.         cmp al, byte ptr [esi] ; compare data with al (LF symbol)
    9.         je exit                ; if equal, then exit
    10.         movsb          
    11.         loop next
    12.     exit:
    13.         mov eax, 0   ;mov eax 0 (string terminator)
    14.         stosb        ;replase CR symbol to 0 (terminate lpString)
    15.         inc esi      ;change file pointer to next symbol after LF
    16.         mov pos, esi ;save file pointer
    17.         ret    
    18. gets endp
    MMX, SSE и др. технологии мне не нужны, т.к. пишу под такие компы, в которых их может и не быть:)
     
  2. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    ASMatik
    ты чё рихнулся?
    ты знаеш что у компов есть ресурс выроботки?
    года 4 назад в госучереждениях жизнь компа ровнялась 3 года и дальше он списывался!!!
    не знаю как сейчас, но где нет MMX - им минимум 8 лет!!
    ты что хочеш расхлёбывать железячные ошибки выробатывшихся компом ;)
    одумайся!! (пиво помогает)
     
  3. ASMatik

    ASMatik New Member

    Публикаций:
    0
    Регистрация:
    3 июл 2008
    Сообщения:
    27
    Пиво не помогло))) Вот сижу сейчас с пивного бодуна. Хз. Ок, тогда буду юзать MMX или SSE. Но как с помощью них можно это оптимизировать?

    Может быть для моей задачи MMX не очень то и нужен. Мне с помощью этой функции только конфиг и считывать. Причем не огромный а малюсенький
     
  4. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    wsd
    Не знаю - не знаю. Контора, для которой пишется мною аська, испокон веку сидит на четыреставосьмидесятниках и Офисе97. Хотя в принципе у нас здесь провинция...

    ЗЫ: щас будет б/м оптимизированный код
     
  5. 2FED

    2FED New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    1.002
    Компы работают вечно!

    ASMatik а нафига воабще что то оптимизировать если малый объём данных проходит? MMX и SSE это уже тяжелая артелерия, и у каждой набор инструкций если не больше обычного процессорново то не меньше точно.
     
  6. DEEP

    DEEP Андрей

    Публикаций:
    0
    Регистрация:
    27 апр 2008
    Сообщения:
    491
    Адрес:
    г. Владимир
    Вот. Не тестировалось, но работать должно. Если попрут баги, выложите, плиз, екзешник - погоняю под отладчиком, а то самому тестирующую прогу писать лень ;)

    Код (Text):
    1. ; <---- На вход также подаётся ESI как указатель на строку
    2. StoreString proc uses esi edi _s:DWORD;
    3.   MOV EDX, 0F5F5F5F5h; <---- NOT 0A0A0A0Ah
    4.   MOV ECX, -4;
    5.  
    6.   @loop:
    7.     ADD ECX, 4;
    8.     MOV EDI, DWORD PTR [ESI+ECX];
    9.  
    10.   ; <---- Здесь ищем терминирующий нуль
    11.   ; <---- Если этого не нужно - уберите
    12.   ; <---- этот блок и смените константу
    13.   ; <---- 0F5F5F5F5h снова на 0A0A0A0Ah
    14.     LEA EAX, [EDI-01010101h];
    15.     NOT EDI;
    16.     AND EAX, EDI;
    17.     AND EAX, 80808080h;
    18.   JNE @copy; <---- Найден нуль!
    19.  
    20.     XOR EDI, EDX;
    21.     LEA EAX, [EDI-01010101h];
    22.     NOT EDI;
    23.     AND EAX, EDI;
    24.     AND EAX, 80808080h;
    25.   JE @loop; <---- LF не найден. Идём дальше
    26.  
    27.   XOR EDX, EDX;
    28.  
    29.   @copy:
    30.   BSF EAX, EAX;
    31.   SHR EAX, 3;
    32.   LEA EDI, [EAX+ECX];
    33.  
    34.   MOV BYTE PTR [ESI+EDI], 0;
    35.   SHR ECX, 2;
    36.   ADD ECX, 1;
    37.   MOV EDI, _s;
    38.   REP MOVSD;
    39.   LEA ESI, [ESI+EAX-3]; <---- Ставим на следующий за найденным символ
    40.   MOV EAX, EDX; <---- EAX != 0 - достигнут завершающий нуль!
    41.   RET;
    42. StoreString endp;
    [+]:
    принцип работы таков:
    сканируется строчка из ESI, блоками по 4 байта, и проверяется на наличие символа 00h или 0Ah - что раньше встретится. Если встретился символ 0Ah - он заменяется на 00h, строка копируется в EDI блоками по 4 байта (поэтому возможны от 1 до 4 "лишних" символов после терминирующего нуля). Если найден 0 - то строка тоже копируется, но функция возвращает ненулевой результат.
     
  7. ASMatik

    ASMatik New Member

    Публикаций:
    0
    Регистрация:
    3 июл 2008
    Сообщения:
    27
    Ок, спасибо огромное. Попробую поковыряю еще. Там просто еще проблема в том, что все виндосские строки в файлах кончаются CR LF, т.е. 0Dh 0Ah. Мой код работает, он считывает строку до символа 0Dh и переводит указатель на следующий символ после 0Ah, а 0Dh заменяет на 0. Я просто хотел узнать стоит ли его еще оптимизировать и нет ли в нем каких либо ошибок или "скользких" мест