c - 需要帮助理解 GCC 汇编代码

标签 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 < UPPER 所在的位置
  • for 循环开始的位置

等等,这样我就可以了解汇编代码是如何构造的。谢谢!

最佳答案

如果我正确理解你的问题,以下是答案:

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

lower位于.rodata内部分(只读数据部分)。它的值由linux加载程序在程序加载阶段初始化为值.long 12。 。 lower构造函数是一个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进入 assembly 。 i 没有显式堆栈预留(主序言中没有像 sub $0x8,%rsp 这样的指令),我认为,因为 main 不调用其他函数。这是 i 的代码初始化(注意编译器知道 lower 初始值为 $12 并在 lower 初始化期间删除对 i 的访问):

movl    $12, -4(%rbp)

问:某些表达式 i = lower 或 i < 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

关于c - 需要帮助理解 GCC 汇编代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23768436/

相关文章:

c - 尝试使用一堆字符串将反向波兰表示法转换为中缀,遇到一个小错误,我不知道是什么原因造成的

c - 3n+1 奇怪的事情发生了

c++ - movl多数据指令与汇编优化比较

iphone - iOS - ASM 代码会在 armv7/armv7s/arm64 上运行吗?

windows - 仅使用系统调用而不是 Windows dll 制作程序

c - 在具有 ARM A9 处理器、L2 CACHE、SRAM 的系统上。是否有可能有一个C程序来获得以下性能数据

.net - 将 IPv4 header 校验和插入虚拟 IP header

c - 为什么即使在使用 -O0 标志时 clang 也会优化我的数组?

c++ - 关于 DSO 引用隐藏符号的警告到底意味着什么?

gcc - 组装结束后附有说明