汇编语言-07灵活定位内存地址
<h2>and和or指令</h2><p>and 指令:逻辑与指令,按位进行与运算。</p>
<p><img src="https://img2020.cnblogs.com/blog/1208477/202005/1208477-20200515170317502-701352078.png" alt=""></p>
<p>通过该指令可将操作对象的相应位设为0,其他位不变。</p>
<p><img src="https://img2020.cnblogs.com/blog/1208477/202005/1208477-20200515170336906-336294397.png" alt=""></p>
<p>or指令:逻辑或指令,按位进行或运算。</p>
<p><img src="https://img2020.cnblogs.com/blog/1208477/202005/1208477-20200515170431726-1203430325.png" alt=""></p>
<p>通过该指令可将操作对象的相应位设为1,其他位不变。</p>
<p><img src="https://img2020.cnblogs.com/blog/1208477/202005/1208477-20200515170444330-228662292.png" alt=""></p>
<h2>ASCII码</h2>
<p>信息存储在计算机中,要对其进行编码,将其转化为二进制信息进行存储。而计算机要将这些存储的信息再显示给我们看,就要再对其进行解码。只要编码和解码采用同样的规则,就可以将人能理解的信息存入到计算机,再从计算机中取出。</p>
<p>世界上有很多编码方案,有一种方案叫做ASCII编码,是在计算机系统中通常被采用的。简单地说,所谓编码方案,就是一套规则,它约定了用什么样的信息来表示现实对象。比如说,在ASCII编码方案中,用61H表示“a",62H表示"b"。一种规则需要人们遵守才有意义。</p>
<p><img src="https://img2020.cnblogs.com/blog/1208477/202005/1208477-20200515171742246-383819107.png" alt=""></p>
<h2>以字符形式给出的数据</h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">assume cs:code,ds:data
data segment
db </span><span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(255, 0, 0, 1)">unIX</span><span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
db </span><span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(255, 0, 0, 1)">foRK</span><span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
data ends
code segment
start:mov al,</span><span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(255, 0, 0, 1)">a</span><span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
mov bl,</span><span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(255, 0, 0, 1)">b</span><span style="color: rgba(255, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
mov ax,4c00h
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> 21h
code ends
</span><span style="color: rgba(0, 0, 255, 1)">end</span> start</pre>
</div>
<p>"db 'unIX' '"相当千"db 75H,6EH,49H,58H","u"、"n"、"I"、"X"的ASCll码分别为75H、6EH、49H、58H;<br>"db 'foRK' "相当于"db 66H,6FH,52H,4BH","f"、"o"、"R"、"k"的ASCII码分别为66H、6FH、52H、4BH;<br>"mov al,'a' "相当千"mov al,61H","a"的ASCII码为61H;<br>"mov bl,'b' "相当千"mov al,62H","b"的ASCII码为62H。</p>
<p><img src="https://img2020.cnblogs.com/blog/1208477/202005/1208477-20200518150824659-465546774.png" alt=""></p>
<p>用r命令分析一下,因为“ds=075A”,所以程序从076A开始。cs为076B是指令执行的入口(end start决定),代码段的起始位置为076A,查看下数据即可。</p>
<h2>大小写转换</h2>
<p>字符串“BaSiC",对其中的小写字母所对应的ASCII码进行减20H的处理,将其转为大写,对其中的大写字母不进行改变;字符串"iNtDrMaTiOn", 对其中的大写字母所对应的ASCII码进行加20H 的处理,将其转为小写,而对千其中的小写字母不进行改变。</p>
<p><img src="https://img2020.cnblogs.com/blog/1208477/202005/1208477-20200519093315646-245254664.png" alt=""></p>
<p> </p>
<p>可以看出来,小写字母的ASCII码值比大写字母的ASCII码值大20H。这样,我们可以想到,如果将“a"的ASCII码值减去20H,就可以得到“A”;如果将“A"的ASCII码值加上20H 就可以得到“a"。</p>
<p>必须判断是大写字母还是小写字母,才能决定进行何种处理,而现在又没有可以使用的用于判断的指令。</p>
<p>重新观察,寻找新的规律。可以看出,就ASCII 码的二进制形式来看,除第5位(位数从0开始计算)外,大写字母和小写字母的其他各位都一样。<span style="text-decoration: underline"><span style="color: rgba(255, 0, 0, 1)"><strong>大写字母ASCII码的第5位为0, 小写字母的第5位为1</strong></span></span>。这样,我们就有了新的方法,一个字母,不管它原来是大写还是小写,将它的第5位置0,它就必将变为大写字母:将它的第5 位置1,它就必将变为小写字母。在这个方法中,我们不需要在处理前判断字母的大小写。比如:对于“BaSiC"中的“ B"按要求,它已经是大写字母了,不应进行改变,将它的第5位设为0,它还是大写字母,因为它的第5位本来就是0。</p>
<p>可以用and和or指令把某一位置改为1或0</p>
<div class="cnblogs_code">
<pre>assume cs:codesg,ds:<span style="color: rgba(0, 0, 0, 1)">datasg
datasg segment
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">BaSIC</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">iNforMaTiOn</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
datasg ends
codesg segment
start</span>:mov ax,<span style="color: rgba(0, 0, 0, 1)">datasg
mov ds</span>:ax <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置ds指向datasg段</span>
mov bx,<span style="color: rgba(128, 0, 0, 1)">0</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置(bx)=0,ds:bx指向,BaSiC' 的第一个字母</span>
mov cx,<span style="color: rgba(128, 0, 0, 1)">5</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置循环次数5,因为'BaSiC'有5个字母</span>
<span style="color: rgba(0, 0, 0, 1)">
s</span>:mov al, <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将ASCII码从ds:bx所指向的单元中取出</span>
and al,11011111B <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将al中的ASCII码的第5位置设为0,变成大写</span>
mov ,al <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将转变后的ASCII码写回原单元</span>
inc bx <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">(bx)加1,ds:bx指向下一个字母</span>
<span style="color: rgba(0, 0, 0, 1)"> loop s
mov bx</span>,<span style="color: rgba(128, 0, 0, 1)">5</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置(bx)=5,ds:bx指向'iNfOrMatiOn'的第一个字母</span>
mov cx,<span style="color: rgba(128, 0, 0, 1)">11</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置循环次数11,因为'iNfOrMaTiOn'有十一个字母</span>
<span style="color: rgba(0, 0, 0, 1)">
s0</span>:mov ax,<span style="color: rgba(0, 0, 0, 1)">
or al</span>,00100000B <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将al中的ASCII码的第5位置设为1,变为小写字母</span>
mov ,<span style="color: rgba(0, 0, 0, 1)">al
inc bx
loop s0
mov ax</span>,<span style="color: rgba(0, 0, 0, 1)">4c00h
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> 21h
codesg ends
end start</span></pre>
</div>
<h2></h2>
<p>用的方式来指明一个内存单元,还可以用一种更为灵活的方式来指明内存单元:表示一个内存单元,它的偏移地址为(bx)+idata(bx中的数值加上idata) 。</p>
<p>mov ax, 的含义:</p>
<p>将一个内存单元的内容送入ax, 这个内存单元的长度为2 个字节(字单元),存放一个字,偏移地址为bx中的数值加上200,段地址在ds中。</p>
<p>数学化的描述为: (ax)=((ds)*l6+(bx)+200)</p>
<p>该指令也可以写成如下格式(常用):</p>
<p>mov ax, </p>
<p>mov ax,200</p>
<p>mov ax, .200</p>
<h2>用的方式进行数组的处理</h2>
<p>将datasg中定义的第一个字符串转化为大写,第二个字符串转化为小写。</p>
<div class="cnblogs_code">
<pre>assume cs:codesg,ds:<span style="color: rgba(0, 0, 0, 1)">datasg
datasg segment
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">BaSIC</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">MinIX</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
datasg ends
codesg segment
start</span>:<span style="color: rgba(0, 0, 0, 1)">
codesg ends
end start</span></pre>
</div>
<p>有了这种表示内存单元的方式,我们就可以用更高级的结构来看待所要处理的数据。观察datasg 段中的两个字符串,一个的起始地址为0,另一个的起始地址为5。我们可以将这两个字符串看作两个数组,一个从0地址开始存放,另一个从5开始存放。那么我们可以用和的方式在同一个循环中定位这两个字符串中的字符。</p>
<div class="cnblogs_code">
<pre>assume cs:codesg,ds:<span style="color: rgba(0, 0, 0, 1)">datasg
datasg segment
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">BaSIC</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">MinIX</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
datasg ends
codesg segment
start</span>:mov ax,<span style="color: rgba(0, 0, 0, 1)">datasg
mov ds</span>,ax <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置ds的段地址为datasg的地址</span>
mov bx,<span style="color: rgba(128, 0, 0, 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, 0, 0, 1)">
mov cx</span>,<span style="color: rgba(128, 0, 0, 1)">5</span><span style="color: rgba(0, 0, 0, 1)">
s</span>:mov al,<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">定位第一个字符串中的字符</span>
and al,11011111b <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">第五位变为0,即转为大写</span>
mov ,<span style="color: rgba(0, 0, 0, 1)">al
mov al</span>,[<span style="color: rgba(128, 0, 0, 1)">5</span>+bx]<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">定位第二个字符串中的字符</span>
or al,00100000b <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">第五位转为1,即转为小写</span>
mov [<span style="color: rgba(128, 0, 0, 1)">5</span>+bx],<span style="color: rgba(0, 0, 0, 1)">al
inc bx
loop s
codesg ends
end start</span></pre>
</div>
<p>也可以写成</p>
<div class="cnblogs_code">
<pre>assume cs:codesg,ds:<span style="color: rgba(0, 0, 0, 1)">datasg
datasg segment
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">BaSIC</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">MinIX</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
datasg ends
codesg segment
start</span>:mov ax,<span style="color: rgba(0, 0, 0, 1)">datasg
mov ds</span>,ax <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置ds的段地址为datasg的地址</span>
mov bx,<span style="color: rgba(128, 0, 0, 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, 0, 0, 1)">
mov cx</span>,<span style="color: rgba(128, 0, 0, 1)">5</span><span style="color: rgba(0, 0, 0, 1)">
s</span>:mov al,<span style="color: rgba(128, 0, 0, 1)">0</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">定位第一个字符串中的字符,0代表第一个数组的起始位置</span>
and al,11011111b <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">第五位变为0,即转为大写</span>
mov <span style="color: rgba(128, 0, 0, 1)">0</span>,<span style="color: rgba(0, 0, 0, 1)">al
mov al</span>,<span style="color: rgba(128, 0, 0, 1)">5</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">定位第二个字符串中的字符,5代表第二个数组的起始位置</span>
or al,00100000b <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">第五位转为1,即转为小写</span>
mov <span style="color: rgba(128, 0, 0, 1)">5</span>,<span style="color: rgba(0, 0, 0, 1)">al
inc bx
loop s
codesg ends
end start</span></pre>
</div>
<p>C语言</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">char</span> a=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">BaSiC</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">char</span> b=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MinIX</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
main()
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> i;
i</span>=<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">do</span><span style="color: rgba(0, 0, 0, 1)">
{
a</span>=a&<span style="color: rgba(128, 0, 128, 1)">0xDF</span><span style="color: rgba(0, 0, 0, 1)">;
b</span>=b|1<span style="color: rgba(128, 0, 128, 1)">0x20</span><span style="color: rgba(0, 0, 0, 1)">;
i</span>++<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">while</span>(i<<span style="color: rgba(128, 0, 128, 1)">5</span><span style="color: rgba(0, 0, 0, 1)">);
}</span></pre>
</div>
<p>c语言和汇编语言的相似之处,数组名称就相当于起始地址。</p>
<ul>
<li>C 语言: a,b</li>
<li>汇编语言: 0,5</li>
</ul>
<p>的方式为高级语言实现数组提供了便利机制。</p>
<h2>SI和DI</h2>
<p>si和di是8086CPU中和bx功能相近的寄存器,si和di不能够分成两个8位寄存器来使用。</p>
<p>下面三组实现相同功能:</p>
<p><img src="https://img2020.cnblogs.com/blog/1208477/202005/1208477-20200519104550223-1386894564.png" alt=""></p>
<p> </p>
<p> 下面三组实现相同功能:</p>
<p><img src="https://img2020.cnblogs.com/blog/1208477/202005/1208477-20200519104556865-906030927.png" alt=""></p>
<p>用si和di实现将字符串'welcome to masm!'复制到它后面的数据区中。</p>
<div class="cnblogs_code">
<pre>assume cs:codesg,ds:<span style="color: rgba(0, 0, 0, 1)">datasg
datasg segment
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">welcome to masm !</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">................</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
datasg ends
codesg segment
start</span>:mov ax,<span style="color: rgba(0, 0, 0, 1)">datasg
mov ds</span>,ax <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置ds地址段</span>
<span style="color: rgba(0, 0, 0, 1)">
mov si</span>,<span style="color: rgba(128, 0, 0, 1)">0</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置偏移量</span>
mov di,<span style="color: rgba(128, 0, 0, 1)">16</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, 0, 1)">
mov cx</span>,<span style="color: rgba(128, 0, 0, 1)">8</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, 0, 1)">
s</span>:mov ax, <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将第一个数组的内容移入ax</span>
mov ,ax <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将ax赋值给第二个数组的相同位置</span>
add si,<span style="color: rgba(128, 0, 0, 1)">2</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">数组增量为2</span>
add di,<span style="color: rgba(128, 0, 0, 1)">2</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">增量为2</span>
<span style="color: rgba(0, 0, 0, 1)"> loops
mov ax</span>,<span style="color: rgba(0, 0, 0, 1)">4c00h
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> 21h
codesg ends
end start</span></pre>
</div>
<p>在程序中,用16位寄存器进行内存单元之间的数据传送,一次复制2个字节,一共循环8次。</p>
<p>改进</p>
<div class="cnblogs_code">
<pre>assume cs:codesg,ds:<span style="color: rgba(0, 0, 0, 1)">datasg
datasg segment
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">welcome to masm !</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">................</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
datasg ends
codesg segment
start</span>: mov ax,<span style="color: rgba(0, 0, 0, 1)">datasg
mov ds</span>,ax <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置ds地址段</span>
<span style="color: rgba(0, 0, 0, 1)">
mov si</span>,O <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)">
mov cx</span>,<span style="color: rgba(128, 0, 0, 1)">8</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, 0, 1)">
s</span>:mov ax,<span style="color: rgba(128, 0, 0, 1)">0</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将第一个数组的内容移入ax</span>
mov <span style="color: rgba(128, 0, 0, 1)">16</span>,ax <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将ax赋值给第二个数组的相同位置</span>
add si,<span style="color: rgba(128, 0, 0, 1)">2</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">增量为2</span>
<span style="color: rgba(0, 0, 0, 1)"> loops
mov ax</span>,<span style="color: rgba(0, 0, 0, 1)">4c00h
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> 21h
codesg ends
end start</span></pre>
</div>
<h2>和</h2>
<p>用和 的方式来指明一个内存单元,我们还可以用更为灵活的方式:和。</p>
<p>表示一个内存单元,它的偏移地址为(bx)+(si)(即bx中的数值加上si 中的数值)。</p>
<p>指令mov ax, 的含义如下:</p>
<p>将一个内存单元的内容送入ax,这个内存单元的长度为2 字节(字单元),存放一个字,偏移地址为bx中的数值加上si中的数值,段地址在ds中。</p>
<p>数学化的描述为: (ax)=((ds)*16+(bx)+(si))</p>
<p>该指令也可以写成如下格式(常用):</p>
<p>mov ax,</p>
<h2>和</h2>
<p>表示一个内存单元,它的偏移地址为(bx)+(si)+idata(即bx中的数值加上si中的数值再加上idata)。<br>指令mov ax, 的含义如下:<br>将一个内存单元的内容送入ax, 这个内存单元的长度为2 字节(字单元),存放一个字,偏移地址为bx 中的数值加上si 中的数值再加上idata, 段地址在ds 中。</p>
<p>数学化的描述为: (ax)=((ds)*16+(bx)+(si)+idata)</p>
<p>该指令也可以写成如下格式(常用):</p>
<div class="cnblogs_code">
<pre>mov ax,
mov ax</span>,[<span style="color: rgba(128, 0, 0, 1)">200</span>+bx+<span style="color: rgba(0, 0, 0, 1)">si]
mov ax</span>,<span style="color: rgba(128, 0, 0, 1)">200</span><span style="color: rgba(0, 0, 0, 1)">
mov ax</span>,.<span style="color: rgba(128, 0, 0, 1)">200</span><span style="color: rgba(0, 0, 0, 1)">
mov ax</span>,.<span style="color: rgba(128, 0, 0, 1)">200</span></pre>
</div>
<h2>不同的寻址方式的灵活应用</h2>
<p>(1) 用一个常量来表示地址,可用于直接定位一个内存单元;<br>(2) 用一个变量来表示内存地址,可用于间接定位一个内存单元;<br>(3) 用一个变量和常量表示地址,可在一个起始地址的基础上用变量间接定位一个内存单元;<br>(4) 用两个变量表示地址;<br>(5) 用两个变量和一个常量表示地址。</p>
<h2>多层循环嵌套</h2>
<h3>用dx实现多层循环</h3>
<p><img src="https://img2020.cnblogs.com/blog/1208477/202005/1208477-20200519144917865-1419337475.png" alt=""></p>
<div class="cnblogs_code">
<pre>assume cs:codesg,ds:datasg<span style="color: rgba(0, 0, 0, 1)">
datasg segment
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">ibm </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">十六个字符,占用16个字节,不足的用空格补到16个</span>
db <span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">dec </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">dos </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">vax </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
datasg ends
codesg segment
start</span>:mov ax,<span style="color: rgba(0, 0, 0, 1)">datasg
mov ds</span>,ax<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置数据段地址</span>
mov bx,<span style="color: rgba(128, 0, 0, 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, 0, 0, 1)">
mov cx</span>,<span style="color: rgba(128, 0, 0, 1)">4</span>
<span style="color: rgba(0, 0, 0, 1)">
s0</span>:mov dx,cx <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将外层循环的cx值保存在dx中</span>
mov si,<span style="color: rgba(128, 0, 0, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">
mov cx</span>,<span style="color: rgba(128, 0, 0, 1)">3</span> <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, 0, 1)">
s</span>:mov al,
and al</span>,11011111b <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">转为大写字母</span>
mov ,<span style="color: rgba(0, 0, 0, 1)">al
inc si
loop s
add bx</span>,<span style="color: rgba(128, 0, 0, 1)">16</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">加16到下一个字母,因为每个db占用16个字节</span>
mov cx,dx <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将dx存储的外层循环恢复到cx中</span>
<span style="color: rgba(0, 0, 0, 1)"> loop s0
codesg ends
end start</span></pre>
</div>
<p>用dx来暂时存放cx中的值,如果在内层循环中,dx寄存器也被使用,该怎么办?</p>
<p>CPU中的寄存器数量毕竟是有限的,如8086CPU只有14个寄存器。在上面的程序中,si、cx、ax、bx,显然不能用来暂存cx中的值,因为这些寄存器在循环中也要使用;cs、ip、ds也不能用,因为cs:ip时刻指向当前<br>指令, ds指向datasg 段;可用的就只有: dx 、di 、es 、ss 、sp 、bp等6 个寄存器了。</p>
<h3>使用内存空间实现多层循环</h3>
<p>可以考虑将需要暂存的数据放到内存单元中,需要使用的时候,再从内存单元中恢复。这样我们就需要开辟一段内存空间。</p>
<div class="cnblogs_code">
<pre>assume cs:codesg,ds:datasg<span style="color: rgba(0, 0, 0, 1)">
datasg segment
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">ibm </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">十六个字符,占用16个字节,不足的用空格补到16个</span>
db <span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">dec </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">dos </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">vax </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
dw </span><span style="color: rgba(128, 0, 0, 1)">0</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">前面每个站16字节,所以这个空间偏移量为40H</span>
<span style="color: rgba(0, 0, 0, 1)">datasg ends
codesg segment
start</span>:mov ax,<span style="color: rgba(0, 0, 0, 1)">datasg
mov ds</span>,ax<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置数据段地址</span>
mov bx,<span style="color: rgba(128, 0, 0, 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, 0, 0, 1)">
mov cx</span>,<span style="color: rgba(128, 0, 0, 1)">4</span>
<span style="color: rgba(0, 0, 0, 1)">
s0</span>:mov ds:,cx <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将外层循环的cx值保存在ds:中</span>
mov si,<span style="color: rgba(128, 0, 0, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">
mov cx</span>,<span style="color: rgba(128, 0, 0, 1)">3</span> <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, 0, 1)">
s</span>:mov al,
and al</span>,11011111b <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">转为大写字母</span>
mov ,<span style="color: rgba(0, 0, 0, 1)">al
inc si
loop s
add bx</span>,<span style="color: rgba(128, 0, 0, 1)">16</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">加16到下一个字母,因为每个db占用16个字节</span>
mov cx,ds: <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将datasg:40H单元存储的外层循环恢复到cx中</span>
<span style="color: rgba(0, 0, 0, 1)"> loop s0
codesg ends
end start</span></pre>
</div>
<p>一般来说,在需要暂存数据的时候,都应该使用栈。</p>
<h3>使用栈实现多层循环</h3>
<div class="cnblogs_code">
<pre>assume cs:codesg,ds:datasg,ss:<span style="color: rgba(0, 0, 0, 1)">stacksg
datasg segment
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">ibm </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">十六个字符,占用16个字节,不足的用空格补到16个</span>
db <span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">dec </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">dos </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
db </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">vax </span><span style="color: rgba(0, 0, 0, 1); font-weight: bold">'</span><span style="color: rgba(0, 0, 0, 1)">
datasg ends
stacksg segment </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">定义一个段,用来做栈段,容量为16个字节</span>
dw <span style="color: rgba(128, 0, 0, 1)">0</span>,<span style="color: rgba(128, 0, 0, 1)">0</span>,<span style="color: rgba(128, 0, 0, 1)">0</span>,<span style="color: rgba(128, 0, 0, 1)">0</span>,<span style="color: rgba(128, 0, 0, 1)">0</span>,<span style="color: rgba(128, 0, 0, 1)">0</span>,<span style="color: rgba(128, 0, 0, 1)">0</span>,<span style="color: rgba(128, 0, 0, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">
stacksg ends
codesg segment
start</span>:mov ax,<span style="color: rgba(0, 0, 0, 1)">stacksg
mov ss</span>,<span style="color: rgba(0, 0, 0, 1)">ax
mov sp</span>,<span style="color: rgba(128, 0, 0, 1)">16</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, 0, 1)">
mov ax</span>,<span style="color: rgba(0, 0, 0, 1)">datasg
mov ds</span>,ax<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置数据段地址</span>
mov bx,<span style="color: rgba(128, 0, 0, 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, 0, 0, 1)">
mov cx</span>,<span style="color: rgba(128, 0, 0, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">
s0</span>:<span style="color: rgba(0, 0, 255, 1)">push</span> ,cx <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">将外层循环的cx值压栈</span>
mov si,<span style="color: rgba(128, 0, 0, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">
mov cx</span>,<span style="color: rgba(128, 0, 0, 1)">3</span> <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, 0, 1)">
s</span>:mov al,
and al</span>,11011111b <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">转为大写字母</span>
mov ,<span style="color: rgba(0, 0, 0, 1)">al
inc si
loop s
add bx</span>,<span style="color: rgba(128, 0, 0, 1)">16</span> <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">加16到下一个字母,因为每个db占用16个字节</span>
<span style="color: rgba(0, 0, 255, 1)">pop</span> cx <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">从栈顶弹出原cx的值,恢复cx</span>
loop s0 <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">外层循环的loop指令将cx中的计数值减一</span>
<span style="color: rgba(0, 0, 0, 1)">
codesg ends
end start</span></pre>
</div>
<p> </p>
</div>
<div id="MySignature" role="contentinfo">
如果这篇文章对你有用,可以关注本人微信公众号获取更多ヽ(^ω^)ノ~<br>
<img id="ViewPicture1_GalleryImage" alt="微信公众号二维码" src="https://images.cnblogs.com/cnblogs_com/aeolian/1679458/o_wechat_gzh_qrcode.jpg" style="height: 258 px; width: 258 px; border-width: 0px">
<br><br><br>
来源:https://www.cnblogs.com/aeolian/p/12895984.html
頁:
[1]