【问题标题】:Getting Procedure Arguments from Stack从堆栈中获取过程参数
【发布时间】:2012-12-27 03:28:14
【问题描述】:

我正在尝试学习如何用汇编语言调用程序。下面是一个显示我的问题的简单示例。我将7 推入堆栈,调用程序;当程序从堆栈中弹出时,该值不是我推送的那个。有人可以帮我了解正在发生的事情以及我可以做些什么来完成这项工作吗?

PUSH 7
CALL FOOBAR
MOV AH, 4CH
INT 21H

FOOBAR PROC
    POP AX ; Not 7
    RET
FOOBAR ENDP

【问题讨论】:

    标签: assembly x86 procedure callstack


    【解决方案1】:

    call 指令将返回地址放入堆栈,因此当您在过程中使用pop ax 时,它不会获得您推送的 7,而是返回地址。 ret 也不起作用(它希望在那里找到返回地址!)尝试类似...

    FOOBAR proc
    push bp ; save caller's reg
    mov bp, sp
    mov ax, [bp + 4]
    ; do something with it
    ; leave - equivalent to:
    mov sp, bp
    pop bp
    
    ret
    

    这里有一个可能的“陷阱”。 “远”过程在堆栈上同时具有段 (cs) 和偏移量,因此返回地址为 4 个字节,push bp 的两个字节将第一个参数置于[bp + 6]。我猜只是 proc 默认为 proc near - 你可能想说,只是为了清楚起见。如果您需要proc far,可能是时候升级到 32 位代码(或 64 位)了。 16 位代码就是这样一个 PITA - 我们真的很高兴忘记它! :)

    【讨论】:

      【解决方案2】:

      这是从 main 调用过程并传递两个参数值分别为 1 和 2 的堆栈的状态:

                    Address    : Value
                    ----------------------
                    0xbffff3b0 : 0x0011e030
                    0xbffff3b4 : 0x08049ff4
            esp --> 0xbffff3b8 : 0xbffff3e8
                    0xbffff3bc : 0x08048419
                    0xbffff3c0 : 0x00284324
                    0xbffff3c4 : 0x00000003
            ebp --> 0xbffff3c8 : 0xbffff3e8 <-- old ebp
                    0xbffff3cc : 0x080483e5 <-- return address
      ebp + 0x8 --> 0xbffff3d0 : 0x00000001 <-- first parameter
      ebp + 0xc --> 0xbffff3d4 : 0x00000002 <-- second parameter
                    0xbffff3d8 : 0x0804840b
                    0xbffff3dc : 0x00283ff4
      

      这段代码取自 32 位程序,所以寄存器实际上是 bp 和 sp,相对偏移量是 0x4 和 0x6:

      【讨论】:

        猜你喜欢
        • 2020-06-13
        • 1970-01-01
        • 1970-01-01
        • 2016-10-04
        • 2013-05-20
        • 1970-01-01
        相关资源
        最近更新 更多