从Stack获取过程参数

时间:2013-01-12 19:13:01

标签: assembly x86 procedure callstack

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

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

FOOBAR PROC
    POP AX ; Not 7
    RET
FOOBAR ENDP

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:0)

这是从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: