Loops 汇编8086,循环指令不';停不下来
下面的代码是用于汇编8086的,我使用Loops 汇编8086,循环指令不';停不下来,loops,assembly,x86-16,Loops,Assembly,X86 16,下面的代码是用于汇编8086的,我使用LOOP指令循环 CL变为零后,循环将永远继续,并将CX值更改为FFFFh。 但是如果我将CL的值更改为最大06h,循环将正常停止。 此外,如果我再次删除第一个循环,它将正常工作 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 我希
LOOP
指令循环
CL
变为零后,循环将永远继续,并将CX
值更改为FFFFh。但是如果我将
CL
的值更改为最大06h,循环将正常停止。此外,如果我再次删除第一个
循环
,它将正常工作
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
(或使用16位时的CX
)达到1且最后一位为0时,则第一个循环不会再次跳起,操作继续到跳过部分。如果我将最后一位数据更改为1,它将使JC跳过
,一切正常。答案很简单
- 8086上的
循环
指令始终使用CX
寄存器(全部)
- 您的代码再次错过了第一个
循环下方的无条件跳转
,以防循环在此终止。这是为了避免在程序的跳过部分失败
它是如何失败的
这就是代码所做的(假设CH=0
):
此时,由于CX
变为0,第1个循环不再向后跳。
代码失效并错误地增加DL
寄存器。第二个循环再次
也从CX
生产CX=65535
中挤出1个
因此,程序愉快地持续了很长一段时间,但它并没有成为一个无限循环。由于循环计数器不再是8的倍数(即AL
中的位数),因此在某一点上,它将是第二个循环,使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!!!
因为这是第二次循环
,所以没有问题,因为我们处于程序的底部
如果我将最后一位数据更改为1,它将使JC跳过,并且一切正常
这就是代码对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!!!
因为它是第二个循环
,所以没有问题,因为我们处于程序的底部。循环计数器是cx
,而不是cl
。如果将cl
设置为一个值,请确保ch
在执行此操作之前为零。在第一次循环之后cx
为零。如果随后达到第二个循环
,它会减小cx
(即0->0xFFFF),因此第二个循环将运行65536次,然后cx
将再次达到零,然后它将完成。不明白为什么它会“不停”,它会的。(在您的代码中使用完整的16位cx
来设置计数器,cl
只是它的低8位,所以您不知道高8位(ch
)中有什么可能是重复的,但我认为嵌套的循环
指令在某些地方有更具体的重复。(loop
只有在离开CX=0时才能通过,这意味着下一个loop
无法通过,所以它是一个无限循环。)哦,第二个循环在第一个循环之前一直向上,我忘了检查,所以是的,这永远不会停止,这是对当前状态的正确描述。。。所以,如果我现在明白你想做什么的话,你可能想在第一个循环结束后进行一些跳跃。。(分别计算零和一),类似于jmp AfterSecondLoop
。。。但实际上只需计算一个计数器,另一个是8计数器,所以你们可以在循环完成一次减法后计算它。你的“更新”是正确的。所以你明白为什么它是这样工作的吗?哦,是的,这看起来像是无意中嵌套的循环,因为在尾部复制后意外掉下来。我不明白这有什么意义,只是在循环中数一数。通过使用mov-dl,8
/sub-dl,bl
,在循环外执行8-bl
,您可以获得零的计数。感谢您的详细解释(并重新格式化问题;),我非常感谢。
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!!!
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!!!
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!!!