汇编函数整数局部变量

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)

eph*_*ent 7

根据平台的不同,GCC可以选择不同的堆栈对齐方式; 这可以被覆盖,但这样做会使程序变慢或崩溃.默认情况下-mpreferred-stack-boundary=4,堆栈与16字节地址对齐.假设堆栈指针已经在函数的开头已经适当地对齐,它将在之后保持对齐sub %esp, $10.

leave是一个x86宏指令,相当于mov %ebp, %esp; pop %ebp.