32位ARM汇编求和程序输出异常求助:结果为极小负数
32位ARM汇编printf参数传递错误导致求和结果异常
你的问题出在printf的参数传递不符合ARM APCS调用规范:
- 对于C标准库函数(比如printf),ARM 32位的调用约定是:前4个参数依次用
r0-r3寄存器传递,超过4个的参数需要压入栈中。 - 你的
response格式串有4个%d,对应4个参数,前三个你已经放到了r1-r3,但第四个求和结果你放到了r4,printf根本不会读取r4的值,所以第四个%d拿到的是栈上的随机垃圾数据,表现为极小负数。 - 你后来尝试的
ldr r4, [r4]完全错误,因为r4里存的是求和后的数值,不是内存地址,去读取这个地址自然会触发段错误。
修复后的代码:
.section .data prompt: .asciz "Hello, enter three integer values (Place a space in between each value): " response: .asciz "You entered the numbers %d, %d, and %d and the sum is %d" pattern: .asciz "%d %d %d" input1: .word 0 input2: .word 0 input3: .word 0 .section .text .global main main: push {lr} ldr r4, =input1 ldr r5, =input2 ldr r6, =input3 ldr r0, =prompt bl printf ldr r0, =pattern mov r1, r4 mov r2, r5 mov r3, r6 bl scanf mov r1, r4 ldr r1, [r1] mov r2, r5 ldr r2, [r2] mov r3, r6 ldr r3, [r3] add r7, r3, r1 add r7, r7, r2 ldr r0, =response ; 第四个参数需要压栈,因为前三个用了r1-r3 push {r7} bl printf ; 调用完printf后要恢复栈指针,平衡栈空间 add sp, sp, #4 mov r0, #0 pop {pc}
关键说明:
- 调用printf前,把求和结果
r7压入栈中,这样printf就能正确读取第四个参数。 - 调用完成后执行
add sp, sp, #4恢复栈指针,避免后续栈操作出现异常。 - 你也可以调整参数寄存器分配:把第三个输入值压栈,将求和结果放到
r3,但上面的写法更贴合你原有代码的逻辑。
内容的提问来源于stack exchange,提问作者BeefCake
相关产品推荐
相关产品推荐

