对于我的家庭作业,我应该转换这个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
- for循环开始的地方
之类的东西,这样我就可以了解汇编代码是如何构造的。谢谢你!
如果我理解对了你的问题,下面是答案:
Q:构造函数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
section(包含静态分配变量的数据段)内。它的值由_init
函数初始化,该函数在程序执行开始时被调用。它的值是0 (.zero 4
)。.bss
节中的每个变量的初始值都为0(链接到wiki的.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
没有显式的堆栈保留(在main序言中没有sub $0x8,%rsp
这样的指令),因为main不调用其他函数。下面是i
初始化的代码(注意编译器知道lower
的初始值是$12
,并且在i
初始化期间删除了对lower
的访问):
movl $12, -4(%rbp)
Q:其中一些表达式i = lower或i <</p>
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调用约定):
jle .L3
movl sum(%rip), %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
Q: for循环开始的位置
它从这里开始:
movl $12, -4(%rbp)
jmp .L2