📄 chapter5.htm
字号:
<td class="general3">0</td>
<td class="general3">0</td>
<td class="general3">1</td>
<td class="general3">0</td>
<td class="general3">1</td>
<td class="general3">1</td>
<td class="general3">1</td>
<td class="general3">0</td>
<td class="general3">1</td>
<td class="general3">1</td>
<td class="general3">0</td>
<td class="general3">1</td>
<td class="general3">0</td>
</tr>
</table>
<p>
如果源和目标均为1,AND把输出位设为1。
</p><p>
如果源和目标中有一个为1,OR把输出位设为1。
</p><p>
如果源和目标位不一样,XOR把输出位设为1。
</p><p>
NOT反转源位
</p><p>
一个例子:
</p>
<p class="def2">
mov ax, 3406<br/>
mov dx, 13EAh<br/>
xor ax,dx<br/>
</p>
<p>
ax=3406(十六进制)是二进制的0000110101001110
</p><p>
dx=13EA(十六进制)是二进制的0001001111101010
</p><p>
对这些位进行xor操作:
</p>
<table>
<tr>
<td class="general2" width="30%">源</td>
<td class="general3" width="70%">0001001111101010 (dx)</td>
</tr>
<tr>
<td class="general2">目标</td>
<td class="general3">0000110101001110 (ax)</td>
</tr>
<tr>
<td class="general2">输出</td>
<td class="general3">0001111010100100 (new ax)</td>
</tr>
</table>
<p>
新dx是0001111010100100 (十进制的7845, 十六进制的1EA4)
</p><p>
另一个例子:
</p>
<p class="def2">
mov ecx, FFFF0000h<br/>
not ecx
</p>
<p>
FFFF0000在二进制中是11111111111111110000000000000000(16个1,16个0)如果反转每位会得到
</p>
<p>
00000000000000001111111111111111(16个0,16个1)在十六进制中是0000FFFF。因而执行NOT操作后,ecx是0000FFFFh。
</p>
<table align="center" border="1" bordercolor="black">
<tr>
<td class="general1" width="80" align="center">步增/减
</td>
</tr>
</table>
<p>
有两个很简单的指令,DEC和INC。这些指令使内存地址和寄存器步增或步减,就是这样:
</p>
<p class="def2">
inc reg -> reg = reg + 1<br/>
dec reg -> reg = reg - 1<br/>
inc dword ptr [103405] -> 位于103405的值步增<br/>
dec dword ptr [103405] -> 位于103405的值步减<br/>
</p>
<table align="center" border="1" bordercolor="black">
<tr>
<td class="general1" width="80" align="center">NOP
</td>
</tr>
</table>
<p>
这条指令什么都不干。它仅仅占用空间和时间。它用作填充或给代码打补丁的目的。
</p>
<table align="center" border="1" bordercolor="black">
<tr>
<td class="general1" width="280" align="center">移位(Bit Rotation 和 shifiting)
</td>
</tr>
</table>
<p>
注意:下面的大部分例子使用8位数,但这只是为了使目的清楚。
</p>
<p>
<B>Shifting函数</B>
</p>
<p class="def2">
SHL 目标,计数(count)<br/>
SHR 目标,计数(count)
</p>
<P>
SHL和SHR在寄存器,内存地址中像左或向右移动一定数目(count)的位。
</p><p>
例如:
</p>
<p class="def2">
;这儿al=01011011(二进制)<br/>
shr al, 3
</p>
<p>
它的意思是:把al寄存器中的所有位向右移三个位置。因而al会变成为00001011。左边的字节用0填充,而右边的字节被移出。最后一个被移出的位保存在carry-flag中。Carry-flag是处理器标志寄存器的一位,它不是像eax或ecx一样的,你可以访问的寄存器(虽然有伪代码干这活),但它的值决定于该指令的结构。它(carry-flag)会在后面解释,你要记住的唯一一件事是carry是标志寄存器的一位且它可以被打开或者关闭。这个位等于最后一个移出的位。
</p>
<p>
shl和shr一样,只不过是向左移。
</p>
<p class="def2">
;这儿bl=11100101(二进制)<br/>
shl bl, 2
</p>
<p>
执行了指令后bl是10010100(二进制)。最后的两个位是由0填充的,carry-flag是1,因为最后移出的位是1。
</p><p>
还有两个伪代码:
</p>
<p class="def2">
SAL 目标, 计数(算术左移)<br/>
SAR 目标, 计数(算术右移)
</p>
<p>
SAL和SHL一样,但SAR不完全和SHR一样。SAR不是用0来填充移出的位而是复制MSB(最高位)例如:
</p>
<p class="def2">
al = 10100110<br/>
sar al, 3<br/>
al = 11110100<br/>
sar al, 2<br/>
al = 11101001
</p><p>
bl = 00100110<br/>
sar bl, 3<br/>
bl = 00000100
</p>
<p>
<B>Rotation(循环移动) 函数</B>
</p>
<p class="def2">
Rol 目标,计数;循环左移<br/>
Ror 目标,计数;循环右移<br/>
Rcl 目标,计数;通过carry循环左移<br/>
Rcr 目标,计数;通过carry循环右移
</p><p>
循环移动(Rotation)看上去就像移(Shifting),只是移出的位又到了另一边。
</p><p>
例如:ror(循环右移)
</p>
<table>
<tr>
<td width="130"> </td>
<td width="30"> </td>
<td width="40" class="general2">
<div>Bit 7</div>
</td>
<td width="40" class="general2">
<div>Bit 6</div>
</td>
<td width="40" class="general2">
<div>Bit 5</div>
</td>
<td width="40" class="general2">
<div>Bit 4</div>
</td>
<td width="40" class="general2">
<div>Bit 3</div>
</td>
<td width="40" class="general2">
<div>Bit 2</div>
</td>
<td width="40" class="general2">
<div>Bit 1 </div>
</td>
<td width="40" class="general2">
<div>Bit 0</div>
</td>
<td width="125"> </td>
</tr>
<tr>
<td width="130" class="general2">移位之前</td>
<td width="30"> </td>
<td width="40">
<div ><font color="#FF9999"><b><font color="#FF0000">1</font></b></font></div>
</td>
<td width="40">
<div ><font color="#FF9999"><b><font color="#FF0000">0</font></b></font></div>
</td>
<td width="40">
<div ><font color="#FF9999"><b><font color="#FF0000">0</font></b></font></div>
</td>
<td width="40">
<div ><font color="#FF9999"><b><font color="#FF0000">1</font></b></font></div>
</td>
<td width="40">
<div ><font color="#FF9999"><b><font color="#FF0000">1</font></b></font></div>
</td>
<td width="40">
<div ><font color="#FF9999"><b><font color="#FF0000">0</font></b></font></div>
</td>
<td width="40">
<div ><font color="#FF9999"><b><font color="#FF0033">1</font></b></font></div>
</td>
<td width="40">
<div ><font color="#FF9999"><b><font color="#FF0000">1</font></b></font></div>
</td>
<td width="125"> </td>
</tr>
<tr>
<td width="130" class="general2">循环移位, 计数= 3</td>
<td width="30"> </td>
<td width="40"> </td>
<td width="40"> </td>
<td width="40"> </td>
<td width="40">
<div ><font color="#FF0000"><b>1</b></font></div>
</td>
<td width="40">
<div ><font color="#FF0000"><b>0</b></font></div>
</td>
<td width="40">
<div ><font color="#FF0000"><b>0</b></font></div>
</td>
<td width="40">
<div ><font color="#FF0000"><b>1</b></font></div>
</td>
<td width="40">
<div ><font color="#FF0000"><b>1</b></font></div>
</td>
<td width="125"><b><font color="#0000CC">0 1 1</font></b> (被移出)</td>
</tr>
<tr>
<td width="130" class="general2">结果</td>
<td width="30"> </td>
<td width="40">
<div ><b><font color="#0000CC">0</font></b></div>
</td>
<td width="40">
<div ><b><font color="#0000CC">1</font></b></div>
</td>
<td width="40">
<div ><b><font color="#0000CC">1</font></b></div>
</td>
<td width="40">
<div ><font color="#FF0000"><b>1</b></font></div>
</td>
<td width="40">
<div ><font color="#FF0000"><b>0</b></font></div>
</td>
<td width="40">
<div ><font color="#FF0000"><b>0</b></font></div>
</td>
<td width="40">
<div ><font color="#FF0000"><b>1</b></font></div>
</td>
<td width="40">
<div ><font color="#FF0000"><b>1</b></font></div>
</td>
<td width="125"> </td>
</tr>
</table>
<p>
如你在上图所见,位循环了。注意,每个被推出的位又移到了另一边。和Shifting一样,carry位装有最后被移出的位。Rcl和Rcr实际上和Rol,Rcr一样。它们的名字暗示了它们用carry位来表明最后移出的位,但和Rol和Ror干同样的事情。它们没有什么不同。
</p>
<table align="center" border="1" bordercolor="black">
<tr>
<td class="general1" width="80" align="center">交换
</td>
</tr>
</table>
<p>
XCHG指令也非常简单。它同在两个寄存器和内存地址之间交换:
</p>
<p class="def2">
eax = 237h<br/>
ecx = 978h<br/>
xchg eax, ecx<br/>
eax = 978h <br/>
ecx = 237h<br/>
</p>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -