分析汇编代码

Onk*_*jan 8 c assembly

 $ gcc -O2 -S test.c -----------------------(1)
      .file "test.c"
    .globl accum
       .bss
       .align 4
       .type accum, @object
       .size accum, 4
    accum:
       .zero 4
       .text
       .p2align 2,,3
    .globl sum
       .type sum, @function
    sum:
       pushl %ebp
       movl  %esp, %ebp
       movl  12(%ebp), %eax
       addl  8(%ebp), %eax
       addl  %eax, accum
       leave
       ret
       .size sum, .-sum
       .p2align 2,,3
    .globl main
       .type main, @function
    main:
       pushl %ebp
       movl  %esp, %ebp
       subl  $8, %esp
       andl  $-16, %esp
       subl  $16, %esp
       pushl $11
       pushl $10
       call  sum
       xorl  %eax, %eax
       leave
       ret
       .size main, .-main
       .section .note.GNU-stack,"",@progbits
       .ident   "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-9)"
Run Code Online (Sandbox Code Playgroud)

这是从这个C程序生成的汇编代码:

#include <stdio.h>
int accum = 0;

int sum(int x,int y)
{
   int t = x+y;
   accum +=t;
   return t;
}

int main(int argc,char *argv[])
{
   int i = 0,x=10,y=11;
   i = sum(x,y);
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

另外,这是从上面的程序生成的目标代码:

$objdump -d test.o -------------------------(2) 

test.o:     file format elf32-i386

Disassembly of section .text:

00000000 <sum>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   8b 45 0c                mov    0xc(%ebp),%eax
   6:   03 45 08                add    0x8(%ebp),%eax
   9:   01 05 00 00 00 00       add    %eax,0x0
   f:   c9                      leave
  10:   c3                      ret
  11:   8d 76 00                lea    0x0(%esi),%esi

00000014 <main>:
  14:   55                      push   %ebp
  15:   89 e5                   mov    %esp,%ebp
  17:   83 ec 08                sub    $0x8,%esp
  1a:   83 e4 f0                and    $0xfffffff0,%esp
  1d:   83 ec 10                sub    $0x10,%esp
  20:   6a 0b                   push   $0xb
  22:   6a 0a                   push   $0xa
  24:   e8 fc ff ff ff          call   25 <main+0x11>
  29:   31 c0                   xor    %eax,%eax
  2b:   c9                      leave
  2c:   c3                      ret
Run Code Online (Sandbox Code Playgroud)

理想情况下,列表(1)和(2)必须相同.但我看到列表(1)中有movl,pushl等,而mov,push in lising(2).我的问题是:

  1. 哪个是在处理器上实际执行的正确汇编指令?
  2. 在清单(1)中,我在开头看到这个:

.file "test.c"
    .globl accum
       .bss
       .align 4
       .type accum, @object
       .size accum, 4
    accum:
       .zero 4
       .text
       .p2align 2,,3
    .globl sum
       .type sum, @function 
Run Code Online (Sandbox Code Playgroud)

最后这个:

.size main, .-main
           .section .note.GNU-stack,"",@progbits
           .ident   "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-9)"
Run Code Online (Sandbox Code Playgroud)

这是什么意思?

谢谢.

CB *_*ley 13

MOV无论使用何种变体,都会调用该指令.该l后缀是只是一个gcc/AT&T组件惯例来指定所希望的操作数的大小,在这种情况下4个字节的操作数.

在Intel语法-哪里有什么歧义-而不是后面添加的指令,通常与所需的大小(例如一个指标来标记内存参数BYTE,WORD,DWORD,等),这是实现同样的事情的另一种方式.

89 55MOV从32位寄存器EBP到32位寄存器的正确字节序列ESP.列表中没有任何错误.


指定生成此汇编代码的文件:

.file "test.c"
Run Code Online (Sandbox Code Playgroud)

说这accum是一个全局符号(带外部链接的C变量):

    .globl accum
Run Code Online (Sandbox Code Playgroud)

以下字节应放在一个bss部分中,这是一个在目标文件中不占用空间但在运行时分配和归零的部分.

       .bss
Run Code Online (Sandbox Code Playgroud)

在4字节边界上对齐:

       .align 4
Run Code Online (Sandbox Code Playgroud)

它是一个对象(一个变量,而不是一些代码):

       .type accum, @object
Run Code Online (Sandbox Code Playgroud)

这是四个字节:

       .size accum, 4
Run Code Online (Sandbox Code Playgroud)

这是accum定义的位置,四个零字节.

    accum:
       .zero 4
Run Code Online (Sandbox Code Playgroud)

现在切换bss到通常存储函数的文本部分.

       .text
Run Code Online (Sandbox Code Playgroud)

添加最多三个字节的填充以确保我们处于4字节(2 ^ 2)边界:

       .p2align 2,,3
Run Code Online (Sandbox Code Playgroud)

sum 是一个全球性的象征,它是一个功能.

    .globl sum
       .type sum, @function 
Run Code Online (Sandbox Code Playgroud)

大小main是"这里" - "从哪里main开始":

.size main, .-main
Run Code Online (Sandbox Code Playgroud)

这些是指定gcc特定堆栈选项的位置.通常,这是您选择具有可执行堆栈(不是非常安全)或不具有(通常是首选)的地方.

       .section .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)

确定编译器生成此程序集的版本:

       .ident   "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-9)"
Run Code Online (Sandbox Code Playgroud)