小鲜 發表於 2021-9-21 21:29:00

汇编语言:实验十三 编写、应用中断例程

<svg xmlns="http://www.w3.org/2000/svg" style="display: none">
                        <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0)"></path>
                  </svg>
                  <h3>第Ⅰ部分</h3>
<p>1.编写并安装int 7ch中断例程,功能为显示一个用0结束的字符串,中断例程安装在 0:200处。<br> 参数:(dh)= 行号,(dl)= 列号,(cl)= 颜色,ds:si指向字符串首地址。</p>
<h4>Solution</h4>
<p>第一部分实验与汇编语言:实验十二 编写0号中断的处理程序类似,这里就贴上代码吧:</p>
<pre><code class="prism language-cpp">assume cs<span class="token operator">:</span>code<span class="token punctuation">,</span> ds<span class="token operator">:</span>data

code segment
start<span class="token operator">:</span>
        jmp install
        mov dh<span class="token punctuation">,</span> <span class="token number">10</span>
        mov dl<span class="token punctuation">,</span> <span class="token number">10</span>
        mov cl<span class="token punctuation">,</span> <span class="token number">2</span>
        mov ax<span class="token punctuation">,</span> data
        mov ds<span class="token punctuation">,</span> ax
        mov si<span class="token punctuation">,</span> <span class="token number">0</span>
        <span class="token keyword">int</span> <span class="token number">7</span>ch
        mov ax<span class="token punctuation">,</span> <span class="token number">4</span>c00h
        <span class="token keyword">int</span> <span class="token number">21</span>h
       
install<span class="token operator">:</span>
        mov ax<span class="token punctuation">,</span> <span class="token number">0</span>
        mov es<span class="token punctuation">,</span> ax
        mov word ptr es<span class="token operator">:</span><span class="token punctuation">[</span><span class="token number">4</span> <span class="token operator">*</span> <span class="token number">7</span>ch<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">200</span>h
        mov word ptr es<span class="token operator">:</span><span class="token punctuation">[</span><span class="token number">4</span> <span class="token operator">*</span> <span class="token number">7</span>ch <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">;</span>安装中断向量表
       
        mov ax<span class="token punctuation">,</span> cs
        mov ds<span class="token punctuation">,</span> ax
        mov ax<span class="token punctuation">,</span> <span class="token number">0</span>
        mov es<span class="token punctuation">,</span> ax
        mov si<span class="token punctuation">,</span> <span class="token number">0</span>
        mov di<span class="token punctuation">,</span> <span class="token number">200</span>h
        mov cx<span class="token punctuation">,</span> offset do7chEnd <span class="token operator">-</span> offset do7ch
        cld
        rep movsb
       
do7ch<span class="token operator">:</span>
data segment
        db <span class="token string">"welcome to masm!"</span><span class="token punctuation">,</span> <span class="token number">0</span>
data ends

        push cx
        push si
        push di
       
        mov ax<span class="token punctuation">,</span> <span class="token number">0</span>b800h
        mov es<span class="token punctuation">,</span> ax
        mov ax<span class="token punctuation">,</span> data
        mov ds<span class="token punctuation">,</span> ax
        mov si<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">;</span>源地址偏移
        mov al<span class="token punctuation">,</span> dh
        mov bl<span class="token punctuation">,</span> <span class="token number">160</span>
        mul bl        <span class="token punctuation">;</span>dh <span class="token operator">*</span> <span class="token number">160</span>
        add ax<span class="token punctuation">,</span> dl
        mov di<span class="token punctuation">,</span> ax

trans<span class="token operator">:</span>
        mov cl<span class="token punctuation">,</span> <span class="token punctuation">[</span>si<span class="token punctuation">]</span>
        mov ch<span class="token punctuation">,</span> <span class="token number">0</span>
        jcxz fin<span class="token punctuation">;</span>如果cx <span class="token operator">=</span> <span class="token number">0</span>,表示已经处理完毕
        mov byte ptr es<span class="token operator">:</span><span class="token punctuation">[</span>di<span class="token punctuation">]</span><span class="token punctuation">,</span> cl
        mov byte ptr es<span class="token operator">:</span><span class="token punctuation">[</span>di <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">11000010</span>B
        inc si
        add di<span class="token punctuation">,</span> <span class="token number">2</span>
        jmp trans

fin<span class="token operator">:</span>
        pop di
        pop si
        pop cx
        iret
       
do7chEnd<span class="token operator">:</span>
        nop
code ends
end start
</code></pre>
<p>需要注意的还是在 <strong>data segment</strong> 的放置,如果直接放在主程序中会出现意想不到的错误哦,必须将其放在子程序中。</p>
<p><strong>运行效果:</strong><br> <img src="https://img-blog.csdnimg.cn/f3e6da8df4b1483499c79275220afd63.gif#pic_center" alt="在这里插入图片描述"></p>
<h2>第Ⅱ部分</h2>
<p>编写并安装 int 7ch 中断例程,功能为完成 loop 指令的功能。<br> 参数:(cx)= 循环次数,(bx)= 位移。<br> <img src="https://img-blog.csdnimg.cn/1f886f53c00545009c3abb27b2745526.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbmVwdV9iaW4=,size_20,color_FFFFFF,t_70,g_se,x_16" alt="在这里插入图片描述"></p>
<h4>Solution</h4>
<p>程序总体涉及到多个部分,不过大体上跟之前一样,只是在<strong>中断处理程序</strong>上有不一样的处理方式。</p>
<h4>install子程序</h4>
<p>先看中断子程序是如何被安装到指定位置的(为了方便观看,这里放上了Notepad++中的代码截图):<br> <img src="https://img-blog.csdnimg.cn/c6889c530f4a4708ab15a2030d2dca9a.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbmVwdV9iaW4=,size_20,color_FFFFFF,t_70,g_se,x_16" alt="在这里插入图片描述"></p>
<p>这段代码也不难,首先是保存相关寄存器,然后填写中断向量表,紧接着将中断处理程序的代码拷贝到指定地址,最后从栈中恢复寄存器的值。</p>
<h4>do7ch中断处理程序</h4>
<p><img src="https://img-blog.csdnimg.cn/c5a6f21bb6184511bbab8b8bdb861637.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbmVwdV9iaW4=,size_20,color_FFFFFF,t_70,g_se,x_16" alt="在这里插入图片描述"><br> 首先是保存bp寄存器(保护工作),int 7ch实现loop指令的功能,在循环的时候需要做如下操作:</p>
<ol><li>dec cx;循环计数变量减一</li><li>如果cx为0,那么不再循环,执行循环代码后面的程序</li><li>如果cx不为0,那么继续循环,CS:IP指向循环体开始部分。<br> 如何让程序跑回循环开始的位置呢?这里bx寄存器已经保存了循环体代码的长度,中断处理过程如下:<br> <img src="https://img-blog.csdnimg.cn/5a019cb8153c45b7b7661710a9c3692d.png" alt="在这里插入图片描述"><br> 所以,栈中是保存了调用程序的位置(IP),那么怎么访问到IP呢,很简单,即可,最上层为bp(我们自己压入的),然后就是IP,再下面是CS,因为bp的长度为2,所以往后偏移2字节即可获得IP的值。(栈的内容如下图)<br> <img src="https://img-blog.csdnimg.cn/dacde8cd5977414faef08e345b21742d.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbmVwdV9iaW4=,size_16,color_FFFFFF,t_70,g_se,x_16" alt="在这里插入图片描述"><br> 完整程序:</li></ol>
<pre><code class="prism language-cpp">assume cs<span class="token operator">:</span>code

code segment
start<span class="token operator">:</span>
        call install        <span class="token punctuation">;</span>调用中断安装程序
        mov ax<span class="token punctuation">,</span> <span class="token number">0</span>b800h
        mov es<span class="token punctuation">,</span> ax
        mov di<span class="token punctuation">,</span> <span class="token number">160</span> <span class="token operator">*</span> <span class="token number">12</span>
        mov bx<span class="token punctuation">,</span> offset s <span class="token operator">-</span> offset se
        mov cx<span class="token punctuation">,</span> <span class="token number">80</span>
       
s<span class="token operator">:</span>
        mov byte ptr es<span class="token operator">:</span><span class="token punctuation">[</span>di<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">'!'</span>
        add di<span class="token punctuation">,</span> <span class="token number">2</span>
        <span class="token keyword">int</span> <span class="token number">7</span>ch
se<span class="token operator">:</span>
        nop
        mov ax<span class="token punctuation">,</span> <span class="token number">4</span>c00h
        <span class="token keyword">int</span> <span class="token number">21</span>h
       
       
install<span class="token operator">:</span>
        push ax
        push es
        push ds
        push si
        push di
        push cx
       
        mov ax<span class="token punctuation">,</span> <span class="token number">0</span>
        mov es<span class="token punctuation">,</span> ax
        mov word ptr es<span class="token operator">:</span><span class="token punctuation">[</span><span class="token number">4</span> <span class="token operator">*</span> <span class="token number">7</span>ch<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">200</span>h
        mov word ptr es<span class="token operator">:</span><span class="token punctuation">[</span><span class="token number">4</span> <span class="token operator">*</span> <span class="token number">7</span>ch <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">;</span>填写中断向量表
       
        <span class="token punctuation">;</span>将中断处理程序拷贝到指定地址
        mov ax<span class="token punctuation">,</span> cs
        mov ds<span class="token punctuation">,</span> ax
        mov ax<span class="token punctuation">,</span> <span class="token number">0</span>
        mov es<span class="token punctuation">,</span> ax        <span class="token punctuation">;</span>目的段地址 <span class="token number">0</span>
        mov si<span class="token punctuation">,</span> offset do7ch<span class="token punctuation">;</span>源偏移地址
        mov di<span class="token punctuation">,</span> <span class="token number">200</span>h<span class="token punctuation">;</span>目的偏移地址
        mov cx<span class="token punctuation">,</span> offset do7chEnd <span class="token operator">-</span> offset do7ch<span class="token punctuation">;</span>程序的长度
        cld
        rep movsb
       
        pop cx
        pop di
        pop si
        pop ds
        pop es
        pop ax
        ret
       
do7ch<span class="token operator">:</span><span class="token punctuation">;</span>从栈中取出子程序的偏移地址
        push bp
        mov bp<span class="token punctuation">,</span> sp
        dec cx
        jcxz fin        <span class="token punctuation">;</span>如果cx已经为<span class="token number">0</span>了,那么不再进行跳转,顺序执行即可
        add <span class="token punctuation">[</span>bp <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span> bx<span class="token punctuation">;</span>修改IP指向使其指向s程序开始处
fin<span class="token operator">:</span>
        pop bp
        iret
do7chEnd<span class="token operator">:</span>
        nop
code ends
end start
</code></pre>
<h4>运行结果</h4>
<p><img src="https://img-blog.csdnimg.cn/d13692d13bff40daa84122c655b95941.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbmVwdV9iaW4=,size_20,color_FFFFFF,t_70,g_se,x_16" alt="在这里插入图片描述"><br> <strong>还差最后一道题,明天更新~</strong></p>
<p><strong>-------------------------------我是分割线 9.22更-----------------------------------</strong></p>
<h2>第Ⅲ部分</h2>
<p>下面的程序,分别在屏幕的第2、4、6、8行显示4句英文诗,补全程序。<br> <img src="https://img-blog.csdnimg.cn/59bc344e720b47ad8b54adfdfaa08e52.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbmVwdV9iaW4=,size_20,color_FFFFFF,t_70,g_se,x_16" alt="在这里插入图片描述"><br> <img src="https://img-blog.csdnimg.cn/2de8f9f8cd704e1386e71632c7f6ffc2.png" alt="在这里插入图片描述"></p>
<h4>Solution</h4>
<p>需要补充的地方并不多,首先要知道,这道题是为了让我们熟悉使用<strong>BIOS和DOS</strong>提供的中断例程编程。</p>
<p><strong>int 10h中断例程</strong>是 BIOS 提供的中断例程。其中包含了多个和屏幕输出相关的子程序。这里使用int 10h中断例程的设置光标的功能来完成在屏幕上的定向输出。</p>
<pre><code class="prism language-c">mov ah<span class="token punctuation">,</span> <span class="token number">2</span>        <span class="token punctuation">;</span>置光标
mov bh<span class="token punctuation">,</span> <span class="token number">0</span>        <span class="token punctuation">;</span>第<span class="token number">0</span>页
mov dh<span class="token punctuation">,</span> <span class="token number">5</span>        <span class="token punctuation">;</span>dh中放行号
mov dl<span class="token punctuation">,</span> <span class="token number">12</span>        <span class="token punctuation">;</span>dl中放列号
<span class="token keyword">int</span> <span class="token number">10</span>h
</code></pre>
<p>(ah)= 2表示调用第 10h 号中断例程的2号子程序,功能为设置光标位置,可以提供光标所在的行号和页号作为参数。</p>
<p>第一处需要填的就是调用int 10h 中断例程需要指定的那些个参数:<br> <img src="https://img-blog.csdnimg.cn/ece8bf34b5924e1fbb5a5121806c09cb.png" alt="在这里插入图片描述"></p>
<hr>
<p><strong>int 21h中断例程</strong>是 DOS 提供的中断例程,其中包含了 DOS 提供给程序员在编程时调用的子程序。</p>
<p>在书中的13.7章节中使用了int 21h中断例程在光标位置显示字符串的功能:</p>
<pre><code class="prism language-c">ds<span class="token operator">:</span>dx 指向字符串        <span class="token punctuation">;</span>要显示的字符串需用<span class="token string">"$"</span>作为结束符
mov ah<span class="token punctuation">,</span> <span class="token number">9</span>        <span class="token punctuation">;</span>功能号<span class="token number">9</span>,表示在光标位置显示字符串
<span class="token keyword">int</span> <span class="token number">21</span>h
</code></pre>
<p>(ah)= 9 表示调用第21h号中断例程的9号子程序,功能为在光标位置显示字符串,可以提供要显示字符串的地址作为参数。</p>
<p>第二处同样是为调用中断例程而设定参数:(设置需要输出的字符串位置)<br> <img src="https://img-blog.csdnimg.cn/27fdda1c90924d5dbabbcc39245acf11.png" alt="在这里插入图片描述"></p>
<p>最后两个需要填写的位置:修改偏移地址,为下一次循环做准备。<br> <img src="https://img-blog.csdnimg.cn/6a1843bb3ddc465b953a91e87f043104.png" alt="在这里插入图片描述"><br> 完整程序</p>
<pre><code class="prism language-c">assume cs<span class="token operator">:</span>code
code segment
s1<span class="token operator">:</span> db <span class="token string">'Good,better,best,'</span><span class="token punctuation">,</span> <span class="token string">'$'</span>
s2<span class="token operator">:</span> db <span class="token string">'Never let it rest,'</span><span class="token punctuation">,</span> <span class="token string">'$'</span>
s3<span class="token operator">:</span>        db <span class="token string">'Till good is better,'</span><span class="token punctuation">,</span> <span class="token string">'$'</span>
s4<span class="token operator">:</span> db <span class="token string">'And better,best.'</span><span class="token punctuation">,</span> <span class="token string">'$'</span>
s<span class="token operator">:</span>         dw offset s1<span class="token punctuation">,</span> offset s2<span class="token punctuation">,</span> offset s3<span class="token punctuation">,</span> offset s4
row<span class="token operator">:</span>db        <span class="token number">2</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">8</span>

start<span class="token operator">:</span>
        mov ax<span class="token punctuation">,</span> cs
        mov ds<span class="token punctuation">,</span> ax
        mov bx<span class="token punctuation">,</span> offset s
        mov si<span class="token punctuation">,</span> offset row
        mov cx<span class="token punctuation">,</span> <span class="token number">4</span>
ok<span class="token operator">:</span>
        mov bh<span class="token punctuation">,</span> <span class="token number">0</span>        <span class="token punctuation">;</span>第<span class="token number">0</span>页
        mov dh<span class="token punctuation">,</span> ds<span class="token operator">:</span><span class="token punctuation">[</span>si<span class="token punctuation">]</span>        <span class="token punctuation">;</span>行号
        mov dl<span class="token punctuation">,</span> <span class="token number">0</span>        <span class="token punctuation">;</span>列号
        mov ah<span class="token punctuation">,</span> <span class="token number">2</span>        <span class="token punctuation">;</span>置光标
        <span class="token keyword">int</span> <span class="token number">10</span>h
       
        mov dx<span class="token punctuation">,</span> ds<span class="token operator">:</span><span class="token punctuation">[</span>bx<span class="token punctuation">]</span>
        mov ah<span class="token punctuation">,</span> <span class="token number">9</span>
        <span class="token keyword">int</span> <span class="token number">21</span>h
        inc si        <span class="token punctuation">;</span>更改显示位置
        add bx<span class="token punctuation">,</span> <span class="token number">2</span>        <span class="token punctuation">;</span>改变偏移地址 <span class="token number">2</span>byte
        loop ok
       
        mov ax<span class="token punctuation">,</span> <span class="token number">4</span>c00h
        <span class="token keyword">int</span> <span class="token number">21</span>h
code ends
end start
</code></pre>
<h4>运行效果</h4>
<p><img src="https://img-blog.csdnimg.cn/bab4f3b3be5b44488427468fddb67fff.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbmVwdV9iaW4=,size_20,color_FFFFFF,t_70,g_se,x_16" alt="在这里插入图片描述"></p><br><br>
来源:https://www.cnblogs.com/bincodes/p/15383981.html
頁: [1]
查看完整版本: 汇编语言:实验十三 编写、应用中断例程