我有这些代码行应该将进位标志设置为1。我通过emu8086中的仿真器运行了此代码,结果显示未设置进位标志。我认为,应将进位标志设置为0xC7(二进制:1100 0111),因为它被移至左侧,因此进位标志应返回1。希望有人能提供帮助。
.model small
.data
.code
main proc
mov ax, 0xC7
xor cl , cl
shl ax,1
jnc a1
inc cl
a1:
shl ax,1
jnc a2
inc cl
a2:
shl ax,1
jnc a3
inc cl
a3:
shl ax,1
jnc a4
inc cl
a4:
endp
end main
答案 0 :(得分:0)
那么您想进行16位移位,但是CF从下半部分的顶部开始设置?我不知道您为什么要这么做,尤其是如果您要去jnc
而不是使用adc cl, 0
来进行CL + = CF。
有很多更有效的方法可以使寄存器的高位字节有效,例如复制寄存器并实际移出位,而不是仅移入寄存器。如果可以使用现代CPU,或者在隔离寄存器中的那些位后使用popcnt
指令。
无论如何,没有一个单独的指令,但是有几个选项可以根据需要设置CF,具体取决于所需的CPU兼容性。最直接的是:
;; 386 for BT/BTS
shl ax, 1
bt ax, 8 ; set CF from the bit that was previously the top of AL
adc cl, 0 ; CL += CF
还有这种方法在旧CPU上可能很慢:x86移位/旋转用&31
(对于64位移位,则是&63
来掩盖计数),因此移位/旋转范围比32位窄< em>可以使用与操作数大小一样大的计数,而不是将其计数为0。
rol
根据从高到低“缠绕”的最后一位来设置CF。 8位寄存器的8计数保持不变,最后一位为低位。此外,286之前的CPU仍然没有掩盖计数,它们只占用与移位计数一样多的时钟周期。 (因此,在没有桶形移位器进行恒定时间旋转的旧式CPU上,这相当慢。)
或者如果Operation section of the manual反映了实际的286实现方式,则将mod size
旋转进行实际的换档工作,但是count != 0
检查是否是否完全基于{ {1}}不是count & 1Fh
。如果有,count mod 8
CF = LSB(dest)
显然,根据特定位设置ZF更加容易,例如
;; 186 for immediate-count shifts/rotates
shl ax, 1
rol ah, 8 ; set CF from the bit that was previously the top of AL
adc cl, 0 ; CL += CF
但是分支与 add ax, ax ; AX <<= 1
test ah, 1 ; ZF = low bit of AH
;test ax, 1<<8 ; ZF = low bit of AH same code size, actually
jz no_increment
inc cl
no_increment:
相比糟透了。
请注意,adc
乘以1基本上没有任何好处,除非您可以将其与寄存器目标一起使用。在某些CPU上,使用shl
左移更为有效。它甚至以相同的方式设置CF(根据之前的最高位)。