Простой ответ
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
на 8086 всегда использует регистр CX
(все это).
- Ваш код пропустил безусловный переход ниже 1
LOOP AGAIN
в случае, если цикл должен завершиться там. Это сделано для того, чтобы избежать попадания в часть программы SKIP .
Как это не получается
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
Вот что делает код (при условии 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!!!
В этот момент, поскольку CX
стал 0, 1-й LOOP AGAIN
больше не возвращается назад.
Код проваливается и ложно увеличивает регистр DL
. 2-й LOOP AGAIN
также отрывает 1 от CX
, производя CX=65535
.
Так что программа счастливо продолжается очень долго , но она не становится бесконечным циклом . Поскольку счетчик цикла больше не кратен 8 (число битов в AL
), в какой-то момент это будет 2-й LOOP AGAIN
, который сделает CX=0
, и в этот момент программа окончательно остановится.
Почему, похоже, работает с модификациями
но если я изменю значение CL на максимум 06h, цикл остановится правильно
Это то, что код делает с 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!!!
Поскольку проваливается 2-й LOOP AGAIN
, проблем нет, поскольку мы находимся внизу программы.
Если я изменю последний бит DATA на 1, это сделает JC SKIP, и все работает просто отлично
Это то, что код делает с 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!!!
Поскольку 2-й LOOP AGAIN
проваливается, проблем нет, так как мы находимся внизу программы.