The following code is for assembly 8086, I'm looping using LOOP
instruction.
The loop continues forever after CL
becomes zero and it changes the CX
value to FFFFh.
But if I change the value of CL
to maximum 06h, the loop stops properly.
Moreover, if I remove first LOOP AGAIN
it will work fine.
DATA DB 01001100b
MOV AL, DATA
MOV CL, 08h
SUB BL, BL
SUB DL, DL
AGAIN:
ROL AL, 1
JC SKIP
INC BL
LOOP AGAIN
SKIP:
INC DL
LOOP AGAIN
I expect it to stop when CL
becomes zero. Any idea why it isn't behaving as expected?
UPDATE 1 I have noticed when CL
(or CX
when using 16 bit) reaches 1 and last bit is 0, then the first LOOP AGAIN
won't jump up and operation continues to the SKIP part. If I change the last bit of DATA to 1 it will make the JC SKIP
and everything works just fine.
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:
LOOP
instruction on 8086 always uses the CX
register (all of it). LOOP AGAIN
in case the loop should terminate there. This is to avoid falling through in the SKIP part of the program. 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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.