汇编语言:实验十 编写子程序
<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]