汇编语言(第三版)王爽著(实验十)编写子程序
实验内容、程序清单及运行结果
显示字符串:
问题:
显示字符串是现实工作中经常要用到的功能,应该编写一个通用的子程序来实现这个功能。我们应该提供灵活的调用接口,使调用者可以决定显示的位置(行、列)、内容和颜色。
提示
(1) 子程序的入口参数是屏幕上的行号和列号,注意在子程序内部要将它们转化为显存中的地址,首先要分析一下屏幕上的行列位置和显存地址的对应关系:
(2) 注意保存子程序中用到的相关寄存器:
(3) 这个子程序的内部处理和显存的结构密切相关,但是向外提供了与显存结构无关的接口。通过调用这个子程序,进行字符串的显示时可以不必了解显存的结构,为编程提供了方便。在实验中,注意体会这种设计思想。
子程序描述
名称:show_str
功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串。
参数:(dh)=行号(取值范围0~24),(dl)=列号(取值范围0~79),
(cl)=颜色,ds:si指向字符串的首地址
本例程序代码如下:
assume cs:code
data segment
db 'Welcome to masm !',0
data ends
code segment
start:
mov dh,8;行
mov dl,3;列
mov cl,2;颜色
mov ax,data
mov ds,ax
mov si,0
call show_str
mov ax,4c00h
int 21h
show_str:
mov bl,cl
mov ax,0b800h
mov es,ax
sub di,di
dec dh
dec dl
;计算显示位置
mov al,160
mul dh
add dl,dl
mov cl,dl
mov ch,0
add ax,cx;行加列
mov di,ax
s: mov cl,ds:[si]
mov ch,0
jcxz ok;判断是否为零
;输出
mov ax,ds:[si]
mov es:[di],ax
inc di
inc si
mov es:[di],bl
inc di
jmp short s
ok: ret
code ends
end start
思路:
先计算行和列的字节数,然后加起来,累加在0b800h后面,即得显示初始位置,然后通过jcxz来判断字符串结尾进行数据传输循环
程序执行截图:
修改相关数据后:
- 解决除法溢出的问题
问题
前面讲过,div指令可以做除法。当进行8位除法的时候,用al存储结果的商,ah存储结果的余数:进行16位除法的时候,用ax存储结果的商,dx存储结果的余数。可是,现在有一个问题,如果结果的商大于ah或ax所能存储的最大值,那么将如何?
子程序描述
名称:divdw
功能:进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型。
参数:(ax)=dword型数据的低16位
(dx)=dword型数据的高16位
(cx)=除数
返回:(dx)=结果的高16位,(ax)=结果的低16位
(cx)=余数
提示
给出一个公式:
X:被除数,范围:[0,FFFF FFFF]
N:除数,范围:[0,FFFF]
H:X高16位,范围:[0,FFFF]
L:X低16位,范围:[0,FFFF]
int():描述性运算符,取商,比如:rem(38/10)=8
rem():描述性运算符,取答数,比如:rem(38/10)=8
公式:X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N
这个公式将可能产生溢出的除法运算:X/N,转变为多个不会产生溢出的除法运算。
公式中,等号右边的所有除法运算都可以用div指令来做,肯定不会导致除法溢出。
代码如下:
assume cs:code
code segment
start:
mov ax,4240h
mov dx,000fh
mov cx,0ah;初始化数据
call divdw
mov ah,4ch
int 21h
divdw:
mov bx,ax;暂存ax
mov ax,dx
sub dx,dx
div cx;得到ax=int(H/N)(结果高位)和dx=rem(H/N)
push ax;结果高位
mov ax,bx
div cx;得到ax=(结果低位)和dx=(结果余数)
push ax;结果低位
push dx;结果余数
pop cx
pop ax
pop dx
ret
code ends
end start
思路:
通过阅读材料得:
结果高位:Int(H/N)
结果低位:[rem(H/N)*65536+L]/N的商
结果余数:[rem(H/N)*65536+L]/N的余数
其中[rem(H/N)*65536+L]/N的16位除法中rem(H/N)为高位,L为低位,
即dx= rem(H/N),ax=L,得结果:ax=结果低位,dx=结果余数
截图:
- 数值显示
问题
编程,将data段中的数据以十进制的形式显示出来。
data segment
dw 123,12666,1,8,3,38
data ends
子程序描述
名称:dtoc
功能:将word型数据转变为表示十进制数的字符串,字符串以0为结尾符。
参数:(ax)=word型数据
ds:si指向字符串的首地址
返回:无
代码:
assume cs:code,ds:data
sdata segment;源数据段
dw 123,12666,1,8,3,38,0
sdata ends
tdata segment;临时数据段
db 20 dup(0)
tdata ends
data segment;结果数据段
db 20 dup(0)
data ends
code segment
start:
mov ax,sdata
mov ds,ax
sub si,si
mov ax,tdata
mov es,ax
sub di,di
call dtoc
mov dh,8;行
mov dl,3;列
mov cl,2;颜色
mov ax,data
mov ds,ax
mov si,0
call show_str
mov ax,4c00H
int 21H
dtoc:
sub bx,bx;计数器,计数据的个数
sum:
mov cx,word ptr ds:[si]
jcxz sum_ok
inc bx
add si,2
jmp short sum
sum_ok:
mov cx,bx;循环的次数
dec bx;求地址用
mov al,2
mul bl
mov si,ax;设置地址到最后一个数据的起始
datac:
push cx
mov ax,ds:[si]
sub dx,dx
mov bx,10
div bx
onec:
add dx,30h
mov es:[di],dl;逆序存放结果到临时段
inc di
mov cx,ax
inc cx
sub dx,dx
div bx
loop onec
mov cl,44
mov es:[di],cl;设置逗号分隔
inc di
sub si,2
pop cx
loop datac
;修正排序
mov ax,tdata
mov ds,ax
sub si,si
mov ax,data
mov es,ax
sub di,di
sub bx,bx;计数器,计数据的字节数
sum_one:
mov cl,ds:[si]
mov ch,0
jcxz sumo_ok
inc bx
inc si
jmp short sum_one
sumo_ok:
dec bx;去掉一个逗号
mov cx,bx;循环的次数
dec bx;数据传输起始位置
mov si,bx
change:
mov ax,ds:[si]
mov es:[di],ax
dec si
inc di
loop change
mov ax,0
mov es:[di],ax
ret
show_str:
mov bl,cl
mov ax,0b800h
mov es,ax
sub di,di
dec dh
dec dl
;计算显示位置
mov al,160
mul dh
add dl,dl
mov cl,dl
mov ch,0
add ax,cx;行加列
mov di,ax
s: mov cl,ds:[si]
mov ch,0
jcxz ok;判断是否为零
;输出
mov ax,ds:[si]
mov es:[di],ax
inc di
inc si
mov es:[di],bl
inc di
jmp short s
ok: ret
code ends
end start
思路:
设置三个数据段:
源数据段:存储数据源
临时数据段:用于字符串逆序暂存
结果数据段:输出最终结果
1.先通过jcxz循环得到源数据段中数据个数,通过计算定位最后一个数据的起始位置,才进行数据转字符处理,这么做的原因是:通过除法转换为十进制的输出是逆序的,所以一开时也将所有操作逆序进行
2.通过上面的处理,获得第一组临时逆序字符串,存放在临时数据段
3.最后通过数据逆序修正,将数据存入结果数据段
通过调用show_str:子程序进行定位显示
截图:
改变相关数据输出:
- 实验结论、实验体会
第一题:
先计算行和列的字节数,然后加起来,累加在0b800h后面,即得显示初始位置,然后通过jcxz来判断字符串结尾进行数据传输循环
第二题:
通过阅读材料得:
结果高位:Int(H/N)
结果低位:[rem(H/N)*65536+L]/N的商
结果余数:[rem(H/N)*65536+L]/N的余数
其中[rem(H/N)*65536+L]/N的16位除法中rem(H/N)为高位,L为低位,
即dx= rem(H/N),ax=L,得结果:ax=结果低位,dx=结果余数
第三题:
设置三个数据段:
源数据段:存储数据源
临时数据段:用于字符串逆序暂存
结果数据段:输出最终结果
1.先通过jcxz循环得到源数据段中数据个数,通过计算定位最后一个数据的起始位置,才进行数据转字符处理,这么做的原因是:通过除法转换为十进制的输出是逆序的,所以一开时也将所有操作逆序进行
2.通过上面的处理,获得第一组临时逆序字符串,存放在临时数据段
3.最后通过数据逆序修正,将数据存入结果数据段
通过调用show_str:子程序进行定位显示
其它实验:
汇编语言(第三版)王爽著(实验一)查看CPU和内存
汇编语言(第三版)王爽著(实验二)用机器指令和汇编指令编程
汇编语言(第三版)王爽著(实验三)编程、编译、连接、跟踪
汇编语言(第三版)王爽著(实验四)[bx]和loop的使用
汇编语言(第三版)王爽著(实验五)编写、调试具有多个段的程序
汇编语言(第三版)王爽著(实验六)实践课程中的程序
汇编语言(第三版)王爽著(实验七)寻址方式在结构化数据访问中的应用
汇编语言(第三版)王爽著(实验八)分析一个奇怪的程序
汇编语言(第三版)王爽著(实验九)根据材料编程
汇编语言(第三版)王爽著(实验十)编写子程序
汇编语言(第三版)王爽著(实验十一)编写子程序
汇编语言(第三版)王爽著(实验十二)编写0号中断的处理程序
DOSBox+MASM搭建汇编环境
汇编语言(第三版)王爽著(实验十)编写子程序相关推荐
- 汇编语言(王爽)实验十 编写子程序
标 题: 汇编实验10-- 编写子程序 作 者: XHS_12302 时 间: 2016_7_28 16:56 实验10编写子程序 在这次实验中,我们将要编写3个子程序,通过它们来认识几个常见的问题和 ...
- 读书笔记:汇编语言 第三版 王爽 清华出版社 前言 章一 章二 章三 章四 章五
汇编语言 第三版 王爽 清华出版社文档记录创建 2020年8月9日15:21:11初稿完成 2020年9月5日15:38:22前言汇编语言,CPU提供的机器指令的助记符的集合不同处理器,机器指令可能不 ...
- 读书笔记:汇编语言 第三版 王爽 清华出版社 章十六 章十七 章十八
第十六章 直接定址表16.1 描述了单位长度的标号地址标号,表征了位置的偏移地址label:数据标号,表征了一段内存空间的物理地址和长度,增强型地址标号段地址,数据标号所在段的关联段寄存器,assum ...
- 读书笔记:汇编语言 第三版 王爽 清华出版社 章六 章七 章八 章九 章十
第六章 包含多个段的程序6.0 概述合法地通过操作系统取得的空间都是安全的操作系统不会让多个程序之间发生空间冲突程序向操作系统获得空间的方法程序加载时分配在程序中定义各种段程序运行时分配通过指令向操作 ...
- 汇编语言-第三版-王爽-实验6、7、9、10、11、12、13、14、15
实验6(p160).实验7(p173).实验9(p189).实验10(p206,p208, p209).实验11(p234).实验12(p251).p256(编写7cH中断例程完成loop指令功能). ...
- 汇编语言-第三版-王爽-第15章 外中断-第16章 直接定址表
P280:在屏幕中间依次显示a~z, 显示过程中,按下ESC键后,改变显示颜色 P283:在DOS下,按F1键后改变当前屏幕的显示颜色,其他的键照常处理 P293:以十六进制的形式显示给定的字节型数据 ...
- 汇编语言-第三版-王爽-课程设计1
课程设计1(p211). * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ...
- 汇编语言 第3版 王爽 检测点习题部分—答案及详细解析
第一章 基础知识 检测点1.1 (1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为()位. (2)1KB的存储器有() 个存储单元,存储单元的编号从()到() . (3)1KB的存储器可以存 ...
- 汇编语言 (第2版) 王爽 中文高清PDF版下载
汇编语言 (第2版) 王爽 中文高清PDF版下载 转载于:https://www.cnblogs.com/gavinhughhu/archive/2009/12/10/1620783.html
- 汇编语言(王爽)实验十
实验十 编写3个子程序 1.显示字符串 功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串 参数:(dh)=行号.(dl)=列号.(cl)=颜色.ds:si指向字符串的首地址 行.列从0开始计 ...
最新文章
- 浙江工业大学计算机学院推免生,浙江工业大学计算机科学与技术学院(专业学位)计算机技术保研...
- xcode项目集成CocoaPods
- BZOJ2837 : 小强的形状
- HDU.5909.Tree Cutting(树形DP FWT/点分治)
- Springboot+Apollo
- AssertJ的SoftAssertions –我们需要它们吗?
- [js] 写一个方法判断数组内元素是否全部相同
- Python nltk包
- 随想录(读书和选书)
- ssas报表项目数据集_处理SSAS多维OLAP多维数据集的有效方法
- 【机器学习】如何处理数据不均衡问题
- android 利用shape做控件背景(小圆点,空心带边框背景)
- 深度学习第一次作业 - 波士顿房价预测
- 水生火热的互联网金融
- 如何在Linux系统中安装DBeaver通用数据库工具
- Linux(Ubuntu)之top命令
- opic4:Qt入门之常用qt控件认知之Button系列
- java 新浪 发送邮件_使用javamail新浪郵箱發送遇到的問題(已解決)
- python如果否则_Python传递参数(如果已定义),否则使用defau
- 【偷鸡系列】华为OD机试 :找终点