【发布时间】:2019-01-19 14:42:51
【问题描述】:
以下代码用于汇编 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(或使用16位时的CX)达到1并且最后一位为0时,第一个LOOP AGAIN不会跳起来,操作继续到SKIP部分.如果我将 DATA 的最后一位更改为 1,它将使 JC SKIP 一切正常。
【问题讨论】:
-
循环计数器是
cx,而不是cl。如果您将cl设置为一个值,请确保ch在此之前为零。 -
在第一个
loop之后,cx为零。如果随后达到第二个loop,它会减少cx(即 0 -> 0xFFFF),因此第二个循环将运行 65536 次,然后cx将再次达到零,然后它将完成。不明白为什么它会“不停”,它会。 (并在代码中使用完整的 16 位cx来设置计数器,cl只是它的低 8 位,所以你不知道高 8 位是什么(ch)) -
How exactly does the x86 LOOP instruction work? 的可能重复项,但我认为在某处嵌套的
loop指令存在更具体的重复项。 (loop只有在离开CX=0的时候才能通过,也就是说下一个loop不能通过,所以是一个无限循环。) -
哦,第二个循环一直在第一个循环之前,我忘了检查,所以是的,这永远不会停止,这是对当前状态的正确描述......所以你想要如果我现在了解您要做什么,可能最终会在第一个循环之后跳转。(分别计算零和一),例如
jmp AfterSecondLoop...但实际上只计算一个计数器,另一个是8 个计数器,因此您可以在循环结束后进行一次减法计算。您的“更新”是正确的。那么你明白它为什么会这样吗? -
哦,是的,这看起来像是无意中嵌套的循环,因为尾部复制后意外掉线。不过,我不明白这一点,只是在循环中数一个。您可以通过在循环外使用
mov dl, 8/sub dl, bl执行8 - bl来获得零计数。