mas*_*wok 2 linux x86 assembly
我正在努力学习基本装配.我用C编写了一个简单的程序来翻译成汇编:
void myFunc(int x, int y) {
int z;
}
int main() {
myFunc(20, 10);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这就是我认为函数的正确翻译将是:
.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
Run Code Online (Sandbox Code Playgroud)
只是为了仔细检查它我在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.
Run Code Online (Sandbox Code Playgroud)
当整数长度为4个字节时,为什么在0x08048377时gcc从堆栈中减去0x10(16个字节)?
此外,休假指令是否等同于以下内容?
movl %ebp, %esp #Restore esp
popl %ebp #Set ebp to 0?
Run Code Online (Sandbox Code Playgroud)
使用:
gcc version 4.3.2 (Debian 4.3.2-1.1)
GNU gdb 6.8-debian
Run Code Online (Sandbox Code Playgroud)
根据平台的不同,GCC可以选择不同的堆栈对齐方式; 这可以被覆盖,但这样做会使程序变慢或崩溃.默认情况下-mpreferred-stack-boundary=4
,堆栈与16字节地址对齐.假设堆栈指针已经在函数的开头已经适当地对齐,它将在之后保持对齐sub %esp, $10
.
leave
是一个x86宏指令,相当于mov %ebp, %esp; pop %ebp
.