将 ARM 代码转换为 C

标签 c assembly arm

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

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

最佳答案

When i cross checked with it by compiler it given differnet result as mov and 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]

How to create ldr in c?

在这种情况下,我看不出您希望编译器生成 LDR 的任何充分理由。
LDR reg,=value 是一个伪指令,它允许您加载不能直接在指令字中编码的立即数。汇编程序通过将值(例如 0x200018)放在 literal pool 中来实现这一点。 ,然后将 ldr w0, =0x200018 替换为来自该文字池的 PC 相关负载(即类似于 ldr w0,[pc,#offset_to_value])。访问内存很慢,因此编译器为您生成了另一个指令序列,以更有效的方式实现相同的目的。

伪指令主要是为了方便人类编写汇编代码,使代码更容易被他们或他们的同事读/写/维护。与人类不同,编译器不会因为一遍又一遍地重复相同的任务而感到疲劳,因此不需要那么多便利。

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

关于将 ARM 代码转换为 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40625733/

相关文章:

c++ - SSE 指令在实践中优化了什么,编译器如何启用和使用它们?

arm - 使用 ARM Neon 内在函数处理饱和整数乘法溢出的最有效方法是什么?

c++ - 指向 volatile 数据的指针 (*((volatile uint32_t *)0x40000000))

c++ - 如何判断Windows是否安装了C/C++编译器?

c - 将 strcmp() 与文件中的字符串一起使用

c - 如何在 Pebble watch 中创建表格

c - 分析生成的汇编代码以操纵命令行参数

assembly - 理解堆栈对齐

linux - Qt Creator 为 Raspberry Pi 2 进行交叉编译和远程部署的正确设置 - 为错误的架构生成二进制文件

c - Diffie-Hellman 中参数的选择