了解C程序的汇编语言输出
#include <stdio.h>
static int i = 100;
/* Declard as extern since defined in hello.c */
extern int global;
int function(char *input)
{
printf("%sn", input);
return global;
};
.file "foo.c"
.data
.align 4
.type i, @object
.size i, 4
i:
.long 100
.text
.globl function
.type function, @function
function:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call puts
movl global, %eax
leave
ret
.size function, .-function
.ident "GCC: (Debian 4.4.5-8) 4.4.5"
.section .note.GNU-stack,"",@progbits
这是什么原因:
subl $ 24,%esp
为什么他通过将堆栈指针递减24字节来为堆栈中的本地变量创建空间? 函数中没有局部变量。 然后他做到了:
movl%eax,(%esp)
为什么 - 因为存储在ebp + 8中的值(指针char *输入)被移动到了eax,现在应该被传递给puts ..但是为什么他会先执行subl - 要存储int的返回值? 但是,这是4个字节。我也读过C不支持调用函数必须在堆栈上为返回值创建空间(重新发布问题)。 这里发生了什么事情:(他可能会将字符边界上的指针参数对齐,但是SysV I386 ABI表示使用了尾部填充。
也,
movl%esp,%ebp
意味着esp和ebp都将指向新功能堆栈框架的基础。 但是,假设有一个“呼叫功能”; 考虑堆栈:你会有:
pushl ptr //push char *ptr
call function
{
pushl ebp So stack contains:
ptr
ret-value
ebp
->with-esp-pointing-to-after-ebp
(ESP always points to the top of the stack but after the last pushed
element..?)
所以他正在设置ebp。 但是,在pg36,SysV ABI I386架构处理器增补4E的ABI规范中,他说:0(%ebp)以前的%ebp(可选)我在猜测:%ebp + 0指向以前的ebp但是正如您所见,ebp + 0实际上指向存储的前一个ebp之后..
在另一个程序中,
andl $-16, %esp
subl $32, %esp
所以他第一次提醒ESP4的最后4位。呃给他多少空间? 然后subl ..
有人可能会建议一个体面的教程或书本..我不想掌握大会,只是想了解一点ABI规范和对齐和GOT / PLT /虚拟寻址和编译器/链接器的东西 - symbolTable / relocation等(我使用Levine书籍,但它很庞大 - 虽然有趣,但COFF和IBM / Sparc的东西:(这就是为什么我开始使用ABI规范。还有Ian Wienand的网站:从底部开始的计算机科学。)
链接地址: http://www.djcxy.com/p/80343.html