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

ARM汇编奇偶求和程序段错误问题排查求助

ARM汇编段错误与值覆盖问题修复

错误分析

你的代码存在5个核心问题,直接导致了段错误和值被0覆盖的现象:

  1. 伪指令语法错误
    原代码中scanf_format: asciz "%d"缺少前缀.,汇编器无法识别该伪指令,会导致scanf使用错误的格式字符串地址,引发输入读取异常。

  2. 未校验scanf返回值
    scanf返回成功读取的参数数量,若输入非整数或读取失败,返回值不等于1。原代码未做校验,会导致后续使用input_num中的非法值,引发逻辑错误。

  3. 违反ARM调用约定
    ARM APCS约定中,r0-r3是调用者保存寄存器,被调用函数(如printf)会直接修改这些寄存器的值。原代码用r2保存input_num地址,多次调用printf后r2被覆盖,导致后续访问input_num时地址错误。

  4. 无效跳转标签
    原代码末尾用b exit跳转,但未定义exit标签,程序会跳转到非法内存地址,直接触发段错误。

  5. 未保存被调用者寄存器
    原代码直接使用r4、r5但未保存,调用外部函数时会破坏这些寄存器的上下文,导致计算值丢失或错误。

修正后的代码

.global main
.extern printf
.extern scanf
.extern exit

.section .data
prompt: .asciz "Enter an integer between 2 and 100: "
error_msg: .asciz "Invalid input. Exiting.\n"
even_msg: .asciz "The even numbers from 1 to %d are:\n"
odd_msg: .asciz "The odd numbers from 1 to %d are:\n"
sum_even_msg: .asciz "The even sum is: %d\n"
sum_odd_msg: .asciz "The odd sum is: %d\n"
int_format: .asciz "%d\n"
scanf_format: .asciz "%d"

.section .bss
input_num: .space 4

.section .text
main:
    // 保存被调用者寄存器,避免被外部函数破坏
    push {r4, r5, r6, lr}

    ldr r0, =prompt
    bl printf

    ldr r0, =scanf_format
    ldr r1, =input_num
    bl scanf
    // 校验scanf是否成功读取1个参数
    cmp r0, #1
    bne invalid_input

    // 用被调用者寄存器r6保存input_num地址,避免被printf覆盖
    ldr r6, =input_num
    ldr r3, [r6]
    cmp r3, #2
    blt invalid_input
    cmp r3, #100
    bgt invalid_input

    ldr r0, =even_msg
    mov r1, r3
    bl printf

    mov r4, #2
    mov r5, #0

even_loop:
    cmp r4, r3
    bgt print_even_sum
    ldr r0, =int_format
    mov r1, r4
    bl printf
    add r5, r5, r4
    add r4, r4, #2
    b even_loop

print_even_sum:
    ldr r0, =sum_even_msg
    mov r1, r5
    bl printf

    ldr r0, =odd_msg
    mov r1, r3
    bl printf

    mov r4, #1
    mov r5, #0

odd_loop:
    cmp r4, r3
    bgt print_odd_sum
    ldr r0, =int_format
    mov r1, r4
    bl printf
    add r5, r5, r4
    add r4, r4, #2
    b odd_loop

print_odd_sum:
    ldr r0, =sum_odd_msg
    mov r1, r5
    bl printf

    mov r0, #0
    bl exit

invalid_input:
    ldr r0, =error_msg
    bl printf
    mov r0, #1
    bl exit

    // 恢复寄存器(exit不会返回,仅作为规范保留)
    pop {r4, r5, r6, lr}
    bx lr

编译运行命令

在树莓派上执行以下命令完成编译运行:

as -o odd_even_sum.o odd_even_sum.s
gcc -o odd_even_sum odd_even_sum.o
./odd_even_sum

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 14:52:35