LC-3中如何存储大于16位的数值并将其输出到控制台
LC-3超16位范围数值的存储与显示实现方案
LC-3原生通用寄存器为16位补码格式,仅支持-32768~32767的有符号数取值,要处理超出这个范围的数值,核心思路是跳出单寄存器的存储边界,通过多字拼接扩展等效字长,具体落地方法如下:
存储层落地规则
- 采用双字长(32位)补码结构存储超范围数值:将一个32位整数拆成两个连续的16位存储段,固定把高16位存在低地址单元、低16位存在高地址单元,符号位统一保留在高16位的最高位,和原16位补码的符号规则完全对齐,无需额外做格式转换。
- 运算时采用固定配对的寄存器组存值,比如用R3存当前数的高16位、R4存当前数的低16位,避免位段拆分错位。
基础运算适配逻辑
- 加减法运算:先对两个操作数的低16位做运算,将运算产生的进位/借位临时保留在PSR标志位中,再对两个操作数的高16位做加减法时,把低16位产生的进位/借位值叠加进运算结果,整个流程和硬件字长扩展的逻辑完全一致。
- 大小比较:优先对比两个数的高16位,高16位的比较结果(正/负/相等)直接决定数值的整体大小;只有高16位完全相等时,再对比低16位的大小即可。
十进制显示实现思路
核心是复用通用的“除10取余”转码逻辑,适配32位字长即可,无需重新造轮子:
- 将存在寄存器对里的32位被除数,反复执行32位除以10的运算,每一轮得到的余数范围为0~9,给每个余数加上ASCII偏移量
x30后,临时压入栈存储。 - 32位除以10的简化实现:不用从零手写复杂的长除法逻辑,直接复用提前写好的16位无符号数除以10的子程序:第一次传入高16位得到部分商,把运算产生的余数左移8位拼接上原低16位,作为第二次除法的入参;第二次运算得到的余数,就是整个32位数值除以10的个位值,两次的商拼接起来就是下一轮循环的被除数。
- 所有位的余数取完后,把栈里存的ASCII字符按出栈顺序依次输出到控制台,即可得到正确的十进制显示顺序。
- 遇到负的大数值,先判断高16位的符号位,如果为负就先输出ASCII码
x2D(即减号),再把32位数值转成对应的补码正数,走上面的转码流程即可。
避坑提醒:不要把超过32767的数值直接硬塞进单个寄存器,这种写法会直接触发16位补码溢出,后续所有基于NZP条件码的判断都会完全错位,调试时很难定位问题。
内容的提问来源于stack exchange,提问作者SalvagedDoor
相关产品推荐
相关产品推荐

