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
?
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