我正在尝试分析函数的汇编代码
double test_class::Operators_2_12_addtion_07(double input) {
/*add input with constant value 5*/
double a = input + 5;
/*Branch unconditional return*/
return a;
}
这是代码的汇编输出:
double test_class::Operators_2_12_addtion_07(double input) {
0: 3d 20 00 00 lis r9,0
4: c0 09 00 00 lfs f0,0(r9)
double a = input + 5;
/*Branch unconditional return*/
return a;
}
8: fc 21 00 2a fadd f1,f1,f0
c: 4e 80 00 20 blr
在代码中,我为通过函数传递的输入参数添加了一个常量值5。指令汇编中列出的指令是:
0: 3d 20 00 00 lis r9,0
4: c0 09 00 00 lfs f0,0(r9)
任何人都可以帮助我理解价值5在装配中的表现方式。
答案 0 :(得分:1)
听取Jester的评论。
当编译器编译代码单元时,通常假定其代码从地址0开始,因此它生成地址相对于0的目标文件(除非生成PIC)。
当链接器链接目标文件时,它通常会将每个代码段一个接一个地放在一起,因此它必须“转移”#34;第一个之后的部分的地址。
加载程序时,其起始地址可以是randomly chosen,因此加载的必须是" shift"所有的地址再一次。
这称为Relocation,它可以以各种方式完成,并暗示存储在对象/二进制文件中的地址通常为零或相对于零。
由于在RISC机器中很常见,因此加载寄存器宽度常量(作为地址)需要两条指令。
一个用于高位,一个用于低位
在PowerPC中,这是通过配对完成的
lis r1, HIGH16 ;Move HIGH16<<16 into r1
ori r1, LOW16 ;r1 = HIGH16<<16 | LOW16
如果地址用于加载某些数据,则第二条指令可以 &#34;稠&#34;通过使用位移
进入负载lis r1, HIGH16 ;Move HIGH16<<16 into r1
lwz r2, LOW16(r1) ;r2 = mem[HIGH16<<16 + LOW16]
当使用浮点的calling a function时,约定是将输入参数放入寄存器 f1 - f8 。
返回值位于 f1
f0 是易失性寄存器。
没有指令立即加载浮点数,因此它必须位于内存中。 我不知道PowerPC使用的浮点格式,我假设IEEE754 在这种情况下,数字5表示为+ 1.01x2 2 ,因为single precision是
S Exp (127+2) Significand (Implicit 1)
+---+-----------+-------------------------+
| 1 | 1000 0001 | 010 0000 0000 0000 0000 |
+---+-----------+-------------------------+
或40a00000h。
您可以使用浮点here进行实验。
; f1 = input
;This load a float at address 0 (not yet relocated) into f0
;Such float is the literal 5.
;The zeros are actually the upper and lower part of the literal address
;(that is not relocated)
lis r9, 0
lfs f0, 0(r9)
;f1 = input
;f0 = 5
fadd f1,f1,f0
;f1 = input + 5
;f0 = 5
blr