分析汇编代码

时间:2010-10-26 04:24:29

标签: 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)"

这是从这个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;
}

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

$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

理想情况下,列表(1)和(2)必须相同。但我明白了 在清单(1)中有movl,pushl等,而mov,push in lising(2)。我的问题是:

  1. 哪个是在处理器上实际执行的正确汇编指令?
  2. 在清单(1)中,我在开头看到了这个:
  3. .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 
    

    ,最后结束:

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

    这是什么意思?

    感谢。

2 个答案:

答案 0 :(得分:13)

无论使用何种变体,该指令都称为MOVl后缀只是一个gcc / AT&amp; T汇编约定,用于指定所需操作数的大小,在本例中为4个字节的操作数。

在英特尔语法中 - 存在任何歧义 - 而不是为指令添加后缀通常用内容参数标记所需大小(例如BYTEWORD,{{1等等,这只是实现同样事情的另一种方式。

DWORD89 55从32位寄存器MOV到32位寄存器EBP的正确字节序列。两个列表都没有错。


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

ESP

表示.file "test.c" 是一个全局符号(带有外部链接的C变量):

accum

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

bss

在4字节边界上对齐:

       .bss

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

       .align 4

这是四个字节:

       .type accum, @object

这里定义了 .size accum, 4 ,四个零字节。

accum

现在从 accum: .zero 4 部分切换到通常存储功能的文本部分。

bss

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

       .text

.p2align 2,,3 是一个全局符号,它是一个函数。

sum

.globl sum .type sum, @function 的尺寸为“此处” - “main开始的地方”:

main

指定gcc特定堆栈选项的位置。通常,您可以选择使用可执行堆栈(不是非常安全)或不使用(通常是首选)。

.size main, .-main

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

       .section .note.GNU-stack,"",@progbits

答案 1 :(得分:0)

汇编程序列表和反汇编程序列表显示相同的代码,但使用不同的语法。附加的-l是gcc使用的语法变体。你在工具中有不同的语法(C编译器输出和反汇编程序)显示你的工具链的弱点。

在sum中偏移量为11的反汇编:显示了一些垃圾字节。下一个函数main的入口点是4字节对齐的,它给出了这个间隙,填充了垃圾。

一堆.statements由汇编程序的文档定义。通常他们不提供任何可执行代码。