Я пытаюсь выучить базовую сборку. Я написал простую программу на C для перевода в сборку:
void myFunc(int x, int y) {
int z;
}
int main() {
myFunc(20, 10);
return 0;
}
Это то, что я думал, что правильный перевод функции будет:
.text
.globl _start
.type myFunc, @function
myFunc:
pushl %ebp #Push old ebp register on to stack
movl %esp, %ebp #Move esp into ebp so we can reference vars
sub $4, %esp #Subtract 4 bytes from esp to make room for 'z' var
movl $2, -4(%ebp) #Move value 2 into 'z'
movl %ebp, %esp #Restore esp
popl %ebp #Set ebp to 0?
ret #Restore eip and jump to next instruction
_start:
pushl $10 #Push 10 onto stack for 'y' var
pushl $20 #Push 20 onto stack for 'x' var
call myFunc #Jump to myFunc (this pushes ret onto stack)
add $8, %esp #Restore esp to where it was before
movl $1, %eax #Exit syscall
movl $0, %ebx #Return 0
int $0x80 #Interrupt
Просто чтобы дважды проверить это, я запустил его в GDB и был смущен результатами:
(gdb) disas myFunc
Dump of assembler code for function myFunc:
0x08048374 <myFunc+0>: push ebp
0x08048375 <myFunc+1>: mov ebp,esp
0x08048377 <myFunc+3>: sub esp,0x10
0x0804837a <myFunc+6>: leave
0x0804837b <myFunc+7>: ret
End of assembler dump.
Почему в 0x08048377 gcc вычел из стека 0x10 (16 байтов), когда целое число имеет длину 4 байта?
Кроме того, инструкция по отпуску эквивалентна следующей?
movl %ebp, %esp #Restore esp
popl %ebp #Set ebp to 0?
Использование:
gcc version 4.3.2 (Debian 4.3.2-1.1)
GNU gdb 6.8-debian