LEGv8汇编STUR指令报错修复:编写堆排序遇标签/助记符错误
修复LEGv8汇编中STUR指令相关的编译错误
问题描述
我是LEGv8汇编语言新手,正在尝试编写堆排序程序,当前出现如下编译错误:
This is LEGv8ASM Build time: Wed Oct 16 08:23:15 CDT 2024 Expected a label or mnemonic (line 2)
当前编写的汇编代码:
fill: STUR X29, [SP, #-8]! // Save frame pointer ADD X29, SP, #0 // Set frame pointer SUB X4, X1, #2 // X4 = s - 2 B.LT fill_end // if (s < 2), return ORR X2, XZR, XZR // i = 0 ADD X3, X1, #1 // X3 = s + 1 LSR X3, X3, #1 // X3 = (s + 1) / 2 fill_end: LDUR X29, [SP], #8 // Restore frame pointer RET
对应的参考C代码:
/* a: address of array of unsigned 64-bit int * s: number of elements in a * * Initializes the contents of a with the numbers 0 through (s - 1). The * array is initialized with even number to the left in descending order, and * odd number on the right in ascending order. */ void fill(uint64_t *a, uint64_t s) { uint64_t i = 0; if (s >= 2) { for (; i < s / 2; i++) { a[((s + 1) / 2) - (i + 1)] = i * 2; a[((s + 1) / 2) + i] = i * 2 + 1; } } if (s & 1) { a[0] = s - 1; } }
错误原因与修复方案
错误原因
编译报错指向第2行,问题出在STUR指令的语法:LEGv8的STUR不支持带!的预变址模式(自动更新栈指针的写法),!是STR指令的专属语法,STUR仅支持固定偏移的内存访问。同时,后面的LDUR [SP], #8后变址写法也不符合STUR/LDUR的规范。
修复代码
将栈操作拆分为手动调整栈指针+固定偏移存储/加载,修改后的代码如下:
fill: SUB SP, SP, #8 // 手动分配8字节栈空间 STUR X29, [SP, #0] // 保存帧指针到栈的固定位置 ADD X29, SP, #0 // 设置帧指针指向当前栈顶 SUB X4, X1, #2 // X4 = s - 2 B.LT fill_end // 如果s < 2,直接跳转到返回逻辑 ORR X2, XZR, XZR // 初始化i=0 ADD X3, X1, #1 // X3 = s + 1 LSR X3, X3, #1 // X3 = (s + 1) / 2 fill_end: LDUR X29, [SP, #0] // 从栈中恢复帧指针 ADD SP, SP, #8 // 手动释放栈空间 RET
关键说明
- LEGv8中,
STUR/LDUR的设计目的是访问相对于帧指针或栈指针的固定偏移地址,不支持自动更新基址寄存器的变址模式;而STR/LDR才支持[SP, #-8]!这类预变址、[SP], #8这类后变址写法。 - 手动调整栈指针的写法更贴合
STUR的语法要求,同时能确保栈帧的完整性,避免栈指针异常。
内容的提问来源于stack exchange,提问作者Ayan Asim
相关产品推荐
相关产品推荐

