Getting Procedure Arguments from Stack

社会主义新天地 提交于 2020-01-05 07:19:39

问题


I am trying to learn how to call procedures in assembly language. Below is a simple example that shows my problem. I push 7 unto the stack, call the procedure; when the procudeure pops from the stack, the value is not the one I pushed. Can someone please help me understand what is happening and what I can do to make this work?

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

FOOBAR PROC
    POP AX ; Not 7
    RET
FOOBAR ENDP

回答1:


The call instruction puts the return address on the stack, so when you pop ax in your procedure, it doesn't get the 7 you pushed, but the return address. The ret won't work, either (it expects to find the return address there!) try something like...

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

There's a possible "gotcha" here. A "far" procedure has both the segment (cs) and offset on the stack, so 4 byes for the return address, and two bytes for the push bp puts the first parameter at [bp + 6]. I guess just proc defaults to proc near - you might want to say that, just for clarity. If you need a proc far it's probably time to graduate to 32-bit code (or 64-bit). 16-bit code is such a PITA - we're really glad to forget it! :)




回答2:


Here's the state of the stack when calling a procedure from main and passing two parameters with values respectively of 1 and 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

This code was taken from a 32 bit program, so registers are actually bp and sp and the relative offsets are 0x4 and 0x6:



来源:https://stackoverflow.com/questions/14296958/getting-procedure-arguments-from-stack

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!