有四個普遍的布爾型運算符,它們是:AND,OR,XOR和NOT。真值表展示了每一個可能的操作數得到的運算結果。
AND運算符
兩個比特位的AND運算結果只有當這兩位都是1時才為1,否則結果就為0,就像真值表3.1展示的一樣。
處理器支持這些運算指令對數據的所有位平等地進行獨立的運算。例如:如果對AL和BL里的內容進行AND運算,那么基本的AND運算將應用于在這兩個寄存器里的8對比特位中的每一對,像圖3.2 展示的一樣。下面是一個代碼例子:
1 mov ax, 0C123H
2 and ax, 82F6H ; ax = 8022H
OR運算符
兩個比特位的包含OR運算結果只有當這兩位都是0時才為0,否則結果就為1,就像真值表3.2展示的一樣。下面是一個代碼例子:
1 mov ax, 0C123H
2 xor ax, 0E831H ; ax = E933H
XOR運算
兩個比特位的互斥XOR運算結果只有當這兩位相等時為0,否則結果就為1,就像真值表3.3展示的一樣。下面是一個代碼例子:
1 mov ax, 0C123H
2 xor ax, 0E831H ; ax = 2912H
NOT運算
NOT運算符是一元運算符(也就是說,它只對一個操作數進行運算,而不像二元運算符,如:AND)。一個比特位的NOT運算結果是這個位值的相反數,像真值表3.4展示的一樣。下面是一個代碼例子:
1 mov ax, 0C123H
2 not ax ; ax = 3EDCH
注意,NOT能得到一個數的補碼。與其它按位運算不同的是,NOT指令并不修改在FLAGS寄存器里的任何一位。
TEST指令
TEST指令執(zhí)行一次AND運算,但是并不儲存結果。它會基于可能的結果對FLAGS寄存器進行設置(非常像CMP指令執(zhí)行了一次減法操作但是只是設置了FLAGS)。例如:如果結果是0,那么ZF就被置位了。
位操作的應用
位操作對于操縱數據單個位而不修改其它位來說是非常有用的。表3.5展示了這些操作的三個普遍的應用。下面是一些實現了這些想法的代碼例子。
AND運算還可以用來得到除以2的幾次方之后的余數。要得到除以數2i之后的余數,只需對這個數和等于2i -1的掩碼進行AND運算。這個掩碼從位0到位2i - 1都為1,也就是這些位包含了余數。AND運算的結果將保留這些位,而將其它位輸出為0。下面是一個得到100除以16的商和余數的代碼小片斷。
使用CL寄存器,就使得修改數據中的任何一位變得有可能。下面是一個對EAX任意比特位置位(開啟)的例子。需要置位的比特位儲存在BH中。
求反任意一個比特位的代碼留給了讀者,做為一個習題。在一個80x86程序中看到這個莫名其妙的指令是很平常的:
xor eax, eax ; eax = 0
一個數字與自己進行XOR運算,其結果總是0。這條指令被使用是因為它產生的機器代碼比功能相同的MOV指令要少。
更多建議: