如何在arm64汇编中使用堆栈

问题描述 投票:0回答:1

我试图编写一个嵌套循环并打印 10x10 的点网格。当我尝试在 _print 子例程中使用 PUSH 和 POP 命令时,汇编器会抛出错误。这是正确的方法还是我做错了什么。请帮忙

.equ WIDTH, 10
.equ HEIGHT, 10

.data
DOT: .ascii "."
BLOCK: .ascii "$"
NEW_LINE: .ascii "\n"

.text
.global _start
_start:
_renderFrame:
    mov x0, HEIGHT
    mov x1, WIDTH
    bl _height

_height:
    cmp x0, 0
    beq _exit
    sub x0, x0, 1
    bl _width
    ldr x3, =NEW_LINE
    bl _print
    bl _height

_width:
    cmp x1, 0
    beq _height
    sub x1, x1, 1
    ldr x3, =DOT
    bl _print
    bl _width

_print:
    push {x0, x1, x2}
    mov x8, 0x40
    mov x0, 1
    mov x1, x3
    mov x2, 1
    svc 0
    pop {x0, x1, x2}
    ret

_exit:
    mov x8, 0x5d
    mov x0, 0
    svc 0

错误如下

main.asm: Assembler messages:
main.asm:35: Error: unknown mnemonic `push' -- `push {x0,x1,x2}'
main.asm:41: Error: unknown mnemonic `pop' -- `pop {x0,x1,x2}'

注意: 之前我尝试在 macOS 中运行汇编,但网上似乎没有太多关于 macOS 的支持文章。因此,我在带有内置汇编器和链接器的 Ubuntu Docker 容器中运行此代码。并且打印和退出系统调用工作正常。

linux ubuntu assembly arm64
1个回答
0
投票

ARM64 汇编中没有

push
pop
指令。也许你把它与 ARM32 搞混了,ARM32 确实有它们。

要在 ARM64 上压入和弹出堆栈,您可以在

sp
寄存器上使用正常的加载和存储指令以及预减/后增量寻址模式。请注意,您必须始终以 16 字节为增量调整
sp
,以便使用
ldp
加载对和
stp
存储对指令一次推送和弹出两个 64 位寄存器非常方便。

示例:

    stp x0, x1, [sp, #-16]!  // push x0 and x1
    ldp x0, x1, [sp], #16    // pop them again

如果你想压入/弹出两个以上的寄存器,你可以重复这个,或者使用第一个/最后一个存储/加载来调整堆栈指针所有寄存器所需的总量,然后使用非前置/后置-增加其他人的存储和负载。

示例:

    stp x0, x1, [sp, #-32]!
    str x2, [sp, 16] // store x2 above x0 and x1
    ldr x2, [sp, 16]
    ldp x0, x1, [sp], #32

不相关,但在代码中使用

bl
似乎很混乱。
bl
用于函数调用;它将返回地址保存到链接寄存器
x30
中,然后分支到目标地址,该目标地址应该是函数或子例程的第一条指令。然后,被调用的函数应以
ret
结束,分支回存储在
x30
中的地址,此时继续执行
bl
后面的指令。因此,不清楚为什么您使用它来跳转到
_width
_height
,它们不是子例程并且不会返回。如果您想要无条件分支,请使用
b
而不是
bl

但是在你的代码中如下:

_height:
    cmp x0, 0
    beq _exit
    sub x0, x0, 1
    bl _width
    ldr x3, =NEW_LINE // this and following lines are unreachable
    bl _print
    bl _height

由于

_width
没有
ret
指令,它不会返回(实际上它通过执行自己的
x30
来覆盖
bl
),因此
bl _width
后面的代码永远无法执行。所以我认为你需要对程序的控制流程多加一些思考。

© www.soinside.com 2019 - 2024. All rights reserved.