在汇编循环中调用_printf,只输出一次

时间:2012-03-25 07:06:03

标签: c gcc assembly x86

我正在学习装配,我在这里有一个非常基本的循环

segment .data
    msg: db '%d',10,0

segment .text

    global  _asm_main
    extern _printf

_asm_main:

    push DWORD 5 ; Should loop 5 times
    call dump_stack
    add esp,4

    ret

dump_stack:
    push ebp
    mov ebp, esp

    mov ecx, 0

loop_start:
    cmp ecx,[ebp+8] ;compare to the first param of dump_stack, (5)
    jnle loop_end

    push ecx ;push the value of my loop onto the stack
    push DWORD msg ;push the msg (%d) should just print the value of my loop
    call _printf
    add esp, 8 ;clear the stack

    inc ecx ;increment ecx
    jmp loop_start ; go back to my loop start

loop_end:

    mov esp, ebp
    pop ebp
    ret

我的输出看起来像这样

  

的Program.exe
  0

只是0,然后换行。我试图通过将我的printf移动到loop_end部分来验证循环正在执行,并且ecx为6,这是正确的。所以循环正在执行但是printf不是......我做错了什么?

(此外,该函数被称为转储堆栈,因为它最初应该转储堆栈的详细信息,但由于相同的原因,这不起作用)

我正在使用nasm -f win32 program.asm -o program.o进行编译 然后我有一个包含windows.h的cpp文件,我用gcc -c include编译它 最后我将它们与gcc -o program program.o include.o联系起来 然后我运行program.exe

1 个答案:

答案 0 :(得分:0)

我的猜测是printf()修改了ecx,它变成了> = [ebp+8],你的循环体只执行一次。如果是这种情况,您需要阅读编译器中使用的调用约定并手动保留和恢复所谓的易失性寄存器(被调用的函数可以自由修改而无需恢复)。请注意,可能有几种不同的调用约定。使用调试器!