如何在LC-3汇编中打印寄存器中存储的多位十进制数?
十进制多位数输出解决方案
要处理大于9的十进制有理数输出,核心思路是将数字拆分为单个数位,再按从高位到低位的顺序逐个打印。因为直接取余得到的是低位到高位的数位,所以需要先暂存这些数位,再逆序输出。以下是具体实现方案:
一、整数部分处理(非负)
假设待输出整数存在R3,ASCII偏移(即字符'0'的ASCII值,通常为0x30)存在R6,架构支持栈操作(PUSH/POP)和基础运算:
; 子程序:打印R3中的非负十进制整数 PRINT_DECIMAL_INT: AND R1, R1, #0 ; R1用作数位计数器,初始化0 ; 第一步:拆分数位并压入栈(栈后进先出,实现逆序存储) SPLIT_DIGITS: CMP R3, #9 BLE PUSH_FINAL_DIGIT ; 若剩余数字≤9,直接处理最后一位 ; 除以10,分离商和余数(假设DIV指令将商存回R3,余数存入R5) MOV R4, R3 DIV R4, #10 MOV R3, R4 ADD R5, R5, R6 ; 余数转ASCII字符 PUSH R5 ADD R1, R1, #1 ; 数位计数+1 B SPLIT_DIGITS PUSH_FINAL_DIGIT: ADD R3, R3, R6 ; 最后一位转ASCII PUSH R3 ADD R1, R1, #1 ; 第二步:从栈弹出数位,按高位到低位打印 PRINT_LOOP: CMP R1, #0 BEQ PRINT_DONE ; 所有数位打印完成,退出 POP R0 OUT ; 输出当前ASCII字符 SUB R1, R1, #1 B PRINT_LOOP PRINT_DONE: BX LR ; 返回调用处
无除法指令的替代实现
如果你的架构没有除法指令,可以用减法循环模拟除以10:
; 子程序:将R3中的数除以10,商存回R3,余数存入R5 DIVIDE_BY_10: AND R5, R5, #0 AND R4, R4, #0 ; R4临时存商的计数 DIV_LOOP: CMP R3, #10 BLT DIV_COMPLETE ; 剩余数<10,余数就是当前R3 SUB R3, R3, #10 ADD R4, R4, #1 B DIV_LOOP DIV_COMPLETE: MOV R5, R3 MOV R3, R4 BX LR
把这个子程序嵌入到上面的SPLIT_DIGITS循环中,替换原有的除法逻辑即可。
二、有理数小数部分处理
如果需要打印小数(比如0.123、12.45这类有理数),可以先打印整数部分,再打印小数点,最后处理小数部分:
- 若小数是固定位数(如两位小数),可将小数部分转为整数(比如0.45转为45),重复整数拆分逻辑打印指定位数。
- 若分数形式的有理数(如
a/b),可通过乘10取整的方式逐位获取小数:每次将余数乘以10,除以分母得到当前小数位,余数继续参与下一轮计算,直到余数为0或达到所需精度。
示例(打印两位小数):
; 假设小数部分整数存于R7,需打印2位 PRINT_DECIMAL_FRAC: MOV R2, #2 ; 指定小数位数 PRINT_FRAC_LOOP: CMP R2, #0 BEQ FRAC_DONE ; 拆分最高位小数(如45→4,余数5) MOV R4, R7 DIV R4, #10 MOV R7, R5 ADD R4, R4, R6 OUT SUB R2, R2, #1 B PRINT_FRAC_LOOP FRAC_DONE: BX LR
三、负数处理(可选)
如果需要支持负有理数,只需在打印整数部分前判断数字符号:若为负,先打印'-'(ASCII0x2D),再取数字的绝对值进行后续处理。
内容的提问来源于stack exchange,提问作者Florian
相关产品推荐
相关产品推荐

