Сборочные петли зацикливаются слишком много раз - PullRequest
0 голосов
/ 08 июня 2018

Я очень новичок в сборке (начал изучать вчера) и у меня проблема с циклами:

Код ниже должен напечатать значения 0-49, но вместо этого он печатает 0-49, а затем ~ 20 строк мусора (я предполагаю, что это часть стека, которую используют другие программы / другие части программы).Я ожидаю, что проблема заключается во втором цикле, .loop, поскольку он печатает неправильное количество строк, а печать обрабатывается .loop.

Я использую программу FASM (Flat Assembler) для компиляции этого.

Код:

format PE console
include "win32ax.inc"
start:
    mov ecx, 50 ;number of loops
    .mainloop: ;for testing purposes, just pushes 49-0 onto the stack
        push ecx ;push onto stack
        dec ecx ;decrement counter
        jnz .mainloop ;jump if counter not zero

    mov ecx, 50 ;reset ecx (counter)
    .loop: ;prints the stack, should print 0-49 but also prints garbage at the end
        pop eax ;pop from stack to eax
        cinvoke printf,formatstring,eax ;print eax
        dec ecx ;decrement counter
        jnz .loop ;loop if counter not zero
    int 15;wait 5 seconds ish
    invoke ExitProcess ;exit

formatstring    db "%d",13,10,0 ;to print digits instead of ASCII chars

section '.idata' import data readable ;stuff I copied but seems to work
    library msvcrt,'msvcrt.dll',\ ;don't understand it
        kernel32,'kernel32.dll'   ;^
    import  msvcrt,printf,'printf';^^
    import  kernel32,ExitProcess,"ExitProcess";^^^

Заранее спасибо.

пс Как отформатировать код с подсветкой синтаксиса?

Ответы [ 2 ]

0 голосов
/ 09 июня 2018

ecx является одним из регистров, «сохраненных вызывающим абонентом», это означает, что любой вызов функции может изменить ecx, и задача вызывающего - сохранить / восстановить его при необходимости.

См.также :

Согласно Intel ABI, которому соответствует подавляющее большинство компиляторов, EAX, EDX и ECX должны быть бесплатными для использования в процедуре или функции и не должныбыть сохраненным.

Ваш звонок на printf в цикле, вероятно, обрушится ecx.

0 голосов
/ 09 июня 2018

Проблема в том, что cinvoke printf,formatstring,eax изменяет регистр ECX, как указано в zx485.Оказывается, он также изменяет регистр EDX.

Чтобы исправить это, я изменил на использование регистра EBX, который не изменен cinvoke printf,formatstring,eax.

Надеюсь, это кому-нибудь поможет.

РЕДАКТИРОВАТЬ: melpomene опубликовал гораздо лучший ответ.

...