Search code examples
clinuxassemblyx86-64stack-pointer

Making a space for local variables in assembly


So I do have to write an assembly program which would call extern C function. So I wrote simple pow function, I compiled my assembly program with this C code. Everything works. But as I saw from -S command from gcc, the compiler makes a space for local variables. I thought it would be like this:

int func(int number)
{
    int a = 10;
    int b = 5;
    int c = 0;
}

We have 3 local variables, so the compiler would subl $12, %esp. But it goes for subl $16, %esp. Even if I only left one number here, still it would decrement by 16. Now I have my code:

main.s:

.section .data
.XD:
    msg: .ascii "%d\n"
    msg_len = . - msg

.text
.globl _pow
.globl main

main:
    pushl   %ebp
    movl    %esp, %ebp
    movl $5, %eax #like int a = 5;
    pushl %eax 
    call _pow #_pow(a);
    movl %eax, -8(%ebp)
    pushl -8(%ebp)
    pushl $.XD
    call printf #printf("%d\n", _pow(a));
    movl $0, %eax
    leave
    ret

func.c:

int _pow(int number)
{
    return number * number;
}

It works as expected, ./main prints out 25. But now, I don't subl anything from %esp. I mean I can add this line, but it doesn't change anything. I've searched through the internet and I found out that maybe my code works just by accident and generally I should decrement %esp. So my question here is: By what value should I decrement %esp in main? Should it be 12 or maybe 16?


Solution

  • Since you are calling a 32-bit C function you have to follow the C calling convention. Unlike for 64-bit systems there is no explicit order for aligning the stack. I couldn't find a statement when such an alignment should take place. The stack might be "misaligned" after pushing the parameters.

    If you want to align the stack you can simply AND -16 after you saved it (movl %esp, %ebp):

    andl $-16, %esp                ; Align 16