【问题标题】:Conversion of ARM code into C将 ARM 代码转换为 C
【发布时间】:2016-11-16 06:50:23
【问题描述】:

这是我的 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;    

当我通过编译器对其进行交叉检查时,它给出了不同的结果作为 mov 和 movs insted of ldr。如何在c中创建ldr?

【问题讨论】:

  • @Lundin:我的评论不正确。最后我不知何故错过了str
  • @Michael 你能解释一下第三条指令“str w0, [x1]”
  • @Michael Ah,我也是。由于一些编辑失误,它最终成为评论。该问题现已恢复。
  • @BasavarajaMS 是 Apple A9 的目标硬件吗?

标签: c assembly arm


【解决方案1】:

当我通过编译器对其进行交叉检查时,它给出了不同的结果作为 mov 和 movs

在我看来,您使用针对 AArch32 的编译器编译了 C 代码,但您显示的汇编代码看起来像是为 AArch64 编写的。 这是我使用 ARM64 GCC 5.4 和优化级别 O3(我添加的 cmets)编译时得到的结果:

    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 的特定形式是伪指令,因此即使禁用所有优化,您也可能无法让编译器生成它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多