Getting procedure arguments from the stack

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

 PUSH 7 CALL FOOBAR MOV AH, 4CH INT 21H FOOBAR PROC POP AX ; Not 7 RET FOOBAR ENDP 
+1
source share
2 answers

The call instruction pushes the return address onto the stack, so when you pop ax in your procedure, it does not get the 7 you pressed, but the return address. ret won't work either (he expects to find the return address!) Try something like ...

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

There is a possible "booty." The β€œdistant” procedure has both a segment (cs) and an offset in the stack, so 4 bytes for the return address, and two bytes for push bp put the first parameter in [bp + 6] . I think that only proc by default - proc near - you can say it just for clarity. If you need proc far , it's probably time to finish the 32-bit code (or 64-bit). The 16-bit code is such a PITA - we are really happy to forget it! :)

+4
source

Here is the state of the stack when calling a procedure from the main one and passing two parameters with values ​​1 and 2, respectively:

  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 the registers are actually bp and sp, and the relative offsets are 0x4 and 0x6:

0
source

All Articles