请仅使用 SHL
和 AND
说明
这种情况的麻烦在于我们无法知道您还可以使用哪些其他指令。您自己的示例已经使用了 MOV
、CMP
、JE
、JMP
,甚至 NOP
。
由于该任务要求循环精确到 16 次迭代,很明显,仅使用 SHL
和 AND
是不可能的。我们至少需要一个条件跳转并使用一个独立的迭代计数器。
基本思想始终是 SHL
将移出的位放入进位标志中。从那里,像 ADC
这样的指令可以选择它并产生结果 BX=1
。
; IN (ax)
mov cx,16
again:
xor bx,bx ; BX=0
shl ax,1 ; -> CF
adc bx,bx ; BX=[0,1]
loop again
现在我将删除您自己没有使用的那些 XOR
、ADC
和 LOOP
说明。本示例仅使用 MOV
、SHL
和 JNC
:
; IN (ax)
mov cx,1
again:
mov bx,0
shl ax,1
jnc cont
mov bx,1
cont:
shl cx,1 ; Produces CF=1 after 16 iterations
jnc again
假设 AX
中的值设置了最低位(如您的示例 0b00101),我们可以不用独立迭代计数器。
; IN (ax)
again:
mov bx,1
jnc cont \
mov bx,1 | These don't change flags
cont: /
jnz again ; Still based on the flags from `shl ax,1`
如果在没有设置最低位的 AX
值上使用此代码段会发生什么,循环将少于 16 次迭代!
如果您觉得至少需要使用一次 AND
指令,您可以使用它来清除 BX
寄存器:
; IN (ax)
mov cx,1
again:
and bx,0 ; ANDing BX with zero produces BX=0
shl ax,1 ; -> CF now has the bit that was shifted out at the high end of AX
jnc cont ; That bit was 0,so BX=0 is fine
mov bx,1 ; Else make BX=1
cont:
shl cx,1 ; Produces carry after 16 iterations
jnc again
在连续迭代中 CX
将保持 1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,0
当值最终变为 0 时,CF 将被设置,因为值加倍(65536)的真实结果不再适合 16 位寄存器。
本文链接:https://www.f2er.com/5403.html