这是A9的汇编代码,
ldr x1, = 0x400020 // Const value may be address also
ldr w0, = 0x200018 // Const value may be address also
str w0, [x1]
以下是预期产出?
*((u32 *)0x400020) = 0x200018;
当我通过编译器与它交叉检查时,它给出了不同的结果,因为ldr的mov和movs insted。如何在c中创建ldr?
答案 0 :(得分:2)
当我通过编译器与它交叉检查时,它给出了不同的结果作为mov和movs
对我来说,就像你用编译器目标AArch32编译C代码一样,但你显示的汇编代码看起来像是为AArch64编写的。
这是我使用ARM64 GCC 5.4和优化级O3
编译时得到的结果(由我添加评论):
mov x0, 32 @ x0 = 0x20
mov w1, 24 @ w1 = 0x18
movk x0, 0x40, lsl 16 @ x0[31:16] = 0x40
movk w1, 0x20, lsl 16 @ w1[31:16] = 0x20
str w1, [x0]
如何在c中创建ldr?
在这种情况下,我看不出有什么理由要求编译器生成LDR
。
LDR reg,=value
是伪指令,允许您加载无法直接在指令字中编码的immediates。汇编程序通过将值(例如0x200018
)放在literal pool中,然后将ldr w0, =0x200018
替换为来自该文字池的PC相对负载(即类似ldr w0,[pc,#offset_to_value]
来实现此目的。 })。访问内存很慢,因此编译器会为您生成另一系列指令,以更有效的方式实现相同的操作。
伪指令主要是为人们编写汇编代码提供便利,使代码更易于他们或他们的同事进行读/写/维护。与人类不同,编译器不会因反复重复相同的任务而感到疲劳,因此对此类便利性的需求也不多。
TL; DR:编译器将生成它认为最好的(根据当前优化级别)指令序列。此外,LDR
的特定形式是伪指令,因此即使禁用所有优化,也可能无法让编译器生成它。