社会你马哥 發表於 2021-9-11 19:28: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>实验10 编写子程序</h3>
<p>这次实验需要编写三个子程序,通过它们来认识几个常见的问题和掌握解决这些问题的方法。</p>
<h4>1.显示字符串</h4>
<h5>问题</h5>
<p><img src="https://img-blog.csdnimg.cn/57150ba39e9047b6b6482fe45919ba05.png" alt="在这里插入图片描述"></p>
<h5>子程序描述</h5>
<p><img src="https://img-blog.csdnimg.cn/78625399c1bb40bcb88750dfa6be2161.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbmVwdV9iaW4=,size_20,color_FFFFFF,t_70,g_se,x_16" alt="在这里插入图片描述"></p>
<h5>提示</h5>
<p><img src="https://img-blog.csdnimg.cn/2f7eba662d27489c95dda4c0ac67b4a5.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>跟之前的文章的风格相似,都是用王爽老师原书中的描述,在完成第一个程序之前,需要稍微了解一下显存相关的内容:汇编语言:实验九 根据材料编程<br> 了解了显存相关的知识,可以动手操作操作了,题目需要将字符串显示在特定的行列,如果学习过数据结构或者对二维数组较为了解,求解二维数组中R行C列的元素前面一共有多少个元素?一定知道这么一个计算方法:(R * nums + C),nums表示每一行元素的个数。<br> <img src="https://img-blog.csdnimg.cn/440e1ca6807a44ab848b4ad6e31089d8.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>显存内存的分布也可以类比成二维数组,每一行一共有 80 个元素,每个元素占用 2 个字节,那么每一行占用了<em>80 * 2 = 160</em>字节,求解R行C列前面占用的空间就可以得到表达式:(R * 160 + C * 2 ) 字节。</p>
<h4>实现代码</h4>
<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
data segment
        db <span class="token string">'Welcome to masm!'</span><span class="token punctuation">,</span><span class="token number">0</span>
data ends
code segment
start<span class="token operator">:</span>
        mov dh<span class="token punctuation">,</span> <span class="token number">10</span>        <span class="token punctuation">;</span>行号 范围 <span class="token number">0</span> <span class="token operator">~</span> <span class="token number">24</span>
        mov dl<span class="token punctuation">,</span> <span class="token number">3</span>        <span class="token punctuation">;</span>列号 范围 <span class="token number">0</span> <span class="token operator">~</span> <span class="token number">79</span>
        mov cl<span class="token punctuation">,</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 operator">~</span> <span class="token number">79</span><span class="token punctuation">)</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 punctuation">;</span>ds偏移
        mov di<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">;</span>es偏移
        mov bl<span class="token punctuation">,</span> cl        <span class="token punctuation">;</span>bl保存需要改变的颜色
       
        mov ax<span class="token punctuation">,</span> <span class="token number">0</span>B800H
        mov es<span class="token punctuation">,</span> ax<span class="token punctuation">;</span>显存位置
       
        mov al<span class="token punctuation">,</span> dh
        mov ah<span class="token punctuation">,</span> <span class="token number">160</span>
        mul ah
        add di<span class="token punctuation">,</span> ax        <span class="token punctuation">;</span>行空间
       
        mov al<span class="token punctuation">,</span> cl
        mov ah<span class="token punctuation">,</span> <span class="token number">2</span>
        mul ah
        add di<span class="token punctuation">,</span> ax        <span class="token punctuation">;</span>列空间
       
        call compare
       
        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
       
compare<span class="token operator">:</span><span class="token punctuation">;</span>调用子程序前的保存工作
        push cx
        push di
        push si
       
show_str<span class="token operator">:</span>
        mov cl<span class="token punctuation">,</span> ds<span class="token operator">:</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>H
        jcxz ok        <span class="token punctuation">;</span>循环结束
        mov es<span class="token operator">:</span><span class="token punctuation">[</span>di<span class="token punctuation">]</span><span class="token punctuation">,</span> cl
        mov 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> bl
        add di<span class="token punctuation">,</span> <span class="token number">2</span>
        inc si
        jmp <span class="token keyword">short</span> show_str
       
ok<span class="token operator">:</span><span class="token punctuation">;</span>调用完子程序之后的恢复工作
        pop si
        pop di
        pop cx
        ret
code ends
end start
</code></pre>
<h4>运行</h4>
<p><img src="https://img-blog.csdnimg.cn/a99ca886bf534bd3a7eb14408962c0ea.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbmVwdV9iaW4=,size_20,color_FFFFFF,t_70,g_se,x_16" alt="在这里插入图片描述"></p>
<h3>2.解决除法溢出的问题</h3>
<h4>问题</h4>
<p><img src="https://img-blog.csdnimg.cn/e6c18179c67e462a80d2e5200ee43bbf.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/0e8cf9b8b2bf4bf6b98d72e3569beb88.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>子问题描述</h4>
<p><img src="https://img-blog.csdnimg.cn/8248e07d50d84a8ebcad44d29cfb8f2c.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>提示</h4>
<p><img src="https://img-blog.csdnimg.cn/653c6fccbaa94adf948ed8749a0f7c7a.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>问题主要用于解决除法溢出的问题。<br> <img src="https://img-blog.csdnimg.cn/f16058bbc2e446aa956d389cdb6d56ba.png" alt=""><br> 程序不难,只是用于熟悉子程序结构、构建。</p>
<pre><code class="prism language-cpp">assume cs<span class="token operator">:</span>code<span class="token punctuation">,</span> ss<span class="token operator">:</span>stack
stack segment
        db <span class="token number">8</span> <span class="token function">dup</span> <span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
stack ends

code segment
start<span class="token operator">:</span>
        mov ax<span class="token punctuation">,</span> stack
        mov ss<span class="token punctuation">,</span> ax
       
        mov ax<span class="token punctuation">,</span> <span class="token number">4240</span>H        <span class="token punctuation">;</span>被除数低位
        mov dx<span class="token punctuation">,</span> <span class="token number">000F</span>H        <span class="token punctuation">;</span>被除数高位
        mov cx<span class="token punctuation">,</span> <span class="token number">0</span>AH        <span class="token punctuation">;</span>除数
        call divdw
       
        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
divdw<span class="token operator">:</span>
        push ax        <span class="token punctuation">;</span>将被除数低位压栈
       
        mov ax<span class="token punctuation">,</span> dx        <span class="token punctuation">;</span>将被除数高位传入ax
        mov dx<span class="token punctuation">,</span> <span class="token number">0</span>        <span class="token punctuation">;</span>进行高位除法
       
        div cx        <span class="token punctuation">;</span>ax <span class="token operator">/</span> cx<span class="token punctuation">,</span>公式中 H <span class="token operator">/</span> N
        mov bx<span class="token punctuation">,</span> ax        <span class="token punctuation">;</span>bx保存 <span class="token keyword">int</span><span class="token punctuation">(</span>H <span class="token operator">/</span> N<span class="token punctuation">)</span>
       
        pop ax        <span class="token punctuation">;</span>低数位出栈,此时dx中为<span class="token function">rem</span><span class="token punctuation">(</span>H <span class="token operator">/</span> N<span class="token punctuation">)</span><span class="token punctuation">,</span>正好满足 <span class="token punctuation">[</span> <span class="token function">rem</span><span class="token punctuation">(</span>H <span class="token operator">/</span> N<span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">65536</span> <span class="token operator">+</span> L<span class="token punctuation">]</span>
       
        div cx        <span class="token punctuation">;</span><span class="token punctuation">(</span>dx <span class="token operator">*</span> <span class="token number">16</span> <span class="token operator">+</span> ax<span class="token punctuation">)</span> <span class="token operator">/</span> cx
        mov cx<span class="token punctuation">,</span> dx
        mov dx<span class="token punctuation">,</span> bx
        ret
code ends
end start
</code></pre>
<h3>3.数值显示</h3>
<h4>问题</h4>
<p><img src="https://img-blog.csdnimg.cn/27051297948b440fa7b87c6e8c8ee194.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>子程序描述</h4>
<p><img src="https://img-blog.csdnimg.cn/e14325c740ec4fe3bfed079d9cfc2b05.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/7b91a612f84d4339b9eab844965d0238.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>提示</h4>
<p><img src="https://img-blog.csdnimg.cn/659edd84d7fb4ed09d02353613e3d952.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/11171cfb0cab45b9968231d450dce5dd.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAbmVwdV9iaW4=,size_20,color_FFFFFF,t_70,g_se,x_16" alt="在这里插入图片描述"><br> 读者对本题应该非常熟悉,在《C语言程序设计》课程中应该完成过“打印一个数字的每位数字”,这道题其实也是那个经典的while循环,按照王爽老师的解析还是可以很轻松地完成的哦。</p>
<pre><code class="prism language-cpp">assume cs<span class="token operator">:</span>code<span class="token punctuation">,</span> ss<span class="token operator">:</span>stack
stack segment
        db <span class="token number">10</span> <span class="token function">dup</span> <span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
stack ends

data segment
        db <span class="token number">10</span> <span class="token function">dup</span> <span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
data ends

code segment
start<span class="token operator">:</span>
        mov ax<span class="token punctuation">,</span> <span class="token number">12666</span>
        mov bx<span class="token punctuation">,</span> data
        mov ds<span class="token punctuation">,</span> bx
        mov bx<span class="token punctuation">,</span> stack
        mov ss<span class="token punctuation">,</span> bx
       
        mov dx<span class="token punctuation">,</span> <span class="token number">0</span>
        mov si<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">;</span>计数器,表示共有多少位
        mov di<span class="token punctuation">,</span> <span class="token number">10</span>        <span class="token punctuation">;</span>充当除数
        call dtoc
       
        mov dh<span class="token punctuation">,</span> <span class="token number">8</span>
        mov dl<span class="token punctuation">,</span> <span class="token number">3</span>
        mov cl<span class="token punctuation">,</span> <span class="token number">2</span>
        call show
       
       
dtoc<span class="token operator">:</span>
        mov cx<span class="token punctuation">,</span> ax
        jcxz change        <span class="token punctuation">;</span>如果ax已经是零,循环结束,将数据转移到ds<span class="token operator">:</span><span class="token punctuation">[</span>x<span class="token punctuation">]</span>
        mov dx<span class="token punctuation">,</span> <span class="token number">0</span>
       
        div di        <span class="token punctuation">;</span>除<span class="token number">10</span>
        push dx        <span class="token punctuation">;</span>将余数压栈
        inc si        <span class="token punctuation">;</span>计数器加一
        jmp <span class="token keyword">short</span> dtoc

change<span class="token operator">:</span>
        mov cx<span class="token punctuation">,</span> si
        mov di<span class="token punctuation">,</span> <span class="token number">0</span>        <span class="token punctuation">;</span>充当ds偏移
       
getAns<span class="token operator">:</span>        <span class="token punctuation">;</span>从栈中弹出数据,并加上<span class="token number">30</span>H
        jcxz ok        <span class="token punctuation">;</span>数据弹出完毕
        pop ax
        add ax<span class="token punctuation">,</span> <span class="token number">30</span>H
        mov <span class="token punctuation">[</span>di<span class="token punctuation">]</span><span class="token punctuation">,</span> ax
        inc di
        dec cx
        jmp getAns

ok<span class="token operator">:</span>
        ret
       
show<span class="token operator">:</span>
        mov si<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">;</span>ds偏移
        mov di<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">;</span>es偏移
        mov bl<span class="token punctuation">,</span> cl        <span class="token punctuation">;</span>bl保存需要改变的颜色
       
        mov ax<span class="token punctuation">,</span> <span class="token number">0</span>B800H
        mov es<span class="token punctuation">,</span> ax<span class="token punctuation">;</span>显存位置
       
        mov al<span class="token punctuation">,</span> dh
        mov ah<span class="token punctuation">,</span> <span class="token number">160</span>
        mul ah
        add di<span class="token punctuation">,</span> ax        <span class="token punctuation">;</span>行空间
       
        mov al<span class="token punctuation">,</span> cl
        mov ah<span class="token punctuation">,</span> <span class="token number">2</span>
        mul ah
        add di<span class="token punctuation">,</span> ax        <span class="token punctuation">;</span>列空间
       
        call compa
       
        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
       
compa<span class="token operator">:</span><span class="token punctuation">;</span>调用子程序前的保存工作
        push cx
        push di
        push si
       
show_str<span class="token operator">:</span>
        mov cl<span class="token punctuation">,</span> ds<span class="token operator">:</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>H
        jcxz okk        <span class="token punctuation">;</span>循环结束
        mov es<span class="token operator">:</span><span class="token punctuation">[</span>di<span class="token punctuation">]</span><span class="token punctuation">,</span> cl
        mov 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> bl
        add di<span class="token punctuation">,</span> <span class="token number">2</span>
        inc si
        jmp <span class="token keyword">short</span> show_str
       
okk<span class="token operator">:</span><span class="token punctuation">;</span>调用完子程序之后的恢复工作
        pop si
        pop di
        pop cx
        ret
code ends
end start
</code></pre>
<h4>运行结果</h4>
<p><img src="https://img-blog.csdnimg.cn/545d7d727e63406cb1ad001f42b62185.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/15383993.html
頁: [1]
查看完整版本: 汇编语言:实验十 编写子程序