views:

105

answers:

3

hi,

i have philosophised about the purpose of stack a little bit and after some coding i figured out what is it's strength. The only thing that lies in my stomache is how does it work with functions? I tried to make some easy function for adding two numbers using universal registers but I suppose that's not how does it work in C for example.. where are all the parameters, local variables and where is the result stored?

how would you rewrite this to assembler?(how would compiler for C rewrite it?)

int function(int a, int &b, int *c){
 return a*(b++)+(*c);
}

i know this example kinda sucks.. but this way i can understand all the possibilities

+4  A: 

What you are looking for is information about calling conventions. The way that functions are called and returned is dependent on many things, including processor architecture, compiler, and operating system. The caller and the callee must agree on the convention in order for parameters and the return value to be passed correctly.

Aaron Klotz
Calling conventions are also known as an Application Binary Interface (ABI) http://en.wikipedia.org/wiki/Application_binary_interface.
Mike DeSimone
mmm, cool indeed. thx
stupid_idiot
+2  A: 

What Aaron said about calling conventions is the correct answer. For my own personal exploration of the topic I have found Smashing the Stack For Fun and Profit to be a great exercise in the role of a stack frame and what can happen when it becomes corrupted. Finlay I recommend the assembly primer for hackers which goes over important assembler concepts as well as fun things you can do with your debugger.

Rook
maaan!!! that video... huaaaahh!! explained everything, even those frustrating segment registers are now clear to me! T H X A L O T!!!
stupid_idiot
Haha, I'm happy to help.
Rook
+4  A: 

First off, references (int&) aren't in C, just C++.

If you want to see what's happening under the hood with gcc, use the -S flag. You don't need to have an actual program.

g++ -S func.c

creates a file func.s which contains (minus headers and such, on an x86 box):

    .text
.globl __Z8functioniRiPi
__Z8functioniRiPi:
LFB2:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
    movl    %edi, -4(%rbp)
    movq    %rsi, -16(%rbp)
    movq    %rdx, -24(%rbp)
    movq    -16(%rbp), %rax
    movl    (%rax), %edx
    movl    %edx, %ecx
    imull   -4(%rbp), %ecx
    movq    -24(%rbp), %rax
    movl    (%rax), %eax
    addl    %eax, %ecx
    incl    %edx
    movq    -16(%rbp), %rax
    movl    %edx, (%rax)
    movl    %ecx, %eax
    leave
    ret

Note the C++ name mangling (__Z8functioniRiPi). Now we give g++ the -O2 flag:

    .text
    .align 4,0x90
.globl __Z8functioniRiPi
__Z8functioniRiPi:
LFB2:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
    movl    (%rsi), %ecx
    movl    %ecx, %eax
    imull   %edi, %eax
    addl    (%rdx), %eax
    incl    %ecx
    movl    %ecx, (%rsi)
    leave
    ret

-O3 gives the same code; there's not really anything else to optimize.

Have fun playing around with assembly. ^_^

Mike DeSimone