问题理解简单的ARM ASM函数

逆向工程 拆卸 反编译 手臂 汇编
2021-06-29 09:06:36

我在试图理解这段简单的代码时有点卡住了。它在 R0 中得到一个数字。第一部分似乎是 R0 = abs(R0),但随后变得更加困难。确定前导零的数量,然后将其左移那么多位,然后检查它是否 > 0,否则返回 0。我不明白整个移位的目的应该是什么,以及添加和附加移位操作应该在那里做什么。

ROM:0005B7BE ; =============== S U B R O U T I N E =======================================
ROM:0005B7BE
ROM:0005B7BE
ROM:0005B7BE sub_5B7BE
ROM:0005B7BE                 ANDS.W  R2, R0, #0x80000000
ROM:0005B7C2                 IT MI
ROM:0005B7C4                 NEGMI   R0, R0
ROM:0005B7C6                 CLZ.W   R3, R0
ROM:0005B7CA                 LSLS.W  R1, R0, R3
ROM:0005B7CE                 BEQ     retZero
ROM:0005B7D0                 RSB.W   R3, R3, #29
ROM:0005B7D4                 ADD.W   R3, R3, #1024
ROM:0005B7D8                 MOV.W   R0, R1,LSL#21
ROM:0005B7DC                 ADD.W   R2, R2, R3,LSL#20
ROM:0005B7E0                 ADD.W   R1, R2, R1,LSR#11
ROM:0005B7E4                 BX      LR
ROM:0005B7E6 ; ---------------------------------------------------------------------------
ROM:0005B7E6
ROM:0005B7E6 retZero
ROM:0005B7E6                 MOV.W   R0, #0
ROM:0005B7EA                 BX      LR
ROM:0005B7EA ; End of function sub_5B7BE
1个回答

这是来自 ARM 编译器库的函数dflt(或__aeabi_i2d)。它执行将 32 位有符号整数 inR0转换为软浮点精度(64 位浮点值) in R0:R1

一个IEEE 754双由一个符号位,11位指数和52位小数的:

 63  62             52 51                                         0
+------------------------------------------------------------------+
| s | exponent(11)    |           fraction(52)                     |
+------------------------------------------------------------------+
+------------------------------------------------------------------+
|           R1                |             R0                     |
+------------------------------------------------------------------+
31                           0 31                                 0  

数字的值为 2^(e-1023)*1.fraction

该代码计算近似原始值的指数和分数,并将其放入 R0:R1。移位中的幻数对于将两个寄存器的分数对齐是必要的,1024 是指数的偏差。