汇编语言程序设计及上机指导5汇编语言语法.ppt_第1页
汇编语言程序设计及上机指导5汇编语言语法.ppt_第2页
汇编语言程序设计及上机指导5汇编语言语法.ppt_第3页
汇编语言程序设计及上机指导5汇编语言语法.ppt_第4页
汇编语言程序设计及上机指导5汇编语言语法.ppt_第5页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第5章 汇编语言语法,【本章提要】 本章以Intel系列微处理器的指令系统和宏汇编工具MASM6. X为主体,介绍汇编语言的基本语法和伪指令,实现简单的汇编语言程序设计。 【学习目标】 熟练掌握进行汇编语言程序设计的基本语法 熟练掌握伪指令以及宏结构的应用 熟练掌握利用MASM6.X工具对程序进行汇编的具体方法,2019年7月13日星期六,指令:是可执行的,汇编后由相应的机器代码所取代; 伪指令:是不可执行的,只是在源程序汇编期间由汇编程序处理的命令,指示汇编程序为数据分配内存空间,或者提供段定义等信息,不产生任何机器代码,5.1 概述,2019年7月13日星期六,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 ;结束汇编,2019年7月13日星期六,5.1.2 汇编语言的基本语法,一、字符集 英文字符:AZ z 数字字符:09 算术运算符: / 关系运算符: 分隔符:,(逗号) ;(分号) ( )(括号) (引号)(空格) TAB(制表符) 控制符:CR(回车) LF(换行)FF(换页) 其它字符:$ 2)从第二个字符开始可以是字母、数字、或“?”、“”、“_”; 3)一个标识符的长短可以由131个字符组成。 例如:X,GAM_31,?JACK5是正确的;而8P,DATA 8是不正确的。,2019年7月13日星期六,三、保留字 寄存器名、指令助记符、伪操作命令、表达式运算符,以及属性操作符等都是系统专用的保留字。这些保留字是不能用作标识符的。 四、语句 一条语句一般只占一行,超过一行时必须用续行符号“”指示 两条语句不能写在同一行。 语句可以有注释,一般写在语句之后或单独占一行,是以“;”开始的字符串。,2019年7月13日星期六,5.2 汇编语言的数据和表达式,汇编语言能识别的数据是常量、变量和标号。 5.2.1 常量 常量是汇编时已经确定的值,主要用于伪指令中给变量赋值,或作为指令语句中的立即数或存储器操作数的组成部分。 一常量的类型,2019年7月13日星期六,二符号定义伪指令 用于给程序中多次出现的同一个常量或表达式赋一个符号名,也可以为其它符号名取一个新名字,并赋给新的类型属性。 (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重新取名 注意:该等值语句只作为符号定义用,不产生任何目标代码,也不占用存储单元,并且不能是程序中曾经定义过的符号名。,2019年7月13日星期六,(2) “”伪指令 “”伪操作命令与EQU具有相同的功能,但它定义的符号允许重新定义。 例:PERSON=10 ;定义PERSON等于10 PERSON=PERSON+5 ;重新定义PERSON等于15,2019年7月13日星期六,5.2.2 变量,变量的值可以在程序运行过程中可随时修改,变量名是存放数据的存储单元符号地址,变量的值为对应存储单元的内容。 一变量的属性 段属性(SEG),指变量所在段的段基址。 偏移地址属性(OFFSET),指变量所在段中的偏移地址,即变量所在地址与段基址之间的字节距离。 类型属性(TYPE),指变量占用存储单元的字节数。 若占用一个字节,称为字节变量,其类型为BYTE; 若占用两个字节,称为字变量,其类型为WORD; 若占用四个字节,称为双字变量,其类型为DWORD; 若占用六字节,其类型为FWORD; 若占用八字节,其类型为QWORD; 若占用十字节,其类型为TBYTE。,2019年7月13日星期六,二变量定义伪指令 就是为数据分配存储单元,且对这个存储单元取一个名字,即变量名。语句的格式如下: 变量名 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,2019年7月13日星期六,(2)字符串变量定义语句 可以用DB来实现,即为串中的每一个字符分配一个字节存储单元。字符串必须用引号括起来,并且不超过256个字符,它们在内存中自左至右把字符的ASCII码按地址递增顺序依次存放。 例: STRING1 DB ABCDEFG 用DW也可以定义字符串变量,即给两个字符组成的字符串分配两个字节存储单元,它们在内存中的顺序是前一个字符为高字节,存放在高地址,后一个字符为低字节,存放在低地址。 例: STRING2 DW AB,CD,EF,2019年7月13日星期六,(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个字节单元。,2019年7月13日星期六,三内存定位和定义数制伪指令,(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,2019年7月13日星期六,(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寄存器内容相同。,2019年7月13日星期六,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伪指令加以改变。,2019年7月13日星期六,二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伪指令的定义,实现了按不同的标号名和不同的转移方式而转移到同一个标号的目的。,2019年7月13日星期六,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 注意:除了加和减运算符可以使用变量或标号外,其它算术运算符只适用于常量的数值运算。,2019年7月13日星期六,二、逻辑运算符 有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,2019年7月13日星期六,三、关系运算符 包括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,2019年7月13日星期六,四、数值返回运算符 运算对象必须是存储器操作数,即变量或标号。 (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,2019年7月13日星期六,属性与返回数值的关系,2019年7月13日星期六,4LENGTHOF运算符,该运算符加在变量名之前,返回的数值是变量中所定义的元素个数。 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,2019年7月13日星期六,5SIZEOF运算符,该运算符加在变量名之前,返回的数值是变量所占的总字节数,且等于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,2019年7月13日星期六,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,2019年7月13日星期六,五、修改属性运算符 (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成为远标号。,2019年7月13日星期六,六、其它运算符 (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,2019年7月13日星期六,运算符的优先级,2019年7月13日星期六,5.3 宏汇编语言的伪指令,符号定义、变量定义、程序分段定义、过程定义、模块定义、宏定义、条件汇编、以及格式和列表控制等。 5.3.1 段定义和程序说明伪指令,2019年7月13日星期六,一、完整分段定义伪指令 1. 段定义伪指令 SEGMENT/ENDS 将程序分成段:代码段,数据段,堆栈段,附加段。 格式: 段名 SEGMENT 定位类型组合属性类别名 (段体) 段名 ENDS,功能:指出段名和段的各种属性, 并表示段的开始和结束位置。,段定义由伪操作SEGMENT开始、ENDS结束。 其中: SEGMENT 和ENDS 必须成对出现, 且语句前必须有段名,段名必须相同。 SEGMENT和ENDS语句之间可以有指令和其他伪指令, 表示存放在该段内存的变量、指令或其他伪指令对该段内存的处理 程序中可以定义多个段。 程序经汇编、连接及装入内存后,段名为一具体的段值。,合法标识符,有段基地址和段内偏移量两个属性,与某个存储单元相联系。,2019年7月13日星期六,(1)定位类型 用于告诉链接程序,链接时(各模块.obj) 本段首地址的边界定位方式,常有四种:, PARA:段的起始地址必须是16的倍数(XXXX0H), 这是一种默认方式。 PAGE:段的起始地址必须是256的倍数(XXX00H), 256字节为一页,在页的起点上。 WORD:段的起始地址必须是偶数(XX0B)。 BYTE:段的起始地址可以是任何地址。,(2) 组合类型 在多模块(每个模块有自己的代码段、数 据段、堆栈段)组合时,告诉Link程序本 段与其他模块中同名段的组合链接关系。,2019年7月13日星期六, NONE: 本段与其他同名段无组合关系,并有自己的段起始 地址,这是一种默认方式。 PUBLIC:在满足定位类型的前提下,LINK程序将其与其他 模块中的同名段邻接在一起,共用一个段地址。 STACK: 同PUBLIC 。链接以后作为堆栈段,并自动初始化 SS、SP。若程序中不说明STACK,则必须由用户 在程序的开始处,自己通过语句设置SS、SP。 COMMON:各模块中同名段重叠覆盖,有着相同的起始地 址。段的长度取决于最长的COMMON段。段的 内容为所链接的最后一个模块中COMMON段的 内容。 MEMERY:链接在其他所有段的后面(高端存储区 )。若有 多个MEMERY段,则只认第一个,其余按 COMMON处理。,2019年7月13日星期六,(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。 以上是定位类型、组合类型、段字和类别名四个参数的说明,各参数之间用空格分隔。在选用时,可以只选其中一个或两个参数项,但不能交换它们之间的顺序。,2019年7月13日星期六,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,2019年7月13日星期六,(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的内容。,2019年7月13日星期六,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,2019年7月13日星期六,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 ;程序结束,2019年7月13日星期六,二、简化分段定义伪指令 在MASM 5.0版本以上的宏汇编语言中段的定义可以非常简单。 .MODEL ;定义程序的存储模式 .STACK ;定义堆栈段, 长度缺省为1K字节 .CODE ;定义代码段 .DATA ;定义数据段 .DATA? ;定义数据段,但初值不确定 .FARDARA ;定义远调用数据段 .FARDARA? ;定义远调用数据段,但初值不确定 .CONST ;定义只读常数数据段 .STARTUP ;程序起始点,并初始化DS、SS .EXIT 0 ;程序结束点,返回到操作系统,2019年7月13日星期六,例: .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 ;汇编结束,2019年7月13日星期六,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模式。,2019年7月13日星期六,(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,2019年7月13日星期六,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伪指令后面使用处理器选择伪指令。,2019年7月13日星期六,3段名的缺省名 使用简化的段定义伪指令时,每个段都有一个缺省名。 在中内存模式和大内存模式时,.CODE伪指令表示的缺省段名为name_TEXT,即name是这个段名的可变部分,当程序模块有一个具体名字时,name就表示这个名字。 .DATA、.CONST、.DATA?、.STACK定义的段内数据存放在一个叫DGROUP的段组中,各个段内的偏移地址均以这个起始地址为起点,而不依本段内的段地址为起点。 .FARDATA或.FARDATA?伪指令使用的缺省名在各种模式下可以替换,它们定义的段内数据不放在任何段中,属于远程数据。,2019年7月13日星期六,4.等价名的使用 MASM 5.0中规定了几个等价名代替真实名。 可以用代替简化段定义伪指令前面的小数点。 CODE代表.CODE定义的段名; FARDATA代表.FARDATA定义的段名; DATA代表.DATA、.DATA?、.CONST和.STACK共享的组段名。 例: ASSUME ES:FARDATA ;ES为远程数据段地址 MOV AX,DATA MOV DS,AX ;DS为DGROUP段组段地址 MOV AX,FARDATA MOV ES,AX 5.段序定义伪指令 MASM可以按照源程序中各个段出现的次序来排列目标文件中各段的先后次序,也可以按照段名的字母顺序来排列次序。缺省情况是按照段出现的次序来排列,可以定义段序: .ALHPA:按照字母顺序对段排序。 .SEG:按照段出现的顺序对段排序。完整段定义格式中,默认按此顺序。 .DOSSEG:按照DOS定义的标准段序对段排序,顺序为:代码段、数据段、堆栈段。采用.MODEL伪指令的简化段定义格式默认按此顺序。,2019年7月13日星期六,三、使用简化段定义的程序框架 (1)EXE标准程序框架 汇编语言源程序经过汇编和连接后生成可执行文件(.exe)。操作系统为程序建立了一个程序段前缀区PSP,其长度为256个字节,主要用于存放用户程序的有关信息,如文件名、文件长度等。而在偏移100H处才装入程序本身。EXE程序加载要重新定位: 1)DS和ES指向PSP段地址,而不是程序的数据段和附加段,所以需在程序中根据实际数据段改变DS和ES; 2)CS:IP和SS:SP是由连接程序确定的值,指向程序的代码段和堆栈段。如果不指定堆栈段,则SS=PSP段地址,SP=100H,堆栈段占用PSP中的部分区域。,2019年7月13日星期六,例,.MODEL SMALL ;小内存模式 .586 ;可汇编并运行586指令 .STACK 100H ;256字节堆栈 .DATA MSG DB Welcome$ ;要写的信息 .CODE .STARTUP MOV DX,OFFSET MSG ;信息存储区首地址送DX MOV AH,9H INT 21H ;DOS写功能调用,在屏幕显示变量MSG内容 Welcome .EXIT 0 ;返回 END,2019年7月13日星期六,(2).COM格式的程序框架 .COM程序是一种将代码、数据和堆栈段合一的结构紧凑的程序,所有的段都在一个逻辑段内,不超过64KB。在程序中采用.MODEL TINY模式定义语句即可生成COM结构的程序。COM文件存储在磁盘上是主存的完全影像,不包含重新定位的加载信息,加载速度更快,占用的磁盘空间更少。COM程序加载后: 1)所有段地址都指向PSP的段地址; 2)程序执行起点是PSP后的第一条指令,既IP=100H;也就是说,COM程序的第一条

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论