2016-11-16 60 views
0

这里是A9我的汇编代码,转换的ARM代码成C

ldr  x1, = 0x400020    // Const value may be address also 
ldr  w0, = 0x200018  // Const value may be address also 
str  w0, [x1] 

以下一项所述的预期输出?

*((u32 *)0x400020) = 0x200018;  

当我通过编译器与它交叉检查它给出不同的结果作为mov和movs insted ldr。如何在c中创建ldr?

+0

@Lundin:我的评论是不正确的。我最终错过了'str'。 – Michael

+0

@Michael你能解释一下第三条指令:“str w0,[x1]” – BasavarajaMS

+0

@Michael Ah,我也是这样说的,因为一些编辑的问题,最后只能作为评论。这个问题现在已经恢复。 – Lundin

回答

2

当我穿过由编译器检查过它给目前存在的结果作为MOV和MOVS

像你编译的C代码编译器靶向AArch32这听起来我,但汇编代码你”显示的样子看起来像是为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是一个伪指令,它允许您加载无法直接在指令字中编码的立即数。汇编器通过将值(例如0x200018)置于literal pool中,然后用来自该文字池的PC相对负载(即诸如ldr w0,[pc,#offset_to_value]之类的东西)替换ldr w0, =0x200018来实现此目的。访问内存很慢,因此编译器会为您生成另一个指令序列,以更有效的方式实现相同的操作。

伪指令主要是方便人类编写汇编代码,使代码更易于他们或他们的同事读/写/维护。与人类不同,编译器不会因重复同样的任务而疲惫不堪,因此对这种便利的需求并不那么多。

TL; DR:编译器会生成它认为最好的(根据当前优化级别)指令序列。此外,LDR的特定形式是伪指令,所以即使您禁用了所有优化,也可能无法让编译器生成它。