【问题标题】:ARM assembly comparing two characters (ascii)比较两个字符的 ARM 程序集 (ascii)
【发布时间】:2018-10-25 14:36:46
【问题描述】:
test:
    ldr r0, [r1, #4]
    bl printf

    ldr r2, [r1, #4]
    ldrb r0, [r2], #1

    cmp r0, #32
    beq test
#32 是空格的十进制ASCII码

代码使用编译

arm-none-eabi-gcc a.s -T generic-hosted.ld

然后运行

arm-none-eabi-run a.out "abcde"
arm-none-eabi-run a.out " bcde"

我想第一个命令会打印一次'abcde',第二个带空格的命令应该打印两次'bcde'。但是我都打印一次,有什么问题?

【问题讨论】:

    标签: assembly arm


    【解决方案1】:

    printf 可以修改 r0、r1、r2、r3 和 r12。

    您将需要使用调用保留寄存器(并在返回之前将其恢复),或者将值保存在堆栈中。

    【讨论】:

      【解决方案2】:

      Timothy Baldwin's answer 是准确的,但我想我会稍微扩展一下。 ARM 应用程序二进制接口 (ABI),尤其是 procedure call standard,定义了如何跨过程调用边界处理每个寄存器。

      总而言之,r0-r3 用于参数和返回值传递,并且必须由 调用者 与“内部过程调用暂存寄存器”r12 一起保存。 被调用者必须保留所有其他通用寄存器。因此,如果您使用汇编语言编写自己的函数,则必须推送您使用的任何 r4-r11,如果您调用任何其他函数,则必须推送 lr (r14),并且您必须确保使用堆栈是“平衡的”,因此sp (r13) 在退出时与进入时具有相同的值。

      大多数编译器(至少在禁用优化的情况下)将生成满足这些要求的代码,方法是在开始时将任何函数参数移出r0-r3,就在推送被调用者保留寄存器之后;在返回之前将任何返回值移动到r0;并且使用r0-r3 仅用于在函数执行期间向被调用函数传递参数。

      此外,在不同的目标文件(即不同的源文件)中的函数之间,堆栈必须是 8 字节对齐的,因此始终保持 8 字节对齐是一个好习惯,因为它很容易做到并且是免费的(出于与缓存相关的原因)。为此,请确保与堆栈的每次交互(每个 PUSH 和 POP)都涉及偶数个寄存器,必要时压入和弹出其他寄存器以组成偶数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-20
        • 1970-01-01
        • 1970-01-01
        • 2014-09-17
        • 2013-12-10
        • 1970-01-01
        • 2021-12-18
        相关资源
        最近更新 更多