汇编语言实验10资料.docx
- 文档编号:8131373
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:14
- 大小:81.74KB
汇编语言实验10资料.docx
《汇编语言实验10资料.docx》由会员分享,可在线阅读,更多相关《汇编语言实验10资料.docx(14页珍藏版)》请在冰豆网上搜索。
汇编语言实验10资料
计算机科学系实验报告(首页)
一、实验目的:
掌握子程序的编写和调用
二、实验内容、程序清单及运行结果
1显示字符串
问题
显示字符串是现实工作中经常要用到的功能,应该编写一个通用的子程序来实现这个功
能。
我们应该提供灵活的调用接口,使调用者可以决定显示的位置(行、列)、内容和颜色。
子程序描述
名称:
show_str
功能:
在指定的位置,用指定的颜色,显示一个用0结束的字符串。
参数:
(dh)=行号(取值范围0~24),(dl)=列号(取值范围0~79),
(cl)=颜色,ds:
si指向字符串的首地址
返回:
无
就用举例:
在屏幕的8行3列,用绿色显示data段中的字符串。
assumecs:
code
datasegment
db'Welcometomasm!
',0
dataends
codesegment
start:
movdh,8;行号
列号
颜色
movdl,3
movcl,2
movax,data
callshowstr
movax,4cOOh
int21h
show_str:
codeends
endstart
10
assumecs:
code
11
12
datasegnent
13
db'Welcometomasm!
*,0
仙
dataends
15
16
codesegment
17
start:
noudh,8
18
moudJ,3
19
mouclt2
20
mouax,data
21
nouds
22
mousi19
23
callshowstr
2即
25
mouax,4c09h
26
int21h
27
2S
shaustr:
moual_160
29
muldh
30
subaxr160
31
moubx
32
33
(noual,2
31*
muldl
35
subax,2
(noudi,ax
37
38
mouax,ObSOOh
39
novcs,ax
40
41
s:
moucl:
[si]
42
novchP0
43
jcxzok
hh
45
noves:
[bx+di],ci
46
incdi
h7
moucht2
49
moves:
[bx*di]Tch
49
incdi
50
incsi
51
jnpshort5
52
53
ok:
ret
强
codeends
55
endstart
pU
G?
7Z:
0G00
B668
MOU
DH.G8
6772:
0602
B2Q3
MDU
DL.03
0772:
0004
BIGS
MDU
CLfQ2
07?
2:
00G6
B870O7
MOU
G7?
2:
0Q09
8ED8
MOU
D3.AX
G?
?
2:
OGGB
BEGOOG
NOU
SLGQ0G
0?
Ueleumt:
to
CALL
0016
0772:
0011
BB0GHC
MOU
AX>1C0tl
0772:
00H
CDZ1
IMT
Z1
0772:
0016
B0A0
MOU
AL.AO
0772:
0018
F6E6
nJL
DH
G?
7Z:
001A
ZDA0O0
SUB
0?
7Z:
0O1D
8BD8
MDU
BX.AX
G77Z:
0eiF
B002
ruu
-g0772:
0011
AX=B800BX=0460
CX^GQGODX-08G3SP=Q0QG
BP=G00OSI=6010D1-0GE4
»S=Q?
70ES=B8G0
SS=G76FCS-0772IP=0G11
MUUPElPLMZACPONC
077Z:
0011
B8Q04C
MOU
AX.4CO0
餾DOSBoxD.74,Cpu^peed:
1000cycles.Frameskip0rProgram;DEBUG
2•解决除法溢出的问题
问题
前面讲过,div指令可以做除法。
当进行8位除法的时候,用al存储结果的商,ah存储结果的余数:
进行16位除法的时候,用ax存储结果的商,dx存储结果的余数。
可是,现在有一个问
题,如果结果的商大于ah或ax所能存储的最大值,那么将如何?
比如,下面的程序段:
movbh,1
movax,1000
divbh
进行的是8位除法,结果的商为1000,而1000在ah中放不下,
又比如,下面的程序段:
movax,1000h
movdx,1
movbx,1
divbx
进行的是16位除法,结果的商为11000H,而11000H在ax中存放不下。
我们在用div指令做除法的时候,很可能发生上面的情况:
结果的商过大,超出了寄存器
所能存储的范围。
当CP执行div等除法指令的时候。
如果发生这样的情况,将引发CPU勺一个内
部错误。
这个错误被称为:
除法溢出。
我们可以通过特殊的程序来处理这个错误,这里我们
不讨论这个错误的处理,这是后面的课程中要涉及的内容。
下面我们仅仅来看一下除法溢出发
生时的一些现象
除法溢出
图中展示了在windowsXP中使用DEBU执行相关程序段的结果,div指令引发了CPU勺除法溢出,系统对其进行了相关的处理。
好了,我们已经清楚了问题的所在:
用div指令做除法的时候可能产生除法溢出。
由于有这样的问题,在进行除法运算的时候要注意除数和被除数的值,比如1000000/10就不能用div指令来计算。
那么怎么办呢?
我们用下面的子程序divdw解决。
子程序描述
名称:
divdw
功能:
进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型。
参数:
(ax)=dword型数据的低16位
(dx)=dword型数据的高16位
(cx)=除数
返回:
(dx)=结果的高16位,(ax)=结果的低16位
(cx)=余数
应用举例:
计算1000000/10(F4240H/0AH)
movax,4240h
movdx,000fh
movcx,0ah
calldivdw
提示
给出一个公式:
X:
被除数,范围:
[O,FFFFFFFF]
N:
除数,范围:
[0,FFFF]
H:
X高16位,范围:
[0,FFFF]
L:
X氐16位,范围:
[0,FFFF]
int():
描述性运算符,取商,比如:
int(38/10)=3
rem():
描述性运算符,取余数,比如:
rem(38/10)=8
公式:
X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N
这个公式将可能产生溢出的除法运算:
X/N,转变为多个不会产生溢出的除法运算。
公式中,等号右边的所有除法运算都可以用div指令来做,肯定不会导致除法溢出。
01
assumecs:
code
02
03
stdcksegment
04
db16dup(O)
05
stackends
06
07
codesegment
胸
start:
nouax,stack
09
nov55
10
mousp
11
12
13
noudxh
仙
nouexvOah
15
calldivdu
16
17
mouaxv4c0Oih
18
int21b
19
20
diudu:
pushax
21
mou姑心
22
moudx.0
23
diucm
2H
nousivdx
25
26
pop3N
27
diuex
28
mouck,dx
2Q
moudxTsi
30
codeends
31
endstart|
DOSE:
OX
DOSBom0.74,Cpuspeed:
3000cycles,Frameskip0rProgram:
DEBUG
AX=QOG1
BX^0O00
CX=Q0GA
DX=0OG5
SP=GGQC
BP=0000
SI=0091
DI=Q0O9
DS=Q?
60
ES=0?
60
SS=G7?
0
CS=e771
IF=06E3
MUUPEl
FLNZMA
POMC
0?
71:
0QZ358
ft
POPAX
AX=4240
DX=0066
SF=0G0E
BP^OGOO
31=0091
DI=0009
DS=G760
ES=G?
60
SS=Q770
CS=0?
71
IP=00Z4
MUUFEl
FLMSNA
P0MC
6771:
0024F7F1
DIUCX
AX=86A0
BX=GQ00
CX=00OA
DX-00G0
SF=ee^
BP-0000
SI=0091
DI=0000
DS=OT60
ES=G?
60
SS=G770
CS=0771
IP=0G(Z6
NUUPEl
PLNZNA
PONC
0771:
GGE6BBCAMUUCX.DX
3.数值显示
问题
编程,将data段中的数据以十进制的形式显示出来。
datasegment
dw123,12666,1,8,3,38
dataends
这些数据在内存中都是二进制信息,标记了数值的大小。
要把它们显示到屏幕上,成为
我们能够读懂的信息,需要进行信息的转化。
比如,数值12666,在机器中存储为二进制信息:
0011000101111010B(317AH),计算机可以理解它。
而我们要在显示器上读到可以理解的数值12666,我们看到的应该是一串字符:
“12666”。
由于显卡遵循的是ASCII编码,为了让我们能
在显示器上看到这串字符,它在机器中应以ASCII码的形式存储为:
31H、32H36H、36H36H
(字符“0”~“9”对应的ASCII码为30H~39H。
通过上面的分析可以看到,在概念世界中,有一个抽象的数据12666,它表示了一个数
值的大小。
在现实世界中它可以有多种表示形式,可以在电子机器中以高低电平(二进制)的
形式存储,也可以在纸上、黑板上、屏幕上以人类的语言“12666”来书写。
现在,我们面临的
问题就是,要将同一抽象的数据,从一种表示形式转化为另一种表示形式。
可见,要将数据用十进制形式显示到屏幕上,要进行两步工作:
(1)将用二进制信息存储的数据转变为十进制形式的字符串:
(2)显示十进制形式的字符串。
第二步我们在本次实验的第一个子程序中已经实现,在这里只要调用一下show_str即可。
我们来讨论第一步,因为将二进制信息转变为十进制形式的字符串也是经常要用到的功能,我们应该为它编写一个通用的子程序。
子程序描述
名称:
dtoc
功能:
将word型数据转变为表示十进制数的字符串,字符串以0为结尾符。
参数:
(ax)=word型数据
ds:
si指向字符串的首地址
返回:
无
应用举例:
编程,将数据12666以十进制的形式在屏幕的8行3列,用绿色显示出来。
在显示时我们调用本次实验中的第一个子程序show-str。
assumecs:
code,ds:
data,ss:
stack
datasegment
db10dup(0)
dataends
stacksegment
dw128dup(0)
stackends
codesegment
start:
movax,stack
movss,ax
movsp,128
movax,12666
movbx,data
movds,bx
movsi,0
calldtoc
movdh,8
movdl,3
movcl,2
callshow_str
movax,4c00h
int21h
0为结尾符
;名称:
dtoc
;功能:
将word型数据转变为表示十进制数的字符串,字符串以
;参数:
(ax)=word型数据
;ds:
si指向字符串的首地址
;返回:
无
dtoc:
pushax
pushbx
pushcx
pushsi
pushdi
movdi,si
movbx,10
movcx,0
s:
pushcx
movcx,axjcxzenddtocpopcxmovdx,0divbxmovds:
[di],dladdbyteptrds:
[di],30hincdiinccxjmpshortsenddtoc:
popcxmov[di],0decdimovax,cxmovbl,2divblmovcl,als1:
moval,ds:
[di]movbl,ds:
[si]movds:
[di],blmovds:
[si],alincsidecdi
loops1
popdipopsipopcxpopbx
popax
ret
;名称:
show_str
;功能:
在指定的位置,用指定的颜色,显示一个用0结束的字符串
;参数:
(dh)=行号(取值范围0~24),(dl)=列号(取值范围0~79),
;(cl)=颜色,ds:
si指向字符串的首地址
;返回:
无show_str:
pushdx
pushsi
pushdi
pushcx
pushax
movax,0b800h
moves,ax
movax,160
muldh
movdh,0
addax,dx
addax,dx
subax,2
movdi,ax
movah,cl
output:
movch,ds:
[si]
movcl,0
jcxzok
movbyteptres:
[di],ch
movbyteptres:
[di+1],ah
incsi
incdi
incdi
jmpshortoutput
ok:
popax
popex
popdi
popsi
popdx
ret
codeends
endstart
三、实验结论、实验体会
要屏幕的8行3列,用绿色显示data段中的字符串。
,实际上就是要将ds:
[si]的数据搬到
B8000H-BFFFFH中,段地址我将其设为es=B8000,偏移地址[bx=dh].[di=dl],循环时,
di递增。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 汇编语言 实验 10 资料