汇编语言基础-1 基本语言元素
<h1 class="md-end-block md-heading"><span class="md-plain">1 基本语言元素:</span></h1><p> 本次汇编语言学习,采取的是Microsoft MASA的汇编器语法规则。</p>
<h2 class="md-end-block md-heading"><span class="md-plain">1.1 第一个汇编程序</span></h2>
<p><span class="md-plain"> </span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 0, 1)">main PROC
</span><span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 255, 1)">mov</span> eax,<span style="color: rgba(128, 0, 128, 1)">5 ;把数字5送入寄存器eax</span>
<span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 255, 1)">add</span>eax,<span style="color: rgba(128, 0, 128, 1)">6 ;eax寄存器加6</span>
<span style="color: rgba(0, 128, 128, 1)">4</span>
<span style="color: rgba(0, 128, 128, 1)">5</span> INVOKE ExitProcess,<span style="color: rgba(128, 0, 128, 1)">0</span> ;程序结束<br><span style="color: rgba(0, 128, 0, 1)">6 main ENDP ;结束标记<br></span></pre>
</div>
<p> 这个程序实现的是将寄存器eax赋值为5并自加6然后退出。</p>
<p> 采用一行一行结束这个代码:第一行的main PROC 是程序的入口,相当于一个C语言的main函数</p>
<p> 第二行是mov eax,5把数字5送入寄存器</p>
<p> 第三行把6加到寄存器eax上。</p>
<p> 第五行 调用windows服务(函数)ExitProcess停止服务。</p>
<p> 第六行 作为主程序结束的标志。</p>
<p> </p>
<h2 class="md-end-block md-heading md-focus"><span class="md-plain md-expand">1.2 程序分段</span></h2>
<p><span class="md-plain md-expand"> 为了使程序更加一目了然,架构清楚,需要添加一些标记或声明来标识程序的代码和数据区分区。</span></p>
<p><span class="md-plain md-expand"> 程序有代码段,数据段,堆栈段等等。</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> .data <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">定义为数据区 </span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span> sum DWORD <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">申明变量sum类型为DWORD,初值为0</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span> .code <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">定义为代码区</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">main PROC
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 255, 1)">mov</span> eax,<span style="color: rgba(128, 0, 128, 1)">5</span>
<span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 255, 1)">add</span>eax,<span style="color: rgba(128, 0, 128, 1)">6</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 255, 1)">mov</span> sum,eax<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">将eax寄存器的值赋值给sum变量</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span> INVOKE ExitProcess,<span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">程序结束</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> main ENDP</pre>
</div>
<h2 class="md-end-block md-heading"><span class="md-plain">1.3 整数变量</span></h2>
<p class="md-end-block md-p"><span class="md-plain">格式:</span></p>
<p class="md-end-block md-p"><span class="md-plain">[{+ | -}] digits </span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">首先符号表示,如果为正可以省略,中间是数值,radix是基数也就是进制,如果为十进制可以省略</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">进制需要用缩写来表示</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">二进制 八进制 十进制 和十六进制的缩写分别是 B Q D H来表示</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">例子:</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 0, 128, 1)">26</span> <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">十进制</span>
26D <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">十进制</span>
11b <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">二进制</span>
1Ah <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">十六进制</span>
42q <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">八进制</span></pre>
</div>
<p>需要注意的是如果十六进制是用字母开头的需要在前面添加一个0防止汇编器把该数作为标识符</p>
<h2 class="md-end-block md-heading"><span class="md-plain">1.4 整形常量表达式</span></h2>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">也就是比平时的加减乘除多了一个取模运算</span></p>
<p class="md-end-block md-p md-focus"><span class="md-plain md-expand">运算优先级</span></p>
<table border="0">
<tbody>
<tr>
<td>运算符</td>
<td>名称</td>
<td>优先级</td>
</tr>
<tr>
<td>() </td>
<td>括号</td>
<td>1</td>
</tr>
<tr>
<td>* /</td>
<td>乘除</td>
<td>2</td>
</tr>
<tr>
<td>MOD</td>
<td>取模</td>
<td>3</td>
</tr>
<tr>
<td>+ -</td>
<td>加减</td>
<td>4</td>
</tr>
</tbody>
</table>
<h2 class="md-end-block md-heading md-focus"><span class="md-plain">1.5 实数常量</span></h2>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">实数常量又叫浮点数常量,用来表示十进制的实数和编码(十六进制)实数。十进制数包含一个可选符号,然后整数,然后小数点和一个可选小数部分整数和一个可选指数</span></span></p>
<div class="cnblogs_code">
<pre>【sign】integer.</pre>
</div>
<p>sign 取值{+,-}</p>
<p>exponent 取值 E[{+,-}]integer</p>
<p>例子:</p>
<p> 2.</p>
<p> +3.0</p>
<p> -44.2E+05</p>
<p> 26.E5</p>
<p> </p>
<h2 class="md-end-block md-heading"><span class="md-plain">1.6<span class="md-tab"> <span class="md-plain">字符常量</span></span></span></h2>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">字符常量是指用单引号或者双引号包含的一个字符,汇编器在内存中保存的是字符的ASCII码的数值</span></span></p>
<p class="md-end-block md-p md-focus"><span class="md-tab"> <span class="md-plain md-expand">例如 'A' 就是保存的对应的ASCII码数值保存为数字65或41h</span></span></p>
<h2 class="md-end-block md-heading"><span class="md-plain">1.7<span class="md-tab"> <span class="md-plain">字符串常量</span></span></span></h2>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">字符串常量(string literal)是用单引号或双引号好汉的一个字符序列(包括了空格符等等),嵌套引号使用也是被允许的。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">和字符常量保存一样,字符串常量只是一个一个拆分成字符常量保存在内存中。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">例如:"ABCD"就包含四个字节41h,42h,43h,44h。</span></span></p>
<p class="md-end-block md-p"> </p>
<h2 class="md-end-block md-heading"><span class="md-plain">1.8保留字</span></h2>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">也就是C语言的关键字的意思,这些保留字都是在汇编语言中有特殊含义的,不能随便用。保留字没有大小写的区分,比如MOV和Mov是一样的。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">分类:</span></span></p>
<h3 class="md-end-block md-heading"><span class="md-tab"> <span class="md-plain">指令助记符:</span></span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">如 MOV,ADD和MUL</span></span></p>
<h3 class="md-end-block md-heading"><span class="md-tab"> <span class="md-plain">寄存器名称:</span></span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">如:eax</span></span></p>
<h3 class="md-end-block md-heading"><span class="md-tab"> <span class="md-plain">伪指令:</span></span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">也就是告诉汇编器怎么编程序,比如分段.data,.code这种</span></span></p>
<h3 class="md-end-block md-heading"><span class="md-tab"> <span class="md-plain">属性:</span></span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">变量的属性,比如BYTE和WORD</span></span></p>
<h3 class="md-end-block md-heading"><span class="md-tab"> <span class="md-plain">运算符</span></span></h3>
<h3 class="md-end-block md-heading"><span class="md-tab"> <span class="md-plain">预定义符号</span></span></h3>
<p class="md-end-block md-p md-focus"><span class="md-tab"> <span class="md-plain md-expand">在之前就定义了的,比如@data在汇编时返回常量的整数值</span></span></p>
<p class="md-end-block md-p md-focus"> </p>
<h2 class="md-end-block md-heading md-focus"><span class="md-plain">1.9<span class="md-tab"> <span class="md-plain">标识符(identity)</span></span></span></h2>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">由程序员自己选定的名称,用来标识变量,常数,函数,子程序代码等等。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">标识符的规则:</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">1.包含所有字符</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">2.不区分大小写</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">3.第一个字符必须以字母,下划线,@ ?或%来处理</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">4.标识符不能和保留字冲突</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">5.通常避免用@和下划线作为第一个字符</span></span></p>
<p class="md-end-block md-p"> </p>
<h2 class="md-end-block md-heading"><span class="md-plain">1.10 伪指令</span></h2>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain md-expand">伪指令(directive)是嵌入源代码中的命令,由汇编器识别和执行。汇编器不允许的时候执行伪指令,但是伪指令可以定义变量,宏,和子程序。给内存段分配名称。默认情况下,伪指令不区分大小写。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"><span class="md-plain md-expand"> 由下面例子区分指令和伪指令:</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"><span class="md-plain md-expand"> </span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">test</span> DWORD <span style="color: rgba(128, 0, 128, 1)">26</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> eax,<span style="color: rgba(0, 0, 255, 1)">test</span></pre>
</div>
<p> DWORD伪指令告诉编译器在程序中保留一个双字空间。mov指令在运行时,将test内容复制到eax寄存器中。</p>
<p> 需要注意的是Intel处理器的所有汇编器使用相同指令集,但是有着不同的伪指令。</p>
<h3 class="md-end-block md-heading md-focus"><span class="md-plain md-expand"> 伪指令的功能:定义段</span></h3>
<p><span class="md-plain md-expand"> 汇编器伪指令的一个重要功能就是定义程序区段,也叫段(segment),程序中的段有不同作用,</span></p>
<p><span class="md-plain md-expand"> .</span></p>
<div class="cnblogs_code">
<pre>.data <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">数据段在这里申明变量</span>
<span style="color: rgba(0, 0, 0, 1)">
.code </span><span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)"> .code伪指令标识的程序区段包含了可执行的指令</span>
<span style="color: rgba(0, 0, 0, 1)">
.stack 100h </span><span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">.stack伪指令的程序区段定义了运行时的堆栈大小</span></pre>
</div>
<p> </p>
<h2 class="md-end-block md-heading md-focus"><span class="md-plain md-expand">1.11 指令</span></h2>
<p><span class="md-plain md-expand"> 指令是一种语句,在程序汇编编译时变得可执行,汇编器将指令翻译为机器语言字节,并且运行时由CPU加载执行。</span></p>
<p><span class="md-plain md-expand"> 一条指令由四个部分组成:</span></p>
<p><span class="md-plain md-expand"> 1.标号(可选)</span></p>
<p><span class="md-plain md-expand"> 2.指令助记符(必需)</span></p>
<p><span class="md-plain md-expand"> 3.操作数(一般是必需)</span></p>
<p><span class="md-plain md-expand"> 4.注释(可选</span><span class="md-plain md-expand">)</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">一般格式</span>
[<span style="color: rgba(0, 128, 128, 1)">label:</span>] mnemonic [<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">comment]</span> </pre>
</div>
<h3 class="md-end-block md-heading md-focus"><span class="md-plain"> 1.11.1 标号</span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain md-expand">标号也就是一种标识符,是指令和数据的位置标记。标号位于指令前端,表示指令的地址,同时也可以位于变量的前端,表示变量的地址。标号有两种类型:数据标号和代码标号。</span></span></p>
<p class="md-end-block md-p"><span class="md-tab"><span class="md-plain md-expand"> <strong>数据标号</strong>标识变量的位置,提供了一种方便的手段在代码中引用该变量。例如:</span></span></p>
<p class="md-end-block md-p"> </p>
<div class="cnblogs_code">
<pre>count DWORD <span style="color: rgba(128, 0, 128, 1)">100</span></pre>
</div>
<p> 汇编器为每一个标号分配一个数学位置。可以在一个标号后面定义多个数据项。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">例子:
array DWORD </span><span style="color: rgba(128, 0, 128, 1)">1024</span>,<span style="color: rgba(128, 0, 128, 1)">2048</span><span style="color: rgba(0, 0, 0, 1)">
DWORD </span><span style="color: rgba(128, 0, 128, 1)">4096</span>,<span style="color: rgba(128, 0, 128, 1)">8192</span> </pre>
</div>
<p><strong> 代码标号:</strong></p>
<p><strong> </strong>代码标号用作跳转和循环指令的目标。</p>
<p> 代码标号必须用冒号 : 来结束</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">例子,下面的JMP指令创建一个循环,将程序控制传递给标号target表示的位置<br>target:<br> mov ax,bx<br> ...<br> jmp target<br></span></pre>
</div>
<p> 代码标号可以与指令在同一行,也可以自己独立一行</p>
<h3 class="md-end-block md-heading"><span class="md-plain"> 1.11.2<span class="md-tab"> <span class="md-plain">指令助记符</span></span></span></h3>
<p class="md-end-block md-p md-focus"><span class="md-tab"> <span class="md-plain md-expand">指令助记符(instruction mnemonic)是标记一条指令的短单词。</span></span></p>
<p class="md-end-block md-p md-focus"><span class="md-tab"><span class="md-plain md-expand"> 例子:</span></span></p>
<p class="md-end-block md-p md-focus"><span class="md-tab"><span class="md-plain md-expand"> </span></span></p>
<table border="0">
<tbody>
<tr>
<td>助记符</td>
<td>说明</td>
</tr>
<tr>
<td>MOV</td>
<td>传送(分配)数值</td>
</tr>
<tr>
<td>ADD</td>
<td>两个数值相加</td>
</tr>
<tr>
<td>SUB</td>
<td>从一个数值减去另一个数值</td>
</tr>
<tr>
<td>MUL</td>
<td>两个数值相乘</td>
</tr>
<tr>
<td>JMP</td>
<td>跳转到一个新位置</td>
</tr>
<tr>
<td>CALL</td>
<td>调用一个子程序</td>
</tr>
</tbody>
</table>
<h3 class="md-end-block md-heading"><span class="md-plain"> 1.11.3<span class="md-tab"> <span class="md-plain">操作数</span></span></span></h3>
<p class="md-end-block md-p md-focus"><span class="md-tab"> <span class="md-plain md-expand">操作数也就是指令输入输出的数值,汇编语言的操作个数是0-3个。可以是寄存器,内存操作数,整数表达式和输出输入端口。</span></span></p>
<p class="md-end-block md-p md-focus"><span class="md-tab"><span class="md-plain md-expand"> 例子:</span></span></p>
<p class="md-end-block md-p md-focus"><span class="md-tab"><span class="md-plain md-expand"> </span></span></p>
<table border="0">
<tbody>
<tr>
<td>示例</td>
<td>操作数类型</td>
</tr>
<tr>
<td>96</td>
<td>整数常量</td>
</tr>
<tr>
<td>2+4</td>
<td>证书表达式</td>
</tr>
<tr>
<td>eax </td>
<td>寄存器</td>
</tr>
<tr>
<td>count</td>
<td>内存</td>
</tr>
</tbody>
</table>
<p> 操作数个数示例:</p>
<p> </p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">stc</span> <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">进位标志位置,没有操作数</span>
<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">一个操作数</span>
<span style="color: rgba(0, 0, 255, 1)">inc</span> eax <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">eax加一</span>
<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">两个操作数</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> eax,<span style="color: rgba(128, 0, 128, 1)">5</span> <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">把5赋值给寄存器eax</span>
<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">三个操作数</span>
<span style="color: rgba(0, 0, 255, 1)">imul</span> eax,ebx,<span style="color: rgba(128, 0, 128, 1)">5</span> <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">ebx和5相乘的结果赋值给eax</span></pre>
</div>
<p> </p>
<h3 class="md-end-block md-heading md-focus"><span class="md-plain"> 1.11.4<span class="md-tab"> <span class="md-plain">注释</span></span></span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain">单行注释<span class="md-tab"> <span class="md-plain">采用分号(;)</span></span></span></span></p>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain md-expand">多行注释,用COMMENT伪指令和一个自定义符号开始。</span></span></p>
<div class="cnblogs_Highlighter">
<pre class="brush:cpp;gutter:true;">COMMENT I
THIS is a comment
this is also a comment
I
</pre>
</div>
<p> </p>
<p> </p>
<h3 class="md-end-block md-heading md-focus"><span class="md-plain"> 1.11.5<span class="md-tab"> <span class="md-plain">NOP(空操作)指令</span></span></span></h3>
<p class="md-end-block md-p"><span class="md-tab"> <span class="md-plain md-expand">nop指令,在程序中不做任何作用,但是占有一个字节,常用来将代码对其,把单字节变成偶数字节</span></span></p>
<p> </p><br><br>
来源:https://www.cnblogs.com/Sna1lGo/p/13375353.html
頁:
[1]