首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >汇编代码分析

汇编代码分析
EN

Stack Overflow用户
提问于 2010-10-26 04:24:28
回答 2查看 5K关注 0票数 8
代码语言:javascript
复制
 $ 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程序生成的程序集代码:

代码语言:javascript
复制
#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;
}

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

代码语言:javascript
复制
$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在lising (2)中有推送。我的问题是:

  1. 是在清单(1)中的处理器?
  2. 上实际执行的正确的程序集指令,我在开头看到这一点:

代码语言:javascript
复制
.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 

最后这一点:

代码语言:javascript
复制
.size main, .-main
           .section .note.GNU-stack,"",@progbits
           .ident   "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-9)"

这是什么意思?

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-10-26 04:40:21

无论使用什么变体,指令都被称为MOVl后缀只是一个gcc / AT&T程序集约定,用于指定所需操作数的大小,在本例中为4个字节操作数。

在英特尔语法中--如果有任何歧义--通常不会在指令后缀上加上所需大小的指示器(例如BYTEWORDDWORD等)来标记内存参数,这只是实现相同目标的另一种方式。

89 55MOV从32位寄存器EBP到32位寄存器ESP的正确字节序列。这两份清单都没有错。

指定从此程序集代码生成的文件:

代码语言:javascript
复制
.file "test.c"

表示accum是一个全局符号(具有外部链接的C变量):

代码语言:javascript
复制
    .globl accum

下面的字节应该放在bss部分中,这是一个在对象文件中不占用空间但在运行时被分配和归零的节。

代码语言:javascript
复制
       .bss

在4字节边界上对齐:

代码语言:javascript
复制
       .align 4

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

代码语言:javascript
复制
       .type accum, @object

它是四个字节:

代码语言:javascript
复制
       .size accum, 4

这里是定义accum的地方,四个零字节。

代码语言:javascript
复制
    accum:
       .zero 4

现在从bss部分切换到文本部分,这是函数通常存储的地方。

代码语言:javascript
复制
       .text

加三个字节的填充以确保我们位于一个4字节(2^2)的边界上:

代码语言:javascript
复制
       .p2align 2,,3

sum是一个全局符号,它是一个函数。

代码语言:javascript
复制
    .globl sum
       .type sum, @function 

main的大小是“这里”-“main开始的地方”:

代码语言:javascript
复制
.size main, .-main

其中指定了gcc特定的堆栈选项。通常,这是您选择具有可执行堆栈(不太安全)或不(通常首选)的地方。

代码语言:javascript
复制
       .section .note.GNU-stack,"",@progbits

标识生成此程序集的编译器的哪个版本:

代码语言:javascript
复制
       .ident   "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-9)"
票数 13
EN

Stack Overflow用户

发布于 2010-10-26 04:50:09

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

偏移量11之和处的可拆卸性:显示的只是一些垃圾字节。下一个函数main的入口点是4字节对齐,这就造成了这个空白,充满了垃圾。

.statements的集合是由汇编程序的文档定义的。通常他们不会给出任何可执行的代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4020683

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档