You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARM64汇编栈操作报错:push/pop指令未识别问题求助

AArch64汇编中PUSH/POP指令报错及循环逻辑修复

我尝试编写嵌套循环来输出一个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上尝试运行汇编代码,但相关支持资料较少,因此现在在Ubuntu Docker容器中运行,其中的汇编器和链接器内置,且print和exit系统调用可正常工作。


问题原因及修复方案

1. PUSH/POP指令报错的原因

你使用的是AArch64(64位ARM)架构,该架构不支持ARM32中push {reglist}、pop {reglist}这种批量操作寄存器的指令语法。AArch64要求手动通过栈指针(SP)分配/释放栈空间,并使用stp(存储一对寄存器)、str(存储单个寄存器)、ldp(加载一对寄存器)、ldr(加载单个寄存器)指令来保存和恢复寄存器。

同时需要注意:AArch64的栈必须保持16字节对齐,所以分配栈空间时要确保SP的值是16的倍数。

修改后的_print子程序如下:

_print:
    sub sp, sp, #32        ; 分配32字节栈空间(满足16字节对齐要求)
    stp x0, x1, [sp, #16]  ; 将x0、x1存入栈中
    str x2, [sp, #24]      ; 将x2存入栈中

    ; 执行系统调用打印字符
    mov x8, #0x40
    mov x0, #1
    mov x1, x3
    mov x2, #1
    svc #0

    ldp x0, x1, [sp, #16]  ; 从栈中恢复x0、x1
    ldr x2, [sp, #24]      ; 从栈中恢复x2
    add sp, sp, #32        ; 释放栈空间,恢复栈指针
    ret

2. 嵌套循环的逻辑错误

除了指令问题,你的循环逻辑还存在缺陷:第一次执行_width循环后,x1会被减到0,后续每次进入_width时,x1始终为0,导致直接返回_height,无法打印每行的点阵。

需要在每次进入行循环(_height)时,重置列计数器x1为WIDTH,修改后的_height子程序:

_height:
    cmp x0, 0
    beq _exit
    sub x0, x0, 1
    mov x1, WIDTH  ; 每次打印新行前,重置列计数器
    bl _width
    ldr x3, =NEW_LINE
    bl _print
    bl _height

完整修复后的代码

.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
    mov x1, WIDTH  ; 重置列计数器
    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:
    sub sp, sp, #32        ; 分配对齐的栈空间
    stp x0, x1, [sp, #16]
    str x2, [sp, #24]

    mov x8, #0x40
    mov x0, #1
    mov x1, x3
    mov x2, #1
    svc #0

    ldp x0, x1, [sp, #16]
    ldr x2, [sp, #24]
    add sp, sp, #32
    ret

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

内容的提问来源于stack exchange,提问作者masteronin99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 23:25:29