已阅读5页,还剩140页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1,封面,第五章 汇编语言程序设计,2,5.1 汇编语言的基本概念 5.1.1 汇编语言源程序的格式 5.1.2 汇编语言上机过程 5.1.3 汇编语言程序和DOS操作系统的接口 5.2 伪指令语句 5.3 宏指令语句 5.4 常用系统功能调用和BIOS中断调用 5.5 汇编语言程序设计的基本方法 5.6 汇编语言与C/C+语言的混合编程,3,5.1 汇编语言的基本概念 1机器语言(Machine Language) 2汇编语言(Assembly Language) 比较几个重要的概念: 1).汇编语言程序(源程序):用汇编语言编写的源程序. 2).汇编程序:将汇编语言程序(源程序)翻译成目标程序的程序,是一种工具软件,如MASM.EXE等.有基本汇编(或小汇编ASM)和宏汇编(MASM)之分。 3).汇编:利用汇编程序(如MASM.EXE等)将汇编语言程序(源程序)翻译成目标程序的过程. 3. 高级语言(High Level Language),4,汇编语言和高级语言(1),汇编语言与处理器密切相关 汇编语言程序的通用性、可移植性较差 高级语言与具体计算机无关 高级语言程序可以在多种计算机上编译后执行,汇编语言和高级语言(1),5,汇编语言和高级语言(2),汇编语言功能有限、涉及硬件细节 编写程序比较繁琐,调试起来也比较困难 高级语言提供了强大的功能,不必关心琐碎问题 类似自然语言的语法,易于掌握和应用,汇编语言和高级语言(2),6,汇编语言和高级语言(3),汇编语言本质上就是机器语言 可以直接、有效地控制计算机硬件 易于产生速度快、容量小的高效率目标程序 高级语言不针对具体计算机系统 不易直接控制计算机的各种操作 目标程序比较庞大、运行速度较慢,汇编语言和高级语言(3),7,汇编语言和高级语言(4),汇编语言的优点: 直接控制计算机硬件部件 可以编写在“时间”和“空间”两方面最有效的程序 汇编语言的缺点: 与处理器密切有关 需要熟悉计算机硬件系统、考虑许多细节 编写繁琐,调试、维护、交流和移植困难,汇编语言和高级语言(4),8,汇编语言和高级语言(5),汇编语言的优点使得它在程序设计中占有重要的位置,是不可被取代的 汇编语言的缺点使得人们主要采用高级语言进行程序开发工作 有时需要采用高级语言和汇编语言混合编程的方法,互相取长补短,更好地解决实际问题,汇编语言和高级语言(5),9,汇编语言的应用场合,程序要具有较快的执行时间,或者只能占用较小的存储容量。 程序与计算机硬件密切相关,程序要直接、有效地控制硬件。 大型软件需要提高性能、优化处理的部分。 没有合适的高级语言、或只能采用汇编语言的时候。 分析具体系统尤其是该系统的低层软件、加密解密软件、分析和防治计算机病毒等等。,汇编语言的应用场合,10,硬指令和伪指令,硬指令使CPU产生动作、并在程序执行时才处理的语句。 伪指令(Directive)不产生CPU动作、在程序执行前由汇编程序处理的说明性语句,例如,定义数据、分配存储区、定义段及定义过程等等。 伪指令与具体的处理器类型无关,但与汇编程序的版本有关,本课程采用微软宏汇编程序 MASM 6.11,11,3.1.2 汇编语言的程序格式,完整的汇编语言源程序由段组成。 一个汇编语言源程序可以包含若干个代码段、数据段、附加段或堆栈段,段与段之间的顺序可随意排列。 需独立运行的程序必须包含一个代码段,并指示程序执行的起始点,一个程序只有一个起始点。 所有的可执行性语句必须位于某一个代码段内,说明性语句可根据需要位于任一段内。 通常,程序还需要一个堆栈段。,5.1.1 汇编语言的程序格式,12,汇编语言源程序,源程序分别用两种格式书写。 第一种格式从MASM 5.0开始支持 简化段定义格式 第二种格式MASM 5.0以前就具有 完整段定义格式(本教程采用的格式),Hello, Everybody !,13,;lt301a.asm(文件名) .model small ;定义程序的存储模式 .stack ;定义堆栈段 .data ;定义数据段 string db Hello, Everybody !,0dh,0ah,$ ;在数据段定义要显示的字符串 .code ;定义代码段 .startup ;程序起始点,建立DS、SS mov dx,offset string ;指定字符串 mov ah,9 int 21h ;利用功能调用显示信息 .exit 0 ;程序结束点,返回DOS end ;汇编结束,例:简化段定义格式,抽象,14,;SampleA.ASM .model small .stack .data . ;在数据段定义数据 .code .startup ;(注1) . ;在代码段填入指令序列 .exit 0 ;(注2) . ;子程序代码 end ;(注3),简化段定义格式 MASM 6.x支持,15,;SampleC.ASM .model small .stack .data . ;在数据段定义数据 .code start:mov ax,data mov ds,ax . ;在代码段填入指令序列 mov ax,4c00h int 21h . ;子程序代码 end start,简化段定义格式 MASM 5.x及以上支持,16,;lt301b.asm(文件名) stack segment stack ;定义堆栈段 dw 512 dup(?) ;堆栈段有512字(1024字节)空间 stack ends ;堆栈段结束 data segment ;定义数据段 string db Hello, Everybody !,0dh,0ah,$ data ends code segment code ;定义代码段 assume cs:code,ds:data,ss:stack start: mov ax,data ;建立DS段地址 mov ds,ax,例:完整段定义格式,17,mov dx,offset string mov ah,9 int 21h mov ax,4c00h int 21h ;利用功能调用返回DOS code ends ;代码段结束 end start ;汇编结束,同时指明程序起始点,例:完整段定义格式,抽象,18,5.1.1 汇编语言源程序的格式,例5.1 要求将两个5字节十六进制数相加,可以编写出以下汇编语言源程序。 3B74AC60F8H+20D59E36C1H=?,19,START: MOV AX,(SEG) DATA MOV DS,AX ;初始化DS MOV CX,5 ;循环次数送CX MOV SI,0 ;置SI初值为0 CLC ;清CF标志 LOOPER: MOV AL,(OFFSET) DATA2SI ;取一个字节加数 ADC (OFFSET) DATA1SI,AL ;与被加数相加,INC SI ;SI加1 DEC CX ;CX减1 JNZ LOOPER ;若不等于0,转LOOPER MOV AH,4CH INT 21H ;返回DOS CODE ENDS ;代码段结束 END START ;源程序结束,DATA SEGMENT ;定义数据段 DATA1 DB 0F8H,60H,0ACH,74H,3BH ;被加数 DATA2 DB 0C1H,36H,9EH,0D5H,20H ;加数 DATA ENDS ;数据段结束 CODE SEGMENT ;定义代码段 ASSUME CS:CODE,DS:DATA,汇编语言源程序的格式与伪指令,20,例5.1分析,-u 0B8B:0000 B88A0B MOV AX,0B8A 0B8B:0003 8ED8 MOV DS,AX 0B8B:0005 B90500 MOV CX,0005 0B8B:0008 BE0000 MOV SI,0000 0B8B:000B F8 CLC 0B8B:000C 8A840500 MOV AL,SI+0005 0B8B:0010 10840000 ADC SI+0000,AL 0B8B:0014 46 INC SI 0B8B:0015 49 DEC CX 0B8B:0016 75F4 JNZ 000C 0B8B:0018 B44C MOV AH,4C 0B8B:001A CD21 INT 21,-d 0b8a:0000 0B8A:0000 F8 60 AC 74 3B C1 36 9E-D5 20 00 00 00 00 00 00,汇编语言源程序的格式与伪指令,21,1.分段结构,汇编语言源程序的结构是分段结构形式,一个汇编语言源程序由若干段(SEGMENT)组成,每个段以SEGMENT语句开始,以ENDS语句结束。整个源程序的结尾是END语句。 这里所说的汇编语言源程序中的段与前面讨论的CPU管理的存储器的段,既有联系,又在概念上有所区别: 1、CPU对存储器是分段管理的,它有四个段寄存器(CS,ES,SS和DS) (各一个)。 2、在汇编语言程序中也要求分段组织指令、数据和堆栈,以便将源程序汇编成为目标程序后,可以分别装入存储器的相应段中。 3、而在汇编语言源程序中,设置段的自由度比较大。例如,一个源程序中可以有多个数据段或多个代码段等等,但至少有一个代码段。,22,2. 汇编语言语句的类型和格式 1)语句的类型 汇编语言源程序中的语句可以分为三种类型:指令语句、伪指令语句和宏指令语句。 (1) 指令语句:它是能产生目标代码,CPU 可以执行的能完成特定功能的语句。 (2) 伪指令语句:它是一种不产生目标代码的语句,它仅仅在汇编过程中告诉汇编程序应如何汇编。例如,告诉汇编程序已写出的汇编语言源程序有几个段,段的名字是什么;定义变量,定义过程,给变量分配存储单元,给数字或表达式命名等。显然,伪指令语句是汇编程序在汇编时使用的。 (3)宏指令语句:它是一种用户利用宏指令语句自己定义的语句。,23,2) 语句的格式 指令语句与伪指令语句的格式是类似的。一般情况下,汇编语言的语句可以由部分构成: 名字 助记符 操作数 ;注释 其中带方括号的部分表示任选项,可以有,也可以没有。例5.1中有如下语句: LOOPER: MOV AL,DATA2SI ; 取一个字节加数 DATA1 DB 0F8H,60H,0ACH,74H,3BH ;被加数,24,1) 名字 在指令语句中,这个名字是一个标号。标号后面通常有一个冒号。 标号有三种属性:段、偏移量和类型(NEAR和FAR)。 伪指令语句中的名字可以是变量名、段名、过程名。伪指令语句的名字后面通常不跟冒号,这是它和标号的一个明显区别。 变量也有三种属性:段、偏移量和类型(BYTE、WORD、DWORD、QWORD、TBYTE)。 注:段名时默认的是段属性;变量名是默认的是偏移量的属性,见例5.1。,25,2) 助记符 汇编语言语句中的第二个组成部分是助记符(Memonic)。 在指令语句中的第二部分是CPU指令系统中指令的助记符,如MOV、ADC等。 在伪指令语句中的第二部分是伪指令的定义符,如DB、SEGMENT、ENDS、END等。它们在程序中的作用是定义变量的类型、定义段以及告诉汇编程序结束汇编等。,26,3) 操作数 汇编语言语句中的第三个组成部分是操作数。在指令语句中是指令的操作数,可能有单操作数或双操作数,也可能无操作数;而在伪指令中可能有更多个操作数。当操作数不止一个时,相互之间应该用逗号隔开。,(1) 常数。常数就是指令中出现的那些固定值,可以分为数值常数和字符串常数两类。汇编语言用不同的后缀加以区别。如: 0B7H, 0FFH,103,35O, ABCDEFG,179,1001100B。,(2) 寄存器。8086/8088CPU的寄存器可以作为指令的操作数。 (3) 标号。由于标号代表一条指令的符号地址,因此可以作为转移(无条件转移或条件转移)、过程调用CALL以及循环控制LOOP指令的操作数。 (4) 变量。因为变量是存储器中某个数据区的名字如(DATA1),所以在指令中可以作为存储器操作数。,27, 算术运算符。常用的算术运算符有:+(加),(减),*(乘),/(除)和MOD(模除,即两个整数相除后取余数)等。, 逻辑运算符。逻辑运算符有:AND(逻辑“与”),OR(逻辑“或”),XOR(逻辑“异或”)和NOT(逻辑“非”)。, 关系运算符。关系运算符有:EQ(等于),NE(不等),LT(小于),GT(大于),LE(小于或等于),GE(大于或等于)等。 当关系不成立(假)时,结果为0(全0);当关系成立(真)时,结果为0FFFFH(全1)。例如: MOV AX,4 EQ 3 ;关系不成立,故(AX)0 MOV AX,4 NE 3 ;关系成立,故(AX)0FFFFH,(5) 表达式。汇编语言语句中的表达式,按其性质可分为两种:数值表达式和地址表达式。,28,分析运算符。分析运算符用于分析一个存储器操作数的属性。 SEG运算符。利用SEG运算符可以得到一个标号或变量所在段的段地址。例如: MOV AX,SEG ARRAY MOV DS,AX OFFSET运算符。利用OFFSET运算符可以得到一个标号或变量的偏移地址。例如: MOV DI,OFFSET DATA1,汇编语言源程序的格式,P167,29, TYPE运算符。获取变量中每个操作数所含的字节数。这个数值与存储器操作数类型属性的对应关系如下表。 VAR DW ? ;变量VAR的类型为字 ARRAY DD 10 DUP(?) ;变量ARRAY的类型为双字 STR DB THIS IS TEST ;变量STR的类型为字节 MOV AX,TYPE VAR ;(AX)=0002 MOV BX,TYPE ARRAY ;(BX)=0004 MOV CX,TYPE STR ;(CX)=0001,汇编语言源程序的格式,30, LENGTH运算符。变量有重复操作符DUP时,获取该变量重复的次数;如果未用DUP说明,则得到的结果总是1。 SIZE运算符。变量有重复操作符DUP时,获取分配给该变量的字节总数;如果未用DUP说明,则得到的是TYPE的返回值。 一般地:SIZE=LENGHTYPE,汇编语言源程序的格式,31,VAR DW ? ;变量VAR的类型为字 ARRAY DD 10 DUP(?) ;变量ARRAY的类型为双字 STR DB THIS IS TEST ;变量STR的类型为字节 MOV AX,TYPE VAR ;(AX)2 MOV BX,TYPE ARRAY ;(BX)4 MOV CX,TYPE STR ;(CX)1,MOV DL,LENGTH VAR ;(DL)=1=01H MOV DL,LENGTH ARRAY ;(DL)=10D=0AH MOV DL,LENGTH STR ;(DL)=1=01H,MOV DH,SIZE VAR ;(DH)=12=2D=02H MOV DH,SIZE ARRAY ;(DH)=104=40D=28H MOV DH,SIZE STR ;(DH)=11=1D=01H,例题:,汇编语言源程序的格式,32,课堂练习:P213-5,6,33,合成运算符(P168), PTR运算符。PTR运算符可以指定或修改存储器操作数的类型,例如: INC BYTE PTRBXSI INC WORD PTRBXSI THIS运算符。THIS运算符也可指定存储器操作数的类型。例如,要求对同一个数据区既可以字节为单位,又可以字为单位进行存取,则可用以下语句: TAB1 EQU THIS WORD ;EQU THIS的作用同LABLE TAB2 DB 100 DUP(?), SHORT运算符。SHORT运算符指定一个标号的类型为SHORT(短标号),即标号到引用该标号指令之间的距离在128+127个字节的范围内。如:JMP (SHORT) LOOPER,JMP NEAR PTR LOOPER,汇编语言源程序的格式,34,其他运算符 段超越运算符“:”。如: MOV AX,ES:DI 字节分离运算符LOW和HIGH。运算符LOW和HIGH分别得到一个数值或地址表达式的低位和高位字节。例如: STUFF EQU 0ABCDH MOV AH,HIGH STUFF ;(AH)0ABH MOV AL,LOW STUFF ;(AL)0CDH 注释。注释前面要求加上分号(;)。汇编程序对于注释不予理会,即注释对汇编后产生的目标程序没有任何影响。,汇编语言源程序的格式,图5.4 汇编语言程序上机过程,5.1.2 汇编语言程序的上机过程,36,在计算机上运行汇编语言程序的步骤是: (1) 用编辑程序(EDIT)建立ASM源程序文件。 (2) 用汇编程序(MASM或ASM)把ASM文件汇编成OBJ文件。 (3) 用连接程序(LINK)把OBJ文件转换成EXE文件。 (4) 用DEBUG调试程序检查可执行文件是否有逻辑或算法上的错误。 (5) 在DOS命令状态下直接键入文件名就可执行该文件。,汇编语言程序的上机过程,37,EXE程序的组成: 1、重定位信息:程序段前缀区PSP 2、装入模块:程序本身。,注:DS、ES指向PSP段地址。程 序中须重新设置,使其指向数 据段(和附加段)。如:,MOV AX,DATA MOV DS,AX,5.1.3 汇编语言和DOS操作系统的接口,当DOS装入或执行一个程序时,DOS确定当时主存最低的可用地址作为该程序的装入起始点。此点以下的区域称为程序段。在程序段内偏移0处,DOS为该程序建立一个程序段前缀控制块PSP(Program Segment Prefix),它占256(=100h)个字节;而在偏移100h处才装入程序本身. 另外,上图中,是指程序定位的初始情况,实际上程序中各段间的先后顺序是依程序的结构而定的。,38,1标准方法 首先将用户程序的主程序定义成一个FAR过程,其最后一条指令为RET。然后在代码段的主程序(即FAR过程)的开始部分用如下三条指令将PSP中INT 20H 指令的段地址及偏移地址压入堆栈: PUSH DS ;保护PSP段地址 MOV AX,0 ;保护偏移地址0 PUSH AX,39,MAIN PROC FAR ;主程序部分 START:PUSH DS ;将DS压入堆栈保存 MOV AX,0 PUSH AX ;将0压入堆栈保存 RET ;(IP)(SP)+1:(SP), (SP)(SP)+2 ;(CS)(SP)+1:(SP), (SP)(SP)+2 MAIN ENDP,. . .,分析(例):一程序如下,设初始化时,0B88:0000 INT 20H,DS,AX,IP,CS,SS,0000H,0B88H,40,2. 非标准方法 也可在用户的程序中不定义过程段,只在代码段结束之前(即CODE ENDS之前)增加两条语句: MOV AH,4CH INT 21H 则程序执行完后也会自动返回DOS状态。 3. 其它方法: 方法一: INT 20H ; 可放在任保指令位置. 方法二: MOV AH,0 INT 21H ;调用DOS的相应功能号,41,硬指令和伪指令,硬指令使CPU产生动作、并在程序执行时才处理的语句。 伪指令(Directive)不产生CPU动作、在程序执行前由汇编程序处理的说明性语句,例如,定义数据、分配存储区、定义段及定义过程等等。 伪指令与具体的处理器类型无关,但与汇编程序的版本有关,本课程采用微软宏汇编程序 MASM.EXE,5.2 伪指令语句,42,5.2.1数据定义伪指令 DB (Define Byte).每个操作数占1个字节. DW (Define Word).每个操作数占1个字. DD (Define Double word).每个操作数占2个字. DF 每个操作数占3个字. DQ 每个操作数占4个字. DT 每个操作数占5个字. 数据定义伪指令的一般格式为: 变量名 伪指令定义符 操作数,操作数 操作数:常数,表达式,字符串,?,汇编语言源程序的格式与伪指令,43,DATA DB 101,0F0H ;存入65H,F0H EXPR DB 2*8+7 ;存入17H STR DB WELCOME! ;存入8个字符的ASCII码值 AB DB AB ;存入41H,42H BA DW AB ;存入42H,41H ABDD DD AB ;存入42H,41H,00,00 OFFAB DW AB ;存入变量AB的偏移地址 ADRS DW STR,STR3,STR5 ;存入3个偏移地址 TOTAL DD DATA ;先存DATA的偏移地址,再存段地址,DATA,EXPR,STR,W E L C O M E !,AB,BA,注: (1)两个字符组成的字符串不能把整个字符串看作是一个操作数,也不能将串中的每一个字符都看成一个操作数,而要根据具体的伪指令定义符DB或DW而定。(2)当字符串中字符个数超过2个时只能用DB定义。,例题讲解,汇编语言源程序的格式与伪指令,44,下面是几个错误的数据定义伪指令语句: ERROR1: DW 99 ;变量名后有冒号 ERROR2 DB 25*90 ;DB的操作数超过255 ERROR3 DD 1234 ;DD的操作数是超过2个字 符的字符串,此时只能用DB定义。,45,思考题:分别分析下面的伪指令是否正确,为什么? 1、DATA1 DB -5 2、DATA2 DB 013BH 3、DATA3 DB ABCDEF 4、DATA4 DW ABCDEF 第1题是正确的,是将“-5”这个数对应的补码(FBH)送到以DATA1为偏移地址的存贮单无中去。 第2题是错误的,因为操作数(常数)为一个字超出了定义范围(DB)。 第3题是正确的。 第4题是错误的。,46,除了常数、表达式和字符串外,问号“?”也可以作为数据定义伪指令的操作数,此时仅给变量保留相应的存储单元,而不赋予变量某个确定的初值。 当同样的操作数重复多次时,可用重复操作符“DUP”表示,其形式为: n DUP(初值 ,初值,) 其中圆括号中为重复的内容,n为重复次数。如果用“n DUP(?) ”作为数据定义伪指令定义符的惟一操作数,则汇编程序产生一个相应的数据区,但不赋任何初值。重复操作符“DUP”可以嵌套。下面是用问号或“DUP”表示操作数的几个例子:,47,FILLER DB ? SUM DW ? DB ?,?,? BUFFER DB 10 DUP(?) ZERO DW 30 DUP(0) MASK DB 5 DUP(OK!) ARRAY DB 100 DUP(3 DUP(8),6),48,课堂练习 课本P213-1.(1),49,5.2.2符号定义伪指令 符号定义伪指令的用途是给一个符号重新命名,或定义新的类型属性等。符号包括汇编语言的变量名、标号名、过程名、寄存器名以及指令助记符等。 EQU 格式:名字 EQU 表达式 EQU伪指令将表达式的值赋予一个名字。以后可用这个名字来代替上述表达式。 例如:,CR EQU 0DH ;常数 LF EQU 0AH A EQU ASCII_TABLE ;变量 STR EQU 64*1024 ;数值表达式 ADR EQU ES:BP+DI+5 ;地址表达式 CBD EQU AAM ;指令助记符 注:EQU伪指令不允许对同一符号重复定义 ,即一个符号只能被定义一次。,汇编语言伪指令,50, =(等号) 格式:名字=表达式 = (等号)伪指令的功能与EQU伪指令基本相同,主要区别在于它可以对同一个名字重复定义。例如:,COUNT=100 MOV CX,COUNT ;(CX)100 COUNT = COUNT10 MOV BX,COUNT ;(BX)90,分析下面两组程序片段的正确与否。 (1). X=7 (2). X EQU 7 X=X+3 X EQU X+3,汇编语言伪指令,51,Partno dw ? Pname db 16 dup(?) Count dd ? Plenth equ $-partno,$地址计数器的值。在汇编程序对源程序汇编过程中,使用地址计数器来保存正在汇编的指令地址。 Plenth=2+16+4=22D=16H,表示正在汇编的指令的偏移地址和指定偏移地址之间所包含的字节数(偏移量)。,课本P207-2. 假设程序中的数据定义如下:,例 题 讲 解(1),问Plenth的值为多少?它表示什么意义?,汇编语言伪指令,52,Buff db 1,2,3,123 Ebuff db 0 L equ ebuff-buff,课本P207-3. 有符号定义语句如下:,L=ebuff-buff=6D=6H, 表示地址EBUFF和BUFF之间的差(偏移量)。,例 题 讲 解(2),问L的值是多少?,汇编语言伪指令,53,设某程序的DATA段的源程序如下,试画出汇编后其内存空间的分配情况.L=?。 DATA SEGMENT NUM DB 5,6,7 N EQU 18 X DD 0ABCH L EQU X-NUM DATA ENDS,例 题 讲 解(3),汇编语言伪指令,54, LABEL,格式:名字 LABEL 类型 LABEL伪指令的用途是定义标号或变量的类型。变量的类型可以是BYTE、WORD、DWORD等;标号的类型可以是NEAR或FAR。和下一条伪指令共享存储器单元。例如:,AGAINF LABEL FAR ;定义标号AGAINF的属性为FAR AGAIN: PUSH AX ;定义标号AGAIN的属性为NEAR,汇编语言伪指令,55,5.3.3 段定义伪指令 段定义伪指令的用途是在汇编语言源程序中定义逻辑段。 1SEGMENT/ENDS内 ;定义段的名称和范围 格式: 段名 SEGMENT 定位类型 组合类型 类别 段名 ENDS 注意:1).当用于定义数据段、附加数据段和堆栈段时,介于SEGMENT和ENDS中间的语句只能使用伪指令语句,不能使用指令语句;只有当用于定义代码段时,中间的语句才能是指令语句以及与指令有关的伪指令语句。 2).一个段一经定义其标号、变量等在段内的偏移地址就己排定,它们都在同一个段地址控制之下,整个段占用的存储空间大小也就确定了。 3).由SEGMENTENDS所定义的段小于64K单元。,汇编语言伪指令,56,1) 定位 (Align) 类型 定位类型任选项告诉汇编程序如何确定逻辑段的边界在存储器中的位置,也就是本段起始地址与前段的最后地址是如何相接的(即对接型参数)。定位类型共有以下四种: BYTE (边界起始地址= B,可从任意地址开始,无空隙,物理地址为H) 该类型表示逻辑段从一个字节的边界开始,即可以从任何地址开始。此时本段的起始地址可紧接在前一个段的后面。 WORD(边界起始地址= 0B,物理地址为0(2,4,6,8)H) 该类型表示逻辑段从字的边界开始。此时本段的起始地址必须是偶数。,汇编语言源程序伪指令,57, PARA(边界起始地址= 0 0 0 0B ,物理地址为0H) 该类型表示逻辑段从一个节(Paragraph)的边界开始(一节等于16个字节),也即段的起始地址能被16整除。如果省略定位类型任选项,则默认其为PARA。 PAGE(边界起始地址= 0 0 0 0 0 0 0 0B ,物理地址为00H) 该类型表示逻辑段从页边界开始(一页等于256个字节),也即段的起始地址能被256整除。故本段的起始地址(十六进制)应为00H。,汇编语言伪指令,58,例:设某计算机提供给下列源程序(开始段为数据段,紧跟的是代码段),数据段初始地址为:1409:0000,即:(DS)=1409H, 数据段开始偏移地址:0000H,结束偏移地址:0008H。回答下列问题: (1)若代码段的段定义伪指令为: CODE SEGMENT BYTE 则:(CS)= ,起始(IP)= 。 (2)若代码段的段定义伪指令为: CODE SEGMENT WORD 则:(CS)= ,起始(IP)= 。 (3)若代码段的段定义伪指令为: CODE SEGMENT PARA 则:(CS)= ,起始(IP)= 。 (4)若代码段的段定义伪指令为: CODE SEGMENT PAGE 则:(CS)= ,起始(IP)= 。,例题讲解,汇编语言源程序的格式与伪指令,59,START: MOV AX,(SEG) DATA MOV DS,AX ;初始化DS MOV CX,5 ;循环次数送CX MOV SI,0 ;置SI初值为0 CLC ;清CF标志 LOOPER: MOV AL,(OFFSET) DATA2SI ;取一个字节加数 ADC (OFFSET) DATA1SI,AL ;与被加数相加,INC SI ;SI加1 DEC CX ;CX减1 JNZ LOOPER ;若不等于0,转LOOPER MOV AH,4CH INT 21H ;返回DOS CODE ENDS ;代码段结束 END START ;源程序结束,DATA SEGMENT ;定义数据段 1409:0000 DATA1 DB 0F8H,60H,0ACH,74H,3BH ;被加数 DATA2 DB 0C1H,36H,9EH,0D5H,20H ;加数 DATA ENDS (1409:0009);数据段结束 CODE SEGMENT BYTE ;定义代码段 ASSUME CS:CODE,DS:DATA,汇编语言源程序的格式与伪指令,60,2) 组合(Combine)类型 :指定与其它模块的同名段(逻辑段)连接的方式 ,即要不要合并成一个逻辑段(共用一个段地址)等. 同段名的段的组合问题。 (1) 不组合(PRIVATE):如果SEGMENT伪指令的组合类型任选项缺省,则汇编程序认为这个逻辑段是不组合的。不同程序(模块)中的同名段(逻辑段),不进行组合,即分别作为不同的逻辑段装入内存。同一个程序模块的同名逻辑段则被集中成为一个逻辑段。 (2) PUBLIC:同名段连接成一个物理段。 (3) COMMON:同名段重叠在一起形成一个物理段。 (4) STACK:各堆栈段紧接着组成一个堆栈物理段。同PUBLIC,仅限用于堆栈段. (5) MEMORY:对其它同名逻辑段来说,该同名逻辑段装在最高地址处。 (6) AT:指定段地址,但不能指定代码段。默认偏移地址为0000H。如: data SEGMENT at 13f5h data1 DB 0f8h,60h,0ach,74h,3bh data2 DB 0c1h,36h,9eh,0d5h,20h data ENDS,汇编语言源程序的格式与伪指令,61,有关各逻辑段在内存中地址分配的讨论(一个模块的情况) 1.根据源程序中各逻辑段的先后顺序,依次分配内存空间。 2.最前面逻辑段地址的确定原则: 1).若段定义伪指令后的组合类型为AT H(不能用在代码段中)则该源程序最前面逻辑段的段地址即为H,偏移地址默认为0000H。 2).若段定义伪指令后的组合类型没有指定具体的段地址,则该源程序最前面逻辑段的段地址由DOS系统决定(由系统的硬件、软件及当前计算机执行的软件所占用的内存情况决定),一般取当前计算机可用的最低段地址,偏移地址默认为0000H。 注:最前面逻辑段从偏移地址为0000H开始的256B放的是该源程序的程序前缀区PSP文件。偏移地址默认为0000H,除非用ORG伪指令另外定义。 3.后续段按该段定义伪指令后的定位类型依次分配。,62,3) 类别(Class) SEGMENT伪指令的第三个任选项是 类别 ,类别必须放在单引号内。类别 的作用是在连接时决定各逻辑段(不同的段名)的装入顺序。基本原则: (1)、类别名不同时,按在源程序中出现的先后顺序装入。 (2)、类别名相同的逻辑段,按出现的先后顺序装入连续(相邻)的内存区。 (3)、没有类别名的逻辑段,与其他无类别名的逻辑段一起连续装入内存。,汇编语言源程序的格式与伪指令,图5.3 逻辑段按类别装入内存的示意图,汇编语言源程序的格式与伪指令,64,2. ASSUME 格式: ASSUME 段寄存器名:段名,段寄存器名:段名, 指明所定义的段与段寄存器的对应关系。必须放在代码段中可执行程序开始位置的前面。 注:ASSUME伪指令只是通知汇编程序有关段寄存器与逻辑段的关系,并没有给段寄存器赋予实际的初值。因此必须给对应的段寄存器(CS、SS除外)赋值。例如:,CODE SEGMENT ASSUME CS:CODE,DS:DATA1,SS:STACK MOV AX,DATA1 MOV DS,AX ;给DS赋值 MOV AX,STACK MOV SS,AX ;给SS赋值 CODE ENDS,汇编语言源程序的格式与伪指令,65,3.定位(对准)伪指令 格式: ORG 常数表达式 作用:指明ORG语句后的指令(包括伪指令)的起始地址(偏移地址)。 例如: ORG 0100H VEAT1 DB 12H,34H,56H,78H,汇编语言源程序的格式与伪指令,66,5.3.4 过程定义伪指令 过程也就是子程序,所以过程定义伪指令也就是子程序定义伪指令。过程中必须至少有一个返回指令RET。 格式: 过程名 PROC NEAR/FAR RET 过程名 ENDP 调用一个过程的格式为:CALL 过程名 注意:若调用程序和子程序(被调用程序)在同一段内,则子程序可不定义成过程,也可以直接调用。,汇编语言源程序的格式与伪指令,67,常用的延时子程序A DELAY1:MOV CX,0030H ABC1: CALL DALAY2 LOOP ABC1 RET DELAY2:PUSH CX MOV CX,8000H ABC2: NOP NOP LOOP ABC2 POP CX RET,常用的延时子程序B DELAY1:MOV CX,0030H ABC1: CALL DALAY2 LOOP ABC1 RET DELAY2:MOV DX,8000H ABC2: NOP NOP DEC DX JNZ ABC2 RET,调用:CALL DELAY2(短时间)或者CALL DELAY1(较长时间),汇编语言源程序的格式与伪指令,68,5.3.5 模块定义与连接伪指令 在编写规模比较大的汇编语言程序时,可以将整个程序划分成为几个独立的源程序(或称模块),然后将各个模块分别进行汇编,生成各自的目标程序 (多个.obj),最后将它们连接成为一个完整的可执行程序(.exe)。各个模块之间可以相互进行符号访问。也就是说,在一个模块中定义的符号可以被另一个模块引用。通常称这类符号为外部符号,而将那些在一个模块中定义,只在同一模块中引用的符号称为局部符号。 为了进行连接以及在这些将要连接在一起的模块之间实现互相的符号访问,以便进行变量传送,常常使用以下几个伪指令:NAME、END、PUBLIC和EXTRN。,汇编语言源程序的格式与伪指令,69,1. NAME 格式:NAME 模块名 NAME伪指令用于给源程序汇编以后得到的目标程序指定一个模块名,连接时需要使用这个目标程序的模块名。 2.END 格式: END 标号 END伪指令用来表明END语句处是源程序的终结。在以后的汇编中,告诉汇编程序只将END语句之前的源程序进行汇编。 END伪指令后面的标号表示程序执行的开始地址。END伪指令将标号的段地址和偏移地址分别提供给CS和IP寄存器。 比较:END 和 HLT指令,汇编程序和CPU分别如何对待这两条指令。,汇编语言源程序的格式与伪指令,70,3. PUBLIC (用在被调用模块中) 格式为:PUBLIC 符号, 指明本模块定义的可供其它模块调用的符号,符号可以为标号、变量或过程名。PUBLIC伪指令可以安排在源程序的任何地方。 4.EXTRN (用在调用模块中) 格式为:EXTRN 名字:类型, EXTRN伪指令指明本模块中的哪些符号是由其它模块定义的。变量的类型可以是BYTE、WORD或DWORD等;标号和过程的类型可以是NEAR或FAR。 Public var1,lab1,var4 Extrn var1:byte,var4:word,汇编语言源程序的格式与伪指令,71,Name module1 Extrn var2:word,lab2:far Public var1,lab1,var4 Data1 segment var1 db ? var4 dw ? Lab1:mov ax,bx,. . .,. . .,Name module2 Extrn var1:byte,var4:word Public va2,lab2 Data1 segment var2 dw ? var3 db 5 Lab2:mov al,cl,. . .,. . .,由两个模块构成一个程序:,由masm.exe生成module1.obj,由masm.exe生成module2.obj,由link.exe: link module1.obj + module2.obj 最后生成一个完整可执行文件如: aaa.exe,例题讲解,汇编语言源程序的格式与伪指令,72,.8086 选择8086指令系统 .286 选择80286指令系统 .286 P 选择保护方式下的80286指令系统 .386 选择80386指令系统 .386 P 选择保护方式下的80386指令系统 .486 选择80486指令系统 .486 P 选择保护方式下的80486指令系统 .586 选择Pentium指令系统 .586 P 选择保护方式下的Pentium指令系统,5.2.6 处理器选择伪指令,有关“选择保护方式下的指令系统”的含义是指包括特权指令在内的指令系统。此外,上述伪指令均支持相应的协处理器指令。 这类伪指令一般放在整个程序的最前面。如不给出,则汇编程序认为其默认值为 .8086。它们也可放在程序中,如程序中使用了一条80486所增加的指令,则可在该指令的上一行加上.486。,73,5.4 宏 指 令 语 句,格式:宏指令名 MACRO 形参1,形参2 (宏定义体) ENDM,宏指令语句,1宏指令、宏定义及宏调用 (1)宏指令:用户定义的,由指令系统中指令组成的新指令,先定义后调用,与使用其他指令一样方便。主要作用是避免重复书写。,说明:宏指令名是必需的,起名规则与标号相同,供调用。 宏定义体由一系列完成某功能的指令构成,以ENDM结束。 形参可有可无,多个形参间以“,分隔,参数个数不限,总字符数小于等于132(调用时以实参代替)。,74,例5.3 若源程序中多处需要将BL和CL寄存器中两个压缩的BCD数相加,并将和送回BL寄存器,则可如下定义宏指令,然后在需要的地方进行调用。 BCDADD MACRO MOV AL,BL ADD AL,CL DAA MOV BL,AL ENDM,宏指令语句,75,(2)宏调用:其格式为: 宏指令名 实参1,实参2 注意:实参顺序与形参对应按顺序结合。 若实参个数大于形参个数,则多余的实参忽略不计;若实参个数小于形参个数,则多余形参变为空(即消失不存在)。 (3)宏展开:汇编过程中若遇到宏定义语句,则以宏定义中的宏体代替宏调用语句。 2宏嵌套 宏定义中允许使用宏调用,但所调用的宏指令必须先经定义。不仅如此,宏定义中还可以包含宏定义。,宏指令语句,76,例5.4 DECADD1 MACRO OPR1,OPR2 MOV AL,OPR1 ADD AL,OPR2 DAA MOV OPR1,AL ENDM,宏指令语句,宏调用:DECADD1 DL,BUFFER 扩展为: MOV AL,DL ADD AL,BUFFER DAA MOV DL,AL,宏调用:DECADD1 AREA1,AREA2 扩展为: MOV AL,AREA1 ADD AL,AREA2 DAA MOV AREA1,AL,77,3宏定义中的标号与变量 在宏定义中的标号与变量,当多次宏调用、宏展开后程序中会出现多个相同的变量和标号,可用LOCAL解决此类问题。 在宏定义中使用伪指令LOCAL定义的局部变量标号,在汇编时将对它们赋以新的编号以避免重复。 格式: LOCAL 参数表 说明:参数表为宏体中所用到的标号变量。 LOCAL应为宏体中的第一个语句。 汇编时,汇编程序将依次?0000、?0001、?0002等来代替程序中的各个标号。,宏指令语句,78,HEXTOASC MACRO REG LOCAL NUM CMP REG,0AH JC NUM ADD REG,07H NUM: ADD REG,30H ENDM,例 题,4宏指令与子程序 相同点:多次使用、调用方便。 不同点:宏指令实际上是一种伪指令,是由宏汇编程序在汇编过程中,在宏定义处将宏体插入,而子程序是CPU指令(供CALL指令调用);子程序节省内存空间,宏指令则不节省
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论