如何输出ecx寄存器而不会破坏它?

时间:2015-04-17 06:04:04

标签: assembly nasm cpu-registers

学习如何迭代命令行参数,我想像这样输出

  

arg [0]:cmdl
  arg [1]:d:/test.src
  arg [2]:foo

在循环中我推送eax,epb和ecx,然后输出arg值。然后弹出3个寄存器,增加ecx,清理堆栈等等。

我在.bss中保留了一个变量:

c:   resd    1

这是我的循环结构:

.do:
    push    ebp
    push    eax
    push    ecx

    mov     [c],    ecx

    push    DWORD   [ebx]
    push    DWORD   [c]
    push    marg
    call    _printf
    add     esp,    8       ; clean up stack

    pop     ecx
    pop     eax
    pop     ebp

    add     ebx,    4       ; move to next arg
    inc     ecx             ; increment counter

    cmp     ecx,    eax
    jne     .do

在.data部分中,marg定义如下:

marg:       db  "arg[%d]: %s", 10, 0

这是我当前的输出,应用程序死了:

  

arg [0]:cmdl
  arg [7020225]:d:/test.src
  arg [7019969]:foo
  arg [7019929] :( null)

1 个答案:

答案 0 :(得分:4)

你没有正确平衡堆栈:

push    DWORD   [ebx]
push    DWORD   [c]
push    marg
...
add     esp,    8       <-- This is wrong

你已经推了3 DWORD s,这是12个字节,但你只是&#34;弹出&#34; 8个字节。

所发生的事情是,当您执行push DWORD [ebx]时,放在ecx堆栈中的字符串指针最终会显示在pop ecx中。所以现在ecx被搞砸了,这就是为什么你在打印输出中得到那些大的参数数字,以及为什么循环永远不会终止。