汇编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
,所以没有问题,因为我们在程序的底部。
以下代码用于汇编 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
,所以没有问题,因为我们在程序的底部。