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
相关产品推荐
相关产品推荐

