微机原理与接口技术第4章汇编语言程序设计.ppt

上传人:小飞机 文档编号:6572785 上传时间:2023-11-13 格式:PPT 页数:196 大小:1.07MB
返回 下载 相关 举报
微机原理与接口技术第4章汇编语言程序设计.ppt_第1页
第1页 / 共196页
微机原理与接口技术第4章汇编语言程序设计.ppt_第2页
第2页 / 共196页
微机原理与接口技术第4章汇编语言程序设计.ppt_第3页
第3页 / 共196页
微机原理与接口技术第4章汇编语言程序设计.ppt_第4页
第4页 / 共196页
微机原理与接口技术第4章汇编语言程序设计.ppt_第5页
第5页 / 共196页
点击查看更多>>
资源描述

《微机原理与接口技术第4章汇编语言程序设计.ppt》由会员分享,可在线阅读,更多相关《微机原理与接口技术第4章汇编语言程序设计.ppt(196页珍藏版)》请在三一办公上搜索。

1、第4章 汇编语言程序设计,4.1 汇编语言的格式4.1.1 8086汇编语言程序的一个例子MY_DATA SEGMENT;定义数据段SUM DB?;为符号SUM保留一个字节MY_DATA ENDS;定义数据段结束MY_CODE SEGMENT;定义码段,ASSUME CS:MY_CODE,;规定CS和DS的内容 DS:MY_DATAPORT_VA1 EQU 3;端口的符号名GO:MOV AX,MY_DATA;DS初始化为MY_DATA MOV DS,AX MOV SUM,0;清SUM单元,CYCLE:CMP SUM,100;SUM单元与100相比较 JNA NOT_DONE;若未超过,转至NO

2、T_DONE MOV AL,SUM;若超过,把SUM单元的内容 OUT PORT_VAL,AL;通过AL输出 HLT;然后停机,NOT DONE:IN AL,PORT_VAL;未超过时,输入下一个字节 ADD SUM,AL;与以前的结果累加 JMP CYCLE;转至CYCLE,MY CODE ENDS;代码段结束 END GO;整个程序结束 由这个例子看到,8086汇编的一个语句行是由4个部分组成的,即标号 操作码 操作数;注释(或名字),4.1.2 8086汇编语言源程序的格式,源程序的一般格式为:NAME1 SEGMENT 语句 语句NAME1 ENDSNAME2 SEGMENT 语句 语

3、句NAME2 ENDS END,4.2 语句行的构成,4.2.1 标记(Token)1IBM宏汇编的字符集(1)字母包含大写的英文字母:ABCDXYZ;小写的英文字母:abcxyz。,(2)数字阿拉伯数字:0123456789。(3)特殊字符,图4-1 IBM宏汇编字符集中可打印字符,2界符(Delimiters),图4-2 IBM宏汇编中的界符集,3常量(Constants),(1)数字(整数)常量 二进制常量 以字母B结尾的由一串“0”和“1”组成的序列。例如,00101100B。,十进制常量,由若干个09的数字组成的序列,可以以字母D作结尾,或没有任何字母作结尾。例如,1234D或123

4、4。,八进制常量,以字母Q结尾,由若干个07的数字组成的序列。例如255Q、377Q等。,十六进制常量,以字母H结尾,由若干个09的数字或AF的字母所组成的序列。,(2)字符串常量,字符串常量是由包含在单引号内的1或2个ASCII字符构成的。,4标识符(Identifiers),标识符是由程序员自由建立起来的、有特定意义的字符序列,如例子中的SUM、CYCLE、PORT_VAL等。一个标识符是由最多为31个字母、数字及规定的特殊字符(?_$)等组成的,且不能用数字打头(以免与十六进制数相混淆)。,下面是一些标识符的例子:XGAMMAJACKSTHIS_DONETHISDONE,5保留字(Res

5、erved Words),保留字看上去像标识符,但是它们在语言中有特殊的意义,而且不能用它们作为标识符。,表4-1IBM宏汇编中的保留字,续表,续表,6注释(Comment),为了使汇编语言的源程序更便于阅读和理解,常在源程序中加上注释。注释是在分号(;)后面的任意的字符序列,直到行的结尾。在汇编时,汇编程序对它们并不进行处理。在可打印的文件中,注释和源程序一起打印。,4.2.2 符号(Symbol),1寄存器(Registers)2变量(Variable)所有的变量都具有三种属性:(1)段值(SEGMENT),即变量单元所在段的段地址(段的起始地址)的高16位,低4位始终为0。,(2)偏移量

6、(OFFSET),即变量单元地址与段的起始地址之间的偏移量(16位)。(3)类型(TYPE),变量有三种类型:字节(Byte)、字(word)和双字(Double Word)。,3标号(Label)4数5其他符号,4.2.3 表达式(Expressions),1操作数(Operands)一个操作数或者是一个寄存器名,或是一个常量(数字常量或字符串常量),或是一个存储器操作数。,(1)常量操作数,具有数字值的操作数是常量或是表示常量的标识符(符号)。例中的常量操作数是100、PORT_VAL。常量操作数的值的允许范围是从65535+65535。,(2)存储器操作数,存储器操作数,通常是标识符。具

7、体地说,可以分成标号(Label)和变量(Variable)两种。,变量可以具有以下几种寻址方式:直接寻址 基址寻址 变址(索引)寻址 基址变址寻址,2运算符(Operators),算术运算符(Arithmetic Operators)逻辑运算符(Logical Operators)关系运算符(Relational Operators)分析运算符(Analytic Operators)合成运算符(Synthetic Operators),(1)算术运算符,一个是加(+)、减()、乘(*)和除(/)运算符。另一个算术运算符是MOD,它产生除法以后的余数,例如,19/7是2(商是2),而19MOD

8、7是5(余数是5)。,因此,对例子中的存储器地址作如下运算:SUM+2CYCLE-5NOT_DONE-GO是有效的表达式。而SUM-CYCLE,(2)逻辑运算符,逻辑运算符是按位操作的AND、OR、XOR和NOT。1010 1010 1010 1010B AND 1100 1100 1100 1100B=1000 1000 1000 1000B1100 1100 1100 1100B OR 1111 0000 1111 0000B=1111 1100 1111 1100BNOT 1111 1111 1111 1111B=0000 0000 0000 0000B,(3)关系运算符,在IBM宏汇编

9、中有以下关系运算符:相等Equal(EQ)不等Not Equal(NE)小于Less Than(LT),大于Greater Than(GT)小于或等于Less Than or Equal(LE)大于或等于Greater Than or Equal(GE),若在程序中有以下关系运算:MOV BX,PORT_VAL LT 5 若PORT_VAL的值小于5,关系为真,则汇编程序在汇编后产生的语句为:MOV BX,0FFFFH 若PORT_VAL的值不小于5,则关系为假,汇编后产生的语句为:MOV BX,0,(4)分析运算符(5)合成运算符,4.2.4 语句(Statements),一个汇编语言的源程

10、序是由一条条语句组成的,语句就是对需要计算机完成的动作的说明。源程序中的语句可分成两类:指令语句和指示性语句。,指令语句,汇编程序把它们翻译成机器代码,这些代码命令8086执行某些操作。如MOV、ADD、JMP等。,对于指示性语句(伪指令),汇编程序并不把它们翻译成机器代码,实际上也不可能翻译成机器代码,只是用来指示、引导汇编程序在汇编时做一些操作,如定义符号、分配存储单元、初始化存储器等,所以伪指令本身不占用存储单元,例如:MY_PLACE DB?,指令语句的格式为:标号:助记符 参数,参数;注释指示性语句的格式为:名字 命令 参数,参数;注释,4.3 指示性语句(Directive Sta

11、tements),在IBM宏汇编中有以下几种指示性语句:(1)符号定义语句(Symbol definition)(2)数据定义语句(Data definition)(3)段定义语句(Segmentation definition)(4)过程定义语句(Procedure definition)(5)结束语句(Termination),4.3.1 符号定义语句,1等值语句EQUNAME EQU EXPRESSION 一些例子如下:BOILING_POINT EQU 212BUFFER_SIZE EQU 32NEW_PORT EQU PORT_VAL+1COUNT EQU CXCBD EQU AAD

12、,2等号(Equal sign)=语句,EMP=6EMP=7EMP=EMP+1,3解除语句PURGE,PURGE语句的格式为:PURGE 符号1,符号2,符号n例如:PURGE NEW_PORTNEW_PORT EQU PORT_VAL+10,4.3.2 数据定义语句,数据定义语句,为一个数据项分配存储单元,用一个符号名与这个存储单元相联系,且为这个数据提供一个任选的初始值。,与数据项相联系的符号名称为变量。以下是数据定义语句的例子:THING DB?;定义一个字节BIGGER_THING DW?;定义一个字BIGGEST_THING DD?;定义一个双字,例如:THING DB 25 不仅使

13、THING这个符号与一个字节的存储单元相联系,而且在汇编时会把25放入与THING相联系的存储单元中。所以THING是一个字节变量,它的初始值为25。,同样,以下语句:BIGGER_THING DW 4142H 在汇编时就会把41H与42H分别放至与BIGGER_THING相联系的两个连续的字节单元中(一个字中),而且42H放在地址低的字节,41H放在地址高的字节。所以,若BIGGER_THING是一个字变量,则它的初始值为4142H。,语句BIGGEST_THING DD 12345678H 在汇编时的初始化如图4-3所示。它定义了一个双字变量,且给了初始值。,IN_PORTDB PORT_

14、VALOUT_PORTDB PORT_VAL+1 其中,PORT_VAL已由EQU语句赋了值。,图4-3 定义双字的数据定义语句的作用,一个存储单元的类型如下:(1)数据字节SUM DB?;定义一个字节(2)数据字(两个连续的字节)BIGGER DW?;定义一个字,(3)数据双字(四个连续的字节)BIGGEST DD?;定义一个双字(4)Near指令单元CYCLE:CMP SUM,100(5)Far指令单元,若在一个程序中,对它的数据段有如下定义:DATA_TABLES SEGMENTBUFFER1 DB 100 DUP(0)BUFFER2 DW 200 DUP(20H)BUFFER3 DD

15、100 DUP(13)DATA_TABLES ENDS,其中的每一个存储单元都有一些属性(或组成部分)。分析运算符SEG,返回的是一个存储单元的段地址(即它所在段的起始地址);OFFSET运算符返回的是每一个存储单元地址的段内偏移量,即它与段地址之间的偏差。故:SEG BUFFER1SEG BUFFER2SEG BUFFER3,都是相同的,它们返回的地址都是DATA_TABLES的地址。所以,若要对数据段寄存器初始化,则可以采用指令:,MOV AX,SEG BUFFER1MOV DS,AX而OFFSET BUFFER1OFFSET BUFFER2OFFSET BUFFER3,是各不相同的。若要

16、向这些缓冲区填入新的数据,可以用一些地址指针,则可以用以下指令来初始化地址指针:MOV BX,OFFSET BUFFER1MOV SI,OFFSET BUFFER2MOV DI,OFFSET BUFFER3 以后,就可以用这些指针来间接寻址这些缓冲区。,表4-2存储器地址操作数的类型值,4.3.3 段定义语句,段定义的主要命令有SEGMENT,ENDS,ASSUME,ORG。SEGMENT和ENDS语句把汇编语言源程序分成段。这些段就相应于存储器段,在这些存储器段中,存放相应段的目标码。,下面的程序是一个简单的例子,它说明了如何使用SEGMENT、ENDS和ASSUME命令,以定义代码段、堆栈

17、段、数据段和附加段。MY_DATA SEGMENT X DB?Y DW?Z DD?,MY_DATA ENDSMY_EXTRA SEGMENT ALPHA DB?BETA DW?GAMMADD?MY_EXTRA ENDSMY_STACK SEGMENT,DW 100 DUP(?)TOP EQU THIS WORDMY_STACK ENDSMY_CODE SEGMENT ASSUME CS:MY_CODE,DS:MY_DATA ASSUME ES:MY_EXTRA,SS:MY_STACK,START:MOV AX,SEG X MOV DS,AX MOV AX,SEG ALPHA MOV ES,AX

18、,MOV AX,MY_STACK MOV SS,AX MOV SP,OFFSET TOPMY_CODE ENDS END START,(1)不要搭接,段中的第一个可用字节是在16字节界限上。MY_SEG SEGMENT MY_SEG ENDS 这是一种正常情况。,(2)允许搭接,但第一个可用字节必须在字的界限上。MY_SEG SEGMENT WORD MY_SEG ENDS,(3)段开始在指定的16个字节界值上,但第一个可用字节在指定的偏移位置上。MY_SEG SEGMENT AT 1A2BH;段地址为1A2BH ORG 0003H;段内从偏移量0003H开始 MY_SEG ENDS,在最后这

19、个例子中,介绍了另一个语句ORG(Origin),它规定了段内的起始地址。伪指令ORG 的一般格式为:ORG,此语句指定了段内在它以后的程序或数据块存放的起始地址,也即以语句中的表达式的值作为起始地址,连续存放,除非遇到一个新的ORG语句。,4.3.4 过程定义语句,过程定义语句的格式为:PROCEDURE_NAME PROC NEAR或PROCEDURE_NAME PROC FAR RETPROCEDURE NAME ENDP,下面是一个过程定义的例子:MY_CODE SEGMENTUP_COUNT PROC NEAR ADD CX,1 RETUP_COUNT ENDPSTART:,CALL

20、 UP_COUNT CALL UP_COUNT HLTMY_CODE ENDS END START,4.3.5 结束语句,START:END START,4.4 指 令 语 句,4.4.1 指令助记符1NOP(No Operation)2保留空格(Place Holder),4.4.2 指令前缀,LOCKREP(Repeat)REPE(当相等时重复)REPNE(当不相等时重复)REPZ(当标志ZF=1时重复)REPNZ(当标志ZF=0时重复)具有前缀的指令语句的例子为:CYCLE:LOCK DEC COUNT,4.4.3 操作数寻址方式,1立即(Immediate)MOV AX,15;15是一

21、个立即数2寄存器(Register)MOV AX,15;AX是一个寄存器操作数,3直接(Direct)SUM DB?MOV SUM,15;SUM是一个直接存储器操作数4通过基址寄存器间接(Indirect Through Base Register)MOV AX,BXMOV AX,BP,5通过变址寄存器间接(Indirect Through Index Register),MOV AX,SIMOV AX,DI,6通过基址寄存器加变址寄存器间接(Indirect Through Base Register Plus Index Register),MOV AX,BXSIMOV AX,BXDIMO

22、V AX,BPSIMOV AX,BPDI,7通过基址或变址寄存器加位移量间接,MANY_BYTES DB 100 DUP(?)MOV AX,MANY_BYTESBX MOV AX,MANY_BYTESBP MOV AX,MANY_BYTESSI MOV AX,MANY_BYTESDI,8通过基址寄存器加变址寄存器加位移量间接,MANY_BYTES DB 100 DUP(?)MOV AX,MANY_BYTESBXSI MOV AX,MANY_BYTESBXDI MOV AX,MANY_BYTESBPSI MOV AX,MANY_BYTESBPDI,4.4.4 串操作指令,ALPHADB?BETA

23、DB?MOVSI,OFFSET ALPHA MOVDI,OFFSET BETA MOVSBETA,ALPHA,下面我们通过一个例子来说明:一个完整的汇编语言源程序应该由哪些部分组成。例子是把两个分别由未组合的BCD码(一个字节为一位BCD数)的串相加。,由于8086中允许两个未组合的十进制数相加,只要经过适当调整就可以得到正确的结果。所以,在程序中把第一个串的一位BCD数取至AL中,与第二个串的相应位相加,经过AAA调整,再把结果存至存储器中。,程序中的前面部分是为了设置段,先设置数据段,用DB伪指令定义两个数据串,用COUNT表示数据的长度。接着是定义堆栈段,为堆栈留下了100个单元的空间(

24、实际上当然要由需要来定),然后是定义代码段,从标号GO开始就是可执行指令部分。程序如下:,NAME ADP_TWO_BCD_STRINGDATA SEGMENT STRI1DB 1,7,5,2 STRI2DB 3,8,1,4 COUNTEQU$-STRI2DATA ENDS,STACK SEGMENT PARA STACK STACK STAPNDB 100 DUP(?)TOP EQU LENGTH STAPNSTACK ENDSCODE SEGMENT ASSUME CS:CODE,SS:STACK,DS:DATA,ES:DATA,STATR PROC FAR PUSH DS MOV AX,

25、0 PUSH AX,GO:MOV AX,DATA MOV DS,AX MOV ES,AX MOV AX,STACK MOV SS,AX MOV AX,TOP MOV SP,AX CLC CLD,MOV SI,OFFSET STRI1 MOV DI,OFFSET STRI2 MOV CX,COUNTCYCLE:LODS STRI1 ADC AL,DI AAA STOS STRI2 LOOP CYCLE RETSTATR ENDP,CODE ENDS END START 程序中的DATA SEGMENT DATA ENDS,4.5 汇编语言程序设计及举例,4.5.1 算术运算程序设计(直线运行程序

26、)例4-1 两个32位无符号数乘法程序。NAME 32 BIT MULTIPLYDATA SEGMENTMULNUM DW 0000,0FFFFH,0000,0FFFFH,4 DUP(?),DATA ENDSSTACK SEGMENT PARA STACK STACK DB 100 DUP(?)STACK ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK,ES:DATA,START PROCFARBEGIN:PUSHDS;DS中包含的是程序段前缀的起始地址 MOVAX,0 PUSHAX;设置返回至DOS的段值和IP值 MOVAX,DATA MOV

27、DS,AX,MOVES,AX;置段寄存器初值 LEABX,MULNUMMULU32:MOVAX,BX;BAX MOVSI,BX+4;DSI MOVDI,BX+6;CDI MULSI;BD,MOVBX+8,AX;保存部分积1 MOV BX+0AH,DX MOV AX,BX+2;AAX MULSI;AD ADDAX,BX+0AH,ADCDX,0;部分积2的一部分与部分积1的相应部分相加 MOV BX+0AH,AX MOV BX+0CH,DX;保存 MOV AX,BX;BAX,图4-4 用16位乘法指令实现32位乘法的程序流程图,MULDI;BC ADDAX,BX+0AH;与部分积3的相应部分相加

28、ADCDX,BX+0CH MOVBX+0AH,AX MOVBX+0CH,DX PUSHF;保存后一次相加的进位位,MOVAX,BX+2;AAX MULDI;AC POPF ADCAX,BX+0CH;与部分积4的相应部分相加 ADCDX,0 MOVBX+0CH,AX MOVBX+0EH,DX,RETSTART ENDPCODE ENDS END BEGIN,4.5.2 分支程序设计,SIGEFMOV AX,BUFFER OR AX,AX JE ZERO JNS PLUS MOV BX,0FFH JMP CONTI,ZERO:MOV BX,0 JMP CONTIPLUS:MOV BX,1CONTI

29、:,图4-5 符号函数的程序流程图,4.5.3 循环程序设计,1用计数器控制循环 例4-2 在一串给定个数的数中寻找最大值(或最小值),放至指定的存储单元。每个数用16位表示。,NAME SEARCH_MAXDATA SEGMENTBUFFER DW X1,X2,.,XnCOUNT EQU$-BUFFERMAX DW?DATA ENDSSTACK SEGMENT PAPA STACK STACK,DB 64 DUP(?)TOP EQU$-STACKSTACK ENDS CODE SEGMENTSTART PROC FAR ASSUME CS:CODE,DS:DATA,SS:STACK,BEGI

30、N:PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX MOV AX,TOP MOV SP,AX,MOV CX,COUNT LEA BX,BUFFER MOV AX,BX INC BX DEC CXAGAIN:CMP AX,BX JGE NEXT,MOV AX,BXNEXT:INC BX LOOP AGAINSTART ENDPCODE ENDS END BEGIN,2多重循环,下面是一个多重循环的例子(没有精确计算延时时间):DELAY:MOV DX,3FFHTIME MOV AX,0FFFFHTIME1

31、 DEC AX NOP,JNE TIME1 DEC DX JNE TIME RET,4.5.4 字符串处理程序设计,1确定字符串的长度 例4-3 从头搜索字符串的结束标志,统计搜索的字符个数,其流程图如图4-6所示。,相应的程序为:NAME LENGTH_OF_STRINGDATA SEGMENTSTRINGDB ABCDUVWXYZ,0DHLL DB?CR EQU 0DHDATA ENDS,STACKSEGMENT PARA STACK STACK DB L00DUP(?)STACKENDSCODE SEGMENT,ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STAC

32、KSTART PROCFARBEGIN:PUSHDS MOVAX,0 PUSHAX MOVAX,DATA MOVDS,AX MOVES,AX,LEA DI,STRING;设串的地址指针 MOV DL,0;置串长度初值为0 MOV AL,CR;串结束标志ALAGAIN:SCASB;搜索串 JE DONE;找到结束标志,停止 INC DL;串长度加1 JMP AGAIN,DONE:LEA BX,LL MOV BX,DL RETSTART ENDPCODE ENDS END BEGIN,图4-6 确定字符串长度的流程图,2加偶校验到ASCII字符,例4-4 若有一个ASCII字符串,它的起始地址放在

33、单元STRING内,要求从串中取出每一个字符,检查其中包含的“1”的个数,若已为偶数,则它的最高有效位置“0”;否则,最高有数位置“1”,然后送回。其流程如图4-7所示。,图4-7 加偶校验位至ASCII字符,相应的程序为:NAME PARITY_CHECKDATA SEGMENTSTRINGDB 1234567890COUNTEPU$-STRINGDATA ENDSSTACKSEGMENT PARA STACK STACK DB 100 DUP(?),STACKENDSCODESEGMENT ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACKSTARTPROC F

34、ARBEGIN:PUSH DS MOV AX,0 PUSH AX,MOV AX,DATA MOV DS,AX MOV ES,AX LEA SI,STRING MOV CX,COUNT,AGAIN:LODSB AND AL,AL JPE NEXT OR AL,80H MOV SI-L,AL,NEXT:DEC CX JNZ AGAIN RETSTARTENDPCODEENDS END BEGIN,4.5.5 码转换程序设计,1十六进制到ASCII的转换 例4-5 若有一个二进制数码串,要把每一个字节中的二进制转换为两位十六进制数的ASCII,高4位的ASCII放在地址高的单元。串中的第一个字节为串

35、的长度(小于128)。能实现这样转换的流程如图4-8所示。,相应的程序为:NAME HEX_CHANGE_TO_ASCIIDATA SEGMENTL1 DW 2STRINGDB 34H,98H12 DW?BUFFERDB 2*2 DUP(?)DATAENDS,STACKSEGMENT PARA STACK STACK DB 100 DUP(?)STACKENDSCODESEGMENT ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK,STARTPROC FARBEGIN:PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX

36、MOV ES,AX MOV CX,LL,LEA BX,STRING LEA SI,BUFFER MOV AX,CX SAL CX,1 MOV 12,CX MOV CX,AXAGAIN:MOV AL,BX,MOV DL,AL AND AL,0FH CALL CHANGE MOV AL,DL PUSH CX MOV CL,4 SHR AL,CL POP CX,CALL CHANGE INC BX LOOP AGAIN RETSTART ENDPCHANGE PROC CMP AL,10 JL ADD_0 ADD AL,A-0-10,ADD_0:ADD AL,0 MOV SI,AL INC SI R

37、ETCHANGE ENDPCODE ENDS END BEGIN,(a)(b)图4-8 把十六进制数转换为ASCII的程序流程图,2从二进制到ASCII串的转换,例4-6 把在内存变量NUMBER中的16位二进制数,每一位转换为相应的ASCII,存入串变量STRING中,其流程如图4-9所示。,相应的程序为:NAME BINARY_TO_ASCIIDATA SEGMENTNUMDW 4F78HSTRINGDB 16 DUP(?)DATAENDSSTACKSEGMENT PARA STACK STACK DB 100 DUP(?),STACKENDSCODESEGMENT ASSUME CS:C

38、ODE,DS:DATA,ES:DATA,SS:STACKSTARTPROC FARBEGIN:PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX,图4-9 把二进制位串的每一位转换为ASCII的程序流程图,MOV ES,AX LEA DI,STRING MOV CX,LENGTH STRING PUSH DI PUSH CX MOV AL,30H;使缓冲区全置为“0”,REP STOSP POP CX POP DI MOV AL,31H MOV BX,NUM,AGAIN:RCL BX,L;左移BX,把相应位进入C标志 JNC NEXT;若为零则转至NE

39、XT MOV DI,AL;若为“1”,则把“1”置入缓冲区NEXT:INC DI,LOOP AGAIN RETSTARTENDPCODEENDS END BEGIN,4.5.6 有关I/O的DOS功能调用,1在CRT上连续输出字符09MOVDL,OUTPUT_CHARMOVAH,2INT 21H,图4-10 在CRT上输出09的程序流程图,相应的程序为:NAME OUTPUT_CHAR_0_9STACK SEGMENT PARA STACK STACK DB 100 DUP(?)STACKENDSCODE SEGMENT ASSUME CS:CODE,SS:STACK,START PROC F

40、ARBEGIN:PUSH DS MOV AX,0 PUSH AX MOV BL,0 PUSH BXGOON:MOV D1,20H;把空格字符DL MOV AH,2,INT 21H;输出空格字符 POP BX MOV AL,BL INC AL DAA;增量后进行十进制调整,AND AL,0FH MOV BL,AL PUSH BX OR AL,30H;转换为ASCII码 MOV D1,AL MOV AH,2 INT 21H;输出一个09之间的字符,MOV CX,0FFFFH;为便于观察,插入一定的延时AGAIN:DEC CX JNE AGAIN JMP GOONSTART ENDPCODE END

41、S END BEGIN,2在CRT上连续显示0059,相应的程序为:NAME OUTPUT_CHAR_00_59STACKSEGMENT PARA STACK STACK DB 100 DUP(?)STACK ENDSDATA SEGMENTBUFFERDB 3 DUP(?),DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKSTART PROC FARBEGIN:PUSH DS MOV AX,0,PUSH AX MOV AX,DATA MOV DS,AX MOV CX,1000;设置最大的循环次数 MOV BL,0 LEA SI,BUF

42、FER PUSH BX,GOON:MOV D1,0DH MOV AH,2;输出回车符 INT 21H MOV D1,0AH MOV AH,2;输出换行符,INT 21H POP BX MOV AL,BL INC AL DAA CMP AL,60H;AL增加到60了吗?JC NEXT;未达到,转去显示 MOV AL,0;到60,置为0,NEXT:MOV BL,AL PUSH BX MOV D1,AL PUSH CX MOV CL,4 SHR AL,CL,OR AL,30H;把AL中十位数,转换为ASCII MOV SI,AL INC SI MOV AL,DL AND AL,0FH OR AL,3

43、0H;把AL中的个位数,转换为ASCII,MOV SI,AL INC SI MOV AL,$MOV SI,AL MOV DX,OFFSET BUFFER MOV AH,9 INT 21H;输出字符串 MOV CX,0FFFFH,AGAIN:DEC CX JNE AGAIN POP CX DEC CX JE DONE MOV SI,OFFSET BUFFER JMP GOON,DONE:RETSTART ENDPCODE ENDS END BEGIN,图4-11 在CRT上连续显示0059的程序,4.5.7 宏汇编与条件汇编,1宏指令的用途(1)在汇编语言的源程序中,若有的程序段要多次使用,为了

44、使在源程序中不重复书写这个程序段,可以用一条宏指令来代替。由宏汇编程序在汇编时产生所需要的代码。,MOVCL,4SALAL,CL若要多次使用,就可以用一条宏指令代替。如下所示:SHFT MACROMOVCL,4SAL AL,CLENDM,(2)宏定义不但能使源程序的书写简洁,而且由于宏指令具有接收参量的能力,所以功能就更灵活。,SHIFT MACRO X MOV CL,X SAL AL,CL ENDM,SHIFT MACRO X,Y MOV CL,X SAL Y,CL ENDM,SHIFT 4,ALSHIFT 4,BXSHIFT 6,DI,这些宏指令在汇编时,分别产生以下指令的目标代码:MOV

45、CL,4SAL AL,CLMOVCL,4SAL BX,CLMOVCL,6SAL DI,CL,(3)形式参量不只可以出现在操作数部分,也可以出现在操作码部分。如:SHIFT MACRO X,Y,Z MOV CL,X S&Z Y,CL ENDM,若有以下调用:SHIFT 4,AL,ALSHIFT 6,BX,ARSHIFT 8,SI,HR,在汇编时,分别产生以下指令的目标代码。MOV CL,4SAL AL,CLMOV CL,6SAR BX,CLMOV CL,8SHR SI,CL,2IBM宏汇编中主要宏操作伪指令,(1)MACRO 其一般格式为:宏定义名 MARCO,(2)PURGE,PURGE伪指令

46、的格式为:PURGE 宏定义名,(3)LOCAL,例如在AL中有一位十六进制数码要转换为ASCII,则可以用以下宏定义:CHANGEMACRO CMP AL,10 JL ADD_0 ADD AL,A-0-10ADD_0 ADD AL,0 ENDM,上面的CHANGE宏定义在有多次调用的情况下,应定义为:CHANGEMACRO LOCAL ADD_0 CMP AL,10 JL ADD_0 ADD AL,A-010ADD_0 ADD AL,0 ENDM,若有宏调用:CHANGE CHANGE 在宏汇编展开时为:+CMP AL,10+JL?0000+ADD AL,A-0-10,+?0000ADD A

47、L,0+CMP AL,10+JL?0001+ADD AL,A-0-10+?0001 ADD AL,0,(4)REPT,其一般格式为:REPT 指令体ENDM,这个伪指令可以重复执行在它的指令体部分所包含的语句。重复执行的次数,由表达式的值所决定。如:X=0REPT 10X=X+1DB XENDM,它把110分配给十个连续的存储单元。利用这个伪指令可以对某个存储区赋值(建立一个表)。,例4-7 把数字09的ASCII填入表TABLE。CHAR=0 TABLE LABEL BYTE REPT 10 DB CHAR CHAR=CHAR+1 ENDM,例4-8 建立一个地址表,其中每个字的内容是下一个

48、字的地址(用作地址指针),而最后一个字的内容是第一个字的地址。TABLE LABEL WORD REPT 99 DW$+2 ENDM DW TABLE,(5)IRP,其一般格式为:IRP 形式参量(参数表)指令体ENDM,IRP X DB XENDM,(6)IRPC,其一般格式为:IRPC 形式参量,字符串(或字符串)指令体ENDM,IRPC X,0123456789DB X+1ENDM,3宏定义嵌套,DIF MACRO N1,N2 MOV AX,N1 SUB AX,N2 ENDMDIFSQRMACRO N1,N2 RESULT PUSH DX PUSH AX,DIF N1,N2 IMUL A

49、X MOV RESULT,AX POP AX POP DX ENDM,4宏指令与子程序的区别,(1)宏指令是为了简化源程序的书写,在汇编时,汇编程序处理宏指令,把宏定义体插入到宏调用处。,所以,宏指令并没有简化目标程序。有多少次宏调用,在目标程序中仍需要有同样多次的目标代码插入。所以,宏指令不能节省目标程序所占的内存单元。,(2)把上述两者的特点加以比较,可以看出:若在一个源程序中多次调用一个程序段,则可用子程序,也可以用宏指令来简化源程序。,用子程序的方法,汇编后产生的目标代码少,也即目标程序占用的内存空间少,节约了内存空间。但是,子程序在执行时,每调用一次都要先保护断点,通常在程序中还要保护现场;在返回时,先要恢复现场,然后恢复断点(返回)。,这些操作都额外增加了时间,因而执行时间长,速度慢。而宏指令恰好相反,它的目标程序长,占用的内存单元多;但是执行时不需要保护断点,也不需要保护现场以及恢复、返回等这些额外的操作,因而执行时间短、速度快。,5条件汇编,IF XX ARGUMENT(语句体1)ELSE(任选)(语句体2)ENDIF,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号