如何在不破坏它的情况下输出 ecx 寄存器?

How to output ecx register without corrupting it?

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

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)

您没有正确平衡堆栈:

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

您已推送 3 DWORDs,即 12 个字节,但您只有 "popping" 8 个字节。

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