《微机原理与接口技术4章.ppt》由会员分享,可在线阅读,更多相关《微机原理与接口技术4章.ppt(84页珍藏版)》请在三一办公上搜索。
1、第四章 汇编语言程序设计,微机原理与接口技术,第四章 汇编语言程序设计,主要内容汇编语言程序的结构汇编语言语句类型和组成汇编语言程序设计,文件名.ASM 文件名.OBJ 文件名.EXE,汇编语言源程序,汇编,目标程序,连接,执行/调试程序,编辑程序EDIT.EXE,汇编程序MASM.EXE,连接程序LINK.EXE,汇编语言程序的开发过程,4.1机器指令/汇编语言,ML 文件名.ASM,汇编语言程序的开发过程,1.源程序的编辑:源程序文件要以ASM为扩展名源程序文件的形成(编辑)可以通过任何一个文本编辑器实现:如DOS中的全屏幕文本编辑器EDIT2.源程序的汇编汇编是将源程序翻译成由机器代码组
2、成的目标模块文件的过程.MASM hello.asm如果源程序中没有语法错误,MASM将自动生成一个目标模块文件(hello.obj);否则MASM将给出相应的错误信息,这时应根据错误信息,重新编辑修改源程序后,再进行汇编3.目标模块的连接连接程序能把一个或多个目标文件和库文件合成一个可执行程序(.EXE、.COM文件):LINK hello.obj如果没有严重错误,LINK将生成一个可执行文件(hello.exe).,汇编语言程序的开发过程,4.可执行程序的运行与调试经汇编、连接生成的可执行程序在操作系统(DOS)下只要输入文件名就可以运行:hello.exe操作系统装载该文件进入主存,并开
3、始运行。在DOS下运行程序时,COMMAND.COM把.EXE文件装入内存。装入后,自动设置DS和ES寄存器指向程序段前缀,CS、IP、SS、SP寄存器设置为由连接程序传过来的值(所以必须在程序中给DS、ES赋值)。,PSP,DS,ES,用户程序区,汇编语言程序的开发过程,程序结束返回DOS的方法:START PROC FARPUSH DS MOV AX,0PUSH AX:RETSTART ENDP,如果出现运行错误,可以从源程序开始排错,也可以利用调试程序帮助发现错误.采用DEBUG.EXE调试程序:DEBUG hello.exe,4.2汇编语言源程序的结构,汇编语言的源程序是分段的,由几个
4、段形成一个源程序,每一段有一个段名,以SEGMENT为段开始,以ENDS结束;源程序最后以END作结束;一般有DATA段,CODE段,STACK段;一个段由若干语句组成,MY_DATA SEGMENT;定义数据段SUM DB?;为符号SUM保留一个字节MY_DATA ENDS;数据段结束MY_CODE SEGMENT;定义代码段ASSUME CS:MY_CODE,DS:MY_DATA;规定CS,DS的内容 PORT_VAL EQU 3;端口的符号名GO:MOV AX,MY_DATA;DS初始化为 MY_DATA MOV DS,AX MOV SUM,0;SUM单元为0CYCLE:CMP SUM,
5、100;SUM与100比较 JNA NOT_DONE;若未超过转至NOT_DONE MOV AL,SUM;若超过把SUM的内容 OUT PORT_VAL,AL;通过AL输出然后停机 HLTNOT_DONE:IN AL,PORT_VAL;输入下一个字节 ADD SUM,AL;与以前的结果累加 JMP CYCLE;转至CYCLEMY_CODE ENDS;码段结束END GO;整个程序结束,4.2汇编语言源程序的结构,一、汇编语言的语句格式 标号:指令助记符 操作数;注解 名字 伪指令助记符 参数;注解,1标号(名字):是给指令或某一存储单元地址所起的名字。可由下列字符组成:字母:A z;数字:0
6、9;特殊字符:?、一、$。当标识符后跟冒号时,表示是标号。它代表该行指令的起始地址;当标识符后不带冒号时,表示变量;伪指令前的标识符不加冒号。2(伪)指令助记符:表示不同操作的指令,可为8088的指令助记符,或伪指令。3操作(参)数:是指令执行的对象。依指令的要求,可能有一个、两个或者没有.4注解,例如:COUNT:INC CX;一个操作数COST DB 3,4,5,6,7;伪指令,5个操作数MOV AX,BP十4;二个操作数,4.2汇编语言源程序的结构,二、段定义语句与段寻址 段定义伪指令一般格式为:段名 SEGMENT 定位类型 组合类型 类别 段名 ENDS(1)定位类型:用来规定段起始
7、边界的要求,可以为以下四种,缺省为 PARA)PAGE:16位段地址的最低8位必须为0,即从一页的起点开始。PARA:16位段地址的最低4位必须为0,即从一段的起点开始。WORD:16位段地址的最低1位必须为0,即从偶地址开始。BYTE:16位段地址可以为任意值,即段可以从任何字节开始,4.2汇编语言源程序的结构,(2)组合类型(表示本段与其他段的关系,为连接程序使用,缺省为NONE):NONE:与其他段不发生关系,每段都有自己的基地址PUBLIC:与其他同名同类别的段连接在一起,使用一个共同的基地址STACK:与PUBLIC同样处理,但作为堆栈段COMMON:与其他同名同类别的段相互重叠在一
8、起,使用一个共同的基地址AT表达式:把本段装在表达式值所指定的段地址上(值为16位;不能指定代码段)MEMORY:把本段定位在所有其他段之上,若有多个则只有连接时遇到的第一个有效,其余按COMMON处理)(3)类别名:为连接程序使用,把类别名相同的段放在连续的存储区间(一般有STACK、CODE、DATA)。,4.2汇编语言源程序的结构,段寻址格式:ASSUME 段寄存器:段名,段寄存器:段名,例如,CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK MOV AX,DATA;DATA段值送AX MOV DS,AX;AX内容送DS,DS才有实际段值CODE
9、ENDS,4.2汇编语言源程序的结构,四、汇编程序结束伪指令END 一般格式:END 表达式 其中表达式表示该汇编程序的启动地址。例如:END START;表明该程序的启动地址为START。,4.2汇编语言源程序的结构,stacks segment stack stackdw 100h dup(?)stacks endsdata segment;Contains all variables for the programmsgdbHello World!,0Ah,0Dh,$data ends,4.2汇编语言源程序的结构,code segment;Contains all codeassume
10、cs:code,ds:data,ss:stacksorg 100hmain proc mov ax,data mov ds,axmov ax,0900hmov dx,offset msg int 21h mov ax,4C00h;terminate the program normallyint 21hmain endpcode endsend main,符号定义语句,1.等值语句EQU给符号定义一个值或别的符号名,或一条可执行的指令。例:NEW_PORT EQU 32 COUNT EQU CX CBD EQU AAD一个符号一经EQU赋值后,不能重新再定义。2.等号(Equal Sign)语
11、句与EQU类似,使用它能对符号进行再定义。例:B1=6;B1定义为6 B1=10;B1重新定义为10,数据定义伪指令,格式1:变量名 伪指令名 表达式1,表达式2,这里伪指令可为DB,DW,DD,表达式有以下几种情况:数值表达式 例:DA_BYTE DB 50H,50,0caH DA_WORD DW 0a3f1H,498dH A1 DD 12345H;Memory:45H,23H,01H,00H?表达式,不带引号的?表示可预置任何内容 例:DA_B DB?,?;要求分配两个字节单元 DA_W DW?,?;要求分配两个字单元 字符串表达式 数据项可以写成字符串形式,但只能用DB、DW、DD定义,
12、而且DW、DD语句定义的串只允许包含两个字符。,例:S1 DB ABCDEF S2 DW AB,CD,EF S3 DD AB,CD 这几个变量在存储器中存放情况如下:S1 41H S2 42H S3 42H 42H 41H 41H 43H 44H 00H 44H 43H 00H 45H 46H 44H 46H 45H 43H 00H 00H,注意:定义多于两个以上字符的字符串时,只能使 用DB伪指令,不能使用DW和DD等伪指令。,数据定义伪指令,格式2:变量名 伪指令名表达式DUP(表达式)用于定义重复的数据或分配一数据块空间例:D_B1DB 20H DUP(?);保留20H个字节 D_B2
13、DB 10H DUP(ABCD);字符串ABCD 重复10H次 D_W1 DW 10H DUP(4);字4重复10H次,4.3.3 过程定义的伪指令PROC和ENDP一个过程由伪指令PROC和ENDP来定义,其格式为:过程名 PROC 类型 过程体 RET 过程名 ENDP其中,过程名是为过程所起的名称,不能省略,类型由FAR(远过程,为段间调用)和NEAR(近过程,在本段内调用)来确定,如果缺省类型,则该过程就默认为近过程。ENDP表示过程结束。过程体内至少应有一条RET指令,以便返回被调用处。过程可以嵌套,也可以递归使用。,4.3.4 ORG 伪指令ORG伪指令规定了在某一段内,程序或数据
14、代码存放的起始偏移地址。一般格式:ORG 例如:DATA SEGMENT ORG2000H BUFF DB STRING DATA ENDS上述变量定义中,BUFF从DATA段偏移为2000H的单元开始存放。,4.4 常量、变量和标号(1)常量 二进制:10111001B 十进制:1234D或1234 八进制:255Q或255O 十六进制:3A5DH,第一位为字母时前面加数字0 字符串常数:用单引号括起来的一个或多个字符组成一个字符串常数,例如:The 在内存中以字符的ASCII码值存放,注意一个空格也是一个字符。如The,在内存中是:54H、68H、65H和20H。,(2)变量:代表存放在某
15、些存储单元的数据。这些数据在程序运行期间随时可以修改。变量有三个属性:段属性、偏移属性和类型属性(所具有的字节数)。(3)标号 标号是一条指令的目标代码的符号地址,它常用作转移指令(或子程序调用指令)的操作数。标号有三个属性:段属性、偏移属性和类型属性。段属性是该标号的段地址,偏移属性是该标号的偏移地址,类型属性是表示该标号的范围是本段(NEAR)或段间(FAR),或称为近或远属性。,4.5 汇编语言的表达式和运算符,表达式:由常数、操作数、操作符和运算符组成。有六种运算符:算术运算符、逻辑运算符和关系运算符、分析运算 符、综合运算符和分离运算符。1、算术运算符+、*、/、MOD(取余)、SH
16、L(左移)、SHR(右移)例:32 MOD 5;结果为2 21H SHL 2;结果为84H 2、逻辑运算符(按位操作)AND(与)24H AND 0FH=04H OR(或)24H OR 0FH=2FH XOR(异或)24H XOR 0FH=2BH NOT(非)NOT 24H=0DBH,4.5 汇编语言的表达式和运算符,3、关系运算符 关系运算是逻辑判定,当为真时结果为全1(0FFFFH),为假时结果为全0。EQ(等于);若PP=25,则25 EQ PP=0FFFFH NE(不等于);25 NE PP=0 LT(小于);25 LT 26=0FFFFH LE(小于等于);25 LE PP=0FFF
17、FH GT(大于);26 GT PP=0FFFFH GE(大于等于);24 GE PP=0关系运算符一般不单独使用,常与其它运算符结合使用。例如:ADD AX,(port GT 60)AND 50)OR(port LE 60)AND 70)当port 的值大于60时,上述指令汇编为 ADD AX,50当port 的值小于或等于60时,上述指令汇编为 ADD AX,70,4、分析运算符 把存储器地址操作数分解成它的组成部分:SEG(求段地址),格式:SEG 符号名 OFFSET(求偏移地址),格式:OFFSET 符号名 TYPE(求符号名类型值),格式:TYPE 符号名 SIZE,求为符号名分配
18、的字节数 格式:SIZE 符号名 回送分配给该符号名的字节数,但此值是LENGTH的值和TYPE的值的乘积。,4.5 汇编语言的表达式和运算符,LENGTH,求为符号名分配的项数。格式:LENGTH 符号名 这里为符号名定义的数据项必须是用 重复格式DUP()定义的。而对于其他情况则回送1。例:K2 DW 10 DUP(?)则 LENGTH K2=10 TYPE K2=2 SIZE K2=20 例:AARR DW 2,4,6 则 LENGTH AARR=1,TYPE AARR=2 SIZE AARR=2可以看出:SIZE=(LENGTH)*(TYPE 符号名),4.5 汇编语言的表达式和运算符
19、,4.5 汇编语言的表达式和运算符,5、综合运算符(1)定义符号名为新类型 格式:类型 PTR 符号名 PTR的功能归纳如下:保证运算时操作数类型的匹配 例:F1DB16H,38H F2DW1234H,26ABH MOV AX,WORD PTR F1;AX=3816H MOV BL,BYTE PTR F2;BL=34H,4.5 汇编语言的表达式和运算符,通过PTR指明是字单元还是字节单元 例:MOVBYTE PTR BX,10H;BX为字节单元MOVWORD PTR SI,20H;SI为字单元 用PTR来改变距离属性 例:JMPFAR PTR LLOOP;段间转移CALLDWORD PTR B
20、X;远程调用(2)指定新类型 格式:符号名 EQU THIS 类型 例:LABC EQU THIS BYTE;LABC是字节类型 LABD DW 4321H,2255H;LABD是字类型 MOV AL,LABC;AL=21H MOV AX,LABD;AX=4321H,4.5 汇编语言的表达式和运算符,(3)分离运算符 取低字节 格式:LOW 符号名 取高字节 格式:HIGH 符号名 例:设SSY=2050H mov al,LOW 3080H;al=80H mov ah,HIGH SSY;ah=20H mov cl,LOW 3a4bH;cl=4bH(4)$运算符,返回地址计数器的当前值例:ARR
21、AY DW 1,2,$+4,3,4,$+4 如果在汇编时,ARRAY的偏移地址是0074H,则在ARRAY数组中,两个$+4得到的结果是不同的,这是由于$的值是在不断变化的,4.5 汇编语言的表达式和运算符,$运算符用在伪操作的参数字段时,和用在指令中的情况是不同的,用在伪操作中它表示的是地址计数器的当前值。用在指令中它只表示该指令的首地址,而与$本身所在的字节无关。例如指令 JNE$+6,表示满足条件时转移到该指令的首地址加6以后所在的单元。1000:2543 JNE$+6则转移地址是2549H例:下面的数据段定义,COUNT 表示什么?DATA SEGMENT BUFDB012345678
22、9ABCD COUNTEQU$-BUF DATAENDS 这里,COUNT的值就是数据区的长度,所以COUNT=14,4.5 汇编语言的表达式和运算符,(5)段超越运算符格式:段寄存器加冒号强迫当前指令的操作数的寻址不按约定的段进行,而由段超越运算符指定的段寻址例:MOV AX,ES:BX;强迫操作数来自ES段(6)SHORT运算符通知汇编器,转移目标在+127-128之间例:JMP SHORT F1,问题:,例:FAR DB 23H,45H AAA:MOV AX,FAR例:MOV BX,OFFSET VAR1MOV BX,7,常量和变量的名字及标号不能用宏汇编的保留字,此程序段汇编时会出现操
23、作类型不明确错误需要修改为:MOV BYTE PTR BX,7;字节操作或MOV WORD PTR BX,7;字操作,4.6基本结构程序设计,程序设计步骤 1、分析问题 2、确定算法 3、画流程图,简单程序也可以不画流程图,直接编程。4、内存空间分配 5、编写程序 6、静态检查 7、上机调试,4.6基本结构程序设计,1、顺序结构顺序结构程序设计是没有分支,没有循环的直线运行程序,程序执行按照IP内容自动增加的顺序进行。例:用数据运算指令对两个16位数做加法,这两个数从地址10050H开始连续存放,结果放在这两个数之后。分析题目:16位数相加,用加法指 令,本题可以不考虑进位问题。确定算法:80
24、86加法指令可以做字操 作,可以用不带进位的加法指 令;若用带进位加法指令,事 前先清除进位。画流程图:见右.,开始 初始化 被加数送AX 被加数+加数送AX AX送(10054H)和(10055H)结束,4.6基本结构程序设计,内存空间分配:内存地址 内容10050H 被加数低8位10051H 被加数高8位10052H 加数低8位10053H 加数高8位10054H 和数低8位10055H 和数低8位,编写程序:movax,1000h;初始化movds,axmovsi,50hmov di,52hmovbx,54hclc;清除进位movax,siadcax,di;带进位加法movbx,axhl
25、t,4.6基本结构程序设计,2、分支结构分支程序的基本思想是根据逻辑判断的结果来形成程序的分支,如图,若A成立,则执行P1;否则执行P2。,例:符号函数 1 当X0 Y=0 当X=0-1 当X0,4.6基本结构程序设计,DATASEGMENTXXDW 12;X存储单元YYDW?;Y存储单元DATAENDSSTACK SEGMENT STACK STACKDB 100H DUP(?)STACK ENDSCODESEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTART:PUSH DSXOR AX,AXPUSH AXMOV AX,DATAMOV DS,AXMOV AX,
26、XX;AX XX,4.6基本结构程序设计,CMPAX,0;X与0比较JGEBIGPR;X0,转BIGPRMOVYY,0FFFF;X0,(YY)-1JMPEXIT;退出BIGPR:JE EQUPR;X=0,转EQUPR MOVYY,1;X0,(YY)1JMPEXITEQUPR:MOVYY,0;X=0,(YY)0EXIT:MOV AX,YY;将结果送AXRET;MOVAX,4C00H;INT21HCODEENDSENDSTART,例:比较两个无符号数的大小,把大数存入MAX单元 解:比较两个无符号数,可采用CF标志位来判断大小,程序如下:DATASEGMENTSOURCEDBX1,X2;两个无符号
27、数X1和X2MAXDB?;保留存放大数的单元DATAENDSCODESEGMENTASSUME CS:CODE,DS:DATAMOVAX,DATAMOVDS,AXMOVAL,SOURCE;X1送ALCMPAL,SOURCE+1;X1-X2JNCBRANCH;若X1X2,转BRANCHMOVAL,SOURCE+1;否则,X2送ALBRANCH:MOVMAX,AL;大数送MAX单元 MOVAX,4C00H INT21HCODEENDSEND,例:将内存中的(源)数据块传送到另一区域去。DATA SEGMENTSTR DB 1000 DUP(?)STR1 EQU STR+7 STR1 EQU STR
28、+25STRCOUNT EQU 50DATA ENDS STACK SEGMENT STACK STACKSTAPN DB 100 DUP(?)STACK ENDSCODESEGMENTASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACKSTART:MOVAX,DATAMOVDS,AX MOVES,AX,MOV CX,STRCOUNT MOV SI,STR1 MOV DI,STR2 CLD PUSH SI ADD SI,STRCOUNT-1 CMPSI,DI POP SI JB OK STD ADD SI,STRCOUNT-1 ADD DI,STRCOUNT-1OK:
29、REP MOVSB MOV AX,4C00H INT 21HCODE ENDS END START,4.6基本结构程序设计,3、循环结构循环程序是经常遇到的程序结构,一个循环结构通常由以下几个部分组成:循环初始化部分。一般要进行地址指针、循环次数及某标志的设置,相关寄存器的清零等操作。只有正确地进行了初始化设置,循环程序才能正确运行,及时停止。循环体。是要求重复执行的程序段部分,对应于要求重复执行的操作。循环控制部分。由该部分修改并判断控制循环的条件是否满足。以决定是否继续循环。循环结束部分。如保存循环运行结果等。,4.6基本结构程序设计,DO-WHILE,DO-UNTIL,例:用循环结构编写
30、程序完成:DATASEGMENTBUFFERDWa1,a2,a10;原始10个数据SUMDW?;存放和数DATAENDSCODESEGMENTASSUME CS:CODE,DS:DATASTART:MOVAX,DATA MOVDS,AX MOVAX,0;AX中为和数,初始为0 MOVDI,OFFSET SUM;存放结果地址送DI MOVBX,OFFSET BUFFER;数据缓冲区首地址送BX,4.6基本结构程序设计,4.6基本结构程序设计,MOV CX,10;循环次数送CX LOP:ADDAX,BX;累加 INCBX;修改数据缓冲区地址 INCBX DECCX;次数减1 JNZLOP;到10次
31、了吗?不到,转LOP MOVDI,AX;到10次,存放结果和 MOVAX,4C00H;返回DOS INT21HCODE ENDS ENDSTART,4.6基本结构程序设计,例:给定一串16位数,找出大于零、等于零和小于零的个数,并紧跟着原串存放。分析:这是一个统计问题,须设定三个计数器分别统计三种情况下的结果。程序如下:DATASEGMENTBUFF DW X1,X2,X3,XnCOUNT EQU$-BUFF;此时,COUNT的值为BUFF所占的字节数PLUSE DB?ZERO DB?MINUS DB?DATAENDSCODESEGMENT ASSUME CS:CODE,DS:DATA,ES:
32、DATA BEGIN:MOVAX,DATA MOVDS,AX MOVCX,COUNT SHRCX,1;相当于除2,正好为BUFF中的数据个数,MOVDX,0;设定计数器初值MOVAH,0;设定计数器初值LEABX,BUFFAGAIN:CMP WORD PTR BX,0JAEPLU;大于等于0,则转PIUINCAH;0,则统计JMPNEXTZER:INCDH;0,则统计NEXT:INCBXINCBXLOOPAGAINMOVPLUS,DLMOVZERO,DHMOVMINUS,AHMOVAX,4C00HINT21HCODEENDSENDBEGIN,4.6基本结构程序设计,4、子程序对于一个子程序,应
33、该注意它的入口参数和出口参数。入口参数是由主程序传给子程序的参数,而出口参数是子程序运算完传给主程序的结果。另外,子程序所使用的寄存器和存储单元往往需要保护,以免影响返回后主程序的运行。参数传递一般有三种方法实现。(1)利用寄存器。这是一种最常见方法,把所需传递的参数直接放在主程序的寄存器中传递给子程序。(2)利用存储单元。这种参数传递方法,把所需传递的参数直接放在一个数据区中。(3)利用堆栈。这种方法将参数压入堆栈,在子程序运行时从堆栈中取参数。,4.6基本结构程序设计,例:两个6字节数相加。分析:将一个字节相加的程序段设计为子程序。主程序分6次调用该子程序,但每次调用的参数不同。DATAS
34、EGMENTADD1DBFEH,86H,7CH,35H,68H,77HADD2DB45H,BCH,7DH,6AH,87H,90HSUMDB 6 DUP(0)COUNTDB6DATAENDSSTACKSEGMENTDB100 DUP(?)STACKENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACK,4.6基本结构程序设计,MADD:MOVAX,DATAMOVDS,AXMOVSI,OFFSET ADD1MOVDI,OFFSET ADD2MOVBX,OFFSET SUMMOVCX,COUNT;循环初值为6CLCAGAIN:CALL SUBADD;调用子程序LO
35、OP AGAIN;循环调用6次MOVAX,4C00HINT21H,4.6基本结构程序设计,;子程序入口参数:SI,DI,BX。出口参数:SI,DI,BXSUBADDPROC;完成一个字节相加MOVAL,SI;SI是一个源操作数指针ADCAL,DI;DI是另一个操作数指针MOVBX,AL;BX是结果操作数指针INCSIINCDIINCBXRETSUBADDENDPCODEENDSEND MADD,例:将内存中的一串1位十六进制数转换为其对应的ASCII码。DATASEGMENTHEXBUFDB02H,08H,0AH,09H,0FHCOUNTEQU$-HEXBUFDATA ENDSSTACKSEG
36、MENT stack stackDB100 DUP(?)STACKENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK,;子程序HEXD,将AL中的BCD码转换成ASCII码 HEXD PROC NEAR CMPAL,0AH JLADDZ;大写字母转换成ASCII码 ADD AL,A-0-0AH ADDZ:ADD AL,0 RETHEXD ENDPCODE ENDS ENDBEGIN,;主程序BEGIN:MOVAX,DATAMOVDS,AXMOVBX,OFFSET HEXBUF MOV CX,COUNTREPEATO:MOV AL,BXCALLBEX
37、D;调用子程序,实现转换 MOV BX,AL INC BX LOOP REPEATO MOVAX,4C00H INT21HCODE ENDS END BEGIN,例:把内存中两个字单元的值分别转换为4个ASCII码表示的十六进制数码串,串的起始地址分别为STRING1及STRING2。DATASEGMENTORG 100HNUMBERDW 25AFH,33FBHSTRING1DB4 DUP(?)STRING2DB4 DUP(?)DATAENDSSTACK SEGMENT stack stackDB100 DUP(?)STACKENDSCODESEGMENTASSUMECS:CODE,DS:DA
38、TA,SS:STACKBEGIN:MOVAX,DATAMOVDS,AXMOVES,AX;第一个子单元的转换 LEABX,STRING1PUSHBX;将参数(结果地址指针)压入堆栈PUSHNUMBER;将源数据压入堆栈CALLBINHEX;调用子程序,;第二个子单元的转换 LEABX,STRING2PUSHBX;将参数(结果地址指针)压入堆栈PUSHNUMBER;将源数据压入堆栈CALLBINHEX;调用子程序MOVAX,4C00HINT21HBINHEX PROC PUSHBPMOVBP,SPPUSHAXPUSHDIPUSHCXPUSHDXPUSHF;以上为保护现场MOVAX,BP+4;取出N
39、UMBERMOVDI,BP+6;取出STRING的偏移地址ADDDI,LENGTH STRING-1;使DI指向转换数据MOVDX,AX;保护原始数据MOVCX,4,AGAIN:ANDAX,0FH;取低4位CALLHEXD;调子程序STDSTOSB;保护转换数据PUSHCX;保护CX的值MOVCL,4SHRDX,CLMOVAX,DXPOPCXLOOPAGAINPOPFPOPDXPOPCXPOPDIPOPAXPOPBPRET4BINHEX ENDP,;将AL中的BCD码转换成ASCII码HEXD PROC CMPAL,0AHJLADDZ;大写字母转换成ASCII码ADDAL,A-0-0AH AD
40、DZ:ADDAL,0 RETHEXDENDPCODEENDSENDBEGIN,4.6基本结构程序设计,4.6基本结构程序设计,例:数的阶乘 1,n=0按照阶乘的定义 n!=n*(n-1)!,n0这是一个递归定义式,可采用子程序的的递归调用形式。,;计算N!结果在result中Data segmentN dw5Result dw?Data ends,4.6基本结构程序设计,Stack_seg segment stack stack db 100 dup(?)Stack_seg endsCodesegmentassume cs:code,ds:data,ss:stack_segStart:mov
41、ax,data mov ds,ax;主程序部分 mov bx,N push bx;保存N call fact;调用求N!子程序 pop result;结果在result中 mov ax,4c00H INT 21H,4.6基本结构程序设计,;子程序,求N!factproc nearpush axpush bp mov bp,sp mov ax,bp+6;取N cmp ax,0,4.6基本结构程序设计,jnefact1;ax不等于零,转fact1 incax;ax=0,0!=1jmpexitfact1:decax;ax=N-1 push ax callfact;递归调用 popax;ax=(N-1
42、)!mulword ptr bp+6;(N-1)!*Nexit:mov bp+6,ax pop bp pop ax retfactendpcodeendsendstart,4.7 DOS功能调用,DOS功能调用通常按照如下4个步骤进行:功能号送AH 入口参数送指定寄存器名 INT 21H 根据出口参数分析功能调用执行情况,4.7 DOS功能调用,1.单个字符输入(2号功能调用)功能号:AH01H出口参数:AL所输入字符的ASCII码功能:等待从标准输入设备输入一个字符并送入寄存器AL;等待用户键盘输入,AL键入字符的ASCII码,并显示MOV AH,1INT 21H,4.7 DOS功能调用,2
43、.从键盘输入一个字符串(10号功能调用)功能号:AH0AH入口参数:DS:DX缓冲区首地址执行该功能调用时,用户按键,最后用回车确认缓冲区的定义:第1字节事先填入最多欲接收的字符个数(包括回车 字符,可以是1255)第2字节将存放实际输入的字符个数(不包括回车符)第3字节开始将存放输入的字符串,4.7 DOS功能调用,例:Buffer db 81;定义缓冲区;第1个字节填入可能输入的最大字符数db 0;存放实际输入的字符数db 81 dup(0);存放输入的字符串.mov dx,seg buffer;伪指令seg取得buffer的段地址mov ds,dx;设置数据段DSmov dx,offse
44、t buffermov ah,0ahint 21h,4.7 DOS功能调用,3.向显示器输出一个字符(2号功能调用)功能号:AH02H入口参数:DL字符的ASCII码功能:在显示器当前光标位置显示给定的字符,光标右移一个字符位置。如按Ctrl-Break或Ctrl-C则退出;在当前显示器光标位置显示一个问号mov ah,02h;设置功能号:ah02hmov dl,?;提供入口参数:dl?int 21h;DOS功能调用:显示,4.7 DOS功能调用,4.显示字符串(9号功能调用)功能号:AH09H入口参数:DS:DX欲显示字符串在主存中的首地址字符串应以$(24H)结束功能:在显示器输出指定的字
45、符串string db Hello,Everybody!,0dh,0ah,$mov ah,09h mov dx,seg string mov ds,dxmov dx,offset stringint 21h,4.文件管理系统调用:AH(功能号)功能 入口参数 出口参数 3C 建立文件 DS:DX=ASCII串地址 成功 AX=文件代号 CX=文件属性 失败 AX=错误码 3D 打开文件 DS:DX=ASCII串地址 成功 AX=文件代号 AL=0读,=1写,=2读写 失败 AX=错误码 3E 关闭文件 BX=文件代号 失败 AX=错误码 3F 读文件或设备 DS:DX=数据缓冲区地址 成功AX
46、=实际读入字数 BX=文件代号 AX=0已到文件尾 CX=读取字节数 读错误:AX=错误码 40 写文件或设备 DS:DX=数据缓冲区地址 成功AX=实际写入字数 BX=文件代号 CX=写入字节数 写错误:AX=错误码 41 删除文件 DS:DX=ASCII串地址 成功 AX=00 错误AX=错误码,4.7 DOS功能调用,例:写数据文件,步骤:输入文件名,建立文件,写文件,关闭文件。Datasegment;数据段mesgndb16 dup(?);文件名字符区dataregdb2048dup(?);数据区DataendsCodesegment;代码段leasi,mesgn;文件名字符区的偏移地
47、址Rep1:movah,1;键入文件名int21hcmpal,0dh;判断是否是回车键jenext1;是,转next1;否继续输入,4.7 DOS功能调用,4.7 DOS功能调用,movsi,al;文件名字符送入incsijmprep1Next1:leadx,mesgn;文件名区的偏移地址movcx,0;文件属性为0movah,3ch;建立文件int21hmovbx,ax;文件代号送bxleadx,dataregmovcx,2048;写入的字节数movah,40h;写文件int21hmovah,3eh;关闭文件int21hCsegendsend,例:读数据文件 Msegsegment;数据段
48、mesgn db 16dup(?)errmesg db“File not found$”datareg db 2048dup(?)Csegsegment;代码段 leasi,mesgnbeg:movah,1;键入文件名 int21h cmpal,0dh jenext1 movsi,al incsi jmp begNext1:leadx,mesgn moval,0 movah,3dh;打开文件,int21h cmpal,2;2为文件未找到jneready;不等于2,转 leadx,errmesgmovah,9;显示字符串int21hcrlf;回车换行宏指令jmpbegReady:leadx,da
49、taregmovcx,2048mov bx,ax;ax中为文件代号movah,3fh;读文件int21hmovah,3eh;关闭文件int21h,4.7 DOS功能调用,4.程序结束,返回DOSINT 20H MOV AH,4CHINT 21H,4.8 宏汇编与条件汇编,宏指令:要多次使用的程序段可以用一条宏指令来代替,而汇编程序汇编到该宏指令时,仍会产生源程序所需的代码。宏指令使用时要经过三个步骤:宏定义、宏调用、宏展开宏定义的一般格式为:宏指令名 MACRO 形式参量表 宏体 ENDM宏调用的一般格式为:宏指令名 实际参量表宏展开:汇编时,汇编程序用已由实参数取代形式参数的宏体取代程序中的
50、 宏指令例如:SHIFT MACRO MOV CL,4 SAL AL,Cl ENDM 这样定义以后,凡是要使AL中内容左移4位的操作都可用一条宏指令SHIFT来代替。,4.8 宏汇编与条件汇编,例:SHIFT MACRO X,Y,ZMOV CL,X;宏体S&Z Y,CL ENDM在程序中引用:SHIFT 4,AL,HR MOV CL,4SHR AL,CLSHIFT 6,BX,AR MOV CL,6SAR BX,CL形式参数可出现在操作数部分,也可以出现在操作码部分.,4.8 宏汇编与条件汇编,例:用宏指令定义两个字操作数相乘,得到一个16位的第三个操作数作为结果。宏定义:MULTIPLYMAC