这个数字在汇编中是如何表示的?

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.01x22single 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