Easy68K数组元素求和程序卡顿问题求助
Easy68K数组求和程序卡顿问题修复
我在Easy68K环境中写了一个计算数组元素和的程序,但程序出现卡顿。我可能没完全搞懂a0、(a0)以及求和的工作机制,请问该怎么修复?
原代码
ORG $8000 array DC 1,2,3,4,5,6,7,8,9,10 ; DC reserves 4 bytes for each element ; $8000 -> 1, $8004 -> 2, etc. len EQU 10 ; Number of elements in the array sum DC 0 ; Variable to store the sum START: suba.l a0,a0 ; Clear register A0 (set to 0) clr d1 clr d0 movea array,a0 ; Load the address of 'array' into A0 move len,d1 move sum,d0 LOOP: TST d1 ; Check if D1 (counter) is zero beq END ; If zero, exit the loop move (a0),d5 ; Load the value at address A0 into D5 add d5,d0 ; Add D5 to D0 (accumulate sum) addq #4,a0 ; Move to the next element in the array (4-byte step) subq #1,d1 ; Decrease the loop counter by 1 bra LOOP END: SIMHALT END START
问题分析与修复方案
你的代码逻辑本身没有死循环,但存在冗余操作和结果未回写的问题,可能导致你误以为程序卡顿:
- 冗余地址寄存器初始化:
suba.l a0,a0清零A0后再用movea array,a0加载地址,完全可以用lea array,a0一步完成地址加载,更高效。 - 冗余累加器赋值:
clr d0已经将累加器清零,move sum,d0重复加载初始值0,完全可以删除。 - 结果未回写内存:循环结束后,累加器D0中已经存了求和结果,但没有写回
sum变量,导致内存中sum始终为0,容易让你误以为程序没运行。 - 不必要的寄存器开销:用D5中转数组元素完全多余,直接将
(a0)的值加到D0即可。
修复后的代码
ORG $8000 array DC 1,2,3,4,5,6,7,8,9,10 ; 每个元素占4字节长字,地址$8000开始依次存放 len EQU 10 ; 数组元素个数 sum DC 0 ; 存储求和结果的变量 START: clr d1 ; 清零循环计数器D1 clr d0 ; 清零累加器D0(初始和为0) lea array,a0 ; 直接将array的起始地址加载到地址寄存器A0 move #len,d1 ; 加载元素总数到计数器D1 LOOP: TST d1 ; 检查计数器是否为0 beq END ; 计数器为0则退出循环 add (a0),d0 ; 将A0指向的数组元素值加到累加器D0 addq #4,a0 ; A0步进4字节,指向下一个数组元素 subq #1,d1 ; 计数器减1 bra LOOP END: move d0,sum ; 将计算得到的最终和存回sum变量 SIMHALT ; 停止模拟运行 END START
关于A0、(A0)和求和机制的说明
- A0地址寄存器:存储的是内存地址,比如这里是数组
array的起始地址$8000,相当于一个“指针”。 - (A0)间接寻址:表示访问A0中存储的地址所指向的内存单元的值,比如A0=$8000时,
(A0)就是数组第一个元素的值1;A0=$8004时,(A0)就是第二个元素的值2。 - 求和核心逻辑:用A0遍历数组每个元素的地址,每次取出
(A0)的值加到累加器D0;因为每个元素是4字节的长字,所以每次A0加4指向下一个元素;同时用D1作为计数器,递减到0时结束循环,此时D0中就是所有元素的和。
内容的提问来源于stack exchange,提问作者Pizza
相关产品推荐
相关产品推荐

