汇编语言期末复习——第二章
<p>一、数据表示</p><ol>
<li>数制 16进制H 2进制B</li>
<li>编码<ol>
<li>N位无符号整数范围0~pow(2,N)-1</li>
<li>补码:最高位为符号位,0正1负。负数补码:全取反再加一(算上符号位在内全取反)</li>
<li>字符编码——BCD 8421<ol>
<li>压缩的BCD:一个字节表达两位BCD</li>
<li>非压缩的BCD:二进制八位仅用低四位表达一个BCD</li>
</ol></li>
<li>字符编码——ASCII<ol>
<li>标准ASC码用7位编码,有128个。</li>
<li>不可显示的控制符:前三十二个和最后一个</li>
<li>可显示和打印的字符:从20H开始的95个编码。</li>
<li>A~Z: 41H~5AH</li>
<li>a~z:61H~7AH</li>
<li>大写字母和小写字母相差20H</li>
<li>0~9:30H~39H</li>
<li>空格:20H</li>
<li>回车:0DH</li>
<li>换行:0AH</li>
</ol></li>
<li>字符编码——Unicode 16位</li>
</ol></li>
</ol>
<p>二、常量表达</p>
<ol>
<li>常数
<ul>
<li> 十六进制常数若以字母开头,则要添加前导0.</li>
</ul>
</li>
<li>字符和字符串
<ul>
<li> 用单引号或双引号括起来的单个字符或多个字符,如果字符串中有单引号本身可以用双引号,反之亦然;或者直接用ASC码表示:单引号27H,双引号22H</li>
</ul>
</li>
<li>符号常量
<ul>
<li> 符号定义伪指令:EQU和=</li>
<li> 格式:
<ul>
<li> 符号名 equ 数值表达式</li>
<li><strong> <span style="color: rgba(255, 0, 0, 1)">符号名 equ <字符串></span></strong></li>
<li> 符号名 = 数值表达式</li>
</ul>
</li>
<li><strong> 字符串只能用EQU</strong></li>
<li> 使用等价伪指令EQU给符号定义一个数值或者定义一个字符串,这个<strong>字符串可以是一条处理器指令:CALLDOS EQU <INT 21H></strong></li>
<li><strong> EQU用于数值等价时不能重复定义符号名,等号可以</strong>
<ul>
<li>
<div class="cnblogs_code">
<pre>COUNT EQU COUNT+64H <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">×</span>
COUNT = COUNT+64H <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">√</span></pre>
</div>
<p> </p>
</li>
</ul>
</li>
</ul>
</li>
<li>数值表达式
<ul>
<li>真值255和-1的机器代码都是FFH</li>
<li>128和-128都是80H </li>
</ul>
</li>
</ol>
<p>三、变量应用</p>
<ol>
<li>变量
<ul>
<li>变量是程序运行中随之发生变化的结果,保存在可读可写的主存空间。</li>
<li>实质是主存单元的数据,因而可以改变。</li>
<li><strong>变量表达主存数据,即存储器操作数。</strong></li>
</ul>
</li>
<li>变量定义
<ul>
<li>变量名 变量定义伪指令 初值表</li>
<li><strong>变量名是用户标识符,表示首元素的逻辑地址</strong></li>
<li>变量定义的伪指令有DB DW DD DF DQ DT</li>
<li>?表示初值不确定,DUP为复制操作符 格式:<strong>重复次数 DUP(重复参数)</strong></li>
</ul>
</li>
<li>字节量数据
<ul>
<li>DB 8位</li>
<li>无符号整数0~255</li>
<li>补码表示的有符号整数:-128~+127</li>
<li>一个字符(ASC码值)</li>
<li>压缩的BCD码:0~99</li>
<li>非压缩的BCD码:0~9</li>
</ul>
</li>
<li>字量数据
<ul>
<li>DW 16位</li>
<li>16位数据含高低两个字节,占两个连续的字节存储单元</li>
<li>Intel采用小端方式存储 低对低高对高
<ul>
<li>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">WVAR6DW3139H,3832H
BVAR6DB39H,31H,32H,38H
DB</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">$</span><span style="color: rgba(128, 0, 0, 1)">'</span>
<span style="color: rgba(0, 0, 255, 1)">MOV</span><span style="color: rgba(0, 0, 0, 1)"> DX , MOFFSET WAR6
</span><span style="color: rgba(0, 0, 255, 1)">MOV</span><span style="color: rgba(0, 0, 0, 1)"> AH,09H
</span><span style="color: rgba(0, 0, 255, 1)">INT</span> 21H</pre>
</div>
<p> </p>
</li>
<li>显示结果:91289128</li>
<li>存储:
<table border="0">
<tbody>
<tr>
<td>存储单元</td>
<td>存储器地址</td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td>38H</td>
<td>0035(H)</td>
</tr>
<tr>
<td>32H</td>
<td>0034</td>
</tr>
<tr>
<td>31H</td>
<td>0033</td>
</tr>
<tr>
<td>39H</td>
<td>0032(L)</td>
</tr>
</tbody>
</table>
<table border="0">
<tbody>
<tr>
<td>存储单元</td>
<td>存储器地址</td>
</tr>
<tr>
<td>38H</td>
<td>0039(H)</td>
</tr>
<tr>
<td>32H</td>
<td>0038</td>
</tr>
<tr>
<td>31H</td>
<td>0037</td>
</tr>
<tr>
<td>39H</td>
<td>0036(L)</td>
</tr>
</tbody>
</table>
</li>
</ul>
</li>
</ul>
</li>
<li>双字量数据 略</li>
<li>变量定位
<ul>
<li>变量定义的存储空间:按照书写的先后顺序一个接着一个分配</li>
<li><strong>ORG 参数:控制存放的偏移地址</strong>
<ul>
<li>例:
<div class="cnblogs_code">
<pre>ORG 100H<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">从偏移地址100H处安排</span></pre>
</div>
<p> </p>
</li>
</ul>
</li>
<li>N字节数据起始于能被N整除的地址</li>
<li><strong>ALIGN N控制对齐N字节边界 EVEN语句指示对齐模2地址</strong><br>
<ul>
<li>例:
<div class="cnblogs_code">
<pre>align <span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">对齐2字节地址边界</span></pre>
</div>
<p> </p>
</li>
<li>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)"> org100H
bvar1 db100 </span><span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">0100 64 </span>
<span style="color: rgba(0, 0, 0, 1)"> align 2
wvar2 dw</span><span style="color: rgba(128, 0, 128, 1)">100</span> <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">0102 0064</span>
<span style="color: rgba(0, 0, 0, 1)"> even
dvar3 dd ? </span><span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">010400000000<br>;1.起始地址本应该为0,使用org控制起始于100<br>;2.100下一个地址为101 使用align 2控制地址能整除2 故分配在102<br></span></pre>
</div>
<p> </p>
</li>
<li>顺序执行的指令之间不能使用align和even</li>
</ul>
</li>
</ul>
</li>
<li>变量属性
<ul>
<li>地址属性:<strong>首个</strong>变量所在存储单元的逻辑地址(含有段基地址和偏移地址)</li>
<li>类型属性:变量定义的数据单位</li>
<li>地址操作符</li>
<ul>
<li>
<ul>
<li>
<table border="0">
<tbody>
<tr>
<td>操作符</td>
<td>作用</td>
</tr>
<tr>
<td>[]</td>
<td>将扩起的表达式作为存储器地址指针</td>
</tr>
<tr>
<td>$</td>
<td>返回当前偏移地址</td>
</tr>
<tr>
<td>OFFSET 变量名</td>
<td>返回变量名所在段的偏移地址</td>
</tr>
<tr>
<td>SEG 变量名</td>
<td>返回段地址(高十六位)</td>
</tr>
</tbody>
</table>
</li>
</ul>
</li>
<li>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">bvar db 12h,34h ;000012 34
org $+</span><span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">
array dw </span><span style="color: rgba(128, 0, 128, 1)">1</span>,<span style="color: rgba(128, 0, 128, 1)">2</span>,<span style="color: rgba(128, 0, 128, 1)">3</span>,<span style="color: rgba(128, 0, 128, 1)">4</span>,<span style="color: rgba(128, 0, 128, 1)">5</span>,<span style="color: rgba(128, 0, 128, 1)">6</span>,<span style="color: rgba(128, 0, 128, 1)">7</span>,<span style="color: rgba(128, 0, 128, 1)">8</span>,<span style="color: rgba(128, 0, 128, 1)">9</span>,<span style="color: rgba(128, 0, 128, 1)">10 ;000C0001 0002 0003 0004 0005 0006 0007 0008 0009 000A</span><span style="color: rgba(0, 0, 0, 1)">
wvar dw 5678h,9abch ;0020 5678 9ABC
arr_size = $-array ;0024= 0022-000C = 0018
arr_len = arr_size/</span><span style="color: rgba(128, 0, 128, 1)">2 ;=000C</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> al,bvar
</span><span style="color: rgba(0, 0, 255, 1)">mov</span> ah,bvar+<span style="color: rgba(128, 0, 128, 1)">1</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> bx,wvar[<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">]
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> cx,arr_len
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> dx,$
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> si,offset wvar
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> di,
</span><span style="color: rgba(0, 0, 255, 1)">mov</span> bp,wvar</pre>
</div>
<p> </p>
<br><br></li>
</ul>
<li>类型操作符
<ul>
<li>
<table border="0">
<tbody>
<tr>
<td>操作符</td>
<td>作用</td>
</tr>
<tr>
<td>类型名 PTR 变量名</td>
<td>将变量名按照指定的类型使用</td>
</tr>
<tr>
<td>TYPE 变量名</td>
<td>返回一个字量的数值,表明变量名的类型</td>
</tr>
<tr>
<td>LENGTHOF 变量名</td>
<td>返回整个变量的数据项数(即元素数)</td>
</tr>
<tr>
<td>SIZEOF 变量名</td>
<td>返回整个变量占用的字节数</td>
</tr>
</tbody>
</table>
</li>
</ul>
</li>
</ul>
</li>
</ol>
<p>四、数据寻址方式</p>
<p> 指令的两个部分:<strong>操作码+操作数</strong></p>
<p> 操作码用<strong>助记符</strong>表示,如mov; 操作数为指令执行的参与者,需要通过<strong>地址</strong>指示。</p>
<p> 数据寻址方式:<strong>通过地址查找数据(操作数)</strong></p>
<ol>
<li>立即数寻址
<ul>
<li>操作数紧跟操作码,是机器代码的一部分。</li>
<li>操作数从指令代码立即得到,即立即数。用常量的形式直接表达。</li>
<li>立即数寻址方式只用于源操作数,常用来给寄存器和存储单元赋值。</li>
<li>立即数没有类型,它的类型取决于另一个操作数的类型。</li>
<li>立即数寻址实例
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">mov</span> al,12h <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> ah,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">d</span><span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">字符(ascii)</span>
<span style="color: rgba(0, 128, 128, 1)">labl:</span> <span style="color: rgba(0, 0, 255, 1)">mov</span> bx,-<span style="color: rgba(128, 0, 128, 1)">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)">mov</span> cx,const <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">符号常量;const = 64</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> dx,const*<span style="color: rgba(128, 0, 128, 1)">4</span>/type wvar <span style="color: rgba(0, 128, 0, 1)">;</span><strong><span style="color: rgba(0, 128, 0, 1)">表达式</span></strong>
<span style="color: rgba(0, 0, 255, 1)">mov</span> si,offset bvar <span style="color: rgba(0, 128, 0, 1)">;</span><strong><span style="color: rgba(0, 128, 0, 1)">操作符(byte sizeof lengthof也属于立即数寻址)</span></strong>
<span style="color: rgba(0, 0, 255, 1)">mov</span> di,labl <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">标号也有地址属性 也可以用offset</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> bvar,<span style="color: rgba(128, 0, 128, 1)">01001100b</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> wvar+<span style="color: rgba(128, 0, 128, 1)">2</span>,12h <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">十六进制常数<br></span></pre>
</div>
<p> </p>
</li>
</ul>
</li>
<li>寄存器寻址
<ul>
<li>使用寄存器名表示它的内容 </li>
<li>绝大多数采用通用寄存器寻址(AX,BX,CX,DX,DI,SI,BP,SP)</li>
<li>部分指令支持专用寄存器,例如段寄存器</li>
<li>要注意两个操作数的类型需要匹配(位数相同)</li>
</ul>
</li>
<li>存储器寻址<ol>
<li style="list-style-type: none">
<ul>
<li>存储器的地址使用逻辑地址(段基地址+偏移地址)</li>
<li>段寄存器有默认的使用规则,在寻址存储器操作数时,段寄存器不用显式说明。</li>
<li>
<table border="0">
<tbody>
<tr>
<td>访问存储器方式</td>
<td>默认的段寄存器</td>
<td>可超越的段寄存器</td>
<td>偏移地址</td>
</tr>
<tr>
<td>读取指令</td>
<td>CS</td>
<td> </td>
<td>IP</td>
</tr>
<tr>
<td>堆栈操作</td>
<td>SS</td>
<td> </td>
<td>SP</td>
</tr>
<tr>
<td>一般的数据访问(下列除外)</td>
<td>DS</td>
<td>CS,ES,SS</td>
<td>EA(有效地址)</td>
</tr>
<tr>
<td>BP为基地址的数据访问</td>
<td>SS</td>
<td>CS,ES,SS</td>
<td>EA(有效地址)</td>
</tr>
<tr>
<td>串指令的源操作数</td>
<td>DS</td>
<td>CS,ES,SS</td>
<td>SI</td>
</tr>
<tr>
<td>串指令的目的操作数</td>
<td>ES</td>
<td> </td>
<td>DI</td>
</tr>
</tbody>
</table>
</li>
<li>偏移地址=有效地址</li>
<li>默认规定:
<ul>
<li>DS数据段: [常数]</li>
<li>SS堆栈段: </li>
</ul>
</li>
<li>显示说明:使用段超越指令前缀 例: ds:</li>
<li>主存操作数常通过变量形式引用,一般不需要使用段超越前缀指令</li>
<li>偏移地址的组成:16位有效地址=基址寄存器+变址寄存器+位移量
<ul>
<li>基址寄存器BX,BP</li>
<li>变址寄存器SI,DI</li>
<li>位移量 8或16位有符号值</li>
</ul>
</li>
</ul>
</li>
<li>直接寻址
<ul>
<li>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">mov</span> ax,count<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">也可以表示为:movax,</span><span style="color: rgba(0, 128, 0, 1)">
;</span><span style="color: rgba(0, 128, 0, 1)">假如操作系统为变量COUNT分配的有效地址是2000H</span><span style="color: rgba(0, 128, 0, 1)">
;</span><span style="color: rgba(0, 128, 0, 1)">则反汇编的指令形式为mov ax,ds:</span><span style="color: rgba(0, 128, 0, 1)">
;</span><span style="color: rgba(0, 128, 0, 1)">再假设DS保存段地址为1492H</span><span style="color: rgba(0, 128, 0, 1)">
;</span><span style="color: rgba(0, 128, 0, 1)">则14920H+2000H=16920H</span><span style="color: rgba(0, 128, 0, 1)">
;</span><span style="color: rgba(0, 128, 0, 1)">将地址为16920H的内容传送给AX寄存器,高字节送给AH寄存器,低字节送给AL寄存器</span></pre>
</div>
<p> </p>
</li>
<li>mov指令不支持两个操作数都是存储器操作数</li>
</ul>
</li>
<li>寄存器间接寻址
<ul>
<li>有效地址存放在寄存器中(寄存器内容=偏移地址=有效地址)</li>
<li>用中括号扩起寄存器</li>
<li><strong>可以使用BX、BP、SI和DI寄存器作为间接寻址寄存器</strong></li>
<li>寄存器间接寻址没有说明存储单元类型</li>
<li>例子:
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> al,
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> cx,
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> ,dl
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> word ptr ,1394H
</span><span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">最后一句的说明:</span><span style="color: rgba(255, 0, 0, 1)">
;<strong>寄存器间接寻址没有说明指向的存储单元是何种类型,如果另一个操作数也没有类型,例如立即数,则需要使用类型操作符PTR显式说明</strong></span></pre>
</div>
<p> </p>
</li>
<li>设计寄存器间接寻址的主要目的之一是方便对数组的元素或字符串的字符进行操作。</li>
<li>值得一说的点:
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">mov</span> di,si <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">正确,支持两个操作数都是寄存器操作数</span>
<strong><span style="color: rgba(0, 0, 255, 1)">mov</span> , <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">错误,加了[]后为存储器寻址 相当于存储单元</span></strong></pre>
</div>
<p> </p>
</li>
</ul>
</li>
<li>寄存器相对寻址
<ul>
<li><strong>只有BX、BP、SI和DI可以用作寄存器相对寻址的寄存器</strong></li>
<li><strong>使用BX、SI、DI默认访问数据段数据</strong>,<strong>使用BP默认访问堆栈段数据</strong>;但是都可以使用段超越前缀指令改变访问的逻辑段</li>
<li>例:
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">mov</span> si, <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">也可以表示成:或4 ;位移量:4</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> di, <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">也可以表达为[-08h]但不能是:-08h;位移量:-08H</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> ax,count <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">也可以表达为或 ;位移量:count</span>
<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">eg212.asm 复制字符串</span>
<span style="color: rgba(0, 0, 0, 1)"> .model small
.stack
.data
srcmsg db </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Try your best, why not.$</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
dstmsg db sizeof srcmsg dup(?)
.code
.startup
</span><span style="color: rgba(0, 0, 255, 1)">mov</span> cx,lengthof srcmsg <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">CX=字符串字符个数</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> bx,<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)">EBX指向首个字符</span>
<span style="color: rgba(0, 128, 128, 1)">again:</span> <span style="color: rgba(0, 0, 255, 1)">mov</span> al,srcmsg <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">取源串一个字符送AL</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> dstmsg,al <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">将AL传送给目的串</span>
<span style="color: rgba(0, 0, 255, 1)">add</span> bx,<span style="color: rgba(128, 0, 128, 1)">1</span> <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">加1,指向下一个字符</span>
loop again <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">字符个数CX减1,不为0,则转到AGAIN标号处执行</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> dx,offset dstmsg <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> ah,<span style="color: rgba(128, 0, 128, 1)">9</span>
<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> 21h
.exit
end</span></pre>
</div>
<p> </p>
</li>
</ul>
</li>
<li>基址变址寻址
<ul>
<li>基址寄存器:BX BP</li>
<li>变址寄存器:SI DI</li>
<li>使用BP默认访问堆栈段 其余默认访问数据段 可以使用段超越</li>
<li>例:
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">mov</span> al, <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> ax, <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> ax,<span style="color: rgba(0, 128, 128, 1)">ds:</span> <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">源操作数在数据段,也可以表示为:ds:</span></pre>
</div>
<p> </p>
</li>
</ul>
</li>
<li>相对基址变址寻址
<ul>
<li>基址寄存器:BX BP</li>
<li>变址寄存器:SI DI</li>
<li>使用BP默认访问堆栈段 其余默认访问数据段 可以使用段超越</li>
<li>例:
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">mov</span> cx, <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">源操作数也可以表示为:4</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> ax,80h <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">源操作数也可以表示为:80h</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> dx,count <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">源操作数也可以表示为:</span></pre>
</div>
<p> </p>
</li>
<li>允许每个部分都使用中括号名单时基址寄存器要写在变址寄存器之前</li>
<li>变量和变量名也可以不卸载中括号内,但是这种情况下中括号前和数字开头不能使用正号或者负号。</li>
</ul>
</li>
<li>数据寻址的组合
<ul>
<li>立即数寻址imm</li>
<li>通用寄存器寻址reg</li>
<li>存储器操作数寻址mem</li>
</ul>
</li>
</ol></li>
</ol>
<p>五、课后习题</p>
<p>2.1 (2)字符“F”和数值46H作为mov指令的源操作数有区别吗?</p>
<p> 没区别。</p>
<p> (3)为什么可以把指令“MOV AX,(34+67H)*3”中的数值表达成是常量?</p>
<p> 汇编程序在汇编过程中对数值表达式计算,得到一个确定的数值,故称数值表达式为常量。</p>
<p> (4)汇编语言为什么规定十六进制数若以A~F开头,需要在前面加个0?</p>
<p> 与标识符区分,因为标识符要求为字母或特殊字符开头。</p>
<p> (7)为什么将查找操作数的方法称为数据"寻址"方式?</p>
<p> 指令的操作数要通过存储器地址或IO地址才能找到数据本身,故称数据寻址方式</p>
<p> (8)为什么变量VAR在指令”MOV AX,VAR“中表达直接寻址?</p>
<p> 变量名代表的是逻辑地址的值,VAR表达了变量在主存中的存储单元。</p>
<p>2.2 判断题</p>
<p> (1)对一个正整数,他的补码与无符号数的编码一样。</p>
<p> 对。</p>
<p> (2)常用的BCD码为8421码,其中的8表示D3位的权重。</p>
<p> 对。</p>
<p> (3)排序一般按照ASCII码大小,从小到大升序排列时,小字母排在大写字母之前。</p>
<p> 错。a:61H A:41H</p>
<p> (4)用“DB”和“DW”定义变量,如果初值相同,则占用的存储空间也一样多。</p>
<p> 错。DB占用1字节,DW占用2自结</p>
<p> <strong>(7)某个字变量存放于存储器地址0403H~0404H中,对齐了地址边界。</strong></p>
<p><strong> 错。<span style="color: rgba(255, 0, 0, 1)">字变量为两字节数据,应该对齐于偶数地址。</span></strong></p>
<p> (8)立即数寻址只会存在于源操作数中。</p>
<p> 对。</p>
<p> (9)存储器寻址方式的操作数当然在主存了。</p>
<p> 对。</p>
<p> (10)指令“MOV AX,VAR+2”与“MOV AX,VAR”功能相同。</p>
<p> 对</p>
<p>2.3 填空题</p>
<p> (1)计算机中有一个”01100001“编码,如果把它认为是无符号数,它是十进制数<span style="text-decoration: underline"> 97 </span>;如果认为他是BCD码,则表示真值<span style="text-decoration: underline"> 61 </span>;如果它是某个ASCII码,则代表字符<span style="text-decoration: underline"> a </span>。</p>
<p> (2)C语言用”\n“表示让光标回到下一行首位,在汇编语言中需要输出两个控制字符:一个是回车,其ASCII码是<span style="text-decoration: underline"> ODH(13) </span>,它将光标移动到当前所在行的首位;另一个是换行,其ASCII码是<span style="text-decoration: underline"> OAH(10) </span>,它将光标移到下一行。</p>
<p> (3)定义字节变量的伪指令助记符是<span style="text-decoration: underline"> DB </span>,获取变量名所具有的偏移地址的操作符是<span style="text-decoration: underline"> OFFSET </span>。</p>
<p> (4)数据段有语句”H8843 DD 99008843H",代码段指令“MOV CX, WORD PTR H8843"执行后,CX= <span style="text-decoration: underline"> 8843H </span> 。</p>
<p> (6)数据段有语句“AVC DB 1,2,3”,代码段指令“MOV CL,ABC+2”执行后,CL=<span style="text-decoration: underline"> 3 </span>。</p>
<p> (7)除外设数据外的存储方式有三种,分别称为<span style="text-decoration: underline"> 立即数寻址 </span>、<span style="text-decoration: underline"> 寄存器寻址 </span>和<span style="text-decoration: underline"> 存储器寻址 </span>。</p>
<p> (8)指令“MOV AX,OFFSET MSG”的目的操作数和源操作数分别采用<span style="text-decoration: underline"> 寄存器寻址 </span>和<span style="text-decoration: underline"> 立即数寻址 </span>。</p>
<p> (9)已知SI=04000H,BX=20H,指令“MOV AX,"中访问的有效地址是<span style="text-decoration: underline"> 4028H </span>。</p>
<p> (10)用BX做基地址的指针,默认采用<span style="text-decoration: underline"> DS </span>段寄存器指向的数据段;如果采用BP作为基地址指针,默认使用<span style="text-decoration: underline"> SS </span>段寄存器指向堆栈段。</p>
<p>2.6 将下列压缩BCD码转换为十进制数:</p>
<p> (1)1001 0001 = 9 1</p>
<p> (2)1000 1001 = 8 9</p>
<p> (3) 0011 0110 = 3 6</p>
<p> (4) 1001 0000 = 9 0</p>
<p>2.7 将下列十进制数用8位二进制补码表示:</p>
<p> (1)0 =0000 0000</p>
<p> (2)127 =0111 1111</p>
<p> (3)-127 =1000 0001</p>
<p> (4)-57 =1100 0111</p>
<p>2.8 进行十六进制数的加减运算,并说明是否有进位或错位:</p>
<p> (1)1234H+7802H =8A36H</p>
<p> (2)F034H+5AB0H =4AE4H 前有进位,去掉</p>
<p> (3)C051H-12345H =0AEIDH <strong>以字母开头要有前导零</strong></p>
<p> (4)9876H-ABCDH =0ECA9H</p>
<p>2.10 设置一个数据段,按照如下要求定义变量或符号常量:</p>
<p> (1)my1b为字符串变量:Personal Computer </p>
<p> my1b db 'Personal Computer'</p>
<p> (2)my2b为用十进制表示的字节变量20</p>
<p> my2b db 20</p>
<p> (3)my3b为用十六进制数表示的字节变量20</p>
<p> my3b db 14h</p>
<p> (4)my4b为用二进制表示的字节变量20</p>
<p> my4b db 00010100b</p>
<p> (5)my5w为20个未赋值的字变量</p>
<p> my5w dw 20 dup(?)</p>
<p> (6)my6c为100的常量</p>
<p> my6c = 100</p>
<p> (7)my7c表示字符串:Personal Computer</p>
<p> my7c equ <Personal Computer></p>
<p>2.11 定义常量NUM,其值为5,数据段中定义字数组变量DATALIST,它的头5个字单元中依次存放-10,2,5和4,最后一个单元处置不确定</p>
<p> NUM = 5</p>
<p> DATALIST DW -10,2,5,4,?</p>
<p>2.13写出每条传送指令执行后寄存器AX的内容:</p>
<p> </p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)"> org 100h
varw dw1234h,5678h
varb db</span><span style="color: rgba(128, 0, 128, 1)">3</span>,<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">
vard dd12345678h
buff db10dup(?)
mess db</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">hello</span><span style="color: rgba(128, 0, 0, 1)">'</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> ax,offset mess ;ax=100h+(2*2+2+4+10)=100+14=114h
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> ax,type buff+type mess+type vard ;1+1+4=6
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)"> ax,sizeof varw+sizeof buff+sizeof mess ;2*2+10+5=19=13h
</span><span style="color: rgba(0, 0, 255, 1)">mov</span> ax,lengthof varw+lengthof vard ;2+1=3</pre>
</div>
<p>2.15 数据段有如下定义,8086处理器将以小段方式保存主存:</p>
<div class="cnblogs_code">
<pre>vardd12345678h</pre>
</div>
<p>现以字节为单位按地址从低到高的顺序,写出这个变量内容,并说明如下指令的执行结果:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">mov</span>bx, word ptr var <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">bx=5678h</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span>cx, word ptr var+<span style="color: rgba(128, 0, 128, 1)">2</span> <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">cx=1234h</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span>dl, byteptrvar <span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">dl=78h</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span>dh, byteptrvar+<span style="color: rgba(128, 0, 128, 1)">3 </span><span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">dh=12h</span></pre>
</div>
<p>2.17 说明下列指令中源操作数的寻址方式? 假设VARW是一个字变量。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)">dx,1234h ;立即数寻址
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)">dx,varw ;直接寻址
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)">dx,bx ;寄存器寻址
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)">dx, ;寄存器间接寻址
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)">dx, ;寄存器相对寻址
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)">dx,varw ;寄存器相对寻址
</span><span style="color: rgba(0, 0, 255, 1)">mov</span><span style="color: rgba(0, 0, 0, 1)">dx, ;基址变址寻址
</span><span style="color: rgba(0, 0, 255, 1)">mov</span>dx, ;相对基址变址寻址</pre>
</div>
<p> </p><br><br>
来源:https://www.cnblogs.com/hotaru-klxx/p/15509094.html
頁:
[1]