ARM汇编中如何打印寄存器r12内的计算结果?
解决ARM汇编中打印寄存器值到终端的问题
问题分析
你已经完成数组与向量的点积计算,结果存放在r12寄存器中,但当前代码缺少输出结果到终端的执行逻辑——仅定义格式字符串和缓冲区是不够的,必须通过系统调用或C库函数触发打印操作。
解决方案1:使用Linux系统调用(write)直接打印
这种方式不依赖C库,适合裸机或纯汇编环境。核心是先将整数转为ASCII字符串,再通过write系统调用输出到标准输出。
修改后的完整代码:
.global _start _start: .data @ 数组与向量定义 myArray: .word 3, 5, 2 myVector: .word 0xFFFFFFFF, 3, 0 @ 输出相关定义 output_buffer: .space 20 @ 存储转换后的ASCII字符串 newline: .asciz "\n" .text @ 原有点积计算逻辑 LDR r1, =myArray LDR r5, =myVector LDR r2, [r1] LDR r3, [r5] MUL r4, r2, r3 LDR r6, [r1, #4] LDR r7, [r5, #4] MUL r8, r6, r7 LDR r9, [r1, #8] LDR r10, [r5, #8] MUL r11, r9, r10 ADD r12, r4, r8 ADD r12, r12, r11 @ 新增:将r12中的整数转为ASCII字符串 MOV r0, r12 @ 待转换整数放入r0 LDR r1, =output_buffer @ 缓冲区地址放入r1 BL int_to_ascii @ 调用转换函数 @ 新增:调用write系统调用打印字符串 MOV r0, 1 @ 文件描述符1=标准输出 LDR r1, =output_buffer @ 字符串地址 MOV r2, r4 @ 字符串长度(转换函数返回值在r4) MOV r7, 4 @ sys_write的系统调用号 SWI 0 @ 触发系统调用 @ 打印换行 MOV r0, 1 LDR r1, =newline MOV r2, 1 MOV r7,4 SWI 0 @ 退出程序 MOV r0, 0 MOV r7, 1 SWI 0 @ 整数转ASCII字符串函数:r0=整数,r1=缓冲区地址;返回r4=字符串长度 int_to_ascii: MOV r2, 10 @ 除数10 MOV r3, 0 @ 字符计数 @ 处理负数 CMP r0, #0 BGE positive MOV r4, #'-' STRB r4, [r1] ADD r1, r1, #1 ADD r3, r3, #1 NEG r0, r0 positive: @ 逐位取余转换 loop: CMP r0, #0 BEQ reverse BL div_mod @ r0=r0/10,r4=r0%10 ADD r4, r4, #'0' @ 转为ASCII字符 STRB r4, [r1, r3] ADD r3, r3, #1 B loop reverse: @ 反转字符串(转换后是逆序) MOV r4, r3 @ 保存长度 MOV r5, #0 @ 起始索引 SUB r6, r3, #1 @ 结束索引 reverse_loop: CMP r5, r6 BGE end_reverse LDRB r7, [r1, r5] LDRB r8, [r1, r6] STRB r8, [r1, r5] STRB r7, [r1, r6] ADD r5, r5, #1 SUB r6, r6, #1 B reverse_loop end_reverse: @ 添加字符串结束符 MOV r7, #0 STRB r7, [r1, r3] MOV r4, r3 @ 返回字符串长度 BX lr @ 除法取模函数:r0=被除数,返回r0=商,r4=余数 div_mod: MOV r4, #0 div_loop: CMP r0, r2 BLT end_div SUB r0, r0, r2 ADD r4, r4, #1 B div_loop end_div: BX lr
编译运行命令:
arm-linux-gnueabi-as -o dot_product.o dot_product.s arm-linux-gnueabi-ld -o dot_product dot_product.o qemu-arm ./dot_product
解决方案2:链接C库使用printf打印
这种方式利用C标准库的printf函数,代码更简洁,但需要链接libc。
修改后的代码:
.global main main: .data @ 数组与向量定义 myArray: .word 3, 5, 2 myVector: .word 0xFFFFFFFF, 3, 0 output_format: .asciz "%d\n" @ 格式化字符串 .text @ 原有点积计算逻辑 LDR r1, =myArray LDR r5, =myVector LDR r2, [r1] LDR r3, [r5] MUL r4, r2, r3 LDR r6, [r1, #4] LDR r7, [r5, #4] MUL r8, r6, r7 LDR r9, [r1, #8] LDR r10, [r5, #8] MUL r11, r9, r10 ADD r12, r4, r8 ADD r12, r12, r11 @ 调用printf打印r12的值 LDR r0, =output_format @ 格式化字符串地址放入r0 MOV r1, r12 @ 要打印的整数放入r1 BL printf @ 调用printf @ 退出程序 MOV r0, #0 BL exit
编译运行命令:
arm-linux-gnueabi-gcc -o dot_product dot_product.s qemu-arm ./dot_product
关键说明
- 方案1无需依赖C库,适合底层开发,但需自行实现整数转ASCII的逻辑;
- 方案2利用现成的C库函数,代码更简洁,但需要链接libc,适合快速验证结果;
- ARM系统调用的参数规则:
r0传递第一个参数,r7存放系统调用号(write为4,exit为1)。
内容的提问来源于stack exchange,提问作者Zximy
相关产品推荐
相关产品推荐

