C 分析汇编代码

C 分析汇编代码,c,assembly,C,Assembly,这是此C程序生成的汇编代码: $ 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

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

 $ 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)"
最后:

.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 
这是什么意思


谢谢。

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

在英特尔语法中,如果存在任何歧义,通常会使用所需大小的指示符(例如,
字节
单词
DWORD
,等等)来标记内存参数,而不是为指令添加后缀,这只是实现相同功能的另一种方法

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


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

.size main, .-main
           .section .note.GNU-stack,"",@progbits
           .ident   "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-9)"
表示
accum
是一个全局符号(带有外部链接的C变量):

以下字节应放在
bss
节中,该节不占用对象文件中的空间,但在运行时分配并归零

    .globl accum
在4字节边界上对齐:

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

它是四个字节:

       .type accum, @object
这里定义了
acum
,四个零字节

       .size accum, 4
现在从
bss
部分切换到文本部分,文本部分通常存储函数

    accum:
       .zero 4
最多添加三个字节的填充,以确保位于4字节(2^2)的边界上:

       .bss
       .text
sum
是一个全局符号,也是一个函数

       .p2align 2,,3

main
的大小为“here”-“where
main
start”:

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

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

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

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

sum:中偏移量11处的disassessablely仅显示一些垃圾字节。下一个函数main的入口点是4字节对齐的,这就产生了这个空白,用垃圾填充


汇编程序的文档定义了一组.statement。通常他们不会给出任何可执行代码。

+9000。非常感谢。关于GCC特定堆栈选项的部分非常有用。
       .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)"