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
Your loop that is based on the D1
contatore runs for too long! In an array that has 5 elements, you can do at most 4 comparisons. That's why you wrote #L-1
. However the DBRA
instruction repeats until the count is -1, so in this case you still get 5 iterations which is 1 too many. Also your code will read and possibly write memory that does not belong to the array!
i don't know why the program goes into infinite loop;
An "infinite" loop could result from not having initialized the whole 16-bit counter for the DBRA D1,LOOP
instruction! Better use MOVE.W #L-1,D1
.
When the non-zero D0
register tells you that a change was made to the array, you repeat the whole code. That can work ok, but it is more efficient to realize that the smallest element will have bubbled to the far end and need not be processed any more. The solution is to have an ever decreasing start value for contatore instead of the constant #L-2
(after correction). This way the part of the array that still needs processing becomes shorter and shorter.
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
Tip: Do not neglect the size suffixes. If you move a couple a byte-sized array elements to a couple of data registers, and then compare those registers without specifying the size, the correct result will depend on the defaults that the particular assembler uses. If the default size happens to be .L
or .W
, then your code will work wrong.
So always state what you need and change CMP D2,D3
into CMP.B D2,D3
. A small effort, but a big reward!