资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,2020年1月25日星期六,汇编语言程序设计及上机指导,第,5,章,返回,#,第,5,章 汇编语言语法,【,本章提要,】,本章以,Intel,系列微处理器的指令系统和宏汇编工具,MASM6.X,为主体,介绍汇编语言的基本语法和伪指令,实现简单的汇编语言程序设计。,【,学习目标,】,熟练掌握进行汇编语言程序设计的基本语法,熟练掌握伪指令以及宏结构的应用,熟练掌握利用,MASM6.X,工具对程序进行汇编的具体方法,04 二月 2025,指令,:,是可执行的,汇编后由相应的机器代码所取代,;,伪指令,:,是不可执行的,只是在源程序汇编期间由汇编程序处理的命令,指示汇编程序为数据分配内存空间,或者提供段定义等信息,不产生任何机器代码,源程序,可执行文件,目标模块,文本编辑器,汇编程序,连接程序,调试程序,机器语言,:,计算机能够直接识别与执行,高级语言,:是完全独立于机器的通用语言,效率低,面向,过程、面向对象,必须译成机器语言。,汇编语言,:符号化语言。用指令的助记符、符号地址、标,号等编写程序的语言。,5.1,概述,04 二月 2025,5.1.1,汇编语言程序的基本概念,指令与伪指令的集合构成汇编语言语句,.MODEL SMALL ;,定义内存工作模式为小模式,.386 ;,定义指令系统为,80386,指令集,.STACK ;,定义,1K,个字节的堆栈段,.DATA ;,数据段开始,DATA1 DD 12340000H ;,定义第一个,32,位数据的值为,12340000H,DATA2 DD 5678H ;,定义第二个,32,位数据的值为,5678H,SUM DD,?,;,定义用来存放前两个数据之和的第三个数据,.CODE ;,代码段开始,数据段结束,.STARTUP ;,程序开始,MOV EAX,DATA1 ;,取第一个数到,EAX,ADD EAX,DATA2 ;,求和,MOV SUM,EAX ;,保存结果,(12345678H),至,SUM,.EXIT 0 ;,程序结束,正常返回到操作系统,END ;,结束汇编,04 二月 2025,5.1.2,汇编语言的基本语法,一、字符集,英文字符:,A,Z,z,数字字符:,0,9,算术运算符:,/,关系运算符:,分隔符:,(,逗号,);(,分号,)()(,括号,)(,引号,),(空格,)TAB(,制表符,),控制符:,CR,(回车),LF,(换行),FF,(换页),其它字符:,$&_,(下划线),?%,!,二、标识符,1,)标识符的第一个字符必须是字母、问号“,?”,、“,”,符、或下划线“,_”;,2,)从第二个字符开始可以是字母、数字、或“,?”,、“,”,、“,_”,;,3,)一个标识符的长短可以由,1,31,个字符组成。,例如:,X,GAM_31,,,?JACK5,是正确的;而,8P,DATA 8,是不正确的。,04 二月 2025,三、保留字,寄存器名、指令助记符、伪操作命令、表达式运算符,以及属性操作符等都是系统专用的保留字。这些保留字是不能用作标识符的。,四、语句,一条语句一般只占一行,超过一行时必须用续行符号“,”,指示,两条语句不能写在同一行。,语句可以有注释,一般写在语句之后或单独占一行,是以“;”开始的字符串。,04 二月 2025,5.2,汇编语言的数据和表达式,汇编语言能识别的数据是常量、变量和标号。,5.2.1,常量,常量是汇编时已经确定的值,主要用于伪指令中给变量赋值,或作为指令语句中的立即数或存储器操作数的组成部分。,一常量的类型,数据形式,格 式,取值范围,举例,注 释,二进制数,B,0,1,10010011B,二进制数以,B,结尾,八进制数,Q,0,7,123Q,八进制数以,Q,结尾,十进制数,D,0,9,256D,,,3458,十进制数以,D,结尾或者缺省,十六进制数,H,0,9,A,F,0A3H,,,12345H,十六进制数以,H,结尾,,最前面必须是,0,9,字符或字符串,ASCII,字符,ABC,两端必须加,或,”,04 二月 2025,二符号定义伪指令,用于给程序中多次出现的同一个常量或表达式赋一个符号名,也可以为其它符号名取一个新名字,并赋给新的类型属性。,(,1,),EQU,伪指令,例:,FIRST EQU 1,;定义常数,SECOND EQU FIRST*3+8,;定义数值表达式,ADDR1 EQU DS:,EBP+4,;定义地址表达式,DWORDS EQU THIS DWORD,;定义下面的字节变量为双字类型,BYTES DB 10 DUP(0),ADDR2 EQU WORD PTR BYTES,;重新定义变量,BYTES,的名字和属性,START:MOV EAX,,,EBX,GOON EQU FAR PTR START,;重新定义标号,START,的名字和属性,COUNT EQU ECX,;为,ECX,重新取名,注意:,该等值语句只作为符号定义用,不产生任何目标代码,也不占用存储单元,并且不能是程序中曾经定义过的符号名。,04 二月 2025,(,2,)“”伪指令,“”伪操作命令与,EQU,具有相同的功能,但它定义的符号,允许重新定义,。,例:,PERSON=10,;定义,PERSON,等于,10,PERSON=PERSON+5,;重新定义,PERSON,等于,15,04 二月 2025,5.2.2,变量,变量的值可以在程序运行过程中可随时修改,变量名是存放数据的存储单元符号地址,变量的值为对应存储单元的内容。,一变量的属性,段属性,(SEG),,指变量所在段的段基址。,偏移地址属性,(OFFSET),,指变量所在段中的偏移地址,即变量所在地址与段基址之间的字节距离。,类型属性,(TYPE),,指变量占用存储单元的字节数。,若占用,一,个字节,称为字节变量,其类型为,BYTE,;,若占用,两,个字节,称为字变量,其类型为,WORD,;,若占用,四,个字节,称为双字变量,其类型为,DWORD,;,若占用,六,字节,其类型为,FWORD,;,若占用,八,字节,其类型为,QWORD,;,若占用,十,字节,其类型为,TBYTE,。,04 二月 2025,二变量定义伪指令,就是为数据分配存储单元,且对这个存储单元取一个名字,即变量名。语句的格式如下:,变量名,DB/DW/DD/DF/DQ/DT,表达式,1,,表达式,2,,,变量名是可选的,,DB/DW/DD/DF/DQ/DT,是伪操作命令必须选用一种,表达式是赋给变量的初值,常见的有如下几种:,(,1,)数值变量定义语句,例:,D_BYTE,DB,30H,40H,DB 50H,D_WORD,DW,1234H,5678H,D_DWORD,DD,D_DWORD,D_TBYTE,DT,?,D_FWORD,DF,1234567890ABH,D_QWORD,DQ,1122334455667788H,04 二月 2025,(,2,)字符串变量定义语句,可以用,DB,来实现,,即为串中的每一个字符分配一个字节存储单元。字符串必须用引号括起来,并且,不超过,256,个字符,它们在内存中自左至右把字符的,ASCII,码按地址递增顺序依次存放。,例:,STRING1 DB ABCDEFG,用,DW,也可以定义,字符串变量,即给两个字符组成的字符串分配两个字节存储单元,它们在内存中的顺序是前一个字符为高字节,存放在高地址,后一个字符为低字节,存放在低地址。,例:,STRING2 DW AB,CD,EF,04 二月 2025,(,3,)?语句,存储单元中不预置确定的值,常用来预留存储单元,存放程序的中间结果或最终结果。,例:,FIRST DB?,;分配一个字节单元,SECOND DD?,?,?,;分配三个双字单元,(,4,)带,DUP,的变量定义语句,DUP,是重复数据定义操作符,可以为若干重复数据分配存储单元,并赋给相应的变量名。,例:,D1 DB 5 DUP(0),D2 DW 10H DUP(5678H),D3 DD 20H DUP(?),第一条语句为变量,D1,分配,5,个字节单元,每个单元初始值都为,0;,第二条语句为变量,D2,重复分配,10H,个字单元,每个单元初始值都为,5678H,,共占有,20H,个字节;,第三条语句为变量,D3,保留,20H,个双字单元,没有定义初始值。,D4 DB 200 DUP(4 DUP(6),8),表示为变量,D4,重复分配,200,个数据序列,6,,,6,,,6,,,6,,,8,,共占有,1000,个字节单元。,04 二月 2025,三内存定位和定义数制伪指令,(,1,),ORG,伪指令和当前位置计数器,汇编时将段名填入段表,同时为该段配备一个初值为,0,的位置计数器,$,。计数器依次累计段内语句被汇编后生成的目标代码字节个数。可用,ORG,伪指令把位置计数器,的值设置成需要的值。,在数据段中,,ORG,后面的数据定义伪指令就从指定位置进行分配单元;,在代码段中,,ORG,后面的一条指令语句就从指定位置生成目标代码;,表达式的值应该是非负的整数。,例:,ORG 0F0H,;从,0F0H,开始安排数据,ORG$+10H,;跳过,10H,个字节后安排数据,DW 1,$+4,$+4,;,100H,单元的字值为,1,102H,单元的字值,;为,106H,104H,单元的字值为,108H,ARRAY DB 12,34,56,5 DUP(?),;定义字节数组,LEN EQU,$-ARRAY,;,LEN,的值为,ARRAY,变量所占的字节数,8,04 二月 2025,(,2,),EVEN,伪指令,用来把段内位置计数器的值置为偶数地址边界对齐,如果遇到,EVEN,时计数器,$,值非偶数,则汇编程序自动插入,NOP,指令,(,在代码段中,),,使其为偶数;或者将,$,的值加,1(,数据段中,),。,(,3,),.RADIX,伪指令,宏汇编默认常量基数都是十进制数,可用,.RADIX,伪命令把缺省基数改为,216,范围内的任意基数:,.RADIX,其中,表达式与当前基数无关,,一定是十进制数,。,例:,MOV AX,0FFH,MOV BX,,,20,.RADIX 16,MOV CX,0FF,MOV DX,20D,其中,AX,和,CX,寄存器的内容相同,,BX,和,DX,寄存器内容相同。,04 二月 2025,5.2.3,标号,标号之后必须有一个冒号,(:),,标号也可以单占一行。,一标号的属性,段属性,(SEG),,指标号所在段的段基址。,偏移地址属性,(OFFSET),,指标号所在段中的偏移地址,即标号所在地址与段基址之间的字节距离。,距离属性或类型属性,(TYPE),,标号可作为转移和调用指令的目标地址,也可作为过程定义伪指令的过程名。,当标号只允许作为段内转移或调用指令的目标地址时,距离属性为,NEAR,;,当标号作为段间转移或调用指令的目标地址时,距离属性为,FAR,。,例如:,JMP LABEL1,;程序跳转到标号,LABEL1,的位置,CALL FAR PTR SUBPROGRAM,;调用,SUBPROGRAM,过程(,FAR,),LABEL1:,;,LABEL1,为段内转移标号,(,距离属性缺省为,NEAR),LABEL2:,;,LABEL2,为段内转移标号,单独占一行,SUBPROGRAM PROC FAR,;,SUBPROGRAM,是属性为,FAR,的过程,RET,标号的距离属性可用,LABEL,伪指令加以改变。,04 二月 2025,二,LABEL,伪指令,(,1,)与变量连用,用来给相连的变量取一个新的名字,并指定新的类型属性。,例:,B_VAR1,LABEL BYTE,W_VAR1 DW 3456H,W_VAR2,LABEL WORD,D_VAR2 DD 87654321H,给字变量,W_VAR1,一个新名字,B_VAR1,,类型属性,BYTE,。如果以字类型访问该变量,应使用变量名,W_VAR1,;而以字节类型访问该变量时,应使用,B_VAR1,。如果想按字访问,D_VAR2,变量,则可以用,W_VAR2,。,注意:,B_VAR1,和,W_VAR2,都是给变量增加类型属性,并不另外占用存储单元,(,2,)与标号连用,用来给相连的指令地址,(,即标号,),定义一个新的标号,并指定新的距离属性。,例:,DISTFAR,LABEL FAR,DISTNEAR:MOV EAX,EBX,给近标号,DISTNEAR,取一个新的标号名,DISTFAR,,距离属性修改为,FAR,。当其它代码段中的转移或调用指令引用时,可使用标号,DISTFAR,,而在本段引用时,只要使用标号,DISTNEAR,即可,但它们实际上是指向同一条指令。用,LABEL,伪指令的定义,实现了按不同的标号名和不同的转移方式而转移到同一个标号的目的。,04 二月 2025,5.2.4,表达式和运算符,一、算术运算符,包括,+,、,-,、*、,/,、,MOD,、,SHL,和,SHR,共七种;,+,、,-,、*、,/,参加运算的数和运算结果均为,整数,;,除法运算为整除,而模除的运算结果为,余数,;,左移或右移运算符可使二进制数左移或右移若干位,相当于二进制数进行乘法或除法运算。,例:,TEMP=10+5,;,TEMP=15,TEMP=TEMP-3,;,TEMP=12,TEMP=TEMP*5,;,TEMP=60,TEMP=TEMP/9,;,TEMP=6,TEMP=TEMP MOD 4,;,TEMP=2,TEMP=-TEMP,;,TEMP=-2,MOV AL,11B SHL 5,;,(AL)=01100000B,注意,:,除了加和减运算符可以使用变量或标号外,其它算术运算符只适用于,常量,的数值运算。,04 二月 2025,二、逻辑运算符,有,AND,、,OR,、,XOR,、,NOT,共四种;,只适用于,对常量,进行逻辑运算,运算是按位进行的;,运算符与逻辑运算指令助记符相同,但在语句中的位置不一样,表达式中的,逻辑运算符是在汇编时完成运算的,;而,逻辑运算指令运算在执行指令时进行,。,例:,MOV AL,NOT,10100101B,;,(AL)=01011010B,MOV AL,11011011B,AND,00001111B,;,(AL)=00001011B,MOV AL,11100001B,OR,10000101B,;,(AL)=11100101B,MOV AL,10111011B,XOR,00100100B,;,(AL)=10011111B,04 二月 2025,三、关系运算符,包括,EQ,、,NE,、,LT,、,GT,、,LE,、,GE,共六种;,可对,常量或同一段内的存储器地址,进行比较运算;,若条件满足,运算结果为真,输出结果为,全“,1”,;,若不满足条件,运算结果为假,输出结果为,全“,0”,。,例:,MOV BX,10,EQ,1010B,;,10,等于,1010B,为真,,(BX)=0FFFFH,MOV DX,20H,GT,32,;,20H,大于,32,为假,,(DX)=0,04 二月 2025,四、数值返回运算符,运算对象必须是存储器操作数,即,变量或标号,。,(,1,),SEG,运算符,:返回该变量或标号所在段的段基址。,例如:,MOV AX,SEG VAR,如果变量,VAR,所在段的段基址为,1000H,,则该指令执行的结果,等效于,MOV AX,1000H,(,2,),OFFSET,运算符,:返回该变量或标号所在段内的偏移地址。,例如:,MOV DI,OFFSET VAR,如果变量,VAR,在,1000H,段内的偏移地址是,100H,,则该指令执行,的结果等效于:,MOV DI,100H,(,3,),TYPE,运算符,:返回该变量的类型属性或者标号的距离属性。,例:,V1 DB 1,2,3,V2 DW 1020H,3040H,V3 DD 12345678H,PF LABEL FAR,PN:MOV AH,TYPE,V1,;等效于,MOV AH,1,MOV AL,TYPE V2,;等效于,MOV AL,2,MOV DL,TYPE V3,;等效于,MOV BL,4,MOV DH,TYPE PF,;等效于,MOV BH,-2,04 二月 2025,属性与返回数值的关系,变量,/,标号属性,返回数值,字节变量,BYTE,字变量,WORD,双字变量,DWORD,三字变量,FWORD,四字变量,QWORD,十字节变量,TBYTE,1,2,4,6,8,10,标号,NEAR,标号,FAR,1FFH,2FEH,04 二月 2025,4,LENGTHOF,运算符,该运算符加在变量名之前,返回的数值是变量中所定义的元素个数。,D1 DW 10H DUP,(,0,),,1234H,D2 DB 20H DUP,(,2 DUP,(,0,),,1,),D3 DQ 1234H,5678H,D4 DB ABCDEFGH,D5 DD 12H,,,34H,,,;加一个续行符,表示一条伪指令占两行,56H,,,78H,D6 DD 12H,,,34H,;未加续行符,则表示这两行是两条伪指令,DD 56H,,,78H,MOV AL,,,LENGTHOF,D1,;(,AL,),=11H,MOV AL,,,LENGTHOF D2,;(,AL,),=60H,MOV AL,,,LENGTHOF D3,;(,AL,),=2H,MOV AL,,,LENGTHOF D4,;(,AL,),=8H,MOV AL,,,LENGTHOF D5,;(,AL,),=4H,MOV AL,,,LENGTHOF D6,;(,AL,),=2H,04 二月 2025,5,SIZEOF,运算符,该运算符加在变量名之前,返回的数值是变量所占的总字节数,且等于,LENGTHOF,和,TYPE,两个运算符返回值的乘积,。例如,对于上例中的变量,,SIZEOF,的返回值如下所示:,MOV AL,,,SIZEOF,D1,;(,AL,),=22H,,即,20H*2H,MOV AL,,,SIZEOF D2,;(,AL,),=60H,,即,60H*1H,MOV AL,,,SIZEOF D3,;(,AL,),=10H,,即,8H*2H,MOV AL,,,SIZEOF D4,;(,AL,),=8H,,即,8H*1H,MOV AL,,,SIZEOF D5,;(,AL,),=10H,,即,4H*4H,MOV AL,,,SIZEOF D6,;(,AL,),=8H,,即,2H*4H,04 二月 2025,LENGTH,运算符,返回变量中所定义的元素个数,如果变量是用重复数据操作符,DUP,说明的,则返回,DUP,前面的数值;如果没有,DUP,说明,则返回的值总是,1,。,例:,D1 DW 10H DUP(0),D2 DB 20H DUP(0),D3 DW 1234H,5678H,D4 DB ABCDEFGH,MOV AL,LENGTH D1,;,(AL)=10H,MOV AL,LENGTH D2,;,(AL)=20H,MOV AL,LENGTH D3,;,(AL)=1H,MOV AL,LENGTH D4,;,(AL)=1H,SIZE,运算符,返回变量所占的总字节数,且等于,LENGTH,和,TYPE,两个运算符返回值的乘积。例如,对于上例中的变量,D1,、,D2,、,D3,、,D4,,,SIZE,的返回值如下所示:,MOV AL,SIZE D1,;,(AL)=20H,MOV AL,SIZE D2,;,(AL)=20H,MOV AL,SIZE D3,;,(AL)=2H,MOV AL,SIZE D4,;,(AL)=1H,04 二月 2025,五、修改属性运算符,(,1,),PTR,运算符,格式:,PTR,根据地址表达式的不同,所赋给的新类型可以是,BYTE,、,WORD,、,DWORD,、,FWORD,、,QWORD,、,TBTYE,、,NEAR,、,FAR,等,它们,只在所在的指令内有效,。,例:,TABLE DB 1,2,3,4,5,6,7,8,ADD,WORD PTR,DI,100,;指明目的操作数为字类型,JMP,DWORD PTR,BX,;指明为段间转移,MOV EAX,DWORD PTR,TABLE,;临时修改,TABLE,为双字类,;型,,(EAX)=04030201H,(,2,),THIS,运算符,把它后面指定的类型或距离属性赋给当前的变量、标号或地址表达式,但不分配新的存储单元,往往与伪指令,EQU,或连用,为当前存储单元定义一个指定类型的变量或标号,类型属性也可以是,BYTE,、,WORD,、,DWORD,、,FWORD,、,QWORD,、,TBTYE,、,NEAR,、,FAR,等。,例:,DAT EQU,THIS WORD,POINT EQU,THIS FAR,第一条语句将变量,DAT,的类型属性定义为字,不管,DAT,原来的类型是什么,从本语句开始,,DAT,成为字节变量;第二条语句将标号,POINT,的距离属性定义为,FAR,,不管,POINT,原来的距离属性是什么,从本语句开始,,POINT,成为远标号。,04 二月 2025,六、其它运算符,(,1,)高低分离运算符,HIGH,运算符和,LOW,运算符分别用于从,16,位运算对象中分离出高字节和低字节。从,MASM6.0,开始引入了,HIGHWORD,运算符和,LOWWORD,运算符分别用于从,32,位符号常量中分离出高字和低字部分。,例:,MOV AH,HIGH,5678H,;,(AL)=56H,DATA16 EQU 1234H,MOV AL,LOW,DATA16,;,(AL)=34H,DATA32 EQU 1234FFFFH,MOV AX,,,LOWWROD,DATA32,;,(AX)=0FFFFH,(,2,)方括号运算符:,运算符中可以是数组变量的下标或地址表达式,以区别操作数和操作数地址。,例:,ARRAY DB 1,2,3,4,5,;,ARRAY,为数组变量,MOV AL,ARRAY4,;”,4”,为下标,,(AL)=5,MOV BX,OFFSET ARRAY,;,(BX)=ARRAY,的偏移地址,MOV AH,BX,;,(AH)=1,MOV DX,WORD PTR ARRAY1,;,(DX)=302H,(,3,)运算符的优先级:,一般可以用括号来改变运算符的优先级别。,例:,MOV AL,,,18 OR 5 AND 10,;,AL=18(12H),MOV AL,,,(18 OR 5)AND 10,;,AL=2,04 二月 2025,运算符的优先级,04 二月 2025,5.3,宏汇编语言的伪指令,符号定义、变量定义、程序分段定义、过程定义、模块定义、宏定义、条件汇编、以及格式和列表控制等。,5.3.1,段定义和程序说明伪指令,具体来说,规定,段的起始和结束,指定,属性,开始地址边界,段类型,同名段如何结合在一起,有两种段定义,简化,段,定义:,对,MASM5.0,以上,版本,完整,段,定义:对所有版本,04 二月 2025,一、完整分段定义伪指令,1.,段定义伪指令,SEGMENT/ENDS,将程序分成段:代码段,数据段,堆栈段,附加段。,格式:段名,SEGMENT,定位类型,组合属性,类别名,(段体),段名,ENDS,功能:,指出段名和段的各种属性,,并表示段的开始和结束位置。,段定义由伪操作,SEGMENT,开始、,ENDS,结束。,其中:,SEGMENT,和,ENDS,必须成对出现,,且语句前必须有段名,段名必须相同,。,SEGMENT,和,ENDS,语句之间可以有指令和其他伪指令,表示存放在该段内存的变量、指令或其他伪指令对该段内存的处理,程序中可以定义多个段。,程序经汇编、连接及装入内存后,段名为一具体的段值。,合法标识符,有段基地址和段内偏移量两个属性,与某个存储单元相联系。,04 二月 2025,(,1,)定位类型,用于告诉链接程序,链接时(各模块,.obj,),本,段首地址的边界定位方式,常有四种:,PARA,:,段的起始地址必须是,16,的倍数(,XXXX0H,),,这是一种默认方式。,PAGE,:段的起始地址必须是,256,的倍数(,XXX00H,),,256,字节为一页,在页的起点上。,WORD,:,段的起始地址必须是偶数(,XX,0B,)。,BYTE,:,段的起始地址可以是任何地址。,(,2,)组合类型,在多模块(每个模块有自己的代码段、数,据段、堆栈段)组合时,告诉,Link,程序本,段与其他模块中同名段的组合链接关系。,04 二月 2025,NONE,:,本段与其他同名段无组合关系,并有自己的段起始,地址,这是一种默认方式。,PUBLIC:,在满足定位类型的前提下,,LINK,程序将其与其他,模块中的同名段邻接在一起,共用一个段地址。,STACK,:同,PUBLIC,。链接以后作为堆栈段,并自动初始化,SS,、,SP,。若程序中不说明,STACK,,则必须由用户,在程序的开始处,自己通过语句设置,SS,、,SP,。,COMMON,:各模块中同名段重叠覆盖,有着相同的起始地,址。段的长度取决于最长的,COMMON,段。段的,内容为所链接的最后一个模块中,COMMON,段的,内容。,MEMERY,:链接在其他所有段的后面(高端存储区)。若有,多个,MEMERY,段,则只认第一个,其余按,COMMON,处理。,04 二月 2025,(,3,)段字属性,在,32,位,80X86,微处理器中,新增加了,USE,属性说明。对于,16,位,CPU,默认的是,16,位段,即,USE 16,。而对于汇编,32,位,80X86CPU,指令时,它默认采用,32,位段,即,USE 32,。但可以使用,USE 16,指定标准的,16,位段。若在程序开头使用了,.386,伪指令(见简化段定义伪指令),缺省类型为,32,位段字长。注意,在禁止用,80386,的情况下,使用,USE,选择项将导致出错。,(,4,)段类别名属性,类别名可以是任何合法的名字,必须用单引号括起来。在连接处理时,链接程序把类别名相同的所有段存放在连续的存储区内。典型的类别名如:,DATA,,,STACK,,,CODE,。,以上是定位类型、组合类型、段字和类别名四个参数的说明,各参数之间用空格分隔。在选用时,可以只选其中一个或两个参数项,但不能交换它们之间的顺序。,04 二月 2025,2.,段寄存器说明伪指令,格式:,ASSUME,段寄存器:段名,,段寄存器:段名,,设定特定的,Sreg,指向特点的段,说明源程序中定义的段应由,哪一个,Sreg,去寻址。,不如此,汇编程序无法生成目标代码程序,。,ASSUME,并未真正的将段地址装入相应的,Sreg,。,Sreg,的初值还必须由用户在程序的开始处用,MOV,指令来设置(,CS,除外)。,(,1,),DS,和,ES,的装入,DS,和,ES,的装入可以通过给寄存器赋初值的指令来完成。但是应注意到,由于段寄存器不能用立即数寻址方式直接传送,因此,装入段基址必须借助于通用寄存器进行间接传送,。,例:,CODES SEGMENT,ASSUME CS:CODES,DS:DATAS,SS:STACKS,ES:EXTRS,START:MOV AX,DATAS,MOV DS,AX,MOV AX,EXTRS,MOV ES,AX,CSEG ENDS,04 二月 2025,(,2,),SS,的装入,一种方法,是在,SEGMENT,语句中,组合类型选用,STACK,,并在,ASSUME,语句中,把堆栈用的段指派给段寄存器,SS,。,STACKS SEGMENT PARA STACK,DB 100H DUP(?),STACKS ENDS,CODES SEGMENT,ASSUME CS:CODES,SS:STACKS,另一种方法,是在,SEGMENT,语句中,组合类型未选用,STACK,参数,或者在程序中使用另一个堆栈段时,可采用类似于,DS,和,ES,的装入方法,用传送指令实现对,SS,的装入操作。,(,3,),CS,和,IP,的装入,CS,和,IP,的装入通常是按照结束伪指令指定的地址来自动完成的。结束伪指令的格式是:,END,起始地址是一个标号或地址表达式,这个地址是程序装入内存后的起始点,它的段基址和偏移量就是,CS,和,IP,的内容。,04 二月 2025,3.,组定义伪指令,GROUP,格式:组名,GROUP,段名,,段名,将程序中若干不同名的段集合成一个组,并赋予一个组名,使它们都装在一个,64KB,的物理段中,这时组内不同类型的段运行时共用一个,Sreg,,组内各段间的跳转都可以看作段内跳转。,例:,STACKSEG SEGMENT STACK,;定义堆栈段,DB 256 DUP(?),STACKSEG ENDS,DATA1 SEGMENT WORD PUBLIC CONST,CONS1 DW 100,;定义数据段,1,DATA1 ENDS,DATA2 SEGMENT WORD PUBLIC VARS,VAR1 DW?,;定义数据段,2,DATA2 ENDS,04 二月 2025,DATAGROUP GROUP DATA1,DATA2,;组合两个数据段,以,DATAGROUP,为段组名,CODESEG SEGMENT PARA PUBLIC CODE,;定义代码段,ASSUME CS:CODESEG,DS:DATAGROUP,SS:STACKSEG,START,:MOV AX,DATAGROUP,MOV DS,AX,;,DS,赋初值对该组寻址,MOV AX,CONS1,;,AX=100,MOV VAR1,AX,;,VAR=100,MOV AX,OFFSET VAR1,;,AX=2,MOV AX,OFFSET DATA1,;,AX=2(,已分配,2,个字节内存单元,),MOV AX,OFFSET DATA2,;,AX=4(,已分配,4,个字节内存单元,),MOV AX,4C00H,INT 21H,;,DOS,功能调用,可正常返回到操作系统,CODESEG ENDS,END,START,;程序结束,04 二月 2025,二、简化分段定义伪指令,在,MASM 5.0,版本以上的宏汇编语言中段的定义可以非常简单。,.MODEL,;定义程序的存储模式,.STACK,;定义堆栈段,长度缺省为,1K,字节,.CODE,;定义代码段,.DATA,;定义数据段,.DATA?,;定义数据段,但初值不确定,.FARDARA,;定义远调用数据段,.FARDARA?,;定义远调用数据段,但初值不确定,.CONST,;定义只读常数数据段,.STARTUP,;程序起始点,并初始化,DS,、,SS,.EXIT 0,;程序结束点,返回到操作系统,04 二月 2025,例:,.MODEL SMALL,;定义小型内存模式,.386,;可以汇编,386,指令,.STACK 100,;定义堆栈段,长度为,100,字节,.DATA,;数据段开始,X DD 12345678H,Y DD 87654321H,Z DD,?,?,.CODE,;代码段开始,.STARTUP,;程序开始,MOV EAX,X,MUL Y,MOV Z,EAX,MOV Z+4,,,EDX,.EXIT 0,;程序结束,返回,,;相当于,MOV AX,4C00H,和,INT 21H,两条指令,END,;汇编结束,04 二月 2025,1,定义内存模式伪指令,.MODEL,存储模式,语言类型,操作系统类型,堆栈类型,(,1,)存储模式,:,TINY,:,微型模式,程序中的数据和代码放在同一,64K,段内,这也就是后缀为,.COM,的程序。这种模式是,MASM6,才引入的。,SMALL,:,小型模式,程序中的代码放在,64KB,的数据段内,数据放在,64KB,代码的段内,(,包括数据段、堆栈段和附加段公用一个段,),因而对代码和数据的访问可通过近程,(NEAR),调用来实现。一般程序默认的都是该模式。,MEDIUM,:,中型模式,程序中的数据放在,64KB,的数据段内,代码量大于,64KB,因而可安排在不同段内。这样,数据是近程的,而代码是远程的。,COMPACT,:,压缩模式,程序中的所有代码放在一个,64KB,的代码段内,而数据区可以大于,64KB,。这样,对代码的访问是近程的,而数据是远程的。,LARGE,:,大型模式,程序中的数据和代码均大于,64KB,但静态(常数)数据限制在,64KB,之内。对程序和数据的访问默认都是远程的。,HUGE,:,巨型模式,程序中的数据和代码均大于,64KB,静态数据也可以大于,64KB,。这样,对代码、数据和数组的访问都是远程的。,FLAT,:,平展模式,用于创建一个,32,位的程序,它只能运行在,32,位,80X86CPU,上。,DOS,下不能使用,FLAT,模式,而编写,32,位,Windows,程序时,必须采用,FLAT,模式。,04 二月 2025,(2),语言类型,:,由它来告诉汇编程序将使用什么样的标识符的命名风格、子程序的调用和返回约定等。可使汇编语言程序与其它语言程序达到共享的目的。有效的语言类型为:,C(C,语言,),、,SYSCALL(,系统调用,),、,STDCALL(,标准调用,),、,Basic(Basic,语言,),、,Fortran(Fortran,语言,),、,Pascal(Pascal,语言,),等。,(3),操作系统类型,:,OS_DOS,是当前唯一支持的选项值,也是该选项的缺省值。,(4),堆栈类型,:,堆栈类型的值主要影响伪指令,.STARTUP,所生成的指令序列。该选项有二个可选值:,NEARSTACK,和,FARSTACK,。其中:,NEARSTACK,是该选项的缺省堆栈类型。,NEARSTACK,堆栈段和数据段是同一段;,FARSTACK,堆栈段和数据段是不同的段,且堆栈不在段组,DGROUP,中。,例:,.MODEL SMALL,C,OS_DOS,FARSTACK,04 二月 2025,2,处理器选择伪指令,.,8086,和,.8087,可用来汇编,8086/8088,处理器和,8087,协处理器的指令,这是缺省模式。,.,286,、,.286C,、,.286P,、,.287,可用来汇编,286,系列微处理器的指令。,.,386,、,.386C,、,.386P,、,.387,可用来汇编,386,系列微处理器的指令。,.,NO87,取消使用协处理器指令。,.,486,、,.486C,、,.486P,可用来汇编,486,系列微处理器的指令。,.,586,、,.586C,、,.586P,可用来汇编,Pentium,系列微处理器的指令。,.,686,、,.686P,可用来汇编,Pentium Pro,系列微处理器的指令。,.MMX,可用来汇编,MMX,指令。,.MMX,和,.686,、,.686P,是,MASM6.12,引入的。,.,K3D,可用来汇编,AMD,处理器的,3D,指令,是,MASM6.13,引入的。,.XMM,可用来汇编,SSE,指令和,SSE2,指令,是,MASM6.15,引入的。,注意:,80386,以上处理器中,如果处理器选择伪指令放在,.MODEL,伪指令前面,那么段将定义成,32,位的段。如果希望处理器使用,16,位的段,则应在,.MODEL,伪指令后面使用处理器选择伪指令。,04 二月 2025,3,段名的缺省名,使用简化的段定义伪指令时,每个段都有一个缺省名。,在中内存模式和大内存模式时,,.CODE,伪指令表示的缺省段名为,name_TEXT,,即,name,是这个段名的可变部分,当程序模块有一个具体名字时,,name,就表示这个名字。,.DATA,、,.CONST,、,.DATA?,、,.STACK,定义的段内数据存放在一个叫,DGROUP,的段组中,各个段内的偏移地址均以这个起始地址为起
展开阅读全文