Вопрос про LOOP :/

Тема в разделе "WASM.BEGINNERS", создана пользователем LOL, 28 апр 2006.

  1. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    Здравствуйте.

    По идее прога должна выводить в консоль 10 раз знак "!", а затем завершить свою работу. В ecx помещаю желаемое кол-во итераций, но "!" выводится всего 1 раз :dntknw: Посмотрел в pdf-ке про loop там тоже "что-то" (англ. знаю плохо =) про ecx...

    Да и в ДОСе вроде бы в cx...

    З.Ы. если поместить push ...&call [GetStdHandle] в тело цикла, то "!" выводиться почему-то 8 раз :/

    З.З.Ы А если в olly смотреть, то цикл выполняется 8 раз всегда, независимо от ecx... бр-р-р... нич-ч-чего не понятно мне :/

    ;------------------------------------------------

    format PE console

    include '\include\win32a.inc'

    entry start



    section '.data' data readable writeable

    msg db "!", 13, 10, 0



    section '.code' code readable executable

    start:

    push STD_OUTPUT_HANDLE

    call [GetStdHandle]



    mov ecx, 3

    lbl1:



    push 1

    push msg

    push eax

    call [WriteConsole]



    loop lbl1



    push 0

    call [ExitProcess]



    section '.import' import data readable

    library kernel32, 'kernel32'

    include '\include\apia\kernel32.inc'

    ;------------------------------------------------
     
  2. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Вызов WriteConsole может портить ecx, поэтоиу его лучше сохранять в стеке, а потом извлекать. Стоит также проверить, не портится ли eax.
     
  3. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    Вах... если судить по Olly то портится все и вся :) Сйечас в оффе попробую... Спасибо!
     
  4. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    Вот в таком виде работает. Пришлось запушить 2 нуля в стэк. (\include\pcount\kernel32.inc :))Надо, наверное, в MSDN про WriteConsole посмотреть.

    [add] А вообще стоило мне на форуме поискать :) - WASM Phorum —› WASM.WIN32 —› Организация циклов при вызове API [/add]

    ;------------------------------------------------

    format PE console

    include '\include\win32a.inc'

    entry start



    section '.data' data readable writeable

    msg db "!", 13, 10, 0



    section '.code' code readable executable

    start:

    push STD_OUTPUT_HANDLE

    call [GetStdHandle]



    mov ecx, 3

    lbl1:

    push ecx

    push eax



    push 0

    push 0

    push 3

    push msg

    push eax

    call [WriteConsole]



    pop eax

    pop ecx



    loop lbl1



    push 0

    call [ExitProcess]



    section '.import' import data readable

    library kernel32, 'kernel32'

    include '\include\apia\kernel32.inc'

    ;------------------------------------------------
     
  5. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Для счетчика и хэндла консоли лучше использовать регистры ebx, esi, edi, т.к. они не изменяются api-функциями. Соответственно, нет необходимости на каждом проходе цикла сохранять их и снова считывать. ebx, esi, edi тоже нужно сохранять, но это делается один раз перед началом цикла.


    Код (Text):
    1.     pushad
    2.     push    STD_OUTPUT_HANDLE
    3.     call    [GetStdHandle]
    4.     mov     ebx,eax
    5.     mov     esi,10
    6. lbl1:
    7.     push    0
    8.     push    0
    9.     push    3
    10.     push    msg
    11.     push    ebx
    12.     call    [WriteConsole]
    13.     dec     esi
    14.     jnz     lbl1
    15.     popad
    16.     push    0
    17.     call    [ExitProcess]




    Компиляторы в качестве счётчика не используют ecx, если есть вызовы апи в цикле.
     
  6. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    Понял =) Спасибо!
     
  7. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    LOL

    ИМХО лучше вообще забыть о существовании инструкции LOOP :)

    Выигрыш в размере кода - один "несчастный" байт по сравнению с dec+jnz, а потери в скорости могут быть в разы. На всех современных процессорах LOOP - сложная инструкция (микропрограмма), состоящая не менее чем из 8-9 микроопераций. Соответственно, декодируется она не менее 3-х тактов (как 9 простых инструкций) и исполняется не менее 8-и. А парочка dec+jnz может декодироваться за один такт и выполняется за 2



    PS: для оформления кода в сообщении используй тег
    Код (Text):
    1.  - места меньше занимает, читать удобнее, да и по Правилам положено ;)
     
  8. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    Спасибо =) Я этот LOOP в ДОСе юзал, когда немного под ним кодил =) А про
    Код (Text):
    1.  я как-то забыл :/
     
  9. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    leo



    Выйгрыш от loop ещё в том, что перед входом в цикл можно использовать jecxz, т.е. общий выйгрыш = 3 байта, если нет уверенности, что счётчик всегда инициализируется != 0.
     
  10. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    Так... я не понял, стоит ли его использовать и если "да", то при каких условиях. Я, конечно, понимаю, что либо "код меньше", либо "код быстрее работает". Не всегда конечно...
     
  11. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    С точки зрения оптимизации по скорости - не стоит, однозначно!
     
  12. LOL

    LOL New Member

    Публикаций:
    0
    Регистрация:
    28 апр 2006
    Сообщения:
    175
    Адрес:
    Russia
    ok. thx!