资源描述
,#,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,1,第,4章 汇编语言程序设计,mov ax,12h,call display,Jmp 1234h,2,主要内容:,汇编语言源程序的结构,汇编语言语句格式,伪指令,功能调用,汇编语言程序设计,3,4.1汇编语言源程序,(1),机器语言,二进制数形式的指令和数据。,B0 64,是什么意思?这就是,机器语言,。既不直观,又不易理解和记忆.,MOV AL,64H,;,很容易记忆理解,这就是,助记符,。,(2),助记符,用便于记忆的英语单词表示的指令操作码。它,反映了指令的功能和主要特征,便于人们理解和记忆。,4,操作数可能放在存储器中,这就涉及,操作数的地址,。程序中遇到转移指令或调用指令,也需要知道转移地址,若采用具体地址就很不方便,一旦有错,改动也很麻烦。于是人们,采用,标号或符号,来代替,地址,例:,LP1,:,MOV AX,VAR,LOOP,LP1,(3),汇编语言,指令助记符,符号地址,标号,伪指令等语言元素的集合以及这些元素使用的规则。,用汇编语言编写的程序叫,汇编语言源程序,。,指令除了操作码以外,还有一个,操作数问题,。,5,汇编程序,(,翻译程序,),源程序的编译程序,汇编程序,汇编语言,源程序,机器语言,目标程序,汇编源程序需翻译成机器语言,变成可执行文件,机器才能执行,这个翻译过程叫,汇编,。,高级语言中称该过程为,“,解释,”,或,“,编译,”,。执行翻译的程序称为,“,汇编程序,”,。,6,汇编语言程序设计与执行过程,输入汇编语言源程序,EDIT,/,NOTEPAD,等 源文件,.,ASM,汇编,(,编译,),MASM/ASM,等 目标文件,.,OBJ,链接,LINK,等 可执行文件,.,EXE,调试,DEBUG/TD,等 最终正确的程序,.,EXE,目前都把上述的软件集成在统一的环境下,以方便用户使用。,建立、编辑 汇编 连接 运行,调试,7,4.1.1 汇编语言源程序的结构,汇编语言源程序通常由一个或几个程序模块组成,每个模块一般由,3,个,(,或,4,个,),逻辑段组成:,数据段,存放数据、变量,(,附加数据段,存放数据、变量,),堆栈段,堆栈区域,代码段,存放程序指令,8,一个基本的汇编语言程序框架如下:,stack,SEGMENT PARA,stack,DB 100 DUP(,stack,),stack,ENDS,data,SEGMENT,data,ENDS,code,SEGMENT,ASSUME CS,:,code,DS,:,data,ES,:,data,SS:,stack,start:,MOV AX,data,MOV DS,AX,MOV ES,AX,MOV AL,4CH,INT 21H,code,ENDS,END,start,堆栈段,数据段,代码段,真指令,9,0000:03FF,环境与代码运行,FFFF:0,堆栈段,数据段,代码段,CS:IP,DS,SS:SP,系统起始运行程序,中断向量区,(系统专用),栈底,最多,4,个活动段,分段结构,ES,10,4.1.,2,汇编语言的语句类型与格式,汇编语言的语句有两种:,指令性语句,由,8086,指令助记符,(,真指令,),构成的语句,指示性语句,由,伪指令,构成的语句,指令性语句,的格式为:,标号,:,指令助记符,目的操作数,源操作数,;,注释,指示性语句,的格式为:,名字,伪指令,操作数,1,操作数,2,;,注释,注:,各部分之间至少要用一个,空格,(,或逗号、分号,),作为分隔符。,11,指示性语句,(,伪指令,),由汇编程序,执行,。它指出汇编程序应如何对源程序进行汇编,如何定义变量、分配存储单元以及指示程序开始和结束等。,指示性语句,无,机器码指令与其相对应。,指令性语句,(,真指令,),由,CPU,执行,,,每一条,指令性语句都,有,一条机器码指令与其对应;,注意,:,指令性语句,汇编时,生成,机器码;,指示性语句,汇编时,不生成,机器码。,12,语句的构成元素:,1.,标号,指令的符号地址,用来代表指令在,存储器中的地址,。,只能出现,在指令性语句,中,标号后应,加,上冒号。,2.,名字,段、过程、变量或宏的名字,用来代表它们在,存储器中的地址,。,只能出现,在指示性语句,中,名字后,不加,冒号。,标号与名字,统称为,标识符,一般最多由,31,个字母、数字及规定的特殊符号(如,_,、,$,、,?,、,)组成,不能以数字开头。默认情况下,汇编程序不区别标识符中的字母大小写,一个程序中,每个标识符的定义是唯一的,还不能是汇编语言采用的保留字,保留字,是汇编程序已经利用的标识符,主要有:,真指令助记符,例如:,MOV,、,ADD,伪指令助记符,例如:,DB,、,EQU,操作符,例如:,OFFSET,、,PTR,寄存器名,例如:,AX,、,CS,13,3.,指令助记符,8086,真指令、伪指令助记符,4.,操作数,即,指令的操作对象,对,指令性语句,(,真指令,),0,,,1,,,2,个,对,指示性语句,(,伪指令,),根据需要而定,操作数之间以逗号分隔,操作数可以是:寄存器、存储单元、常数或,表达式,例如:,AX,,,DI+BX+10,,,200,,,16*8+TABLE,,等等,14,例如:,以下为同一条指令写的注释,1,),MOV CX,100 ;,传送,100,到,CX,2,),MOV CX,100 ;,循环计数器置初值,显然,第二种写法要比第一种写法要好。,5.,注释,以分号开头,可放在指令后,也可单独一行。,注意注解的写法。,要写指令(段)在程序中的,作用,,而不要写指令的操作。,注释不能加程序的汇编,不生成目标程序,只为阅读方便。,15,汇编语言的一个实例,:hello.asm,data,SEGMENT,Hello,DB,Hello,world!,0DH,0AH,data,ENDS,prog,SEGMENT,ASSUME,CS:,prog,DS:,data,start,:MOV AX,data,MOV DS,AX,LEA DX,hello,;,取字符串首地址,MOV AH,9,INT 21H;,显示字符串,MOV AH,4CH,INT 21H;,退回,DOS,prog,ENDS,END,start,名字,标号,16,4.1.,3,数据项与表达式,1,常量,二进制数,以,B,或,b,结尾,。如,01001101,B,。,十进制数,以字母,D,或,d,结尾,缺省情况下,后缀,D,或,d,可以省略如,85,。,十六进制数,以,H,结尾,。以字母,A,F,开头的十六进制数,前面要用,0,表达,以避免与其他符号混淆,如,0,F160,H,。,字符串,:用,引号括起来,的,1,个或多个字符。,如,ERROR!,a,汇编时被翻译成对应的,ASCII,码,4,5H,52H,52H,4FH,52H,21H,61H。,数据项,(,操作数的形式,),包括,常量,、,标号,/,名字,、,变量,及,表达式,。,17,有三个,属性:,段地址,:即标号所在段的段地址;,偏移量,:标号所代表存储单元的段内偏移地址;,类 型,:,NEAR,或,FAR,NEAR,表示标号所在语句与转移指令,/,调用指令在同一码段内,跳转时只需改变,IP,即可。,FAR,标号所在语句与转移指令,/,调用指令不在同一代码段内。跳转时需改变,CS,和,IP,即可。,若没有对类型进行说明,默认为,NEAR,。,标号,通常作为,转移指令,或,CALL,指令,的转移地址。,2.,标号,/,名字,指令或数据所在内存单元的符号地址,如,Start,:,MOV AX,data,JMP/CALL,Start,Hello,DB 06H,45H,44H,PTR,18,变量也有三个,属性:,段地址,变量所在段的段地址,偏移量,变量单元地址与段首地址之间的位移量。,类 型,有,BYTE,、,WORD,、,DWORD,三种之一。,变量,在程序中作为,存储器操作数,被引用。,3.,变量,如,Start:MOV AX,data,PTR,变量,即内存中的存储单元或数据区。,变量名,是存储单元,(,数据区,),的,符号,地址,或,名字,。,19,例如:,正确的,:,LP1,AGAIN,NEXT,_GO,OK_1,错误的,:,4M,LOOP,AAA,#HELP,+ONE,标号和变量名,的使用规则,:,组成,:,A-Z(,不分大小写,),0-9,?,.,_$,不能,以数字开头,以免与十六进制数相混。,长度,小于,31,个字符,不能与保留字,(,指令助记符、伪指令、预定义符号等,),重名,对定义的符号不区分大小写。,20,注:,变量要,事先,定义才能使用,变量类型应与指令要求的操作数,类型相符,。例:,MOV BL,V1;,要求,V1,应该是字节属性的变量。,变量定义后,变量名,只对应,这个数据区的,首地址,,若有这个数据区有若干个数据项时,其地址要改变。,指令中的操作数的段基地址不直接表示出来,是默认的。在使用变量时,其段属性应与其所指的段寄存器相符,若不相符,要加上段超越。,21,4,.,表达式,表达式,是常数、寄存器、标号、变量与运算符的组合。,有,数字,表达式,和,地址,表达式,两种。,汇编时按,优先规则,对表达式进行计算,计算出具体的,数值,或,地址,。运行时不能改变。,表达式中的,运算符有,6,类:,算术、逻辑、关系、取地址、属性、杂类,。,如,Start:MOV AX,16*8+TABLE,22,用于,地址,表达式,例:,LEA SI,TAB+3,若,TAB,的偏移地址为,1000H,,则汇编后的形式为:,LEA SI,1003H,(1),算术,运算符,+、-、*、/,,MOD,用于,数字,表达式,例:,MOV AX,4*1024,汇编后的形式为,:,MOV AX,4096,23,注意,:,不要把,逻辑运算符,与,逻辑运算指令,混淆:,例:,AND AX,3FC0H AND 0FF00H,汇编后源操作数被翻译为:,3F00H,,所以上述指令与,AND AX,3F00H,等价。,(2),逻辑,运算符,AND、OR、XOR,、,NOT,逻辑运算符,只能用于,数字,表达式,中。,例:,MOV CL,36H AND 0FH,经汇编后:,MOV CL,06H,24,例:,MOV BX,PORT GT 300H,若,PORT,的值大于,300H,为真,则汇编后为:,MOV BX,0FFFFH,若,为假,则汇编后为:,MOV BX,0,(3),关系,运算符,EQ,、,NE,、,LT,、,GT,、,LE,、,GE,关系运算的结果,是一个逻辑值:,真,或,假,关系为真,结果为全,1,关系为假,结果为全0,25,(4),取地址,运算符,SEG,、,OFFSET,SEG,:取变量,/,标号的段地址,OFFSET,:取变量,/,标号的偏移地址,例:,VAR DB 12H,MOV BX,,,OFFSET,VAR,;取变量,VAR,的偏移地址,MOV AX,,,SEG,VAR,;取变量,VAR,的段地址,注意,:,SEG,、,OFFSET,只能对符号地址操作,MOV AX,SEG BX,MOV BX,OFFSET SI,26,例:,VAR DW 1,,,2,,,3,,,4,,,5,则,TYPE,VAR=2,LENGTH,VAR=1,SIZE,VAR =2,(5),取值,运算符,TYPE,、,LENGTH,、,SIZE,TYPE,取,变量的类型(,1,,,2,,,4,),LENGTH,取所定义,变量,的长度,(,无,DUP,时为,1,,有时为,DUP,前面的值),SIZE,取所定义存储区的字节数,(,=TYPE*LENGTH,),27,LENGTH,和,SIZE,运算符的具体运算规则是:如果变量是用重复操作符,DUP,定义的,那么运算符,LENGTH,的运算结果是外层,DUP,的给定值(即外层重复次数),如果没有用,DUP,定义的变量,运算结果总是,1,。,而运算符,SIZE,是,LENGTH,和,TYPE,两个运算结果的乘积。,【,例,】,取出变量占存储单元个数。,DATASEGMENT,A DBABCDEF,BDW10DUP,(,1,,,2DUP,(,2,),DATAENDS,MOVAX,,,LENGTH A,;,1AX,MOVBX,,,LENGTHB,;,10BX,28,SIZE,A,=LENGTH A*TYPE A=1,SIZE,B,=LENGTH B*TYPE B=20,若,BUFFER,存储区是用如下伪指令定义:,BUFFER,DW,200,DUP(0),则:,TYPE BUFFER,等于,2,LENGTH BUFFER,等于,200,SIZE BUFFER,等于,400,29,(6),属性,运算符,PTR,用来指定地址操作数的类型。,格式:,PTR,类型,BYTE,WORD,DWORD,和,NEAR,FAR,SHORT,BYTE,、,WORD,、,DWORD,用于描述数据存储单元,(,变量,),地址,NEAR,、,FAR,(SHORT?),用于描述转移、调用的目的地址,30,例:,MOV,BYTE PTR,DI,0;,字节类型,MOV,WORD,PTR,DI,0;,字类型,MOVDI,0B5H ;,类型不定,PTR,也可用来进行,强制类型转换,例:,STR1,DW,?;STR1,定义为字类型,MOVAX,STR1 ;,合法,MOVAL,STR1 ;,非法,MOV AL,BYTE PTR,STR1,;,合法,31,7,)其它运算符,方括号“,”,指令中用方括号表示存储器操作数,方括号的内容表示操作数的偏移地址,例:,MOV AX,,,1000H,段重设运算符“:”,它跟在段寄存器名之后,表示段重设,用来指定一个存储器操作数的段属性而不管其,原来,的隐含的段是什么。,例:,MOV AX,,,ES,:,DI,32,在计算具有多个运算符的表达式值时,按以下规则操作:,优先级高的先运算,优先级低的后运算。,当优先级相同时,按表达式中从左到右的顺序进行运算,使用括号可以提高表达式运算的优先级。,表达式中的运算符的优先级,高,优,先,级,低,1,括号中的项,即(,)和,2,LENGTH,,,SIZE,3,PTR,,,OFFSET,,,SEG,,,TYPE,4,,,/,,,MOD,5,+,,,-,6,EQ,,,NE,,,L,,,LE,,,GT,,,GE,7,NOT,8,AND,9,OR,,,XOR,33,4.2 伪指令,数据定义,伪指令,符号定义,伪指令,段定义和段寄存器指定,伪指令,过程定义,伪指令,结束,伪指令,由汇编程序执行的指令,它本身不被汇编成机器指令。,常用的伪指令,有:,34,4.2.1,数据定义,伪指令,(,变量定义,),功能,:,用于定义变量的类型,给变量赋初值或给变量分配存储空间。数据定义伪指令的格式为:,变量名,数据定义伪指令 操作数,操作数,,常用的数据定义伪指令有如下几种:,DB,定义,字节,DW,定义,字,DD,定义,双字,DQ,定义,四字,DT,定义,十字节,35,变量名为用户自定义标识符,,表示操作数首元素的逻辑地址,;用这个符号表示地址,常称为,符号地址,变量名可以没有。这种情况,汇编程序将直接为初值表分配空间,无符号地址,设置变量名是为了方便存取它指示的存储单元,变量名,36,操作数,操作数是用逗号分隔的参数,主要由数值常数、字符串、表达式或?、,DUP,组成,?,表示初值不确定,即未赋初值;,DUP,表示重复初值,DUP,的格式为:,重复次数,DUP(,重复参数,),37,1),定义字节单元伪指令,DB,DB,伪指令用于分配一个或多个,字节,单元,并可以将它们初始化为指定值,初值表中每个数据一定是字节量(,Byte,),存放一个,8,位数据:,可以是,0255,的无符号数,或是,128,127,带符号数,也可以是,字符串常数,datasegment,;数据段,Xdb a,-5,db 2 dup(100),?,Ydb ABC,dataends,字节单元定义实例,38,2),定义字单元伪指令,DW,DW,伪指令用于分配一个或多个,字单元,,并可以将它们初始化为指定值,初值表中每个数据一定是字量(,Word,),一个字单元可用于存放任何,16,位数据:,一个段地址,一个偏移地址,两个字符,0,65535,之间的无符号数,32768,32767,之间的带符号数,datasegment,;数据段,countdw 8000h,?,AB,maxintequ 64h,numberdw maxint,arraydw maxint dup(0),dataends,字单元定义实例,39,3),定义双字单元伪指令,DD,DD,伪指令,用于分配一个或多个双字单元,并可以将它们初始化为指定值,初值表中每个数据是一个,32,位的双字量(,Double Word,):,可以是有符号或无符号的,32,位整数,也可以用来表达,16,位段地址(高位字)和,16,位的偏移地址(低位字)的远指针,varddDD 0,?,12345678h,farpointDD 00400078h,40,例1:,DATA_B,DB,10,5,10H,DATA_W,DW,100H,-4,DATA_D,DD,0FFFBH,汇编后的内存分配情况,如右图所示。,05H,10H,00H,01H,FCH,FFH,FBH,FFH,00H,00H,0AH,Q,DATA_B,DATA_W,DATA_D,10,5,10H,100H,-,4,0FFFBH,41,例2:,操作数可以是字符串,例如,STR,DB,HELLO,汇编后的情况如图:,STR,H,E,L,L,O,注意,:,下面两个定义的不同之处:,DB,AB,;41H,在低字节,,42H,在高字节,(,先,A,后,B,),DW,AB,;42H,在低字节,,41H,在高字节,(,先,B,后,A,),48H,45H,4CH,4CH,4FH,注意,:,3,个及其以上的字符,只能用,DB,定义,42,操作数,?,用来保留存储空间,但不存入数据.,例3:,ABC DB 0,1,2,3,4,OK,$,RSV DW,?,?,?,?,?,?,?,?,复制操作符,DUP,:,重复的数据可以使用复制操作符,DUP,如上面,RSV,亦可写成:,RSV,DW,8,DUP,(,?,),43,4.2.2,符号定义,伪指令,把一个表达式用一个符号表示,以后凡出现该表达式的地方都可用这个符号表示。,符号定义伪指令有,两种,:,EQU,,,=,用,EQU,定义的符号未清除前,不能重新定义。,用,”,=,”,定义的符号可在任何时候进行重定义。,二者,均不占用存储空间,仅是给符号赋值,44,1,、,EQU,CR,EQU,0DH,;常数,A,EQU,ASC-TABLE,;变量(事先已定义),STR,EQU,64 1024,;数值表达式,ADR,EQU,ES,:,BP+DI+5,;地址表达式,EQU,不允许对一个符号重复定义。,2,、,等号语句,=,同,EQU,,但可重新定义一个符号。,COUNT,=,100,同,COUNT EQU 100,CONNT,=,57 COUNT,重新定义,45,例:,FIVE,EQU,5,COUNT,=,10,DIST,=,BYTE PTRSI+BP,GOTO,=,JMP,MOV AX,TEN,MOV CX,COUNT,ADD,DIST,FIVE,DIST,=,WORD PTRSI+BP+1,ADD,DIST,AX,GOTO,LABEL,定义,引用,46,4.2.3,段定义,伪指令,汇编语言程序是按段来组织程序和数据的。,和存储器的物理段相对应,汇编语言程序中的段称为逻辑段。汇编连接后被映射到物理段中。,3/4,类段:代码,(,程序,),、数据,/,附加数据、堆栈,段定义伪指令:,SEGMENT、ENDS,定义一个,段的基本格式:,段名,SEGMENT,定位类型,组合方式,类别,段名,ENDS,47,这两个伪指令总是成对出现,二者前面的段名应一致,但不能与保留字重名,.,SEGMENT,说明了一个段的开始,,ENDS,说明了一个段的结束。,对数据段和堆栈段,段中的语句一般是,变量定义,。,对代码段则是,指令语句,。,如:,data,SEGMENT,data,ENDS,SEGMENT,和,ENDS,伪指令,48,SEGMENT,语句后可以,带有可选参数,,,用以,规定逻辑段的其他一些,属性,。它的格式为:,1,.,定位类型,说明,如何确定逻辑段的边界,。有,4,种:,PARA,(Paragraph):,逻辑段从一个,节,(,16个字节,),的边界开始,。,即,段的起始地址应能被16整除,或这说段,起始物理地址应为,0,H。,默认类型,BYTE:,逻辑段,从,字节,边界,开始,即段可以从任何地址开始。,WORD:,逻辑段从,字,边界开始,。即段的起始地址必须是偶数。,PAGE:,逻辑段,从,页,边界,开始。,256字节称为一页,,故段的起始物理地址应为00,H。,也即:,PAGE,(,页边界,)-,能被,256,除;,PARA,(,段边界,)-,能被,16,除,;,WORD,(,字边界,)-(,能被,2,除,),;,BYTE,(,字节边界,),段名,SEGMENT,定位类型,组合类型,类别,49,2.,组合类型,功能,:,用在具有多个模块的程序中,用于说明,不同模块中,同名段,的组合方式,,共,6,种,:,NONE,:,本段与其它逻辑段不组合,。,PUBLIC,:,所有此类型的,同名段,组合成一个逻辑段,公用一个段地址,运行时装入同一个物理段中,构成一个大的逻辑段。,STACK,:,专用于说明堆栈段,组合方式同,PUBLIC,COMMON,:,所有此类型的同名段具有相同的起始地址,(,覆盖,),,各个逻辑段重叠在一起,共享相同的存储区域。,MEMORY,:,本逻辑段,置于地址最高处,多个时取第一个,其余作为,COMMON,AT,:,使段地址是表达式所计算出来的,16,位值,,CS,除外。,50,【,例,】,有两个模块,各模块段定义如下,模块,1,:,DATA1SEGMENT,PARA PUBLIC,DATA1,M1DB 45H DUP,(,0,),DATA1ENDS,DATA2SEGMENT PARA COMMON,DATA2,N1 DB 102H DUP,(,0,),DATA2ENDS,END,模块,2,:,DATA1SEGMENT PARA PUBLIC,DATA1,M2DB 104H DUP,(,11H,),DATA1ENDS,DATA2SEGMENT PARA COMMON,DATA2,N2DB 105H DUP,(,0,),DATA2ENDS,DATA3SEGMENT,T1DB 50 DUP,(,20H,),DATA3ENDS,END,51,该段的定位组合方式示意图如图所示。,52,3.,类别,用,单引号,括起来的字符串,。如代码段,CODE,”,所有,同类别的段,被安排在,连续,的存储区域中,。类别名相同的逻辑段按出现的先后顺序排列,.,如:在模块,1,中有段定义:,seg1,SEGMENT PARA STACK,stack,seg1 ENDS,在模块,2,中有段定义:,seg2,SEGMENT PARA STACK,stack,seg2 ENDS,则连接时这两个段被安排在一起。,53,4.2.4,设定段寄存器,伪指令,ASSUME,伪指令用于,指明,已定义的,段与段寄存器之间关系,。,格式为,:,ASSUME,段寄存器:段名,,段寄存器:段名,.,其中段寄存器名必须是,CS,DS,ES,和,SS,中的一个。段名必须是由,SEGMENT,定义的段中的段名。,也就是说,ASSUME,指令是告诉汇编程序用,SEGMENT,指令定义过的,段,的,段,地址将放在哪个,段,寄存器中,.,例,:DATA1SEGMENT,ADB 1,,,2,,,3,DATA1ENDS,CODE SEGMENT,ASSUME DS,:,DATA1,,,CS,:,CODE,.,CODE ENDS,54,注意,:,ASSUME,伪指令,只是告知,汇编程序有关,段寄存器与段的关系,并,没有,给段寄存器,赋予实际的初值,。故下面的语句,MOVAX,data,MOV,DS,AX,MOV,ES,AX,MOVAX,stack,MOV,SS,AX,将段基址装入段寄存器,。如果程序中用到堆栈段,则,SS,也需装入实际的初值。,代码段基地址,不需要程序员装入,CS,寄存器,而由,操作系统,(,OS),负责装入。,55,段定义伪操作:,完整的段定义格式举例,data,segment,;,定义数据段,data,ends,;-,extra,segment,;,定义附加段,extra,ends,;-,code,segment,;,定义代码段,assume,cs:code,ds:data,es:extra,start:,mov ax,data,mov ds,ax ;,段地址,段寄存器,code,ends,end start,注,:,汇编时,系统自动将代码段的段地址装入,CS,不用在程序中初始化,其它的段则要用指令把其初始化,.,56,结论:,1.,ASSUME,语句只起指示作用,没有赋值作用,2.,程序中用到内存操作数时,,应按操作数的寻址方式,给相应的段寄存器赋值,。,57,4.2.,5,过程定义,伪指令,PROC,、,ENDP,过程就是子程序,。一个过程可以被其它程序所调用,(,用,CALL,指令,),,过程的最后一条指令一般是返回指令,(RET),。,过程定义伪指令的格式为,PROC,NEAR/FAR,类型,RET,ENDP,注意:,PROC,和,ENDP,必须成对出现且同一过程的名字必须相同。,若为近调用,则类型可省,58,过程的类型,有两种:,NEAR,表示段内调用,(,默认类型,),FAR,表示段间调用,调用一个过程的格式为:,CALL,程序经汇编、连接及装入内存后,过程名为一具体的,内存地址,,指示子程序入口。,过程名常用作,CALL,调用指令的操作数,子程的最后安排,RET,返回指令,使执行完子程后能返回调用处。,59,例,1,display PROC,RET,;NEAR,属性的过程对应段内返回,display ENDP,例,2,display PROC,FAR,RET,;,FAR,属性的过程对应段间返回,display ENDP,60,4.2.,6,宏定义,伪指令,宏指令:,是源程序中具有独立功能的一段程序代码,程序员事先根据需要自定义的“指令“。此后在宏指令出现的地方,汇编程序自动把它们替换成相应的语句序列。宏指令的使用过程为宏定义、宏调用。,1,、宏定义,格式:,宏指令名,MACRO,形参,,形参,ENDM,61,说明:,宏指令名是为该宏定义所起的名字,可以象指令助记符一样出现在源程序中;,形参间用逗号隔开,在宏指令调用时,形参被实参依次取代,形参为可选项;,MACRO,表示宏定义开始,,ENDM,表示宏定义结束,二者之间的程序段称为宏体。,62,2,、宏调用,格式:,宏指令名,实参,,实参,功能,:,宏指令名的调用就是宏调用,它要求 汇编程序把定义的宏体目标代码拷贝到调用点;调用时实参依次替代形参,实参数目与形参数目可以不相同,当实参数多于形参数时,忽略多余实参,当实参数少于形参数时,剩余的形参处理为空白。,63,例,:,两个数之和的宏定义和宏调用。,宏定义为:,DADD,MACRO,X,Y,Z,MOV AX,X,ADD AX,Y,MOV Z,AX,ENDM,上面宏定义中,X、Y、Z,是,形式参数,。,调用宏,DADD,时可写,为:,DADD,DATA1,DATA2,SUM,上面宏调用中,,DATA1,DATA2,SUM,是,实际参数,,,由,它们替换定义中的,X、Y、Z,,即,形实结合,。,64,CALL,DADD,RET,DADD:,CALL,DADD,CALL,DADD,DADD yy,DADD MACRO xx,DADD yy,DADD yy,ENDM,相同,=,或,主程序,+,过程,(,子程序,),主程序,+,宏定义,宏扩展,宏调用,与,过程,(,子程序,)调用,异同点示意图,65,宏调用,与,过程,(,子程序,)调用,异同点,相同点,:,都是一次定义,多次调用,。,不同点,:,执行形式,:,宏命令伪指令由宏汇编程序,在汇编过,程,中进行处理,;,而,CALL,、,RET,则是,由,CPU,执行,的,指令,。,汇编结果,:,宏命令伪指令,汇编后被展开。,执行速度,:,宏命令,执行速度较快,(,因无调用转移,),占用内存,:,宏指令简化了源程序,但不能简化目标程序,,,并不节省内存单元,;,使用过程可以节省代码(源程序和目标程序)占用的内存空间。,66,3.,宏展开,:,汇编程序会把宏调用按宏定义展开。,例如:,宏定义为:,DISPLAY,MACRO string,LEA DX,,,string,MOV AH,,,9,INT 21H,ENDM,程序中宏调用:,DISPLAY,ERROR_MESSAGE,DISPLAY,EXIT_MESSAGE,汇编后的结果:,(,带有,+,号的指令为宏展开后的结果,),+LEA DX,,,ERROR_MESSAGE,+MOV AH,,,9,+INT 21H,+LEA DX,,,EXIT_MESSAGE,+MOVAH,,,9,+INT 21H,67,4.2.,7,汇编结束,伪指令,END,汇编语言源程序的最后,,,要加,汇编结束伪指令,END,,,以使汇编程序结束汇编。,格式:,END,表达式,END,后跟的,表达式,通常就是程序第一条指令的标号,,指示,程序的启动地址,(,要执行的第一条指令的地址,),。,汇编程序对,END,之后的语句不进行处理。程序中所有有效语句应放在,END,语句之前。,源程序中必须有,END,结束语句。汇编程序对无,END,语句的源程序不进行处理,只给出无,END,语句错误信息。,68,(,1,),NAME,伪指令,格式:,NAME,模块名,在源程序开始可用,NAME,模块命名,模块名的作用是指示给,连接程序进行连接用,。,源程序中可无模块定义,此时源文件名作为模块名。,4.2.8,模块定义和连接伪指令,69,(,2,)模块间通信伪指令,在编写规模较大的汇编语言源程序时,可以将整个程序划分为几个独立的源程序,称之为模块。,将各模块分别进行汇编,生成各自的目标程序,最后将它们连接成为一个完整的可执行程序。,各模块之间可以相互进行符号访问。,为了进行模块之间连接和实现相互的符号访问,以便进行变量传送,通常使用以下几个伪指令:,PUBLIC,、,EXTRN,。,70,STACK-SEGSEGMENT,STACK-SEGENDS,DATA-SEGSEGMENT,DATA-SEG ENDS,EXTRA-SEG SEGMENT,EXTRA-SEG ENDS,CODE-SEG SEGMENT,START:,CODE-SEG ENDS,END START,源程序的典型,框架结构,为,:,定义堆栈段,定义数据段,定义附加数据段,定义代码段(即指令),源程序模块结束,
展开阅读全文