首页 > 解决方案 > 从 C 语言转换为 ARM 程序集——不断出现分段错误,与 ldr 和 str 混淆?

问题描述

我是 ARM 程序集的新手,正在尝试将一些简单的代码片段从 C 转换为程序集。我不确定我是否正确使用了 ldr 和 str (尽管我觉得我已经尝试了所有方法)并且当我尝试运行它时我不断收到 seg 错误。

C代码是

int main() {
    int x = 10;
    int y = 5;
    int z = 20;

    int min = y;

    if (x < min) {min = x;}
    if (z < min) {min = z;}

    return min;
}

我的汇编代码:

.global main
.text

main:
    push {ip, lr}

    mov r0, #10
    mov r1, #5
    mov r2, #20

    str r3, [r1]

    cmp r0, r3
    bge done
    str r0, [r3]

    cmp r2, r3
    bge done
    str r2, [r3]

done:
    ldr r0, [r3]
    pop {ip, pc}

标签: csegmentation-faultarm

解决方案


C代码是

int main() {
    int x = 10;
    int y = 5;
    int z = 20;

    int min = y;

    if (x < min) {min = x;}
    if (z < min) {min = z;}

    return min;
}

不要使用ldrandstr因为它们将寄存器值存储到内存中。例如str rX, [rY]意味着使用'rY'的值作为内存地址来存储'rX'的值。当您有许多可用寄存器时,无需使用内存。例如,

mov   r0, #5    ; min = y = #5
mov   r1, #10   ; x = 10
mov   r2, #20   ; z = 20
cmp   r1, r0    ; if (x < min)
movlt r0, r1    ;  min = x
cmp   r2, r0    ; if (z < min)
movlt r0, r2    ;  min = z
mov   pc, lr    ; return min (is r0)

如果不完整,则接近。请检查我的寄存器使用,因为有些可能被调换了。您也可以考虑是否需要签名或未签名。如果“x > y > z”,您使用的原件bge done将不起作用。您需要根据“C”代码使用“小于”。

对于像这样的非常简单的代码,我建议不要使用编译器开始。如果你有很多变量,那么从编译器开始。在你尝试之后,看看编译器做了什么。在某些情况下,你可能有比编译器更好的结构思想;可能不是这样的数字问题。如果您立即使用编译器,则很难想到对函数进行编码的替代攻击。通常,您最初的尝试和编译器的想法会结合在一起,得到一些非常好的东西。


推荐阅读