590 likes | 786 Vues
第 4 章 汇编语言程序格式. 4.1 汇编程序功能 ⒈汇编语言程序的开发过程 ⒉ 汇编程序 属于系统软件 ⒊汇编语言源程序的基本组成单位: 语句 ⒋汇编语言源程序中的三种语句: 指令语句 伪指令语句 宏指令语句. 汇编程序 如 MASM. 连接程序 如 LINK. 汇编语言源程序 .ASM. 可执行程序 .EXE. 目标程序 .OBJ. 调试程序 如 DEBUG. 调试和运行程序. 汇编语言程序的开发过程. 2. 汇编程序的主要功能 检查源程序,给出出错信息。 产生目标文件 ( .obj ) 和列表文件 ( .lst ) 。
E N D
第4章 汇编语言程序格式 4.1汇编程序功能 ⒈汇编语言程序的开发过程 ⒉汇编程序属于系统软件 ⒊汇编语言源程序的基本组成单位:语句 ⒋汇编语言源程序中的三种语句: • 指令语句 • 伪指令语句 • 宏指令语句
汇编程序 如MASM 连接程序 如LINK 汇编语言源程序 .ASM 可执行程序 .EXE 目标程序 .OBJ 调试程序 如DEBUG 调试和运行程序 汇编语言程序的开发过程
2. 汇编程序的主要功能 • 检查源程序,给出出错信息。 • 产生目标文件(.obj)和列表文件(.lst)。 • 展开宏指令。
4.2伪操作 伪操作:又称为伪指令是汇编程序对源程序进行汇编时处理的操作,完成处理器选择、存储模式定义、数据定义、存储器分配、指示程序开始结束等功能。 伪操作的种类有如下几种: • 处理器选择伪操作 • 段定义伪操作 • 程序开始和结束伪操作 • 数据定义及存储器分配伪操作 • 表达式赋值伪操作 • 地址计数器与对准伪操作 • 基数控制伪操作
4.2.1处理器选择伪操作 由于80X86的所有处理器都支持8086/8088指令系统,但每一种高档的机器的机型又都增加一些新的指令,因此在编写程序的时候要告诉汇编程序应该选择哪一种指令系统。 .8086 选择 8086 指令系统 .286 选择 80286 指令系统 .286P 选择保护模式下的 80286 指令系统 .386 选择 80386 指令系统 .386P 选择保护模式下的 80386 指令系统 .486 选择 80486 指令系统 .486P 选择保护模式下的 80486 指令系统 .586 选择 Pentium 指令系统 .586P 选择保护模式下的 Pentium 指令系统 • 这类伪操作一般放在整个程序的最前面。如不给出,则汇编程序认为其默认值为.8086,使用时在类型前加一“.”号。
4.2.2段定义伪操作 1.段定义伪操作:把标号和变量(代码段和数据段的符号地址) 的偏移地址通过目标模块传送给连接程序,以便连接程序把不 同的段和模块连接在一起,形成一个可执行程序。 2.ASSUME伪操作:指明段和段寄存器之间的关系。 格式:段名 SEGMENT [定位类型,组合类型,使用类型,类别] …… 段名 ENDS 格式:ASSUME 段寄存器:段名,……,段寄存器:段名 ASSUME NOTHING: 可取消前面由ASSUME所指定的段寄存器
DS ES 文件头 PSP SS CS 装入模块 EXE程序的内存映象图 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 例4.1
(1)定位类型(align_type) 功能:说明段的起始地址应有怎样的边界值。 BYTE:该段可以从任意地址开始,起始偏移地址可能不是0 WORD:该段必须从字的边界开始,即段起始地址必须为偶数 DWORD:该段必须从双字的边界开始,即段起始地址的最低 十六进制数位必须为4的倍数。 PARA:指定段的起始地址必须从小段边界开始,即段起始地 址的最低的16进制数位必须为0。偏移地址可从0开始 PAGE:该段必须从页的边界开始,段起始地址的最低两个16 进制数位必须为0(该地址能被256整除)。 定位类型的默认项为PARA。
(2)组合类型(combine_type) 功能:说明程序连接时的段合并方法。 PRIVATE:(私有段),连接时不与其他模块中的同名分段合并(默认的组合类型) PUBIC:可把不同模块中的同名段相连接形成一个段,连接次序由命令决定。 COMMON:可把不同模块中的同名段重叠而形成一个段,由于各同名分段有相同的起始地址,所以产生覆盖。连接的长度为各分段的最大长度。 MEMORY:与PUBIC同义。 STACK:把不同模块中的同名段组合而形成一个堆栈段,段长为各段长度的总和。
(3)使用类型(use_type) 功能:说明使用16位寻址方式还是32位寻址方式 类型 寻址方式 段长 段地址 偏移地址 USE16 16位 不超过64KB 16位 16位 USE32 32位 可达到4GB 16位 32位 (4)类别(‘class’):在引号中给出连接时组成段组的类型名。类别说明并不能把相同类别的段合并起来,但在连接后形成的装入模块中,可以把它们的位置靠在一起。
2.存储模型与简化段定义伪操作 1)MODEL伪操作: 格式:. MODEL 存储模型 [,模型属性] 七种存储模型:TINY、SMALL、MEDIUM、COMPACT、LARGE、 HUG、FLAT 三种模型属性选项:高级语言接口选项 操作系统选项 堆栈距离选项:NEARSTACK、FARSTACK 2)简化的段定义伪操作:参考书122页 3)段组定义伪操作: 格式:段组名 GROUP 段名[,段名] 汇编语言自动的把各数据段组成一个段组DGROUP,以便程序在访问各数据段时使用一个数据段寄存器(DS)。
4.2.3程序开始和结束伪操作 1)NAME伪操作格式: NAME 模块名 功能:定义模块名 2)TITLE伪操作格式:TITLE TEXT 功能:TITLE可指定列表文件的每一页的标题。 若无NAME伪操作,则汇编语言用TEXT中的前六个字符作为模块名。 若既无NAME伪操作又无TITLE伪操作,则用源文件名作为模块名。 3)END伪操作格式:END [程序首地址标号] 功能:表示源程序结束 如果多个程序模块相连接,则只有主程序要使用标号,其它子模块则只用END不用标号。 4)STARTUP伪操作格式:STARTUP 功能:用来定义程序的初始入口点,并且产生设置DS,SS和SP的代码。如果程序中使用了.startup,则END伪操作中不必再指定程序的入口点标号。 5)EXIT伪操作格式:EXIT [ return_value ] 功能:用来产生退出程序并返回操作系统的代码。
4.2.4数据定义及存储器分配伪操作 格式:[变量] 助记符 操作数[,操作数,…] [;注释] 变量:用符号地址表示(与指令语句前的标号作用相同),它可有可无。 注释:字段用来说明该伪操作的功能,它也是可有可无的。 助记符:DB DW DD DF DQ DT 这些助记符可把跟在其后的数据存入指定的存储单元中,形成初始化数据;或者只分配存储空间而并不存入确定的数据,形成未初始化数据。DW和DD伪操作还可存储地址,DF伪操作则可存储由16位段地址及32位偏移地址组成的远地址指针。 DB:定义字节,其后的每个操作数都占有一个字节。 DW:定义字,其后的每个操作数都占有一个字,存储偏移地址 DD:定义双字,其后的每个操作数都占有两个字,存储整个地址(16偏移地址+16段地址) DF:定义6个字节的字,每个操作数都占有48位,存放远地址。 DQ:定义4个字,每个操作数都占有4个字,存放双精度浮点数。 DT:定义10个字节,其后的每个操作数都占有10个字节,形成压缩的BCD码。存储整个地址(32偏移地址+16段地址)
数据定义伪指令 数据定义伪指令中的表达式的四种形式: ①数值表达式 ②字符表达式 ③?表达式 ④带DUP表达式
DATA_BYTE DATA_WORD 100d 100h -5 FFH 04H 10H - 64H 00H 00H 01H FBH 3c 00 FD 00 00 FF 00 00 0AH DATA_DW 60d 0FFFDH 数据定义伪指令中的表达式是数值表达式 10d 4 10h ? • 例4.7操作数可以是常数,或者是表达式 DATA_BYTE DB 10,4,10H,? DATA_WORD DW 100,100H,-5,? DATA_DW DD 3*20,0FFFDH
数据定义伪指令中的表达式是数值表达式 偏移地址 主存 ①数值表达式 DATA1 SEGMENT VAR1 DB 10,10H VAR2 DW 1234H VAR3 DD 12345678H DATA1 ENDS 00000H VAR1 0AH 字节 10H VAR2 34H ARY[0] 字 12H VAR3 78H ARY[0] 56H 双字 34H 12H FFFFFH
48H 45H 4CH 4CH 4FH 41H 42H 42H 41H 数据定义伪指令中的表达式是字符表达式 例4.8操作数是字符串 ARRAY DB ‘HELLO’ DB ‘AB’ DW ‘AB’ H E L L O ARRAY A B B A
数据定义伪指令中的表达式是字符表达式 偏移地址 主存 DATA2 SEGMENT STRING1 DB ’AB’ STRING2 DW ’AB’ STRING3 DD ’AB’ DATA2 ENDS 00000H … STRING1 41H 字节 42H 42H STRING2 ARY[0] 字 41H STRING3 42H ARY[0] 41H 双字 00H ARY[0] 00H … FFFFFH 存储器分配示意图
数据定义伪指令注意 1 、在DB伪指令中,字符串的每一个字符分配一个字节单元并以ASCII码形式存放,字符串从左到右依次存放。其长度不超过255个字符。 2 、在DW伪指令中,每一个字符串表达式只能由1~2个字符组成,为每个字符串分配两个字节单元并以ASCII码形式存放,字符串从右到左依次存放。 3 、在DD伪指令中,每一个字符串表达式只能由1~2个字符组成,为每个字符串分配四个字节单元并以ASCII码形式存放,字符串从右到左依次存放,两个高字节单元中存放00H。
数据定义伪指令中的表达式是字符表达式 主存 偏移地址 00000H … STRING1DB ’ABC’ STRING2DW ’AB’,’CD’ 问: ①这两条数据定义伪指令如何分配存储空间 ②STRING2+2访问的是存储单元的内容是多少? STRING1 41H 字节 42H 43H 42H STRING2 ARY[0] 字 41H 44H STRING2+2 ARY[0] 字 43H … FFFFFH 存储器分配示意图
数据定义伪指令中的表达式是字符表达式 偏移地址 主存 00000H … STRING2 DD ’A’ 41H STRING2 00H 双字 00H ARY[0] 00H … FFFFFH 存储器分配示意图
数据定义伪指令中的表达式是?表达式 偏移地址 主存 00000H … ③ ?表达式 只分配存储单元,不赋初值。 举例: VAR_A DB ?,? VAR_B DW ? VAR_C DD ? VAR_A 00H 字节 00H 00H VAR_B ARY[0] 字 00H VAR_C 00H ARY[0] 00H 双字 00H 00H … FFFFFH 存储器分配示意图
数据定义伪指令中的表达式是带DUP表达式 ④带DUP表达式 为连续的存储单元提供重复数据。 格式: 表达式1是重复次数,表达式2是重复数据的内容 DB 表达式1 DUP (表达式2) 变量名 DW DD
数据定义伪指令中的表达式是带DUP表达式 偏移地址 主存 00000H … 例: ARYB1 DB 10H DUP(2) ARYB1 02H 02H ARY[0] 重复10H次,共10H个字节 ARY[0] … ARY[0] 02H … FFFFFH 存储器分配示意图
数据定义伪指令中的表达式是带DUP表达式 ARYB2 DB 20H DUP(’ABC’) 设ARYB2在数据段,其偏移地址是0010H, 问: ①该数据定义伪指令如何分配存储空间 ②ARYB2+4访问的是哪个存储单元,其内容是多少? ③ARYB2+59访问的是哪个存储单元,其内容是多少? ④ARYB2+60访问的是哪个存储单元,其内容是多少? ARYB2+60H访问的是哪个存储单元,其内容是多少?
数据定义伪指令中的表达式是带DUP表达式 偏移地址 主存 00000H … ARYB2 DB 20H DUP (’ABC’) 0010H ARYB2 41H 42H 43H 41H 0014H 42H 重复20H次,共60H个字节 43H … 41H 42H 43H 0070H ARYB2+60H … FFFFFH 存储器分配示意图
数据定义伪指令中的表达式是带DUP表达式 偏移地址 主存 00000H … ARYB2 DB 20H DUP (’ABC’) EA=ARYB2+4内容42H EA=ARYB2+59内容43H EA=ARYB2+60内容41H EA=ARYB2+60H内容不确定 0010H ARYB2 41H 42H 43H 41H 0014H 42H 重复20H次,共60H个字节 43H … 41H 42H 43H 0070H ARYB2+60H … FFFFFH 存储器分配示意图
数据定义伪指令举例2 S1 DB ’ IBM PC’ DB 0AH,0DH 问: ①这两条数据定义伪指令如何分配存储空间 ②S1+2访问的是存储单元的内容是多少? ③ MOV AH,S1+5 MOV AL,S1+6 MOV BH,S1+7 (假设数据是在数据段中。) 指令执行后AX的内容是多少?BH的内容是多少?
数据定义伪指令举例2 偏移地址 主存 00000H … S1 DB ’IBM PC’ DB 0AH,0DH S1 49H 42H S1+1 4DH S1+2 共6个字节 20H S1+3 S1+4 50H 43H S1+5 … 0AH S1+6 共2个字节 0DH S1+7 … FFFFFH 存储器分配示意图
数据定义伪指令举例3 VAR5 DB 15H DUP( 3,3 DUP(2)) 问: ①这条数据定义伪指令如何分配存储空间 ②VAR5+6访问的存储单元的内容是多少? 重复次数 重复次数
数据定义伪指令举例3 偏移地址 主存 00000H … VAR5 DB 15H DUP( 3, 3 DUP(2)) VAR5 03H 02H 02H 共3个字节 02H 重复15H次,共54H个 字节 03H 02H VAR5+6 … 02H 02H … 02H … FFFFFH 存储器分配示意图
数据定义伪指令举例4 VAR6 DB 2H DUP( 1 ,3 DUP(3),’AB’) 问: ①这条数据定义伪指令如何分配存储空间 ②VAR6+6访问的存储单元的内容是多少?
数据定义伪指令举例4 主存 偏移地址 00000H … VAR6 DB 2H DUP( 1, 3 DUP (3), ’AB’) VAR6 01H 03H 共3个字节 03H 03H 重复2H 次,共12个字节 41H 42H … 01H VAR6+6 03H … 42H … FFFFFH 存储器分配示意图
数据定义伪指令举例4 主存 00000H … VAR6 DB 2H DUP( 1, 3 DUP(3), ’AB’) VAR6 01H 03H 共3个字节 03H 03H 重复2H 次,共12个字节 41H 42H … 01H 03H VAR6+6访问的存储单元的内容是01H … 42H … FFFFFH 存储器分配示意图
01 OPER1 02 OPER2 34 12 78 56 例: OPER1 DB ?, ? OPER2 DW ?, ? … MOV OPER1, 0 ; 字节指令 MOV OPER2, 0 ; 字指令 例: OPER1 DB 1, 2 OPER2 DW 1234H, 5678H … MOV AX, OPER1+1 × MOV AL, OPER2 × 类型不匹配 MOV AX, WORD PTR OPER1+1 MOV AL, BYTE PTR OPER2 (AX)=3402H (AL)=34H
PTR属性操作符:可指定操作数的类型属性,它优先于隐含的类型属性。PTR属性操作符:可指定操作数的类型属性,它优先于隐含的类型属性。 格式:TYPE PTR 变量表达式 (同一个变量可使用不同的类型属性) TYPE:BYTE、WORD、DWORD、FWORD、QWORD、TBYTE LABEL伪操作:也可用来指定操作数的类型属性。 格式:NAME LABEL TYPE 对于数据项:NAME:变量 TYPE: BYTE、WORD、DWORD、FWORD、 QWORD、TBYTE 对于可执行代码:NAME:标号 TYPE:NEAR、FAR 对于16/32位段,NEAR为2/4字节,FAR为4/6字节
BYTE_ARRAY WORD_ARRAY 作用:100个字节的数组中的第一个字节的地址分别有两个不同的类型的变量名。 例4.16: BYTE_ARRAY LABEL BYTE WORD_ARRAY DW 50 DUP (?) MOV WORD _ARRAY+2, 0 功能:把该数组中的第3和第4个字节置0 MOV BYTE_ARRAY+2, 0 功能:把该数组中的第3个字节置0
4.2.5表达式赋值伪操作EQU • 格式:表达式名 EQU 表达式 用途:用符号来表示常量或数据表达式;用符号表示字符串;重新定义关键字或助记符。 CONSTANT EQU 256 ALPHA EQU 7 BETA EQU ALPHA-2 HELLO EQU ‘HOW ARE YOU!’ MOVE EQU MOV COUNT EQU CX “=”伪操作的格式:变量=表达式 … EMP=7 … EMP=EMP+1 … 注意:EQU伪操作中的表达式不允许重复定义,而=伪操作允许重复定义。
ARRAY 01 0074 00 02 00 7C 0078 00 03 00 04 00 82 007E 00 4.2.6地址计数器与对准伪操作 • 1.地址计数器$ • 功能:保存当前正在汇编的指令的偏移地址 例: ($ 用在指令中,表示本指令的第一个字节的地址) JNE $+6 ; 转向地址是JNE的首址+6 例:$用在伪操作的参数字段——表示地址计数器的当前值 例4.17 ARRAY DW 1, 2 , $+4 , 3 , 4 , $+4 0078+4 007E+4
2. ORG伪操作 • 作用:设置当前地址计数器中的值。 • 格式:ORG 常数表达式 • 如常数表达式的值为n,则ORG伪操作可以使下一个字节的地址成为常数表达式的值n. 例:ORG 100H START: …... (START的偏移地址是100H) 例如: SEG1 SEGMENT ORG 10 VAR1 DW 1234H ORG 20 VAR2 DW 5678H ORG $+8 VAR3 DW 1357H SEG1 ENDS 则VAR1的偏移地址值为0AH,而VAR2的偏移地址值为14H BUFFER LABEL BYTE ORG $+8 其功能相当于:BUFFER DB 8 DUP (?)
3.EVEN伪操作 功能:使下一个变量或指令开始于偶数字节地址 格式: EVEN ;使下一地址从偶地址开始 A DB ‘morning’ EVEN B DW 2 DUP (?) • 4. ALIGN伪操作 功能:可以保证双字数组边界从4的倍数开始。 格式: ALIGNBOUNDARY (其中BOUNDARY必须是2的幂) 例如: ALIGN 4 ARRAY DB 100 DUP(?) … 就可保证ARRAY的值为4的倍数。 ALIGN 2 和 EVEN 是等价的。
4.2.7基数控制伪操作 功能:把默认的基数改变为2~16范围内的任何基数。 格式:.RADIX 表达式 (2,8,10,16) ;规定无标记数的基数 (表达式用十进制数表示) 例:.RADIX 16 MOV BX, 0FF MOV BX, 178D MOV BX, 0FFH MOV BX, 178 注意:某个十六进制数的末字符为D,后应加H。
4.3汇编语言程序格式 源程序的每条语句可由4项组成,格式如下为: [符号地址] 操作操作数[; 注释] 变量 指令寄存器 说明程序或语句 标号 伪指令标号 的功能 名字 宏指令变量 常数 表达式 表达式:是常数、寄存器、标号/变量、与一些操作符相结合的序列,也可以是数字表达式、 地址表达式
4.3.1名字项 标识符(变量/标号)的组成: 字母 A ~ Z 数字 0 ~ 9 专用字符 ? .@ — $ 注意:★ 除数字外,所有字符都可放在源语句的第一个位置。 ★ 如果有 . 必须是第一个字符。 ★ 一个程序中,每个标识符的定义是唯一的,还不能是汇编语言采用的保留字 变量和标号:所有的变量和标号都有三种属性 段值(SEG):定义变量/标号的段起始地址 偏移量(OFFSET):段起始地址到定义变量/标号的位置间的字节数 类型(TYPE):变量(字节/字/双字/六字节/四字/十字节) 标号(NEAR / FAR)
保留字(Reserved Word)是汇编程序已经利用的标识符 主要有: ★ 硬指令助记符——例如:MOV、ADD ★ 伪指令助记符——例如:DB、EQU ★ 操作符——例如:OFFSET、PTR ★ 寄存器名——例如:AX、CS ★ 预定义符号——例如:@data • 汇编语言大小写不敏感
4.3.2操作项 • 操作项:可以是指令、伪操作或宏指令的助记符。 指令,汇编程序将其翻译为机器语言指令。 伪操作,汇编程序将根据其所要求的功能进行处理。 宏指令,则将根据其定义展开。 • 4.3.3操作数项 • 操作数项由一个或多个表达式组成,多个操作数项之间一般用逗号分开。对于指令,操作数项一般给出操作数地址,它们可能有一个或两个,或三个,或一个也没有。对于伪操作或宏指令,则给出它们所要求的参数。 • 操作数项可以是常数、寄存器、标号、变量或表达式组成。表达式是常数、寄存器、标号、变量与一些操作符相组合的序列,可以有数字表达式和地址表达式两种。
汇编 AND AX, 1 (1)算术操作符: , , , , mod 例: ADD AX, A+2 ; 符号地址常数有意义 (2)逻辑操作符:AND, OR, XOR, NOT 移位操作符:SHL SHR 例: OPR1 EQU 25;00011001B OPR2 EQU 7;00000111B …… AND AX, OPR1 AND OPR2
(3)关系操作符:EQ(相等), NE (不等), LT (小于), LE (小于或等于), GT (大于), GE (大于或等于) 计算结果为逻辑值:真 0FFFFH 假 0000H 例:MOV FID, (OFFSET Y - OFFSET X) LE 128 X: …… …… Y: …… 若128(真0FFFFH) 汇编结果 MOV FID, -1 若128(假0) 汇编结果 MOV FID, 0
(4)数值回送操作符: OFFSET / SEG变量(或标号) 功能:回送变量或标号的偏址 / 段址 例:MOV BX, OFFSET X MOV DX, SEG X TYPE变量(或标号) 变量:DB DW DD DF DQ DT 标号:NEAR FAR 值: 1 2 4 6 8 10 -1 -2 LENGTH变量 功能:回送由DUP定义的变量的单元数(重复次数), 其它情况回送1。若用到了嵌套,返回最外层的重复次数。 SIZE 变量 功能:LENGTH*TYPE,回送分配给变量的字节数。
例:ARRAY DW 100 DUP (?) TABLE DB ‘ABCD’ ADD SI, TYPE ARRAY ; ADD SI, 2 ADD SI, TYPE TABLE ; ADD SI, 1 MOV CX, LENGTH ARRAY ; MOV CX, 100 MOV CX, LENGTH TABLE ; MOV CX, 1 MOV CX, SIZE ARRAY ; MOV CX, 200 MOV CX, SIZE TABLE ; MOV CX, 1