8086汇编语言学习(六) 8086处理结构化数据(模拟高级语言结构体、数组)
<h1>一、8086汇编定义数据</h1><p> 要处理结构化数据,必须先定义数据。8086汇编作为一门编程语言,定义数据的方式比起复杂的高级语言要简单不少。</p>
<p> 汇编语言贴近机器底层,所处理的数据逻辑上都可以视为二进制数据,按照对不同大小内存单元的处理,分为三种:<strong>db、dw、dd</strong>。</p>
<h3>1.db</h3>
<p> <strong>db 即define byte</strong>,定义一个字节变量。例如 db 1h,代表着db指令后的值占用<strong>一个字节</strong>的内存空间 1h=>01h。</p>
<p> 特别的,使用db可以比较简单的定义字符串数据,例如db "ABC",代表着定义A、B、C三个连续的字符。</p>
<h3>2.dw</h3>
<p> <strong>db 即define word</strong>,定义一个字变量。例如 dw 1h,代表着dw指令后的值占用<strong>一个字/两个字节</strong>的内存空间 1h=>0001h。</p>
<h3>3.dd</h3>
<p> <strong>dd 即define doubleword</strong>,定义一个双字变量。例如 dd 1h,代表着dw指令后的值占用<strong>两个字/四个字节</strong>的内存空间 1h=>0000 0001h。</p>
<p> 在连续定义数据时,可以通过逗号进行缩写。例如 db 1h,2h,3h等价与db 1h;db 2h;db 3h。</p>
<p> 同时上述三种方式都可以与dup关键字(duplicate)使用。例如,定义3个值为1h的字形数据,可以写为dw 3 dup(1h),其等价于dw 1h,1h,1h。在定义复数个相同的数据时,可以简化程序,增强可读性。</p>
<p> <strong>db、dw、dd、dup都属于8086汇编的伪指令,由汇编器在编译时进行处理,并没有对应的机器指令。</strong></p>
<h1>二、8086汇编处理结构化数据</h1>
<p> 之前介绍了8086各种不同方式的内存寻址方式,下面介绍8086如何利用这些多样的寻址方式来处理结构化的数据。</p>
<p> 举一个简单的例子,假设存在一个结构化的数据(公司),拥有五个属性。</p>
<h3>公司属性:</h3>
<p> 公司名称: BLZ<br> 总裁名称: Deckard Cain<br> 公司排名: 15<br> 年收入(亿元): 50<br> 产品: WOW</p>
<p> 需求是,在内存中定义该数据并且对其中的部分属性进行修改,将公司排名修改为10,年收入修改为80,产品名称修改为OWO。</p>
<p><strong> 整理思路后的伪代码:</strong></p>
<p> 1. 先按照顺序在内存中存放对应的数据结构</p>
<p> 2. 找到公司排名所在的内存地址,将其修改(偏移地址 0Fh) </p>
<p> 3. 找到年收入所在的内存地址,将其修改(偏移地址 11h)</p>
<p> 4. 找到产品所在的内存地址(14h),并将产品名称字符串中的字符逐一修改 </p>
<p> 令P=0h<br> 修改13h+P处的字符<br> P=P+1h<br> 修改13h+P处的字符<br> P=P+1h<br> 修改13h+P处的字符</p>
<p> <img src="https://img2020.cnblogs.com/i-beta/1506329/202003/1506329-20200309171946670-1316128199.png" alt=""></p>
<p><strong>根据上述伪代码,写出对应汇编程序:</strong></p>
<div class="cnblogs_code">
<pre>assume <span style="color: rgba(0, 128, 128, 1)">cs:</span>codesg,<span style="color: rgba(0, 128, 128, 1)">ds:</span><span style="color: rgba(0, 0, 0, 1)">data
data segment
db </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">BLZ</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)">Deckard Cain</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 128, 0, 1)">; 定义公司名称、总裁名称
</span> dw 15h,50h<span style="color: rgba(0, 128, 0, 1)">; 定义排名、年收入
</span> db <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">WOW</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 128, 0, 1)">; 定义产品名称
</span><span style="color: rgba(0, 0, 0, 1)"> data ends
codesg segment
</span><span style="color: rgba(0, 128, 128, 1)">start:</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> ax,data<span style="color: rgba(0, 128, 0, 1)">;
</span> <span style="color: rgba(0, 0, 255, 1)">mov</span> ds,ax<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)"> 设置段基址为data</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> bx,0h<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)"> 设置数据在段中的起始位置为0h</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> word ptr ,10h<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">修改排名所在的字数据为10</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> word ptr ,80h<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)"> 修改收入所在的子数据为80</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> si,<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)"> 引入si变量,遍历产品名称</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> byte ptr ,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">O</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)"> 第一个字符设置为0</span>
<span style="color: rgba(0, 0, 255, 1)">inc</span> si<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)"> si自增1,bx+idata+si 指向下一个字符</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> byte ptr ,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">M</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)"> 第二个字符设置为M</span>
<span style="color: rgba(0, 0, 255, 1)">inc</span> si<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)"> si自增1,bx+idata+si 指向下一个字符</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> byte ptr ,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">O</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)"> 第三个字符设置为0</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> ax,4c00H<span style="color: rgba(0, 128, 0, 1)">;
</span> <span style="color: rgba(0, 0, 255, 1)">int</span> 21H<span style="color: rgba(0, 128, 0, 1)">;
</span><span style="color: rgba(0, 0, 0, 1)">
codesg ends
end start</span></pre>
</div>
<p> 如果用C这种较高级的语言来实现,则简单很多。</p>
<p><strong>用C语言的结构体表示为:</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">struct</span><span style="color: rgba(0, 0, 0, 1)"> company{
</span><span style="color: rgba(0, 0, 255, 1)">char</span> cname[<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">char</span> hname[<span style="color: rgba(128, 0, 128, 1)">12</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> rank;
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> income;
</span><span style="color: rgba(0, 0, 255, 1)">char</span> product[<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">];
} </span></pre>
</div>
<p><strong>用C语言实现需求:</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(0, 0, 255, 1)">struct</span> company blz={<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">BLZ</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)">Deckard Cain</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 128, 1)">15</span>,<span style="color: rgba(128, 0, 128, 1)">50</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">WOW</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)"> 定义数据</span>
<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> i;
blz.rank</span>=<span style="color: rgba(128, 0, 128, 1)">10</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 修改排名</span>
blz.income=<span style="color: rgba(128, 0, 128, 1)">80</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 修改收入</span>
i=<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
blz.product </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">O</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)"> 修改产品名称</span>
i++<span style="color: rgba(0, 0, 0, 1)">;
blz.product </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">M</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
i</span>++<span style="color: rgba(0, 0, 0, 1)">;
blz.product </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">O</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
} </span></pre>
</div>
<p> 通过对比,可以清楚看到,C语言的实现比起汇编要来的轻松和简洁许多。8086汇编提供了指定偏移地址的语法糖,使得寻址时的程序更像高级语言,可读性更高。</p>
<p><strong>将上述的汇编程序以类似C语言的风格进行部分重构:</strong></p>
<div class="cnblogs_code">
<pre>assume <span style="color: rgba(0, 128, 128, 1)">cs:</span>codesg,<span style="color: rgba(0, 128, 128, 1)">ds:</span><span style="color: rgba(0, 0, 0, 1)">data
data segment
db </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">BLZ</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)">Deckard Cain</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 128, 0, 1)">;
</span> dw 15h,50h<span style="color: rgba(0, 128, 0, 1)">;
</span> db <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">WOW</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 128, 0, 1)">;
</span><span style="color: rgba(0, 0, 0, 1)"> data ends
codesg segment
</span><span style="color: rgba(0, 128, 128, 1)">start:</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> ax,data<span style="color: rgba(0, 128, 0, 1)">;
</span> <span style="color: rgba(0, 0, 255, 1)">mov</span> ds,ax<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)"> 设置段基址为data</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> bx,0h<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)"> 设置数据在段中的起始位置为0h</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> word ptr .0fh,10h<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)">修改排名所在的字数据为10</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> word ptr .11h,80h<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)"> 修改收入所在的子数据为80</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> si,<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)"> 引入si变量,遍历产品字段</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> byte ptr .13h,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">O</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)"> 第一个字符设置为0</span>
<span style="color: rgba(0, 0, 255, 1)">inc</span> si<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)"> si自增1,bx+idata+si 指向下一个字符</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> byte ptr .13h,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">M</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)"> 第二个字符设置为M</span>
<span style="color: rgba(0, 0, 255, 1)">inc</span> si<span style="color: rgba(0, 128, 0, 1)">;</span><span style="color: rgba(0, 128, 0, 1)"> si自增1,bx+idata+si 指向下一个字符</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> byte ptr .13h,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">O</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)"> 第三个字符设置为0</span>
<span style="color: rgba(0, 0, 255, 1)">mov</span> ax,4c00H<span style="color: rgba(0, 128, 0, 1)">;
</span> <span style="color: rgba(0, 0, 255, 1)">int</span> 21H<span style="color: rgba(0, 128, 0, 1)">;
</span><span style="color: rgba(0, 0, 0, 1)">
codesg ends
end start </span></pre>
</div>
<p> 主要是对数据内存寻址的方式进行了重构。这里的ds:相当于C程序中的变量blz,.0fh相当于blz的属性rank,而.11h则相当于blz的属性income。</p>
<p> .14h相当于blz的属性product,.14h相当于product字符数组中的某一字符项。</p>
<p> <strong>使用类似高级语言语法的寻址方式优化过后的汇编程序,比标准化的寻址方式更易理解,减少了程序出错的可能性。</strong></p><br><br>
来源:https://www.cnblogs.com/xiaoxiongcanguan/p/12431062.html
頁:
[1]