树莓派4 32位ARM汇编程序运算结果全为0问题求助
问题排查与修正方案
核心问题分析
你的代码存在两个关键错误,导致运算结果无法正确输出:
- printf参数传递不完整:运算结果的格式化字符串(如
sum_message)包含3个%d占位符,需要传入3个整数参数(输入值1、输入值2、运算结果),但你调用printf时仅传入了前两个参数,第三个参数未设置,导致读取到寄存器的默认残留值(此处为0)。 - 非易失寄存器未遵循调用规范:ARM AAPCS调用标准中,r4-r6属于非易失寄存器,函数使用这些寄存器前必须将其压栈保存,避免被其他函数(如
printf)破坏。
修正后的代码
/* -- two_int_data_op.s -- */ .section .data /* Prompt message */ prompt: .asciz "Please enter two signed integers: " /* Response message */ response: .asciz "You entered %d and %d from the keyboard, now some operations on those values!\n" sum_message: .asciz "Sum of %d and %d is %d\n" /*print out the sum of chosen values*/ product_message: .asciz "Product of %d and %d is %d\n" /*print out the product of chosen values*/ logical_and_message: .asciz "Logical AND of %d and %d is %d\n" /*print out the logical AND of chosen values*/ logical_or_message: .asciz "Logical OR of %d and %d is %d\n" /*print out the logical OR chosen values*/ /* Format pattern for scanf */ pattern: .asciz "%d %d" /* Where scanf will store the number read */ value_read1: .word 0 value_read2: .word 0 .section .text .global main main: push {r4, r5, r6, lr} /* 保存非易失寄存器和返回地址 */ // use r4, r5 as registers holding pointers to value_read1, and value_read2 ldr r4, =value_read1 ldr r5, =value_read2 ldr r0, =prompt /* r0 contains pointer to prompt message */ bl printf /* call printf to output our prompt */ ldr r0, =pattern /* r0 contains pointer to format string for our scan pattern */ mov r1, r4 /* r1 contains pointer to variable label where our first number is stored */ mov r2, r5 /* r2 contains pointer to variable label where our second number is stored */ bl scanf /* call to scanf */ next: ldr r0, =response /* r0 contains pointer to response message */ mov r1, r4 /* r4 contains pointer to value_read1 */ ldr r1, [r1] /* r1 contains value dereferenced from r1 in previous instruction */ mov r2, r5 ldr r2, [r2] bl printf /* call printf to output our response */ // 加法运算与输出 mov r1, r4 /* r4 contains pointer to value_read1 */ ldr r1, [r1] /* r1 contains first input value */ mov r2, r5 ldr r2, [r2] /* r2 contains second input value */ add r6, r1, r2 /* calculate the sum of the two integers, store result r6 */ ldr r0, =sum_message /* r0 contains pointer to sum message */ mov r3, r6 /* 将运算结果传入第三个参数寄存器r3 */ bl printf /* call printf to output sum */ // 乘法运算与输出 mov r1, r4 /* r4 contains pointer to value_read1*/ ldr r1, [r1] /* r1 contains first input value */ mov r2, r5 ldr r2, [r2] /* r2 contains second input value */ mul r6, r1, r2 /* calculate the product of the two integers, store result r6 */ ldr r0, =product_message /* r0 contains pointer to product message*/ mov r3, r6 /* 将运算结果传入第三个参数寄存器r3 */ bl printf /* call printf to output product */ // 按位与运算与输出 mov r1, r4 /* r4 contains pointer to value_read1*/ ldr r1, [r1] /* r1 contains first input value */ mov r2, r5 ldr r2, [r2] /* r2 contains second input value */ and r6, r1, r2 /* bitwise and r1 and r2, store result in r6*/ ldr r0, =logical_and_message /* r0 contains pointer to logical and message*/ mov r3, r6 /* 将运算结果传入第三个参数寄存器r3 */ bl printf // 按位或运算与输出 mov r1, r4 /* r4 contains pointer value_read1 */ ldr r1, [r1] /* r1 contains first input value */ mov r2, r5 ldr r2, [r2] /* r2 contains second input value */ orr r6, r1, r2 /* bitwise or r1, r2, store result in r6 */ ldr r0, =logical_or_message /* r0 contains pointer to logical or message */ mov r3, r6 /* 将运算结果传入第三个参数寄存器r3 */ bl printf mov r0, #0 /* exit code 0 = program terminated normally */ pop {r4, r5, r6, pc} /* 恢复寄存器并退出 */
关键修改说明
- 寄存器保存:在main函数开头将r4、r5、r6与lr一起压栈,结尾恢复,符合ARM调用规范。
- 参数补全:每次调用printf输出运算结果前,将存放在r6的运算结果赋值给r3(printf的第三个参数寄存器),确保格式化字符串的所有占位符都能获取到正确的值。
- (额外优化)移除了格式化字符串末尾多余的空格,避免输出不必要的空白。
内容的提问来源于stack exchange,提问作者Vincent_Matthew
相关产品推荐
相关产品推荐

