了解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

上一篇: Understanding Assembly language output of a C program

下一篇: stack frame align to different size?