需要帮助了解GCC汇编代码

时间:2014-05-20 19:36:05

标签: c gcc assembly compilation

对于我的家庭作业,我应该转换这个C代码

 #define UPPER 15
 const int lower = 12;

 int sum = 0;

 int main(void) {
   int i;
   for (i = lower; i < UPPER; i++) {
     sum += i;
   }
   return sum;
 }

进入gcc程序集。我已经将它编译成第一次研究代码,然后单手操作(显然手工翻译看起来会有很大的不同)。这是我收到的汇编代码:

.file   "upper.c"
.globl  lower
.section    .rodata
.align 4
.type   lower, @object
.size   lower, 4
    lower:
.long   12
.globl  sum
.bss
.align 4
.type   sum, @object
.size   sum, 4
     sum:
.zero   4
.text
.globl  main
.type   main, @function
    main:
    .LFB0:
.cfi_startproc
pushq   %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq    %rsp, %rbp
.cfi_def_cfa_register 6
movl    $12, -4(%rbp)
jmp .L2
    .L3:
movl    sum(%rip), %edx
movl    -4(%rbp), %eax
addl    %edx, %eax
movl    %eax, sum(%rip)
addl    $1, -4(%rbp)
    .L2:
cmpl    $14, -4(%rbp)
jle .L3
movl    sum(%rip), %eax
popq    %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
    .LFE0:
.size   main, .-main
.ident  "GCC: (SUSE Linux) 4.8.1 20130909 [gcc-4_8-branch revision 202388]"
.section    .note.GNU-stack,"",@progbits

现在我想知道是否有人能给我一些像

这样的例子
  • 其中构造函数i,lower,upper和sum位于代码
  • 其中一些表达式i = lower或i&lt; UPPER位于
  • for-loop开始的地方

这样的事情让我可以了解汇编代码的构造方式。谢谢!

1 个答案:

答案 0 :(得分:2)

如果我理解你的问题,请回答:

问:构造函数i,lower,upper和sum在代码中的位置是什么?

lower位于.rodata部分(只读数据部分)。它的值在程序加载阶段由linux加载程序初始化为值.long 12lower构造函数是一个linux加载器。它只是从二进制映像加载lower值。

.globl  lower
.section    .rodata
.align 4
.type   lower, @object
.size   lower, 4
    lower:
.long   12

sum位于.bss部分内(包含静态分配变量的数据段)。它的值由_init函数初始化,在程序执行开始时调用它。它的值为零(.zero 4)。位于.bss部分内的每个变量的初始值均为零(link to wiki's article for .bss)。

.globl  sum
.bss
.align 4
.type   sum, @object
.size   sum, 4
     sum:
.zero   4

upper是常数。编译器没有将它的声明放入程序集中。此处有upper-1(如$14)的引用:

    .L2:
cmpl    $14, -4(%rbp)

i是一个堆栈临时变量。使用相对%rbp的地址访问它的值(%rbp是指向当前函数堆栈帧的指针)。没有明确声明i进入装配。 i没有明确的堆栈保留(主要序言中没有sub $0x8,%rsp之类的指令),我认为,因为main不会调用其他函数。以下是i初始化的代码(注意编译器知道lower初始值为$12并在lower初始化期间删除了对i的访问权限:

movl    $12, -4(%rbp)

问:其中一些表达式i = lower或i&lt; UPPER位于

i = lower

movl    $12, -4(%rbp)
jmp .L2

i < UPPER

    .L2:
cmpl    $14, -4(%rbp)
jle .L3

i++

addl    $1, -4(%rbp)

sum += i;

movl    sum(%rip), %edx
movl    -4(%rbp), %eax
addl    %edx, %eax
movl    %eax, sum(%rip)

return sum;%eax寄存器用于保存函数返回值 - 有关此内容的更多信息:X86 calling conventions):

jle .L3
movl    sum(%rip), %eax
popq    %rbp
.cfi_def_cfa 7, 8
ret

问:for循环开始的地方

从这里开始:

movl    $12, -4(%rbp)
jmp .L2