Сборка 8086, инструкция LOOP не останавливается - PullRequest
0 голосов
/ 19 января 2019

Следующий код предназначен для сборки 8086, я зацикливаюсь, используя инструкцию LOOP.

Цикл продолжается вечно после того, как CL становится равным нулю, и значение CX изменяется на FFFFh.
Но если я изменю значение CL на максимальное значение 06 ч, цикл будет остановлен правильно.
Более того, если я сначала удалю LOOP AGAIN, он будет работать нормально.

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

Я ожидаю, что он будетостановитесь, когда CL станет нулевым.Любая идея, почему он не ведет себя, как ожидалось?

ОБНОВЛЕНИЕ 1 Я заметил, когда CL (или CX при использовании 16 бит) достигает 1 и последний бит равен 0,тогда первый LOOP AGAIN не подпрыгнет, и операция продолжится до части SKIP .Если я изменю последний бит DATA на 1, то получится JC SKIP, и все будет работать нормально.

1 Ответ

0 голосов
/ 21 января 2019

Простой ответ

    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 проваливается, проблем нет, так как мы находимся внизу программы.

...