对于我的家庭作业,我应该转换这个 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/