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

ARM汇编中atoi函数使用异常:命令行参数校验触发段错误

问题分析与修复

你的段错误根源在于违反ARM64调用约定,同时存在一处参数传递错误,具体如下:

1. 被调用者保存寄存器未做栈保存

ARM64调用规范中,x19-x29属于被调用者保存寄存器——你的代码若要使用这些寄存器,必须先把它们的值保存到栈上,调用外部函数(如atoi、printf)后再恢复。你直接使用w19、w20、w21却未做栈保存,导致外部函数调用时这些寄存器被覆盖,后续访问argv_r(x21)或i_r(w19)时拿到非法地址/值,触发段错误。

2. top段中atoi的参数传递错误

top段里调用atoi时,你错误地将参数加载到x1,但atoi要求输入参数放在x0寄存器中,这会导致atoi读取垃圾值,进一步触发段错误。

修复后的代码

define(i_r, w19)
define(argc_r, w20)
define(argv_r, x21)

fmt:     .string "%d "
err:     .string "usage: a5b mm dd\n"

        .balign 4
        .global main
main:   
        // 扩展栈空间,保存被调用者寄存器x19-x21
        stp x29, x30, [sp, -32]!
        stp x19, x20, [sp, 16]
        str x21, [sp, 24]
        mov x29, sp

        mov argc_r, w0          // 保存argc
        mov argv_r, x1          // 保存argv
        mov i_r, 1              // 从第二个参数开始处理
        cmp argc_r, 3           // 检查参数数量是否为3
        b.ne error              // 参数数量不对则跳转到错误处理

        ldr x0, [argv_r, i_r, SXTW 3]   // 加载第二个参数字符串
        bl atoi                         // 转换为整数
        cmp w0, 12                      // 检查月份是否大于12
        bgt error                       // 超出范围则报错
        cmp w0, 0                       // 检查月份是否小于0
        blt error                       // 超出范围则报错

        mov w1, w0                      // 把转换后的整数传给printf的参数w1
        adrp x0, fmt                    // 加载格式化字符串
        add x0, x0, :lo12:fmt
        bl printf                       // 打印月份

        add i_r, i_r, 1                 // 切换到第三个参数

top:    
        ldr x0, [argv_r, i_r, SXTW 3]   // 加载当前参数字符串到x0(atoi的参数)
        bl atoi                         // 转换为整数
        mov w1, w0                      // 把转换后的整数传给printf的参数w1
        adrp x0, fmt                    // 加载格式化字符串
        add x0, x0, :lo12:fmt
        bl printf                       // 打印当前参数

        add i_r, i_r, 1                 // 切换到下一个参数
        cmp i_r, argc_r                 // 检查是否处理完所有参数
        b.lt top                        // 未处理完则继续循环

end:
        // 恢复被调用者寄存器
        ldp x19, x20, [sp, 16]
        ldr x21, [sp, 24]
        ldp x29, x30, [sp], 32
        ret

error:
        adrp x0, err
        add x0, x0, :lo12:err
        bl printf
        b end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 07:04:53