汇编 8086,LOOP 指令没有停止

Naw*_*ras 3 assembly loops x86-16

以下代码适用于程序集 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
Run Code Online (Sandbox Code Playgroud)

我希望它在CL变为零时停止。知道为什么它没有按预期运行吗?

更新 1 我注意到当CL(或CX当使用 16 位时)达到 1 并且最后一位为 0,那么第一个LOOP AGAIN不会跳起来并且操作继续到SKIP部分。如果我将DATA的最后一位更改为 1,它将使JC SKIP一切正常。

Sep*_*and 5

简单回答

    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:
Run Code Online (Sandbox Code Playgroud)
  • LOOP8086 上指令总是使用CX寄存器(全部)。
  • LOOP AGAIN如果循环应该在那里终止,您的代码错过了低于 1 次的无条件跳转。这是为了避免在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
Run Code Online (Sandbox Code Playgroud)

这是代码的作用(假设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!!!
Run Code Online (Sandbox Code Playgroud)

此时因为CX变成了 0 1 号LOOP AGAIN就不再往回跳了。代码失败并错误地增加了DL寄存器。第二个LOOP AGAIN也从CX生产中夹断 1 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!!!
Run Code Online (Sandbox Code Playgroud)

因为它是第 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!!!
Run Code Online (Sandbox Code Playgroud)

因为它是第 2 个LOOP AGAIN失败的,所以没有问题,因为我们处于程序的底部。