汇编8086,LOOP指令不停

Assembly 8086, LOOP instruction doesn't stop

以下代码用于汇编 8086,我正在循环使用 LOOP 指令。

CL 变为零并且将 CX 值更改为 FFFFh 后循环将永远继续。
但是,如果我将 CL 的值更改为最大值 06h,循环将正确停止。
此外,如果我先删除 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 不会跳起来并且操作继续到 跳过部分。如果我将 DATA 的最后一位更改为 1,它将使 JC SKIP 一切正常。

简单回答

    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:
  • 8086 上的 LOOP 指令总是使用 CX 寄存器(全部)。
  • 您的代码错过了第一个 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 寄存器。第二个 LOOP AGAIN 也从 CX 中截取 1 产生 CX=65535.
于是程序愉快地继续了很长时间但并没有变成死循环。因为循环计数器不再是 8(AL 中的位数)的倍数,所以在某个时候它将是第 2 个 LOOP AGAIN 使程序成为 CX=0终于要停止了。

为什么它似乎可以修改

but if I change the value of CL to maximum 06h, the loop stops properly

这就是代码对 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,所以没有问题,因为我们在程序的底部。

If I change the last bit of DATA to 1 it will make the JC SKIP and everything works just fine

这就是代码对 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,所以没有问题,因为我们在程序的底部。