1

i´ve written a simple code to understand assemblercode. It´s the following:

    int sum(int a, int b){
        int res = a+b;
    }

And in the main-function I invoke the sum-function. So, and I get the assemblercode(I only take the part of sum function here)4

    push ebp,
    mov ebp, esp
    sub esp, 16
    mov eax, DWORD PTR[ebp + 12]
    mov edx, DWORD PTR[ebp + 8]
    add eax, edx
    mov DWORD PTR [ebp-4], eax
    mov eax, DWORD PTR [ebp-4]
    leave

and now to my questions. I have two questions about that: First, is there a reason why the values of the sum parameter, for example sum(5,4), are strored in ebp+12 and ebp+8 and the result in ebp-4 ? Why we do that? Is it always the same or are that randomly choosen?

Second, the part in which we have:

    mov DWORD PTR [ebp-4], eax
    mov eax, DWORD PTR [ebp-4]

why we do the result first in ebp-4 and then in eax again before we leave the function? Is there also a reason?

nrz
  • 10,435
  • 4
  • 39
  • 71
user3097712
  • 1,565
  • 6
  • 27
  • 49

2 Answers2

2

This is generally how the stack frame is created in x86 systems.

The caller will convert this to ...

push b
push a
call sum

As each item is pushed onto the stack, the stack grows down. That is, the stack-pointer register is decremented by four (4) bytes (in 32-bit mode), and the item is copied to the memory location pointed to by the stack-pointer register.

At this point in time, the 'call' instruction has been issued and we are now at the start of the called routine. If we want to access our parameters, we can access them like

[esp + 4]   - parameter 'a'
[esp + 8]   - parameter 'b'

However, this can get clumsy after we carve out space for local variables and stuff. So, we use a stackbase-pointer register in addition to the stack-pointer register. However, we want the stackbase-pointer register to be set to our current frame, and not the previous function. Thus, we save the old one on the stack (which modifies the offsets of the parameters on the stack) and then copy the current stack-pointer register to the stackbase-pointer register.

push ebp        ; save previous stackbase-pointer register
mov  ebp, esp   ; ebp = esp

Putting it all together. Parameters are accessed using the stackbase-pointer registe

[ebp + 12]  - parameter 'b'
[ebp + 8]   - parameter 'a'
[ebp + 4]   - return address
[ebp + 0]   - saved stackbase-pointer register

Source: What is stack frame in assembly?

Community
  • 1
  • 1
Madhur Ahuja
  • 22,211
  • 14
  • 71
  • 124
0

You can find this information by looking for keywords such as:

  • calling conventions
  • fastcall
  • stdcall

Back then, a 16bit word parameter would be passed with AX ( and32bit one ) in EAX. The return would be also AX/EAX. A 64bit parameter ( or 2 parameters would be in EDX:EAX ) and returned with same. That's for a typical FASTCALL calling convention (which I believe old Pascal was using )

Now for C/C++ fastcall is not typically use (maybe because it isn't as portable). Most everything used the stack and this is where EBP comes in to play. EBP being your base stack pointer -4, -8, -12 are just offset pointers in your local stack where parameter are stored and returned.

Here are a few links: http://en.wikibooks.org/wiki/X86_Disassembly/Calling_Convention_Examples http://en.wikipedia.org/wiki/X86_calling_conventions

Rastikan
  • 517
  • 5
  • 18