收藏 分享(赏)

汇编语言程序设计第4章.ppt

上传人:wspkg9802 文档编号:5957348 上传时间:2019-03-22 格式:PPT 页数:271 大小:712.50KB
下载 相关 举报
汇编语言程序设计第4章.ppt_第1页
第1页 / 共271页
汇编语言程序设计第4章.ppt_第2页
第2页 / 共271页
汇编语言程序设计第4章.ppt_第3页
第3页 / 共271页
汇编语言程序设计第4章.ppt_第4页
第4页 / 共271页
汇编语言程序设计第4章.ppt_第5页
第5页 / 共271页
点击查看更多>>
资源描述

1、第4章 伪指令及汇编语言源程序结构,4.1 汇编程序结构 4.2 汇编语言语句格式 4.3 伪指令语句 4.4 标号、变量和表达式 4.5 段的组织 4.6 程序段前缀,4.1 汇编程序结构,4.1.1 寄存器组和语法元素,180x86的可编程的寄存器组1) 通用寄存器组EAX、EBX、ECX、EDX、ESI、EDI、EBP和ESP是32位可编程的通用寄存器,即程序员编程可以使用的寄存器。其中低16位用AX、BX、CX、DX、SI、DI、BP或SP表示。AX、BX、CX、DX还可以分成两个8位寄存器,即低8位为AL、BL、CL、DL;高8位为AH、BH、CH、DH。,2) 段寄存器8086有4

2、个16位的段寄存器:CS、SS、DS、ES,而80486有六个16位的段寄存器:CS、SS、DS、ES、FS和GS。在实地址方式下,段寄存器的内容左移4位而得到段基地址。在保护方式下,段寄存器存放的是描述符的选择符。3) 指令计数器指令计数器保存下一条指令相对于CS段基地址的偏移值,它可作16位用,也可作32位用。指令计数器采用16位段时用IP,采用32位段时用EIP。调试程序时,(E)IP的值显示的是下条要执行的指令在CS段中的偏移地址。,4) 标志寄存器EFLAGS是一个32位的标志寄存器,可用指令PUSHFD压入堆栈,指令POPFD从堆栈弹出。可对EFLAGS的低16位FLAGS单独进行

3、操作,通过PUSHF将其压入堆栈,POPF从堆栈弹出。5) 控制寄存器4个32位控制寄存器CR0、CR1、CR2、CR3中的3个,即CR0、CR2、CR3为程序员使用。Intel公司保留了CR1。使用MOV指令传送控制寄存器CR0、CR2、CR3中的内容。例如,指令MOV CR0,EBX实现的功能就是将EBX的内容送到CR0中。,6) 调试寄存器DR4和DR5为Intel公司保留,程序员编程时不能使用DR4和DR5,其余的调试寄存器的内容可通过MOV指令传送。例如,指令MOV EAX,DR6是将调试寄存器DR6中的内容送到EAX中。7) 测试寄存器程序员编程时能使用的测试寄存器只有TR6和TR

4、7,其他为Intel公司保留,则不能使用。例如,指令MOV ECX,TR7实现的功能就是将TR7的内容送到ECX中。,8) 系统地址寄存器80486用4个寄存器把在保护模式中常用的数据结构基地址、限制和其他属性保存起来,以确保其快速性。这4个寄存器是:全局描述符寄存器GDTR、局部描述符寄存器LDTR、中断描述符寄存器IDTR和任务寄存器TR。与这4个寄存器有关的指令是LGDT、LIDT、LLDT、LTR、LGDT或LIDT,实现的功能就是将内存中六个字节的内容装入GDTR或IDTR中。LLDT或LTR把寄存器或内存中两个字节的内容装入LDTR或TR中,与上述4条指令传送方向相反的指令是SGD

5、T、SIDT、SGDT、STR。注意这里任务寄存器TR与测试寄存器TR6、TR7的区别。,2语法规则和语法要素1) 字符集汇编语言字符集是ASCII字符集的一个子集,源文件中的每一个字符都应该是下列字符之一:(1) 字母 26个英文大小写字母;(2) 数字 09;(3) 特殊字符 / ( ) ; 。 ” : ? $ &;(4) 定界符 空格符、制表符、回车符(CR)、换行符(LF)。,程序中出现不在上列字符集中的字符,汇编系统把该字符当作一个逻辑空格符来处理。逻辑空格符就是把多个连续的空格符或制表符当作一个空格符来处理。在程序中,字母的大小写是无关的,可以互换。但是字符串中的字母大小写是不能互

6、换的,如XYZ与xyz,是不相等的字符串。,2) 标识符一个标识符是程序员用来定义段、变量、标号或常量等项目的名字。一个有效的标识符应遵循以下规则:(1) 标识符的首位字符必须是一个字母或下述3个特殊字符之一: ? (问号)、 (AT符号)、_ (下划线符号)(2) 其余的字符可以是字母、数字或是上面3个特殊字符,标识符中间不能有分隔符(逻辑空格或定界符);(3) 一个标识符可有长达255个字符,系统只识别前31个字符;(4) 一个程序模块内的每一个标识符只代表而且仅仅代表一个项,在模块的任何地方都可以通过标识符访问它所表示的项。,3) 关键字和保留字汇编语言的关键字和保留字都是系统自己预定义

7、的标识符。关键字指的是指令助记符,如加法指令ADD、中断返回指令IRET等。保留字指的是伪指令或其他功能符号,如SEGMENT、DWORD等。,4) 语言符号和分隔符语言符号是源程序中最小的有意义的单元,非常类似英语语句中的单词。汇编语言的语言符号有以下几种:(1) 一条语句的结束,如换行符(LF)或回车/换行符(CR/LF),用来分开两条汇编语句;(2) 一个定界符,如逗号“,”和分号“;”;(3) 一个标识符,如用户定义的PROGRAM_DATA、FTT等;,(4) 一个常量,如56DEH、3.1415等;(5) 一个关键字或保留字,如SUB、ASSUME等。ASSUME是一条伪指令语句,

8、其格式、功能和使用方法将在4.3.2节的“逻辑段定义伪指令”中讲述。一个分隔符是一个逻辑空格或一个定界符,在相邻的标识符、常量、关键字、保留字之间,必须用分隔符把它们隔开。最常用的分隔符是空格。,该源程序结构中的每行语句的用法及含义是:1) NAME MAIN_PROGMODULENAME是保留字,用于定义程序模块的名称,MAIN_MODULE是程序名称,用户可用任意一个标识符为程序命名。,5) ASSUME CSCODE,SSSTACK,DSDATA,ESDATAASSUME是保留字,指示段寄存器对应前面定义的哪个段。CSCODE,SSSTACK,DSDATA,ESDATA分别指出CS、SS

9、、DS和ES寄存器与CODE、STACK、DATA段对应。6) STARTSTART是程序员定义的程序入口处的标号名。用冒号“:”说明START是一个标号。,8) CODE ENDS这条语句指出所定义的CODE代码段到此结束。9) END STARTEND是保留字,指示整个程序模块到此结束。 按上述格式写出的一个程序如例4-2所示:,例4-2 NAME SIMPLE_EXAMPLE FIRST_DATA SEGMENT STRING_DA DB This is My First Program $ ;要显示的字符串 FIRST_DATA ENDS FIRST_STACK SEGMENT PAR

10、A STACK STACKDB 100 DUP(?) FIRST_STACK END FIRST_CODE SEGMENT ASSUME DSFIRST_DATA,SSFIRST_STACK,CSFIRST_CODE,START:MOV AX,FIRST_DATAMOV DS,AXMOV DX,STRING_DAMOV AH,02HINT 21H ;DOS功能调用MOV AH,4CHINT 21H FIRST_CODE ENDSEND START,该程序运行的结果是在屏幕上显示一行字符:“This is My First Program”。80x86系列微处理器的存储器采用了分段管理的方法,其

11、汇编语言是以逻辑段为基础,按段的概念来组织代码和数据的,汇编语言源程序的结构特点有:(1) 由若干逻辑段组成,各逻辑段由伪指令语句定义和说明。(2) 整个源程序以END伪指令结束。,(3) 每个逻辑段由语句序列组成,各语句可以是:指令语句完成一定操作功能,能够翻译成机器代码的语句,即为第3章介绍的指令所形成的语句。指令语句对应于CPU指令系统中的一条指令,因此为可执行语句。汇编时汇编成目标码。,伪指令语句CPU不执行的语句,只是为汇编程序在翻译成汇编语言源程序时提供有关信息,并不翻译成机器代码的语句。因此,伪指令语句是协助汇编系统实现某种特定的操作,决定程序的数据段、堆栈段和代码段的组织。伪指

12、令语句本身并不完成任何机器指令的功能,但对汇编系统生成的所有操作码是要产生影响的。如:在某程序中:BUFFERA DB 35HBUFFERB DW 123AHSUM DD ?,就是伪指令语句,其功能是在内存中设置3个存储单元,单元的名字分别是:BUFFERA、BUFFERB和SUM。BUFFERA、BUFFERB的初值是35H和123AH,而SUM单元未定义初值。宏指令语句由若干条指令语句形成的语句。一条宏指令语句的功能相当于若干条指令语句的功能。宏指令语句实际上是一个指令序列,汇编时产生对应的目标代码序列。,注释语句以分号“;”开始的说明性语句,汇编程序不予以处理,只起注释作用,使程序易于理

13、解。空行语句为保持程序书写清晰,仅包含回车换行符的语句行。注意:有关逻辑段的定义和说明伪指令,以及其他伪指令/指令语句的格式与参数规定等,因汇编程序的类型和版本不同而有所不同。,(4) 80x86汇编语言源程序一般具有数据段、附加数据段、堆栈段和代码段。但是,根据程序的实际情况,堆栈段、数据段和附加段也可以没有;只有代码段是必不可少的,每个程序至少必须有一个。当然,对于复杂、庞大的源程序,这几种逻辑段也分别允许定义多个。不过允许同时使用的段则是有限定的:8086/8088只允许同时使用4个段,即堆栈段(SS)、数据段(DS)、附加段(ES)和代码段(CS)各一个;80486允许同时使用6个段,

14、即除以上4个段外,还可有FS和GS两个附加数据段。在8086和实地址方式下,每个段的大小可以是164 KB;而在保护方式下,80486允许4 GB。,(5) 由于段寄存器说明伪指令只说明了各段寄存器与逻辑段的关系,并没有设置段寄存器的初值,所以在源程序中,除代码段CS(有时还有堆栈段SS)外,其他所有定义的段寄存器的初值都要在程序代码段的起始处由用户自己设置,以建立这些逻辑段的可寻址性。(6) 每个源程序在其代码段中都必须含有返回到DOS操作系统的指令语句,以保证程序执行完后能自动返回DOS状态,可继续向计算机键入命令或程序。终止当前程序,使其正确返回DOS状态的方法通常有以下四种:, 采用D

15、OS 4CH号功能调用。这种方法在代码段结束前加调用语句:MOV AH,4CH ;功能号4CHAHINT 21H ;中断调用 这种方法在前面的源程序结构中我们已使用过。这是返回DOS最有效且兼容性最好的一种方法。, 利用20号软中断调用。调用方式:INT 20H 这种方法在产生扩展名为.EXE的可执行文件中是不能使用的,但可用于小模式的扩展名为.COM的可执行文件中,作为返回DOS的一种方法。但是任一汇编语言源程序经汇编、连接之后产生的可执行文件都是扩展名为.EXE类型的,这时如果源程序是按小模式形式编写的,则在连接之后可用DOS提供的“EXE 2BIN”转换程序将.EXE文件转换成.COM文

16、件。这样在程序中的INT 20H指令就可使控制权返回到DOS。, 利用DOS的0号功能调用。调用方式:MOV AH,0INT 21H 该方式也是只有在.COM格式的可执行文件中才可使用。,4.2 汇编语言语句格式,4.2.1 语句种类根据汇编语言的语法规则,编写汇编语言源程序除了需要用第3章介绍的指令系统中的指令并满足一定的结构要求外,还要用到伪指令甚至宏指令。汇编语言使用的语句一般包括:指令语句,伪指令语句,宏指令语句。,4.2.2 语句格式本节只介绍指令语句和伪指令语句的格式,有关宏指令语句格式及其使用在第8章中讲述。指令语句和伪指令语句的格式基本相同,均由4部分(又称4个域)组成。其格式

17、分别是:指令语句: 标号:助记符操作数;注释伪指令语句:名字定义符操作数;注释 其中,格式中方括号“ ”内的内容为可选项。这两种语句在格式上的主要不同在于,指令语句中的标号后面要加冒号“:”,而在伪指令语句中的名字后面不能跟冒号。现对格式中的四个部分作如下说明。,1标号和名字标号和名字分别是给指令单元和伪指令起的符号名称,统称为标识符。标号指出了指令的起始地址。程序员可通过标号来引用所标识的指令,如可作为JMP和CALL指令的转移目标,与具体的指令地址相联系。而伪指令语句中的名字一般用作定义变量名、过程名、记录名等,不作为指令的操作数使用。标号可以任选或省略,而名字有时可任选或省略,有时则是强

18、制的,具体取决于实际的定义符。标号和名字都可由不超过31个的字符串组成。可选字符集为:,1标号和名字标号和名字分别是给指令单元和伪指令起的符号名称,统称为标识符。标号指出了指令的起始地址。程序员可通过标号来引用所标识的指令,如可作为JMP和CALL指令的转移目标,与具体的指令地址相联系。而伪指令语句中的名字一般用作定义变量名、过程名、记录名等,不作为指令的操作数使用。标号可以任选或省略,而名字有时可任选或省略,有时则是强制的,具体取决于实际的定义符。标号和名字都可由不超过31个的字符串组成。可选字符集为:,(1) 字母AZ或az;(2) 数字09;(3) 特殊符号 :? () ;/ * 等。必

19、须注意,标号不允许用数字开头,也不允许用特殊符号单独作为标识符,更不允许用汇编语言中有特定意义的保留字,如指令助记符、伪指令、寄存器名和运算符等。,2助记符和定义符助记符和定义符分别用于规定指令语句的操作性质和伪指令语句的伪操作功能,所以统称为操作符。要注意的是,在指令语句的助记符前面,还可根据需要加“前缀”。,3操作数操作数也叫参数。助记符和定义符都可后跟一个或多个操作数,作为操作处理的对象,当然也可不跟。各操作数之间要用逗号“,”分隔开。根据寻址方式等因素的不同,操作数可以有4类:常量、寄存器、存储器和表达式。对常量、存储器和表达式3种操作数作如下说明。,1) 常量操作数常量操作数可以是二

20、、八、十或十六进制的整型常数,十六进制实数,字符串和已赋值的常数标识符,也可以是寄存器名和I/O端口地址,如EAX、SI和5FH等。,2) 存储器操作数存储器操作数分为标号和变量两种。标号是某条指令所存放单元的符号化地址,这个地址一定在代码段中,它是转移/调用指令的目标操作数。变量则是数据所存放单元的符号化地址,它一般位于数据段或堆栈段中,不可能在代码段中。可用各种寻址方式对变量进行存取。,作为存储器操作数的标号和变量有三种共同属性:段值段基址,可用SEG运算符求得。偏移值段内偏移地址,可用OFFSET运算符求得。类型对变量有字节、字、双字、四字、十字等5种类型;对标号有NEAR和FAR两种类

21、型。可用TYPE运算符求得。除此之外,变量操作数还有另外两个属性:长度和字节数,可分别用LENGTH和SIZE运算符求得。,3) 表达式操作数它由各种操作数、界限符(如圆括号“( )”、方括号“ ”等)和运算符组成。汇编时,每个表达式都能产生一个确定的值。运算符包括:算术运算符、逻辑运算符和关系运算符。操作符有分析操作符和合成操作符两种。(1) 算术运算符有:加(+)、减(-)、乘(*)、除(/)和求模(MOD)。算术运算符总可以应用于数字操作数,结果也是数字的。应用于存储器地址操作数时,有意义的运算符是加和减。,(2) 逻辑运算符是按位操作的与(AND)、或(OR)、异或(XOR)和非(NO

22、T)。逻辑运算符的操作数只能是数字的,且结果也是数字的。存储器地址操作数不能进行逻辑运算。注意:有些运算符尽管与指令的名字相同,但它们与指令有着本质区别:指令是在程序运行时执行的语句,而运算符是在汇编时由汇编程序完成其功能的。如:AND、OR、XOR和NOT也是指令助记符。作为运算符使用时,它们是在程序汇编时计算的。而作为指令助记符时,则是在程序执行时计算的。例如,AND DX,PORT AND 0FEH 其中第二个AND是逻辑运算符,在汇编时,计算PORT AND 0FEH后,产生一个立即数作为指令的操作数。而第一个AND是指令助记符,在汇编以后,执行AND指令时,DX的内容与上述立即数相“

23、与”,结果放在DX中。,(3) 关系运算符有相等(EQ)、不等(NE)、小于(LT)、大于(GT)、小于或等于(LE)、大于或等于(GE)。关系运算符连接两个操作数,必须都是数字的或是在同一段内的存储器地址。运算结果始终是一个数字值。若关系是假(关系不成立),则结果为0;若关系为真,则结果为0FFFFH。,例4-4MOV BX,PORT LT 5 若PORT的值小于5,则汇编程序将把这条指令汇编为MOV BX,0FFFFH 否则,若PORT的值不小于5,则汇编为MOV BX,0,一般不单独使用关系运算符。因为运算的结果不是0就是0FFFFH,没有别的选择,所以,常与其他运算符组合起来使用。例如

24、:MOV BX,(PORT LT 5) AND 20) OR (PORT GE 5) AND 30) 当PORT的值小于5时,上述指令将汇编为MOV BX,20 否则为 MOV BX,30,(4) 分析操作符和合成操作符。分析操作符也叫分解操作符,可从变量或标号中分解出某些属性值,把存储器操作数分解为它的组成部分;合成操作符也叫属性操作符,可用来改变原有变量或标号的类型,把组成部分综合为存储器操作数。分析操作符有:SEG(返回段基址)、OFFSET(返回偏移地址)、LENGTH(返回变量单元数)、TYPE(返回元素字节数)、SIZE(返回变量总字节数),返回的运算结果分别是:段基址、偏移地址、

25、单元数、字节数和总字节数。分析操作符和合成操作符将在4.3.1节中作详细介绍。,4注释注释部分以分号开始,其作用与注释语句相同。注释语句是对后跟程序段的功能加以说明,而以分号开始的注释是对语句的功能加以说明,目的在于增加程序的可读性。注释部分不被汇编程序汇编,也不被执行,只对源程序起说明作用。,4.3 伪 指 令 语 句,4.3.1 符号/数据/标号定义伪指令语句1符号定义伪指令符号定义伪指令可用来为表达式赋予一个符号名,表达式可以是常数、变量、标号、指令语句和字符等。在程序中,任何需要这种表达式的地方都可使用被赋予的符号名来代替它。符号定义伪指令语句有两种,即等值语句和等号语句。,1) 等值

26、语句(EQU)格式:符号名 EQU 表达式功能:用符号名代替表达式的值,供以后引用。说明:EQU语句不能重新定义,即在同一源程序中,用它定义的符号名不能再赋予不同的值。使用EQU语句时,必须先赋值后使用。例4-5 下面是等值语句的例子。X EQU 50Y EQU X+10COUNT EQU CX,2) 等号语句(=)格式:符号名表达式功能:等号语句的功能与EQU语句的功能相同,只是其符号名可以再定义。例4-6 下面是等号语句的3个例子。PORT130HPORT1PORT120HPORT1325 * 8,2) 数据定义伪指令格式:符号名 DB/DW/DD/DF/DQ/DT 初值序列功能:为数据项

27、分配一个或多个字节/字/双字/长字/四字/十字节的存储空间,给它们赋初值,并用一个符号名与之相联系。,说明:(1) 数据定义伪指令按数据长度可分为DB、DW、DD、DF、DQ、DT 6种类型,分别定义8位、16位、32位、48位、64位、80位数据。具体地讲就是: DB指一个操作数占用一个字节单元,定义的变量为字节变量; DW指一个操作数占用一个字单元(2个字节单元),定义的变量为字变量; DD指一个操作数占用一个双字单元(4个字节单元),定义的变量为双字变量;, DF指一个操作数占用一个三字单元(6个字节单元),定义的变量为三字变量,该助记符仅用于386以上的CPU,定义的变量作为指针使用,

28、其低4字节存放偏移地址,高2字节存放段地址; DQ指一个操作数占用一个四字单元(8个字节单元),定义的变量为四字变量; DT指一个操作数占用10个字节单元,定义的变量为十字节变量,使用该助记符时,对于十进制操作数,必须给出后缀D,没有后缀的默认为压缩BCD码。,(2) 与数据项相联系的符号名称为变量,经过定义的变量名有3个属性:数据类型(字节、字、双字、长字、四字、十字)、偏移量(可用OFFSET运算符获得)和段基址(可用SEG运算符求得),符号名为可选项。,(3) 给变量赋初值: 可以是赋确定的值,也可以是赋用“?”表示不确定的值。赋不确定值,实质是不赋值,而只预留规定长度的存储空间。 初值

29、序列可以是一个元素,也可以是用逗号分隔的多个元素。 用DUP运算符建立单个值的多次拷贝,确定值可以是整数、浮点数(只允许DD、DQ和DT伪指令,并只用于80486和80387/80287协处理器上)、字符、字符串或表达式。,例4-7 VAR1 DB ? ;给变量VAR1分配一个字节,但不赋初值 VAR2 DD ? ;给变量VAR2分配4个字节,但不赋初值 XY DT 3456H ;给变量XY分配10个字节,初值为3456H STR1 DB ABCDE ;给字符串分配5个字节,并赋初值(ASCII码) ARRAY DW 20 DUP(1) ;给数组变ARRAY分配20个字,初值均为1 BUFF

30、DB 6 DUP(?) ;相当于DB ?,?,?,?,?,? COUNT DB 25,35,45 ;给变量COUNT分配3个字节,并赋初值。,(4) 对操作数的说明。 操作数是常数或表达式(代表的是数据或内存单元地址)。 例4-8 操作数是数据的定义形式。DATAB DB 18H,-1,30 ;每个数占用一个字节单元DATAW DW 18H,2A45H ;每个数占用一个字单元DATAD DD 18H,2F3A124BH ;每个数占用一个双字单元,在内存中的存储情况如图4-1所示。说明:操作数可用各种进制形式书写,汇编程序将其转换成相应的补码存入内存单元中。同样一个数(如18H),由于数据定义助

31、记符的不同,所占用的内存空间是不一样的。数据的高字节存放在高地址单元,低字节存放在低地址单元。,图4-1 内存中的存储情况,例4-9 操作数是地址的定义形式。ADDR1 DW NEXT ;存放偏移地址ADDR2 DD NEXT ;存放偏移地址和段地址NEXT: MOV AL,34HNEXT是一条指令的标号,表示这条指令所在单元的地址,ADDRW是一个字单元,只存放偏移地址,ADDRD是一个双字单元,存放的是偏移地址和段地址,存储情况如图4-2所示。,图4-2 偏移地址和段地址, 操作数是字符串时,内存中存放的是每个字符的ASCII码。 例4-10 下面3个定义语句是等价的。STR1 DB AB

32、CDSTR1 DB A,B,C,DSTR1 DB 41H,42H,43H,44H,例4-11 下面两个定义语句是等价的。STR2 DB,AB STR2 DW,BA当定义的字符串中字符多于两个时,只能使用DB定义,不能使用DW。例如,定义STR3 DW,ABCD是错误的。, 操作数是“?”,此时只分配单元,不定义初值。例如:BUF1 DB 5,6,7,?BUF2 DW 56H,78H,?,345FH, 复制操作符DUP。操作数用复制操作符DUP,表示操作数重复若干次。例如:BUFFER1 DB 2 DUP(2,3,4) 等价于 BUFFER1 DB 2,3,4,2,3,4BUFFER2 DW 1

33、,2,3 DUP(6) 等价于 BUFFER2 DW 1,2,6,6,6BUFFER3 DB 2 DUP(5,6,3 DUP(7) 等价于 BUFFER3 DB 5,6,7,7,7,5,6,7,7,7,(5) 指令单元NEAR和FAR。一个指令单元能出现在一个JMP或CALL指令语句中。若这个单元的类型是NEAR,汇编程序将产生一个段内JMP或CALL指令;若单元的类型是FAR,则产生一个段间JMP或CALL指令。个NEAR指令单元规定了个长度为两个字节的指针,即此指令单元在段内的地址偏移量。获取了此地址偏移量,就可以实现段内的转移和调用。一个FAR指令单元规定了一个长度为四个字节的指针,即此

34、指令单元所在段的段地址和段内的地址偏移量。只有获取了这四个字节,才能得到一个FAR指令单元的全地址,才能实现段间的调用和转移。,例4-12CYCLE:CMP SUM,100若存储单元CYCLE的类型是NEAR,当汇编程序遇到指令JMP CYCLE 时,就产生一个段内JMP指令。从一个存储单元加或减一个数字值形成的新的存储器地址与原存储单元有相同的类型。若SUM、BIG、CYCLE分别是字节型、字型、NEAR型指令单元,则SUM+2、BIG-3、CYCLE+1也分别是字节型、字型、NEAR型指令单元。,3除定义伪指令PURGE 格式:PURGE 符号1,符号2,符号n 功能:解除指定符号的定义,

35、解除符号定义后,可用EQU重新定义。 例4-13 执行指令DATA EQU 7PURGE DATA 后,DATA可重新用EQU进行定义。DATA EQU 28,4标号定义伪指令(LABEL)格式:符号名 LABEL 类型功能:将紧跟在本伪指令语句后的标号、操作码、过程或变量建立新的符号名,并刷新其类型属性。对标号、操作码或过程,其类型为NEAR、FAR;对变量,其类型为TYTE、WORD、DWORD、FWORD、QWORD或TBYTE。,这里用两种方法定义了数组。由于LABEL伪指令不为变量分配存储空间,因此BARRAY与ARRAY的地址实际上是相同的,即它们指向同一个数组,只是BARRAY被

36、定义为字节型,而ARRAY被定义为字型。这样,可根据需要按不同类型去存取数组中的数据。,5分析和合成操作符(1) 分析操作符把存储器地址操作数分解成它们的组成部分。这些操作符是SEG、OFFSET、TYPE、SIZE、LENGTH。 SEG操作符。格式:SEG 功能:计算变量或标号的段地址,即返回存储器地址操作数所在段的段地址部分。, OFFSET操作符。格式:OFFSET 功能:计算变量或标号的段内偏移地址,即返回地址的段内偏移量部分。例4-14 说明指令MOV AX,SEG DATA和MOV SI,OFFSET DATA的功能。指令MOV AX,SEG DATA的功能是把DATA的段地址存

37、入AX寄存器中,指令MOV SI,OFFSET DATA的功能是把DATA的偏移地址存入SI寄存器中,等价于指令LEA SI,DATA。, TYPE操作符。格式:TYPE 功能:计算变量的类型值或标号的类型值,即返回一个数字值,它表示存储器操作数的类型部分。各种存储器地址操作数类型部分的值如下:,存储器操作数 类型部分 字节数据 1 字数据 2 双字数据 4 长字数据 6 四字数据 8 十字数据 10 NEAR指令单元 - -1 FAR指令单元 -2,从此表可看出,用DB、DW、DD、DF、DQ、DT定义的变量对应的类型值分别为1、2、4、6、8、10;NEAR、FAR型标号对应的类型值分别为

38、-1、-2。注意:字节、字、双字、长字、四字和十字的类型部分,分别是它们所占有的字节数,而指令单元的类型部分的值没有实际的物理意义。若TYPE放在一个结构名前,则返回此结构所占用的字节数。, LENGTH和SIZE操作符只应用于数据存储器地址操作数。格式:LENGTH 功能:返回一个与存储器地址操作数相联系的单元数,对于使用DUP定义的变量,计算分配给该变量的单元数,其他变量的LENGTH值为1。格式:SIZE 功能:返回一个为存储器地址操作数分配的字节数,即计算分配给该变量的字节数,其值为TYPE和LENGTH的乘积。,例4-15 若MULT_WORDS定义为MULT_WORDS DW 50

39、 DUP(0) 则LENGTH MULT_WORDS是50,而SIZE MULT_WORDS是100,即SIZE X(LENGTH X)(TYPE X)(2) 合成操作符由地址部分建立存储器地址操作数,这些操作符是:PTR和THIS。, PTR操作符。格式:类型 PTR 表达式类型可以是BYTE、WORD、DWORD、NEAR、FAR。功能:给表达式(一般是变量或标号)指定类型,不管它原来有无类型或是什么类型,均以PTR前的类型为准。对于变量,可以指定的类型是BYTE(字节)、WORD(字)、DWORD(双字);对于标号,可以指定的类型是NEAR(段内引用型)、FAR(段间引用型)。PTR操作

40、符建立一个存储器地址操作数,它与其后的存储器地址操作数有相同的段地址偏移量,但有不同的类型。不像一个数据定义语句,PTR操作符并不分配存储器,它可以给已分配的存储器一个另外的意义。,例4-16 若TWO_BYTE定义为TWO_BYTE DW ? 于是能给TWO_BYTE的第一个字节定义为ONE_BYTE EQU BYTE PTR TWO_BYTE这里,PTR操作符建立了一个与TWO_BYTE有相同的段和偏移量的新的存储器地址操作数,但它的类型部分是字节。可以给第二个字节定名为OTHER_BYTE EQU BYTE PTR TWO_BYTE+1 或简单地定义为OTHER_BYTE EQU ONE

41、_BYTE+1,例4-17 用PTR操作符建立字和双字。 MANY_BYTES DB 100 DUP(?) ;一个100个字节的矩阵 FIRST_WORD EQU WORD PTR MANY_BYTES ;50个字 SECOND_DOUBLE EQU DWORD PTR MANY_BYTES ;25个双字,例4-18 设INCHES的类型是NEAR,使用PTR运算符为MILES建立FAR型的指令单元。INCHES:CMP SUM,100 JMP INCHES ;段内转移MILES EQU FAR PTR INCHES ;MILES类型是FARJMP HILES ;段间转移, THIS操作符。像

42、PTR一样,合成操作符THIS可用来建立一个特殊类型的存储器地址操作数,而没有为它分配存储器。新的存储器地址操作数的段和偏移量部分,就是下一个能分配的存储单元的段和偏移量。格式:THIS 功能:将变量或标号定义成指定的类型,但并不分配新的存储单元,其寻址空间与跟在后面的变量的寻址空间相同。对于变量,类型可以是BYTE、WORD、DWORD,对于标号,类型可以是NEAR、FAR。,例4-19 定义:HY_BYTE EQU THIS BYTEHY_WORD DW ? 后,将建立HY_BYTE具有字节类型,且与HY_WORD具有相同的段和偏移量部分。在这个例子中,HY_BYTE也可用PTR操作符建立

43、:HY_BYTE EQU BYTE PTR HY_WORD,注意:上例中使用THIS操作符,并不需要有一个与MILES具有相同的段和偏移量的NEAR指令单元。但若用PTR操作符代替THIS这样的NEAR指令是需要的。说明:用数据定义伪指令,定义的变量是有类型的。在指令中使用变量作操作数时,要注意其类型与其他操作数的匹配。,例4-20 如果有数据定义伪指令OPDATA1 DB 23H,4AHOPDATA2 DW 127FH,25A6H 则如下两条指令是错误的,MOV BX,OPDATA1 ;BX为字寄存器,OPDATA1为字节变量MOV AL,OPDATA2 ;AL为字节寄存器,OPDATA2为

44、字变量,使用合成操作符PTR,书写成如下形式才是正确的:MOV BX,WORD PTR OPDATA1 ;BX为字寄存器,OPDATA1为字变量MOV AL,BYTE PTR OPDATA2 ;AL为字节寄存器,OPDATA2为字节变量 指令执行后,BX=4A23H,AL=7FH。,6操作符及运算符的优先权级的规定操作符及运算符的优先权级按如下顺序,从高到低排列为: 圆括号、(记录中使用的)尖括号、方括号、(结构中使用的)圆点符、LENGTH、SIZE、WIDTH、MASK。 PTR、OFFSET、SEG、TYPE、THIS、段寄存器名:(加段前缀)。 *、/、MOD(求模)、SHL、SHR。

45、 HIGH、LOW(操作数高、低字节)。, 、。 EQ、NE、LT、LE、GT、GE。 NOT。 AND。 OR、XOR。 SHORT。当各种运算符同时出现于同一表达式中时,具有不同的优先级。优先级相同的运算符操作顺序为先左后右。,4.3.2 程序结构伪指令语句1方式选择伪指令方式选择伪指令又称指令集选择伪指令。这是汇编程序为区分使用的是哪种CPU执行程序而提供的选择处理器的伪指令。每种处理器的指令系统都有一个汇编执行语句集合,也就是通常所称的指令集,处理器方式选择伪指令本质上就是指令集选择伪指令。这些指令的一个共同特点是,使用时用一点“.”为引导,程序中放在段外,一般放在程序的开始处,对整个

46、源程序起作用。.586和.586P用于MASM6.11以上的汇编语言版本,其他的可用于MASM5.0以上的汇编语言版本。,(1) .8086:默认方式,此伪指令可以省略,选择8086/8088指令集,即汇编程序只接受8086/8088指令。(2) .286/.286C:选择80286指令集。.286不包括特权指令,汇编程序只接受8086/8088及80286非保护方式(即实地址方式)下的指令,用.8086可删除该伪指令。(3) .286P:选择80286指令集。.286P包括特权指令,允许汇编程序接受8086/8088及80286的所有指令(包括保护方式和非保护方式下的指令)。该伪指令一般只有

47、系统程序员使用,并可用.8086伪指令删除。,(4) .386/.386C:选择80386指令集。.386不包括特权指令。允许汇编8086/8088及非保护方式下的80286/80386指令。与.286/.286C类似,在此方式下将禁止所有保护方式下的指令出现,否则将出错。可用.8086删除。(5) .386P:选择80386指令集。.386P包括特权指令,除具有.386/.386C功能外,还允许汇编保护方式下的80286/80386指令。一般只有系统程序员使用,并可用.8086伪指令删除。(6) .8087/.287/.387:分别选择8087、80287和80387数字协处理器指令集,并指

48、定实数的二进制码为IEEE格式。,(7) .486/.486P:选择80486指令集,.486不包括特权指令。与.386/.386C类似,允许汇编80486非保护方式下的指令。(8) .486P:选择80486指令集,.486包括特权指令。与.386P类似,允许汇编80486的全部指令。(9) .586/.586P:选择Pentium指令集,不包括特权指令,.586P包括特权指令。,2逻辑段定义伪指令逻辑段定义的方法有两种:完整段定义和简化段定义。使用MASM5.0以上的汇编语言版本中,既可定义完整段,也可定义简化段;在低于MASM5.0的版本中,只能定义完整段。1) 完整段定义伪指令采用完整

49、段定义伪指令可具体控制汇编程序(MASM)和连接程序(LINK)在内存中组织代码和数据的方式。它包括3种伪指令语句:, 定位类型用于规定段的起始地址要求,即指定该段起点的边界类型,有5种可选类型,默认方式为PARA。PARA(节):段起始地址从段边界开始(必为16的倍数),段起始单元20位地址的最低4位二进制位必为0。BYTE(字节):段起始地址从字节边界开始,即该段可以从任何单元开始。WORD(字):段起始地址从字边界开始(必为偶数),段起始单元20位地址的最低1位二进制位必为0。,DWORD(双节):段起始地址从双字边界开始(必为4的倍数),段起始单元20位地址的最低2位二进制位必为0,一般用于80386的32位段中。PAGE(页):段起始地址从页边界开始(必为256的倍数),段起始单元20位地址的最低8位二进制位必为0。,

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

当前位置:首页 > 网络科技 > 开发文档

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报