返回介绍

14.2 ARM

发布于 2025-02-22 14:00:45 字数 2136 浏览 0 评论 0 收藏 0

ARM 处理器,就像其他的“纯”RISC 处理器一样,缺少除法指令,缺少 32 位常数乘法的单条指令。利用一个技巧,通过加法,减法,移位是可以实现除法的。 这里有一个 32 位数被 10(20,3.3 常量除法)除的例子,输出商和余数。

#!bash
; takes argument in a1
; returns quotient in a1, remainder in a2
; cycles could be saved if only divide or remainder is required
    SUB     a2, a1, #10         ; keep (x-10) for later
    SUB     a1, a1, a1, lsr #2
    ADD     a1, a1, a1, lsr #4
    ADD     a1, a1, a1, lsr #8
    ADD     a1, a1, a1, lsr #16
    MOV     a1, a1, lsr #3
    ADD     a3, a1, a1, asl #2
    SUBS    a2, a2, a3, asl #1  ; calc (x-10) - (x/10)*10
    ADDPL   a1, a1, #1          ; fix-up quotient
    ADDMI   a2, a2, #10         ; fix-up remainder
    MOV     pc, lr

14.2.1 Xcode 优化模式(LLVM)+ARM 模式

#!bash
__text:00002C58 39 1E 08 E3 E3 18 43 E3     MOV     R1, 0x38E38E39
__text:00002C60 10 F1 50 E7                 SMMUL   R0, R0, R1
__text:00002C64 C0 10 A0 E1                 MOV     R1, R0,ASR#1
__text:00002C68 A0 0F 81 E0                 ADD     R0, R1, R0,LSR#31
__text:00002C6C 1E FF 2F E1                 BX      LR

运行原理

这里的代码和优化模式的 MSVC 和 GCC 生成的基本相同。显然,LLVM 在产生常量上使用相同的算法。

善于观察的读者可能会问,MOV 指令是如何将 32 位数值写入寄存器中的,因为这在 ARM 模式下是不可能的。实际上是可能的,但是,就像我们看到的,与标准指令每条有四个字节不同的是,这里的每条指令有 8 个字节,其实这是两条指令。第一条指令将值 0x8E39 装入寄存器的低十六位,第二条指令是 MOVT,它将 0x383E 装入寄存器的高 16 位。IDA 知道这些顺序,并且为了精简紧凑,将它精简转换成一条伪代码。

SMMUL (Signed Most Significant Word Multiply) 实现两个 32 位有符号数的乘法,并且将高 32 位的部分放在 r0 中,弃掉结果的低 32 位部分。

“MOV R1,R0,ASR#1“指令算数右移一位。
“ADD R0,R1,LSR#31” R0=R1+R0>>32

事实上,在 ARM 模式下,并没有单独的移位指令。相反,像(MOV,ADD,SUB,RSB)3 这样的数据处理指令,第二个操作数需要被移位。ASR 表示算数右移,LSR 表示逻辑右移。

14.2.2 优化 Xcode(LLVM)+thumb-2 模式

#!bash
MOV         R1, 0x38E38E39
SMMUL.W     R0, R0, R1
ASRS        R1, R0, #1
ADD.W       R0, R1, R0,LSR#31
BX          LR

在 thumb 模式下有些单独的移位指令,这个例子中使用了 ASRS(算数右移)

14.2.3 Xcode 非优化模式(LLVM) keil 模式

非优化模式 LLVM 不生成我们之前看到的那样的代码,它插入了一个调用库函数的 call __divsi3

关于 keil:通常插入一个调用库函数的 call __aeabi_idivmod

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文