⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chapter5.htm

📁 win32汇编资料 教程!
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
<Title>5.0-伪代码</Title>
<LINK REL="stylesheet" HREF="css/basestyles.css" TYPE="text/css">
<LINK REL="stylesheet" HREF="css/tutorials.css" TYPE="text/css">
</HEAD>
<BODY>
<h1 align="center">Win32Asm 教程 </h1>
<TABLE ALIGN="CENTER">
			<TR>
			<TD CLASS="tutnav" VALIGN="MIDDLE" WIDTH="60" HEIGHT="20"><A HREF="chapter4.htm">前一章</A></TD>
			<TD CLASS="tutnav" VALIGN="MIDDLE" WIDTH="60" HEIGHT="20">
				<A HREF="contents.htm">目录</A></TD>
			<TD CLASS="tutnav" VALIGN="MIDDLE" WIDTH="60" HEIGHT="20"><A HREF="chapter6.htm">下一章</A></TD>
			</TR>
</TABLE>
<h2>5.0-伪代码</h2>

<p>伪代码是给处理器的指令,它实际上是原始十六进制代码的可读版。因此,汇编是最低级的编程语言。汇编中的所有东西被直接翻译为十六进制码。换句话说,你没有把高级语言翻译为低级语言的编译器上的烦恼,汇编器仅仅把汇编代码转化为原始数据。
</p><p>
本章将讨论一些用来运算,位操作等的伪代码。还有跳转指令,比较等伪代码在后面介绍。</p>

<h2>5.1-一些基本的计算伪代码</h2>
<table align="center" border="1" bordercolor="black">
<tr>
<td class="general1" width="80" align="center">MOV
</td>
</tr>
</table>
<p>
这条指令用来把一个地方移往(事实上是复制到)另一个地方。这个地方可以是寄存器,内存地址或是直接数值(当然只能作为源值)。Mov指令的语法是:
</p>
<p class="def2">
mov 目标,源
</p>
<p>
你可把一个寄存器移往另一个(注意指令是在复制那个值到目标中,尽管“mov”这个名字是移的意思)
</p><p class="def2">
mov edx, ecx
</p><p>
上面的这条指令把ecx的内容复制到了ecx中,源和目标的大小应该一致。例如这个指令是非法的:
</p><p class="def2">
mov al, ecx;非法
</p>
<p>
这条伪代码试图把一个DWORD(32位)值装入一个字节(8位)的寄存器中。这不能个由mov指令来完成(有其他的指令干这事)。但这些指令是允许的因为源和目标在大小上并没有什么不同:
</p>
<p class="def2">
mov al, bl<br/>
mov cl, dl<br/>
mov cx, dx<br/>
mov ecx, ebx<br/>
</p>
<p>
内存地址由offset指示(在win32中,前一章中有更多信息)你也能从地址的某一个地方获得一个值并把它放入一个寄存器中。下面有一个例子:
</p>
<table align="center" width="80%">
<tr>
<td width="10%" class="general3">offset</td>
<td class="general3" width="6%">34</td>
<td class="general3" width="6%">35</td>
<td class="general3" width="6%">36</td>
<td class="general3" width="6%">37</td>
<td class="general3" width="6%">38</td>
<td class="general3" width="6%">39</td>
<td class="general3" width="6%">3A</td>
<td class="general3" width="6%">3B</td>
<td class="general3" width="6%">3C</td>
<td class="general3" width="6%">3D</td>
<td class="general3" width="6%">3E</td>
<td class="general3" width="6%">3F</td>
<td class="general3" width="6%">40</td>
<td class="general3" width="6%">41</td>
<td class="general3" width="6%">42</td>
</tr>
<tr>
<td class="general3">data</td>
<td class="general2">0D</td>
<td class="general2">0A</td>
<td class="general2">50</td>
<td class="general2">32</td>
<td class="general2">44</td>
<td class="general2">57</td>
<td class="general2">25</td>
<td class="general2">7A</td>
<td class="general2">5E</td>
<td class="general2">72</td>
<td class="general2">EF</td>
<td class="general2">7D</td>
<td class="general2">FF</td>
<td class="general2">AD</td>
<td class="general2">C7</td>
</tr>
</table>
<p>
每一个块代表一个字节
</p>
<p>
offset的值这里是用字节的形式表示的,但它事实上是32位的值,比如3A(这不是一个常见的offset的值,但如果不这样简写表格装不下),这也是一个32位的值:0000003Ah。只是为了节省空间,使用了一些不常见的低位offset。所有的值均为16进制。
</p><p>
看上表的offset 3A。那个offset的数据是25, 7A, 5E, 72, EF等。例如,要把这个位于3A的值用mov放入寄存器中:
</p><p class="def2">
mov eax, dword ptr[0000003Ah]
</p><p>
(h后缀表明这是一个十六进制值)
</p><p>
mov eax, dword ptr[0000003Ah]这条指令的意思是:把位于内存地址3A的DWORD大小的值放入eax寄存器。执行了这条指令后,eax包含了值725E7A25h。可能你注意到了这是在内存中时的反转结果:25 7A 5E 72。这是因为存储在内存中的值使用了little endian格式。这意味着越靠右的字节位数越高:字节顺序被反转了。我想一些例子可以使你把这个搞清楚。
</p><p>
十六进制dword(32位)值放在内存中时是这样:40, 30, 20, 10(每个值占一个字节(8位))
</p><p>
十六进制word(16位)值放在内存中时是这样:50, 40
</p><p>
回到前面的例子。你也可以对其他大小的值这么做:
</p><p class="def2">
mov cl, byte ptr [34h] ; cl得到值0Dh(参考上表)</p><p>
mov dx, word ptr [3Eh] ; dx将得到值 7DEFh (看上表,记住反序)
</p><p>
大小有时不是必须的。
</p><p class="def2">
Mov eax,[00403045h]
</p><p>
因为eax是32位寄存器,编译器假定(也只能这么做)它应该从地址403045(十六进制)取个32位的值。
</p><p>
可以直接使用数值:
</p><p class="def2">
mov edx, 5006
</p><p>
这只是使得edx寄存器装有值5006,综括号[和]用来从括号间的内存地址处取值,没有括号就只是这个值。寄存器和内存地址也可以(他应该是32位程序中的32位寄存器):
</p><p class="def2">
mov eax,403045h;使eax装有值403045h(十六进制)</p><p class="def2">
mov cx,[eax];把位于内存地址eax的word大小的值(403045)移入cx寄存器。
</p><p>
在mov cx, [eax]中,处理器会先查看eax装有什么值(=内存地址),然后在那个内存地址中有什么值,并把这个word(16位,因为目标-cx-是个16位寄存器)移入cx。
</p>
<table align="center" border="1" bordercolor="black">
<tr>
<td class="general1" width="180" align="center">ADD, SUB, MUL, DIV
</td>
</tr>
</table>
<p>
许多伪代码做计算工作。你可以猜出它们中的大多数的名字:add(加),sub(减),mul(乘),div(除)等。
</p>
<p>
Add伪代码有如下语法:
</p><p class="def2">
Add 目标,源
</p><p>
执行的运算是 目标=目标+源。下面的格式是允许的。
</p>
<table>
<tr>
<td class="general2">目标</td>
<td class="general2">源</td>
<td class="general2">例子</td>
</tr>
<tr>
<td class="general3">Register</td>
<td class="general3">Register</td>
<td class="general3">add ecx, edx</td>
</tr>
<tr>
<td class="general3">Register</td>
<td class="general3">Memory</td>
<td class="general3">add ecx, dword ptr [104h] / add ecx, [edx]</td>
</tr>
<tr>
<td class="general3">Register</td>
<td class="general3">Immediate value</td>
<td class="general3">add eax, 102</td>
</tr>
<tr>
<td class="general3">Memory</td>
<td class="general3">Immediate value</td>
<td class="general3">add dword ptr [401231h], 80</td>
</tr>
<tr>
<td class="general3">Memory</td>
<td class="general3">Register</td>
<td class="general3">add dword ptr [401231h], edx</td>
</tr>
</table>
<p>
这条指令非常简单。它只是把源值加到目标值中并把结果保存在目标中。其他的数学指令有:
</p>
<p class="def2">
sub 目标,源(目标=目标-源)<br/>
mul 目标,源(目标=目标×源)<br/>
div 源(eax=eax/源,edx=余数)<br/>
</p>
<p>
减法和加法一样做,乘法是目标=目标×源。除法有一点不同,因为寄存器是整数值(注意,绕回数不是浮点数)除法的结果被分为商和余数。例如:
</p>
<p>
28/6->商=4,余数=4<br/>
30/9->商=3,余数=3<br/>
97/10->商=9,余数=7<br/>
18/6->商=3,余数=0<br/>
</p>
<p>
现在,取决于源的大小,商(一部分)被存在eax中,余数(一部分)在edx:
</p>
<table>
<tr>
<td class="general2" width="25%">源大小</td>
<td class="general2" width="25%">除法</td>
<td class="general2" width="25%">商存于</td>
<td class="general2" width="25%">余数存于</td>
</tr>
<tr>
<td class="general3">BYTE (8-bits)</td>
<td class="general3">ax / source</td>
<td class="general3">AL</td>
<td class="general3">AH</td>
</tr>
<tr>
<td class="general3">WORD (16-bits)</td>
<td class="general3">dx:ax* / source</td>
<td class="general3">AX</td>
<td class="general3">DX</td>
</tr>
<tr>
<td class="general3">DWORD (32-bits)</td>
<td class="general3">edx:eax* / source</td>
<td class="general3">EAX</td>
<td class="general3">EDX</td>
</tr>
</table>
<p>
*:例如,如果dx=2030h,而ax=0040h,dx:ax=20300040h。dx:ax是一个双字值。其中高字代表dx,低字代表ax,Edx:eax是个四字值(64位)其高字是edx低字是eax。
</p>
<p>
Div伪代码的源可以是
</p>
<ul>
        <li>an 8-bit register (al, ah, cl,...)</li>
        <li>a 16-bit register (ax, dx, ...)</li>
        <li>a 32-bit register (eax, edx, ecx...)</li>
        <li>an 8-bit memory value (byte ptr [xxxx])</li>
        <li>a 16-bit memory value (word ptr [xxxx])</li>
        <li>a 32-bit memory value (dword ptr [xxxx])</li>
</ul>
<p>
源不可以是直接数值因为处理器不能决定源参数的大小。
</p>
<table align="center" border="1" bordercolor="black">
<tr>
<td class="general1" width="80" align="center">位操作
</td>
</tr>
</table>
<p>
这些指令都由源和目标,除了“NOT”指令。目标中的每位与源中的每位作比较,并看是那个指令,决定是0还是1放入目标位中。
</p>
<table>
        <tr> 
          <td class="general2">指令</td>
          <td colspan="4" class="general2">AND</td>
          <td colspan="4" class="general2">OR</td>
          <td colspan="4" class="general2">XOR</td>
          <td colspan="2" class="general2">NOT</td>
        </tr>
        <tr> 
          <td class="general2">源位</td>
          <td class="general3">0</td>
          <td class="general3">0</td>
          <td class="general3">1</td>
          <td class="general3">1</td>
          <td class="general3">0</td>
          <td class="general3">0</td>
          <td class="general3">1</td>
          <td class="general3">1</td>
          <td class="general3">0</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>
        </tr>
        <tr> 
          <td class="general2">目标位</td>
          <td class="general3">0</td>
          <td class="general3">1</td>
          <td class="general3">0</td>
          <td class="general3">1</td>
          <td class="general3">0</td>
          <td class="general3">1</td>
          <td class="general3">0</td>
          <td class="general3">1</td>
          <td class="general3">0</td>
          <td class="general3">1</td>
          <td class="general3">0</td>
          <td class="general3">1</td>
          <td class="general3">X</td>
          <td class="general3">X</td>
        </tr>
        <tr> 
          <td class="general2">输出位</td>
          <td class="general3">0</td>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -