AArch64汇编打印数字时栈值cmp比较失效及段错误问题求助
代码错误及不规范问题说明
- 核心逻辑错误:退出判断的寄存器选择错误
你将存储栈地址的x1和终止标记10做比较,x1存放的是内存地址,永远不可能等于10,导致判断永远不生效,循环持续打印栈后非法内存数据,最终触发段错误。正确判断对象应该是存放弹出值的x3寄存器。 - 系统调用参数缺失
AArch64 Linux下write系统调用(调用号64)的第一个参数x0需要指定文件描述符,打印到标准输出需要赋值x0 = 1,你未对该寄存器赋值,属于未定义行为,仅在碰巧x0初始值为1时能正常输出。 - 缺少退出逻辑实现
代码中跳转目标exit标签未定义,即使判断生效也会导致程序跑飞。AArch64 Linux下exit系统调用号为93,需要指定返回值后调用。 - 数字拆分逻辑冗余
你通过udiv得到的x14已经是x12除以10的商,无需先减余数再做一次除法,直接将x12赋值为x14即可,可省略两句冗余指令。 - 操作说明:你使用的
ldr x3, [sp], #16就是AArch64标准的「弹出栈顶值到寄存器」操作,执行逻辑就是先读取当前sp指向的数据到x3,再将sp加16完成出栈,你的使用方式是正确的。
修正后的完整代码
.globl _start _start: mov x12, #12345 /* 待打印的数字 */ mov x16, #10 /* 预分配栈空间并压入终止标记10 */ sub sp, sp, #(16*20) str x16, [sp, #-16]! getStrs: udiv x14, x12, x16 msub x13, x14, x16, x12 /* 求余数,即当前数位 */ mov x12, x14 /* 直接用商更新x12,省略冗余操作 */ add x13, x13, #48 /* 转ASCII码 */ str w13, [sp, #-16]! cmp x12, #0 beq printStrs b getStrs printStrs: mov x0, #1 /* 指定标准输出为目标 */ mov x1, sp ldr x3, [sp], #16 /* 弹出栈顶值到x3 */ mov x2, #1 mov w8, #64 /* write系统调用号 */ svc #0 cmp x3, #10 /* 判断弹出的是否为终止标记换行符 */ beq exit /* 匹配则退出 */ b printStrs exit: mov x0, #0 /* 退出返回值0 */ mov w8, #93 /* exit系统调用号 */ svc #0
内容的提问来源于stack exchange,提问作者Maritn Ge
相关产品推荐
相关产品推荐

