自定义CPU实现斐波那契序列时陷入无限循环的问题排查求助
排查自定义CPU斐波那契代码的无限循环问题
根据你提供的代码、执行流程和指令集,我帮你梳理出几个核心问题,正是这些问题导致了逻辑混乱甚至无限循环:
1. 初始斐波那契数未写入内存
你的代码一开始将AX和BX设为斐波那契的前两个值(1,1),但没有把这两个初始值写入RAM,直接执行ADD AX,BX得到2并存入RAM[0]。这导致RAM中存储的第一个数就不符合预期(应该是1,而非2),后续所有计算的基础都错了。
2. 循环起始位置错误
你用JILT 3跳转到地址3(ADD AX,BX),但每次跳转回来都会直接执行加法,没有先从RAM中正确加载前两个需要相加的数。更严重的是,第一次循环时:
- 执行
MVRR CX,DX后DX=0,接着DEC DX让DX=-1(无效内存地址) MVARD DX,BX试图读取RAM[-1]的值,这会导致未定义行为(模拟器可能返回0或破坏寄存器数据),使得后续的加法逻辑完全混乱。
3. 循环逻辑与预期输出不匹配
你说预期输出前5个斐波那契数,但循环条件是CX < 20——这意味着代码会先生成20个数才会执行输出。如果模拟器在生成过程中因为无效内存访问进入异常状态,就可能陷入无限循环。
修正后的代码示例
以下是调整后的代码,修复了上述问题,能够正确生成并输出前5个斐波那契数:
; Macros for registers $MACRO AX : 0 $MACRO BX : 1 $MACRO CX : 2 $MACRO DX : 3 ; 先将前两个斐波那契数写入RAM MVDR 1, AX MVRAD AX, 0 ; RAM[0] = 1 MVDR 1, BX MVRAD BX, 1 ; RAM[1] = 1 ; 设置循环索引为2(前两个已生成,从第三个开始) MVDR 2, CX ; 循环生成斐波那契数 loop_start: ; 加载前两个数到AX和BX MVARD CX, DX ; DX = CX DEC DX ; DX = CX-1 MVARD DX, BX ; BX = RAM[CX-1] DEC DX ; DX = CX-2 MVARD DX, AX ; AX = RAM[CX-2] ; 相加得到当前斐波那契数 ADD AX, BX ; AX = AX + BX ; 存入RAM MVRAD AX, CX ; 递增索引 INC CX ; 循环条件:生成到第5个数(索引<5) CPRD CX, 5 JILT loop_start ; 跳转到循环起始位置 ; 输出前5个值 MVARD 0, CX OUT CX, 0 MVARD 1, CX OUT CX, 0 MVARD 2, CX OUT CX, 0 MVARD 3, CX OUT CX, 0 MVARD 4, CX OUT CX, 0
关键修正点说明
- 先将初始的1、1写入RAM[0]和RAM[1],确保计算基础正确
- 调整循环起始位置,每次循环先从RAM加载前两个需要相加的数,避免无效内存访问
- 将循环条件改为
CX < 5,符合你输出前5个数的预期,减少不必要的计算 - 明确循环标签(
loop_start),让跳转逻辑更清晰
如果你的模拟器仍然出现无限循环,建议检查以下模拟器实现细节:
CPRD指令是否正确比较寄存器值和常量JILT指令是否正确识别“小于”的条件跳转DEC指令处理0值时是否会正确生成负数,以及模拟器对负内存地址的处理逻辑
内容的提问来源于stack exchange,提问作者Nikki
相关产品推荐
相关产品推荐

