ARM汇编奇偶求和程序段错误问题排查求助
ARM汇编段错误与值覆盖问题修复
错误分析
你的代码存在5个核心问题,直接导致了段错误和值被0覆盖的现象:
伪指令语法错误
原代码中scanf_format: asciz "%d"缺少前缀.,汇编器无法识别该伪指令,会导致scanf使用错误的格式字符串地址,引发输入读取异常。未校验scanf返回值
scanf返回成功读取的参数数量,若输入非整数或读取失败,返回值不等于1。原代码未做校验,会导致后续使用input_num中的非法值,引发逻辑错误。违反ARM调用约定
ARM APCS约定中,r0-r3是调用者保存寄存器,被调用函数(如printf)会直接修改这些寄存器的值。原代码用r2保存input_num地址,多次调用printf后r2被覆盖,导致后续访问input_num时地址错误。无效跳转标签
原代码末尾用b exit跳转,但未定义exit标签,程序会跳转到非法内存地址,直接触发段错误。未保存被调用者寄存器
原代码直接使用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
相关产品推荐
相关产品推荐

