【问题标题】:How to output ecx register without corrupting it?如何在不损坏的情况下输出 ecx 寄存器?
【发布时间】:2015-04-17 06:04:03
【问题描述】:

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

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)

【问题讨论】:

    标签: assembly nasm cpu-registers


    【解决方案1】:

    你没有正确平衡堆栈:

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

    您已经推送了 3 个DWORDs,即 12 个字节,但您只“弹出”了 8 个字节。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-27
      • 2014-12-11
      • 2021-12-05
      • 1970-01-01
      • 1970-01-01
      • 2011-09-29
      • 2010-09-27
      相关资源
      最近更新 更多