我理解的汇编语言0736061 冯大林.docx
《我理解的汇编语言0736061 冯大林.docx》由会员分享,可在线阅读,更多相关《我理解的汇编语言0736061 冯大林.docx(16页珍藏版)》请在冰豆网上搜索。
我理解的汇编语言0736061冯大林
我理解的汇编语言
07电子0736061冯大林
一、程序解析
1、程序A
(1)实现功能
已知用于LED数码管的显示代码表为:
LEDtabledb0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h
db80h,90h,88h,83h,0c6h,0c1h,86h,8eh
它依次表示0~9、A~F这16个数码管的显示代码。
现编写一个程序实现从键盘中输入一个数字(0~9、A~F),转换成对应的LED显示代码在屏幕上显示出来。
cmpbl,'z';判断是否小于z
jadone
subbl,57h;将ASCII码转换成16进制数字
next:
movsi,offsetledtable;将显示代码的地址赋
给SI
andbx,00ffh
addsi,bx;bx为输入值的偏移地址
movdl,[si]
movcl,4
shrdl,cl;将代码的高位取出
cmpdl,0ah;与0ah比较,以便将16进制数
jcstep3转化为ASCII码
adddl,57h
jmpagain
step3:
adddl,30h
again:
movah,2
int21h;输出代码的高位
movdl,[si]
anddl,0fh;将代码的低位取出
cmpdl,0ah
jcstep4
adddl,57h
jmpagain2
step4:
adddl,30h
again2:
movah,2
int21h;输出代码的低位
done:
cends
endstart
dsegment
ledtabledb0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h
db80h,90h,88h,83h,0c6h,0c1h,86h,8eh
dends
csegment
assumeds:
d,cs:
c
start:
pushds
movax,0
pushax
movax,d
movds,ax
movah,1
int21h;从键盘上输入一个数
movbl,al
cmpbl,'0';判断是否大于0
jcdone
cmpbl,'9';判断是否小于9
jastep1
subbl,30h;将ASCII码转换成16进制数字
jmpnext
step1:
cmpbl,'A';判断是否大于A
jcdone
cmpbl,'Z';判断是否小于Z
jastep2
subbl,37h;将ASCII码转换成16进制数字
jmpnext
step2:
cmpbl,'a';判断是否大于a
jcdone
(2)源代码如下:
(3)程序功能的实现方法
本程序实现的功能很简单,就是将从键盘中输入的16进制数字所对应的代码在屏幕中显示出来。
具体算法就是,首先调用01号功能,从键盘中输入一个数字,由于输入的是该数字的ASCII码,因此先依次判断该数字所在的范围(0~9、A~F、a~f),以便于将其化成16进制数字,求出代码的偏移地址。
然后将代码送入寄存器,分别将高位和低位取出,依次判断该位数字的范围(0~9、a~f),然后将其转化成ASCII码,最后调用2号功能将其输出。
该程序反复用到了条件转移指令,还有输入、输出功能的调用。
(4)程序调试过程
A、用MASM.EXE编译,生成.LST文件和.OBJ文件,若没有.OBJ文件生成,则应根据.LST文件中的错误提示修改程序。
B、若生成了.LST文件和.OBJ文件,则用LINK.EXE生成.EXE文件,并在DEBUG下运行,查看程序能否实现应有的功能。
下面是程序在DEBUG下的运行结果:
输入0
输入9
输入A
输入F
输入a
输入f
2、程序B
(1)实现功能
编写主程序以及子程序
主程序的功能为:
从键盘输入一个两位10进制数字
子程序1功能为:
a、把输入的10进制数转化为16进制
b、入口参数:
DH=十进制的ASCII码,DL=个位数的ASCII码
c、出口参数:
AL=对应的二进制数
子程序2的功能为:
将转化的16进制数输出,后边带符号“H”。
子程序3的功能为:
在输入的10进制数和输出的16进制数之间换行
(2)源代码
popax
movdl,al;将低位数取出,并转化成ASCII码输出
anddl,0fh
cmpdl,0ah
jcstep4
adddl,57h
jmpagain2
step4:
adddl,30h
again2:
movah,2
int21h
movdl,'H';输出符号“H”
movah,2
int21h
popcx;回复保护的内容
popdx
ret
outputendp
crproc;实现换行的子程序
pushax
pushdx
movah,2
movdl,0dh
int21h
movah,2
movdl,0ah
int21h
popdx
popax
ret
crendp
cends
endstart
csegment
assumecs:
c
start:
movah,01h;输入十位数
int21h
movdh,al
movah,01h;输入个位数
int21h
movdl,al
calltrans;调用子程序,转换进制
callcr;换行
calloutput;调用子程序,输出16进制数
movax,4c00h;主程序结束
int21h
transproc
pushdx;保护寄存器内容
subdh,30h;获得十位数
subdl,30h;获得个位数
shldh,1;下面四行指令实现DH=DH×10
moval,dh
shldh,1
shldh,1
addal,dh
addal,dl;得到16进制数
popdx;回复保护的内容
ret
transendp
outputproc
pushdx;保护寄存器内容
pushcx
pushax
movdl,al;将高位数取出,并转化成ASCII码输出
movcl,4
shrdl,cl
cmpdl,0ah
jcstep3
adddl,57h
jmpagain
step3:
adddl,30h
again:
movah,2
int21h
(3)程序功能的实现方法
实现功能的算法如下:
首先调用1号功能,依次输入10位数和个位数,分别保存在DH和DL中。
以DX为入口参数,进入子程序TRANS,首先将ASCII码转化为一位16进制数(10进制0~9与16进制是一样的),然后将十位数乘以10,×10就是×(8+2),即将DH左移1位的结果加上左移3位的结果,再加上DL就得到需要转化的16进制数,并赋给AL。
然后,以AL为入口参数进入子程序OUTPUT,这个程序可以直接照搬程序A,这里不再赘述。
(4)程序在DEBUG下的运行结果
3、程序C
(1)实现功能
编写程序,根据AL=0、1、2,依次实现对大写字母转换成小写字母、小写字母转换成大写字母或者大小写字母的转换。
(2)源代码
cmpbyteptr[si],41h;与‘A’比较
jbagain1小于‘A’直接输出
cmpbyteptr[si],5ah;与‘Z’比较
jaagain1;大于‘Z’直接输出
addbyteptr[si],20h;在这之间转化成小写字母
again1:
calldisp;调用输出子程序
incsi;指针指向下一个元素
loopone;继续循环
jmpdone
two:
andcx,00ffh
cmpbyteptr[si],61h;与‘a’比较
jbagain2;小于‘a’直接输出
cmpbyteptr[si],7ah;与‘z’比较
jaagain2;大于‘z’直接输出
subbyteptr[si],20h;;在这之间转化成大写字母
again2:
calldisp
incsi
looptwo
jmpdone
three:
andcx,00ffh
cmpbyteptr[si],41h;与‘A’比较
jbagain4;小于A直接输出
cmpbyteptr[si],5ah;与‘Z’比较
jaagain3;大于‘Z’继续比较
addbyteptr[si],20h;在这之间转换成小写字母
jmpagain4
again3:
cmpbyteptr[si],61h;与‘a’比较
jbagain4;小于‘a’直接输出
cmpbyteptr[si],7ah;与‘z’比较
jaagain4;大于‘z’直接输出
subbyteptr[si],20h;在这之间转换成大写字母
again4:
calldisp
incsi
loopthree
jmpdone
done:
movax,4c00h;主程序结束
int21h
crproc;实现换行的子程序
pushax
pushdx
movah,2
movdl,0dh
int21h
movah,2
movdl,0ah
int21h
dsegment
keynum=100
keybufdbkeynum
db0
dbkeynumdup(0)
rmddb"Pleaseinputastring(lessthan100characters):
",'$'
codb"Makeyourchoice(0=capitaltosmall,1=smalltocapital,2=interchange)",'$'
dends
csegment
assumecs:
c,ds:
d
start:
pushds
movax,0
pushax
movax,d
movds,ax
movdx,offsetrmd;给出输入提示
movah,09h
int21h
callcr;换行
movdx,offsetkeybuf;输入字符串
movah,0ah
int21h
callcr
movdx,offsetco;再次给出输入提示
movah,09h
int21h
callcr
movah,01h;输入转换方式
int21h
movsi,offsetkeybuf
incsi
movcx,byteptr[si];将字符串的元素个数赋给cx
incsi
callcr
cmpal,30h;0=capitaltosmall
jzone
cmpal,31h;1=smalltocapital
jztwo
cmpal,32h;2=interchange
jzthree
jmpdone;若都不是,直接结束程序
one:
andcx,00ffh;
int21h
popdx
popax
ret
dispendp
cends
endstart
popdx
popax
ret
crendp
dispproc;实现输出的子函数
pushax
pushdx
movdl,[si]
movah,02h
(3)程序功能的实现方法
程序的算法在注释中已经解释的比较清楚,程序中用的比较多的是循环指令以及条件转移指令。
应当注意的是,将输入的字符串的个数赋给cx后,在循环开始之前,为了得到真正的循环次数,应该加一条andcx,00ffh的指令。
(4)程序运行结果
二、论述
1、汇编语言的存在意义何在?
虽然汇编语言是相当底层的语言,而且相对于C语言、JAVA等高级语言,汇编语言书写的时候又比较的繁琐,但是它仍然具有其存在的重大意义,原因如下:
汇编语言是最接近于机器语言的编程语言。
如果说机器语言是计算机操作的本质,那么汇编语言就是最最接近本质的语言。
汇编语言最大的特点就是直接面向硬件,所以,我们在使用汇编语言的时候,我们能够感知计算机的运行过程和原理,从而能够对计算机硬件和应用程序之间的联系和交互形成一个清晰的认识。
其次,相对于繁复的高级语言,汇编语言指令集合更简约,指令操作更直接。
汇编语言是计算机技术的基础。
之所以说汇编重要,其一个重要的原因就是,汇编语言能够让你更好的理解高级语言,尤其是高级语言中的C语言。
汇编语言对于内存的操作都是基于内存地址的,而C语言中最令人头疼的指针概念,说白了就是内存的地址。
由于汇编的操作跟硬件紧密相关,所以,很多硬件设施的嵌入式编程使用的都是使用的汇编语言,因为汇编语言更直接,更有效率!
我们现在的数码产品很多,而这些数码产品赖以生存的芯片,主板等,都包含了嵌入式程序,而这些程序中,汇编语言的使用是相当重要的!
汇编语言在执行的时候所占用的资源远比C语言等高级语言要少,正因为汇编语言有“与机器相关性”的特性,程序员用汇编语言编写程序时,可充分发挥自己的聪明才智,对机器内部的各种资源进行合理的安排,让它们始终处于最佳的使用状态,这样做的最终效果就是:
程序的执行代码短,执行速度快。
2、为什么所有的微控制器都有自己专属的指令系统?
由于机器指令与CPU、内存以及端口紧密相关,所以,不同种类的微控制器所对应的机器指令也就不同,而且它们的指令系统往往相差很大。
这也是为什么汇编语言可移植性差、没有通用性的原因。
举个例子,汇编语言的操作对象是CPU上的寄存器,系统内存,或者立即数。
在80X86微处理器中,有8个通用的16位寄存器,其中包括四个16位数据寄存器AX、BX、CX、DX,两个16位变址寄存器SI、DI,两个16位指针寄存器BP和SP,8086的汇编语言可以直接对这些寄存器进行操作。
而8051单片机包含21个8位寄存器,如,ACC(累加器)、B(用于辅助累加器做某些运算的寄存器)、SCON(串行口功能控制器)、TMOD(定时/计数器工作模式控制器)、TCON定时/计数器控制字)等,51单片机的汇编语言照样可以直接对其进行操作。
很显然,我们不能把8086的汇编语言移植到8051上。
3、微处理器的指令系统、汇编语言是如何揭示微控制器的组成原理、工作原理的?
CPU所能执行的各种不同类型指令的总和,即CPU所能执行的全部操作称之为指令系统,它描述了CPU内部全部的控制信息和“逻辑判断”能力。
从微处理器组成原理的角度讲,指令是软件与硬件的接口、交界面。
用户通过编写软件来生成指令,进而控制硬件来执行各种功能。
由于汇编语言所生成的指令系统需要对微处理器中所有寄存器、内存单元以及I/O口进行点名式的控制,因此,微处理器的指令系统必然就包含了构成微处理器的所有部件。
从微处理器工作原理的角度讲,微处理器是根据指令来工作的,8086的汇编级指令共有115条,可以分为数据传送指令、算术运算指令、位处理指令、字符串指令、程序转移指令以及处理器控制指令等6大类,微处理器就是依照这些指令进行运转的。
举个例子,我们写一条简单的汇编语言指令:
pushax,汇编器将它转换成CPU能认识的机器语言,CPU就可以根据这条指令做出反应,将AX寄存器中的内容压入栈中。
而所有能完成更为复杂功能的复杂程序正是由一条一条这样的简单指令所构成,微处理器接受到指令便开始不停的高速运转,按照一定的顺序执行所有的指令,直到接收到停止的指令。
可以说,指令系统就像CPU的一张工作图纸,告诉CPU该怎样去工作,CPU失去这样一张图纸便不知如何去运转了。
因此,我们说微处理器指令系统揭示了微控制器的组成原理和工作原理。