ARM乘法编译器优化

逆向工程 手臂 编译器优化
2021-07-11 02:22:16

我需要帮助解释这个编译器优化:

   ;R12 = 0x88888889;
    UMULL           LR, R2, R12, R3 ; R3 * 0x88888889;
    MOV             R2, R2,LSR#3 ; ((R3 * 0x88888889 << 32) >> 3)
    RSB             R2, R2, R2,LSL#4 ; (R3 * 0x88888889 >> 32 >> 3) << 16
    RSB             R2, R2, R3,LSL#1 ; (R3 << 1) - ((R3 * 0x88888889 >> 32 >> 3) << 16);

目前我是这样解释的(不确定它是否正确):

(R3 * 2) - ((R3 * 0x88888889 * 120) / 0xFFFFFFFF);

我发现它可能是整数除法,我希望有人能帮助我更好地理解这个优化

谢谢。

1个回答

您在整数除法的正确行上。

前 3 条指令相当清晰——

  • R2afterUMULL是整数除以 1.875 ( = 0x100000000 / 0x88888889) 的结果
  • 下面MOV是一个进一步的整数除以 8 导致 R2 现在包含原始R3除以 15 (= 1.875 * 8)
  • 第一个RSB是乘以 15 ( = R2 * 16 - R2 )

此时R2 = 15 * int( R3 / 15 )

最后RSB给出最终结果R2 = R3 * 2 - 15 * int( R3 / 15 )

编辑:事实上,这可以简化为R2 = R3 + (R3 % 15)(其中 % 是模运算符。)

您可以在此处查看这两个公式的示例汇编