【发布时间】:2011-01-28 17:51:31
【问题描述】:
所以...我正在使用 gcc -S -O2 -m32 编译成汇编程序:
void h(int y){int x; x=y+1; f(y); f(2); }
它给了我以下信息:
.file "sample.c"
.text
.p2align 4,,15
.globl h
.type h, @function
h:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call f
movl $2, 8(%ebp)
leave
jmp f
.size h, .-h
.ident "GCC: (GNU) 4.4.3 20100127 (Red Hat 4.4.3-4)"
.section .note.GNU-stack,"",@progbits
现在我知道什么是 pushl 和 movel:它们将当前帧指针存储到堆栈中,然后将帧指针寄存器的值设置为堆栈指针的值。
- 但我不知道 subl $24, %esp 是什么。我知道它将堆栈指针向下移动了 24 个字节。正确吗?
- 顺便说一下什么?
- 为什么 movl 8(%ebp), %eax 使用 8?是8个字节吗?这是为了适应 h 的返回值 + 参数 y 吗?还是我完全离开这里。所以这意味着从堆栈指针回溯 8 个字节?
- movl $2, 8(%ebp) 有什么作用?它将 contant 2 复制到帧指针前 8 个字节的位置。当我们调用 f 时,帧指针是否发生了变化?如果是,则 8(%ebp) 指向 f 的参数位置。
- 请假有什么用?它如何“删除”堆栈帧?我的意思是你不能只删除一段记忆。在文档中它说它确实 mov(esp, ebp), pop ebp。
谢谢!
【问题讨论】:
-
有趣的是,下面的答案被标记为已接受,尽管它实际上并没有对问题 1 做出解释。Here 是另一个对问题 1 进行解释的问题/答案。
标签: assembly