从80386开始增加了位操作指令。这些位操作指令可以直接对一个二进制位进行测试、设置和扫描等操作。利用这些指令可以更有效地进行操作。
位操作指令可分为位扫描指令组和位测试及设置指令组。
1. 位测试及设置指令组
位测试和设置指令组含有如下4条指令:位测试(BitTest)指令BT、位测试并取反(Bit Test and Complement)指令BTC、位测试并复位(BitTest and Reset)指令BTR和位测试并置位(Bit Test and Set)指令BTS.
这4条位测试和设置指令的格式如下:
BT OPRD1,OPRD2
BTC OPRD1,OPRD2
BTR OPRD1,OPRD2
BTS OPRD1,OPRD2
其中,操作数OPRD1可以是16位或32位通用寄存器和16位或32位存储单元,用于指定要测试的内容;操作数OPRD2必须是8位立即数或者与操作数OPRD1长度相等的通用寄存器,用于指定要测试的位。
设操作数OPRD2除以操作数OPRD1R的长度后所得商是disp,所得余数是offset.那么这些指令要测试的位是根据如下方法确定的;如果操作数OPRD1是寄存器,Offset是寄存器操作数OPRD1中要测试位的位号;如果操作数OPRD1是存储单元,存储器操作数OPRD1的偏移与disp相加之和是实际测试存储单元的偏移,Offset是该存储单元中要测试位的位号。操作数OPRD2取符号整数值,所以当OPRD2为16位时,可访问(-32K)到(32K-1)范围内的位串,当OPRD2是32位时,可访问(-2G)到(2G-1)范围内的位串。
位测试指令BT的功能是把被测试位的值送标志位CF.
位测试并取反指令BTC的功能是把被测试位的值送标志CF,并且把被测试位取反。
位测试并复位指令BTR的功能是把被测试拉的值送标志CF,并且把被测试位复位,也即清0。
位测试并置位指令BTS的功能是把被测试位的值送标志CF,并且把被测试位置也即置1.
其它标志CF、SF、OF、AF和PF无定位
OPRD1是寄存器例如:
MOV BX,4567H ;7H->0111B(第三位是0)
MOV ECX,3
BT BX,CX ;CF=0,BX=4567H
BTC BX,3 ;CF=0,BX=456FH(第三位取反7H->0111B(取反)->1111B)
BTR BX,CX ;CF=1,BX=4567H(第三位清0)
BTS EBX,ECX ;CF=0,BX=4567H(第三位置1)
OPRD1是存储单元例如:
假设数据段有如下变量:
IMAGEW DW 1234H,5678H
IMAGED DD 12345678H
代码段有如下指令(设已置妥DS):
BT IMAGEW,4 ;CF=1,IMAGEW=1234H(第4位是1,34H->00110100B)
MOV CX,22 ;CX是IMAGEW的1.6倍
BTC IMAGEW,CX ;CF=1,[IMAGEW+2]=5638H(2表是1个字=2字节组成,5678H的第六位是1,78H=01111000B->00111000B(取反)->38H)
BTR IMAGED,6 ;CF=1,IMAGED=12345638H(第六位是1,清0算入结果中)
MOVZX EAX,CX
BTS IMAGED,EAX ;CF=0,IMAGED=12745638H(CF取先22们0,在置1算入结果中)
要特别指出,在这些位测试指令中,如果用于指定测试位号的操作数OPRD2是立即数,那么其值不应超过被测试操作数OPRD1的长度,否则将产生未定义的位偏移量。这个规则允许规定在一个寄存器内的任何位移量,而且将存储器位串中的立即数位移量限制在规定存储单元字或双字之内。但汇编程序可以支持对于内存位串的更大的立即数偏移量,汇编程序可将该立即数位移量的低5位(对于32位操作数)或低4位(对于16位打操作数)作为机器指令中的打操作数OPRD2,将该立即数位移量的相应高位右移后加到内存位串开始单元的偏移上,作为机器指令中的操作数OPRD1.
例:如下程序片段把寄存器AL的位0、2、4、6依次重复一次,所得的8位数保存在寄存器AL中:
MOV DL,0
MOV CX,4
MOV BX,0
NEXT:
BT AX,BX ;依次测0、2、4、6位
SETC AH ;根据被测位,置AH
OR DL,AH
ROR DL,1
OR DL,AH
ROR DL,1
INC BX
INC BX
LOOP NEXT
MOV AL,DL
2. 位扫描指令组
位扫描指令组含有如下2条指令:顺向位扫描(BitScan Forward)指令BSF和逆向位扫描(Bit Scan Reverse)指令BSR.
这两条位扫描指令的格式如下:
BSF OPRD1,OPRD2 (位0~位15或位31)
BSR OPRD1,OPRD2 (位15或位31~位0)
其中,操作数OPRD1和OPRD2可以是16或32位通用寄存器和16位或32位存储单元;但操作OPRD1和OPRD2的位数(长度)必须相等。
功能:扫描单字或双字操作数OPRD2中第一个含”1”的位,并把扫描到的第一个含”1”的位的位号送操作数OPRD1。
如果字或双字操作数OPRD2等于0,那么零标志ZF被置1,操作数OPRD1的值不确定;
否则零标志ZF被清0.
其它标志CF、SF、OF、AF和PF无定义。
例:
MOV EBX,12345678H
BSR EAX,EBX ;EAX=1CH(28位),ZF=0
BSF DX,AX ;DX=2,ZF=0
BSF CX,DX ;CX=1,ZF=0
摘录于《汇编语言程序设计教程》