这个数字在汇编中是如何表示的?
How is this number being represented in assembly?
我正在尝试分析函数的汇编代码
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 在程序集中的表示方式。
TL;DR
听杰斯特的评论。
搬迁
当编译器编译一个代码单元时,通常假定它的代码从地址0开始,所以它生成地址相对于0的目标文件(除非生成PIC)。
当链接器链接目标文件时,它通常将每个代码节一个接一个地放置,因此它必须 "shift" 第一个节之后的节的地址。
程序加载时,其起始地址可以是randomly chosen,所以加载必须"shift"一次所有地址。
这称为 Relocation,可以通过多种方式完成,这意味着存储在 object/binary 文件中的地址通常为零或相对于零。
PowerPC地址加载
由于在 RISC 机器中很常见,加载寄存器宽度常量(作为地址)需要两条指令。
高位一位,低位一位
在 PowerPC 中,这是通过对
lis r1, HIGH16 ;Move HIGH16<<16 into r1
ori r1, LOW16 ;r1 = HIGH16<<16 | LOW16
如果地址用于加载一些数据,第二条指令可以
"fused" 进入负载虽然使用位移
lis r1, HIGH16 ;Move HIGH16<<16 into r1
lwz r2, LOW16(r1) ;r2 = mem[HIGH16<<16 + LOW16]
PowerPC(部分)调用约定
当calling a function使用浮点数时,约定是将输入参数放入寄存器f1-f8。
return 值在 f1.
中
f0是易失性寄存器。
把所有这些放在一起
没有立即加载浮点数的指令,因此它必须位于内存中。
我不知道 PowerPC 使用什么浮点格式,我假设 IEEE754.
在这种情况下,数字 5 表示为 +1.01x22 而 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
我正在尝试分析函数的汇编代码
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 在程序集中的表示方式。
TL;DR
听杰斯特的评论。
搬迁
当编译器编译一个代码单元时,通常假定它的代码从地址0开始,所以它生成地址相对于0的目标文件(除非生成PIC)。
当链接器链接目标文件时,它通常将每个代码节一个接一个地放置,因此它必须 "shift" 第一个节之后的节的地址。
程序加载时,其起始地址可以是randomly chosen,所以加载必须"shift"一次所有地址。
这称为 Relocation,可以通过多种方式完成,这意味着存储在 object/binary 文件中的地址通常为零或相对于零。
PowerPC地址加载
由于在 RISC 机器中很常见,加载寄存器宽度常量(作为地址)需要两条指令。
高位一位,低位一位
在 PowerPC 中,这是通过对
lis r1, HIGH16 ;Move HIGH16<<16 into r1
ori r1, LOW16 ;r1 = HIGH16<<16 | LOW16
如果地址用于加载一些数据,第二条指令可以 "fused" 进入负载虽然使用位移
lis r1, HIGH16 ;Move HIGH16<<16 into r1
lwz r2, LOW16(r1) ;r2 = mem[HIGH16<<16 + LOW16]
PowerPC(部分)调用约定
当calling a function使用浮点数时,约定是将输入参数放入寄存器f1-f8。
return 值在 f1.
中
f0是易失性寄存器。
把所有这些放在一起
没有立即加载浮点数的指令,因此它必须位于内存中。
我不知道 PowerPC 使用什么浮点格式,我假设 IEEE754.
在这种情况下,数字 5 表示为 +1.01x22 而 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