3
votes

I am a newbie to assembly programming and i am trying to decode the assembly emitted by 64 but GNC Compiler (GCC).

void fun(int a, int b)
    {
    int h=0;
    }

    int main()
    {
    int d = 0;
    fun(d,10);
    }

The assembly for this is

.globl fun
    .def    fun;    .scl    2;  .type   32; .endef
fun:
    pushq   %rbp     #
    movq    %rsp, %rbp   #,
    subq    $16, %rsp    #,
    movl    %ecx, 16(%rbp)   # a, a
    movl    %edx, 24(%rbp)   # b, b
    movl    $0, -4(%rbp)     #, h
    leave
    ret
    .def    __main; .scl    2;  .type   32; .endef
.globl main
    .def    main;   .scl    2;  .type   32; .endef
main:
    pushq   %rbp     #
    movq    %rsp, %rbp   #,
    subq    $48, %rsp    #,
    call    __main   #
    movl    $0, -4(%rbp)     #, d
    movl    -4(%rbp), %eax   # d, tmp59
    movl    $10, %edx    #,
    movl    %eax, %ecx   # tmp59,
    call    fun  #
    leave
    ret

I have some doubts on this assembly.

[1] what is the exact arithmetic for subtracting 48 from stack pointer in main. [2] In fun, I believe the offset from base pointer to access the function argument starts from 16 (return address and base pointer that is two memory location into stack (stack frame being 8 bytes) , but why the next offset is 24 instead of 16.

    movl    %ecx, 16(%rbp)   # a, a
    movl    %edx, 24(%rbp)   # b, b

Why it is not: movl %ecx, 16(%rbp) # a, a movl %edx, 20(%rbp) # b, b

[3] What is the logic behind subtracting 16 from stack pointer in fun, when only one local variable is involved. Shouldnt be it 8?

Thanks.

1
I cannot reproduce your assembly no matter what options and version of gcc that I try: pastebin.com/Fa6TLqWC Compiler used: gcc.godbolt.org - Brandon

1 Answers

0
votes
  1. In general you can only guess why the compiler does what it does. In this case, optimizations are clearly not enabled, so the compiler presumably just allocates a worst-case stack frame that just doesn't get optimized down. You might want to try with optimizations enabled.
  2. rbp points to the pushed rbp on the stack, rbp+8 is the return address, rbp+16 is first argument, rbp+24 is second argument. Note that in 64 bit mode stack is used in 8 byte chunks.
  3. Presumably calling convention mandates 16 byte alignment.

For points [2] and [3] see the appropriate abi documentation.