Easy answer
MOV AL, 01001100b
MOV CX, 0008h
SUB BL, BL
SUB DL, DL
AGAIN:
ROL AL, 1
JC SKIP
INC BL
LOOP AGAIN ; The 1st
JMP ENDOFLOOP
SKIP:
INC DL
LOOP AGAIN ; The 2nd
ENDOFLOOP:
- The
LOOP
instruction on 8086 always uses the CX
register (all of it).
- Your code missed an unconditional jump below the 1st
LOOP AGAIN
in case the loop should terminate there. This is to avoid falling through in the SKIP part of the program.
How it fails
MOV AL, 01001100b
MOV CL, 08h
SUB BL, BL
SUB DL, DL
AGAIN:
ROL AL, 1
JC SKIP
INC BL
LOOP AGAIN ; The 1st
SKIP:
INC DL
LOOP AGAIN ; The 2nd
This is what the code does (assuming CH=0
):
ROL AL, 1 LOOP
AL=01001100b AL=10011000b CF=0 BL=1 CX=7 The 1st jumps back
AL=10011000b AL=00110001b CF=1 DL=1 CX=6 The 2nd jumps back
AL=00110001b AL=01100010b CF=0 BL=2 CX=5 The 1st jumps back
AL=01100010b AL=11000100b CF=0 BL=3 CX=4 The 1st jumps back
AL=11000100b AL=10001001b CF=1 DL=2 CX=3 The 2nd jumps back
AL=10001001b AL=00010011b CF=1 DL=3 CX=2 The 2nd jumps back
AL=00010011b AL=00100110b CF=0 BL=4 CX=1 The 1st jumps back
AL=00100110b AL=01001100b CF=0 BL=5 CX=0 The 1st FALLS THROUGH!!!
At this point because CX
became 0 the 1st LOOP AGAIN
no longer jumps back.
The code falls through and falsely increments the DL
register. The 2nd LOOP AGAIN
also pinches off 1 from CX
producing CX=65535
.
So the program happily continues for a very long time but it does not become an infinite loop. Because the loop counter is no longer a multiple of 8 (the number of bits in AL
), at some point it will be the 2nd LOOP AGAIN
that will make CX=0
at which point the program will finally stop.
Why it seems to work with modifications
but if I change the value of CL to maximum 06h, the loop stops properly
This is what the code does with CX=6
:
ROL AL, 1 LOOP
AL=01001100b AL=10011000b CF=0 BL=1 CX=5 The 1st jumps back
AL=10011000b AL=00110001b CF=1 DL=1 CX=4 The 2nd jumps back
AL=00110001b AL=01100010b CF=0 BL=2 CX=3 The 1st jumps back
AL=01100010b AL=11000100b CF=0 BL=3 CX=2 The 1st jumps back
AL=11000100b AL=10001001b CF=1 DL=2 CX=1 The 2nd jumps back
AL=10001001b AL=00010011b CF=1 DL=3 CX=0 The 2nd FALLS THROUGH!!!
Because it's the 2nd LOOP AGAIN
that falls through, there's no problem since we're at the bottom of the program.
If I change the last bit of DATA to 1 it will make the JC SKIP and everything works just fine
This is what the code does with AL=01001101b
:
ROL AL, 1 LOOP
AL=01001101b AL=10011010b CF=0 BL=1 CX=7 The 1st jumps back
AL=10011010b AL=00110101b CF=1 DL=1 CX=6 The 2nd jumps back
AL=00110101b AL=01101010b CF=0 BL=2 CX=5 The 1st jumps back
AL=01101010b AL=11010100b CF=0 BL=3 CX=4 The 1st jumps back
AL=11010100b AL=10101001b CF=1 DL=2 CX=3 The 2nd jumps back
AL=10101001b AL=01010011b CF=1 DL=3 CX=2 The 2nd jumps back
AL=01010011b AL=10100110b CF=0 BL=4 CX=1 The 1st jumps back
AL=10100110b AL=01001101b CF=1 DL=4 CX=0 The 2nd FALLS THROUGH!!!
Because it's the 2nd LOOP AGAIN
that falls through, there's no problem since we're at the bottom of the program.