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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 04:19:51