1

我正在摩托罗拉 68k 上学习组装,我能够按升序而不是降序进行 BubbleSort,我不知道为什么程序会进入无限循环;谢谢!; 编码:

  ORG  $2000
  START LEA  ARRAY,A0
  CLR  D0 *Flag di scambio      
  MOVE.B #L-1,D1 *contatore      
  LOOP  MOVE.B (A0),D2
  MOVE.B 1(A0),D3
  CMP    D2,D3
  BLE    ELSE
  MOVE.B D2,1(A0)
  MOVE.B D3,(A0)
  MOVE.B #1,D0      
  ELSE  ADD  #1,A0
  DBRA D1,LOOP      
  TST D0
  BNE START
  SIMHALT
  ORG  $1000
  ARRAY DC.B 1,5,2,4,3
  L     EQU  5           
  END  START  
4

1 回答 1

1
      MOVE.B #L-1,D1 *contatore      
LOOP  MOVE.B (A0),D2
      MOVE.B 1(A0),D3
      CMP    D2,D3
      BLE    ELSE
      MOVE.B D2,1(A0)
      MOVE.B D3,(A0)
      MOVE.B #1,D0      
ELSE  ADD    #1,A0
      DBRA   D1,LOOP

您基于D1 contatore的循环运行时间过长!在一个有 5 个元素的数组中,您最多可以进行 4 次比较。这就是你写的原因#L-1。但是,该DBRA指令会重复直到计数为-1,因此在这种情况下,您仍然会获得 5 次迭代,这已经是 1 太多了。此外,您的代码将读取并可能写入不属于数组的内存!

我不知道为什么程序会进入无限循环;

没有为DBRA D1,LOOP指令初始化整个 16 位计数器可能会导致“无限”循环!更好用MOVE.W #L-1,D1


当非零D0寄存器告诉您对数组进行了更改时,您重复整个代码。这可以正常工作,但是意识到最小的元素将冒泡到远端并且不再需要处理会更有效。解决方案是让contatore的起始值不断减小,而不是常数#L-2(校正后)。这样,仍然需要处理的数组部分变得越来越短。

START MOVE.W #L-2,D4   *first_contatore

NEXT  LEA    ARRAY,A0
      CLR.L  D0        *Flag di scambio      
      MOVE.W D4,D1     *contatore      
      
LOOP  MOVE.B (A0),D2
      MOVE.B 1(A0),D3
      CMP.B  D2,D3
      BLE    ELSE
      MOVE.B D2,1(A0)
      MOVE.B D3,(A0)
      MOVEQ  #1,D0      
ELSE  ADDQ.L #1,A0
      DBRA   D1,LOOP
      TST.L  D0
      BEQ    DONE      *Nothing was changed, earliest exit
      DBRA   D4,NEXT

DONE  SIMHALT

提示:不要忽略大小后缀。如果您将几个字节大小的数组元素移动到几个数据寄存器,然后在不指定大小的情况下比较这些寄存器,则正确的结果将取决于特定汇编程序使用的默认值。如果默认大小恰好是.Lor .W,那么您的代码将出错。
因此,请始终说明您需要什么并更改CMP D2,D3CMP.B D2,D3. 小小的努力,却收获很大!

于 2021-12-04T16:56:14.777 回答