【问题标题】:Assembly loops loop too many times装配循环循环太多次
【发布时间】:2018-06-08 20:59:00
【问题描述】:

我对组装非常陌生(昨天开始学习)并且有循环问题:

下面的代码应该打印值 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";^^^

提前致谢。

附言如何使用语法高亮格式化代码?

【问题讨论】:

  • 可能cinvoke printf,formatstring,eax ;print eax 确实更改了ECX 寄存器,因为它被操作系统视为易失性。
  • 我会调查的
  • 是的,你的权利。谢谢!

标签: windows assembly x86 fasm


【解决方案1】:

ecx 是“调用者保存”寄存器之一,这意味着任何函数调用都可以修改ecx,调用者的工作是在必要时保存/恢复它。

See also:

根据绝大多数编译器遵循的英特尔 ABI,EAX、EDX 和 ECX 可以在过程或函数中免费使用,无需保留。

您在循环中对printf 的调用可能会破坏ecx

【讨论】:

    【解决方案2】:

    问题是cinvoke printf,formatstring,eax改变了ECX寄存器,正如zx485所指出的那样。事实证明,它还更改了EDX 寄存器。

    为了解决这个问题,我改为使用EBX 寄存器,它没有cinvoke printf,formatstring,eax 修改。

    我希望这对某人有所帮助。

    编辑:melpomene 发布了一个更好的答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-11
      • 2015-09-22
      • 1970-01-01
      • 2018-12-18
      • 1970-01-01
      相关资源
      最近更新 更多