《80x86汇编语言程序设计》教案及答案 下载本文

内容发布更新时间 : 2024/9/14 5:53:08星期一 下面是文章的全部内容请认真阅读。

(IP)←(EA)

或(EIP)←(EA) AND 0000FFFFH

当操作数长度为32位时,Push (EIP)

(EIP)←(EA)

说 明:指令中DST为除立即数以外的任一种寻址方式,由指定的寄存器或存储单元的内

容给出转向地址。

3). 段间直接远调用:指令的操作数是一个远过程,该过程在另一个代码段内。 指令格式:CALL DST

执行操作:当操作数长度为16位时,Push (CS)

Push (IP)

(IP)←DST指定的偏移地址 (CS)←DST指定的段地址

当操作数长度为32位时,Push (CS)

Push (EIP)

(EIP)←DST指定的偏移地址 (CS)←DST指定的段地址

4). 段间间接远调用:指令的操作数是一个存储器地址。 指令格式:CALL DST

执行操作:当操作数长度为16位时,Push (CS)

Push (IP) (IP)←(EA) (CS)←(EA+2)

当操作数长度为32位时,Push (CS)

Push (EIP) (EIP)←(EA) (CS)←(EA+4)

说 明:指令中DST为任一种存储器寻址方式,由指定的存储单元的内容给出转向地址。

(2). RET——子程序(过程)返回指令

RET指令放在子程序的末尾,它使子程序在功能完成后返回调用程序继续执行,而返回地址是调用程序调用子程序(或称转子)时存放在堆栈中的,因此RET指令的操作是返回地址出栈送IP或EIP寄存器(段内或段间)和CS寄存器(段间)。

1). 段内近返回

指令格式:RET ;DEBUG反汇编为RET,机器码为C3H 执行操作:当操作数长度为16位时,(IP)←Pop ( )

386及其后继机型:(EIP)←(EIP) AND 0000FFFFH 当操作数长度为32位时,(EIP)←Pop ( )

2). 段内带立即数近返回 指令格式:RET EXP ;DEBUG反汇编为RET n,机器码为C2 xxxxH 执行操作:在完成与1)的RET完全相同的操作后,还需要修改堆栈指针:

(SP或ESP)←(SP或ESP)+D16

说 明:其中EXP是一个表达式,根据它的值计算出来的常数成为机器指令中的位移量

D16。主程序通过压入堆栈操作将一定的参数或参数地址传递给子程序。子程序运行过程中,使用了这些参数或参数地址,子程序返回时没有必要再将这些参数或参数地址保留在堆栈中,因而,可以在返回指令后面加上参数EXP,以腾出那些无用的参数或参数地址所占的单元。

3). 段间远返回

指令格式:RET ;DEBUG反汇编为RETF,机器码为CBH 执行操作:当操作数长度为16位时,(IP)←Pop ( )

386及其后继机型:(EIP)←(EIP) AND 0000FFFFH

(CS)←Pop ( )

当操作数长度为32位时,(EIP)←Pop ( )

(CS)←Pop ( ) (32位数出栈,高16位废除)

4). 段间带立即数远返回

指令格式:RET EXP ;DEBUG反汇编为RETF n,机器码为CA xxxxH 执行操作:在完成与3)的RET完全相同的操作后,还需要修改堆栈指针:

(SP或ESP)←(SP或ESP)+D16

说 明:①.从近过程返回和从远过程返回的指令是一样的,但机器编码不一样。段内返回

指令的代码为C3H,段间返回指令的代码为CBH。

②.RET EXP指令为带参数的返回指令;EXP可为0~FFFFH范围中的任何一个偶数。

6. 中断

(1). 中断的概念

1). 中断:当系统运行或者程序运行期间遇到某些特殊情况时,需要计算机自动执行一组专门的服务程序来进行处理,这种情况称为中断。中断分为内部中断和外部中断。 a. 内部中断:由中断指令或者是程序运行结果产生的中断称为内部中断。 b. 外部中断:由于外部I/O设备随机请求而产生的中断称为外部中断。

2). 中断服务程序:在中断中运行的一组服务程序称为中断服务程序或中断子程序。 3). 中断向量:中断服务程序的入口地址。 4). 中断类型码N:为了区分各种中断而给每个中断按序从0~FFH编的号码称为中断类型码,用N表示。

5). 中断向量表:8086/8088 CPU将所有的中断向量按中断类型码顺序存放在内存的起始1KB地址单元中,这1KB地址单元就称为中断向量表。 (2). INT——中断调用指令

指令格式:INT TYPE

或INT ;TYPE=3时,缺省

执行操作:Push (FLAGS)

IF←0 TF←0 AC←0 Push (CS) Push (IP)

(IP)←(TYPE*4) (每个中断向量占4个字节) (CS)←(TYPE*4+2)

说 明:①.其中TYPE为类型号,它可以是常数或常数表达式,其值需在0~255范围内。

②.类型0的中断称为除数为0中断,由CPU自动产生,不能用中断指令调用。 ③.类型1的中断称为单步中断,CPU进入单步中断的依据为(TF)=1。不能用中断指令来调用。单步中断由调试程序DEBUG使用。

④.类型2的中断称为非屏蔽中断,属硬件中断,紧急情况使用,不许用中断指令来调用。

⑤.类型3的中断称为断点中断。用在调试程序中。INT又称为断点中断指令,它是单字节指令。与其他INT TYPE不同,是双字节指令。

⑥.类型4的中断称为溢出中断。有专门的溢出中断调用指令INTO。无INT 4指令。见下面。

(3). INTO——若溢出则中断指令

指令格式:INTO

执行操作:若OF=1,则:Push (FLAGS)

IF←0 TF←0 AC←0 Push (CS) Push (IP) (IP)←(10H) (CS)←(12H)

(4). IRET——从中断返回指令

指令格式:IRET ;适用于操作数长度为16位的情况 执行操作:(IP)←Pop ( )

(CS)←Pop ( ) (FLAGS)←Pop ( )

(5). IRETD——从中断返回指令

指令格式:IRETD ;适用于操作数长度为32位的情况 执行操作:(EIP)←Pop ( )

(CS)←Pop ( )

(EFLAGS)←Pop ( ) 3.3.6 处理器控制与杂项操作指令

1. 标志处理指令

(1). CLC——清进位标志指令

指令格式:CLC ;(CF)←0 (2). CMC——对进位标志求反指令

指令格式:CMC ;(CF)←(CF) (3). STC——置进位标志指令

指令格式:STC ;(CF)←1 (4). CLD——清方向标志指令

指令格式:CLD ;(DF)←0 (5). STD——置方向标志指令

指令格式:STD ;(DF)←1 (6). CLI——清中断允许标志指令

指令格式:CLI ;(IF)←0 (7). STI——置中断允许标志指令

指令格式:STI ;(IF)←1 (8). 设置单步标志程序段:置(TF)=1程序。

PUSHF POP AX ;(AX)←(FLAGS) OR AX,0100H ;(TF)←1 PUSH AX POPF

(9). 清除单步标志程序段:清(TF)=0程序。

PUSHF

POP AX ;(AX)←(FLAGS) AND AX,0FEFFH ;(TF)←0 PUSH AX POPF

2. 其它处理器控制与杂项操作指令

(1). NOP(No operation)——空操作指令:CPU执行指令时不进行任何操作,但占用3个时钟周期和一

个字节的空间,然后继续执行下一条指令。起延时作用或为其他指令保留存储空间。 指令格式:NOP ;空操作,占用3个时钟周期

(2). HLT(Halt)——暂停指令:执行HLT指令后,CPU进入暂停状态,CS和IP指向HLT后面的一条

指令的地址。外部中断或复位信号RESET可使CPU退出暂停状态。 指令格式:HLT ;暂停指令的执行 (3). ESC(Escape)——交权指令

指令格式:ESC ext_op,reg/mem ;ext_op是外操作码(协处理器的操作码)

(4). WAIT(Wait while TEST pin not asserted)——等待指令:8086在执行WAIT指令的过程中,不断检

测TEST引腿上的信号;而协处理器在完成工作以后,会往8086的TEST引腿送入一个低电平信号。8086检测到此信号以后,便退出等待状态。 指令格式:WAIT ;等待协处理器操作结束

1). 外部中断可使CPU离开等待状态,但中断返回后又回到等待状态。 2). 一般在用ESC指令前先用一条WAIT指令,以防8086同时让协处理器干两件及两件以上的事。这是协处理器不允许的。

(5). LOCK(Lock bus)——总线封锁指令:指令前缀。

1). LOCK指令前缀是一个特殊的可以放在任何指令前面的单字节指令前缀。

2). 该指令前缀迫使CPU封锁总线,并在LOCK线输出低电平,直到执行完前缀后面的指令为止。外部硬件可接收这个LOCK信号,而无法得到总线控制权。 (6). BOUND——界限指令(286及其后继机型可用)

指令格式:BOUND reg,mem

执行操作:BOUND指令检查给出的数组下标是否在规定的上下界之内。在则执行下一条指令;

如超出了上下界范围,则产生中断5。如发生中断,则返回时返回地址仍指向BOUND指令,而不是其下一条指令。

(7). ENTER——建立堆栈帧指令(286及其后继机型可用,堆栈帧在第6章介绍)

指令格式:ENTER imm16,imm8

执行操作:指令中所给出的两个操作数均为立即数。第一个操作数为16位立即数,由其指定堆

栈帧的大小,即其所占据的字节数。第二个操作数为8位立即数,它给出过程的嵌套层数,此数的范围应为0~31。该指令完成以下操作: ①.Push (BP)或Push (EBP),以保存该寄存器的原始内容。

②.(BP)←(SP)或(EBP)←(ESP),使BP或EBP寄存器保存当前堆栈指针SP或ESP的内容,以便在过程运行期间,以BP(或EBP)为基准访问堆栈帧中存放的变量。 ③.(SP)←(SP)-imm16或(ESP)←(ESP)-imm16,这样就建立了堆栈帧所占有的存储空间。

(8). LEAVE——释放堆栈帧指令(286及其后继机型可用)

指令格式:LEAVE

执行操作:该指令在程序中位于退出过程的RET指令之前,用来释放由ENTER指令建立的堆

栈帧存储区。该指令完成以下操作: ①.(SP)←(BP)或(SP)←(EBP) ②.(BP)←Pop ( )或(EBP)←Pop ( )

第 4 章 汇编语言程序格式

【教学目的】

本章内容也是本课程的重点,通过本章学习,使学生明确汇编语言的程序格式及程序设计方法,掌握汇编程序MASM、连接程序LINK及调试程序DEBUG等的功能和用法,掌握MASM和LINK所用到的伪操作。特别是汇编语言程序的上机操作方法,为该课程实验打下基础。 【重点难点】

段定义伪操作、数据定义伪操作等的格式和用法,汇编语言程序格式、表达式和运算符,MASM、LINK及DEBUG等的功能和用法。 【课 时 数】

7学时。

4.1 汇编程序功能

1. 汇编程序(MASM):把用户编写的汇编语言源程序翻译成机器语言目标程序的一种系统程序。 2. 汇编语言源程序:用汇编语言编写的程序称为汇编语言的源程序(扩展名为“.ASM”)。

3. 汇编程序的作用:把汇编语言源程序转换成用二进制代码表示的目标文件(称为“.OBJ”文件)。 4. 在计算机上运行汇编语言程序的步骤是 (1). 用编辑程序建立ASM源文件;

(2). 用MASM程序把ASM文件转换成OBJ文件; (3). 用LINK程序把OBJ文件转换成EXE文件; (4). 用DOS命令直接键入文件名就可执行该程序。 5. 汇编程序的主要功能

(1). 检查汇编语言源程序。

(2). 测出源程序中的语法错误,并给出出错信息。

(3). 产生源程序的目标程序,并给出列表文件。 (4). 展开宏指令。

4.2 伪操作

伪操作(伪指令):用来为汇编程序提供某些信息,让汇编程序在汇编过程中执行某些特定功能的指令叫伪指令。它不是CPU指令系统中的指令。要注意的是:指令是指挥CPU执行什么操作,而伪操作是指挥MASM怎样工作。 4.2.1 处理器选择伪操作

这一组伪操作的功能是要告诉汇编程序应该选择哪一种指令系统。主要有以下几种: .8086 ;选择8086指令系统,缺省时的默认值即为此 .286 ;选择80286指令系统 .286P ;选择保护方式下的80286指令系统 .386 ;选择80386指令系统 .386P ;选择保护方式下的80386指令系统 .486 ;选择80486指令系统 .486P ;选择保护方式下的80486指令系统 .586 ;选择Pentium指令系统 .586P ;选择保护方式下的Pentium指令系统

这类伪操作一般放在整个程序的最前面,也可放在程序中间。 4.2.2 段定义伪操作

1. 完整的段定义伪操作

(1). SEGMENT/ENDS——段定义伪操作:此对伪操作可以将汇编语言源程序分成几个段,通常为数

据段、堆栈段、附加段和代码段。

伪操作格式:segname SEGMENT [align_type][combine_type][use_type] [‘class’]

segname ENDS

说 明:①.定位类型(align_type):说明段的起始地址应有怎样的边界值。它们可以是:

PARA:指定段的起始地址必须从小段边界开始,即段地址必须能被16整除。

这样起始偏移地址可以从0开始。缺省时默认为PARA。

BYTE:该段可以从任意地址开始。这样起始偏移地址可能不是0。 WORD:该段必须从字的边界开始,即段地址必须为偶数。

DWORD:该段必须从双字的边界开始,即段地址必须能被4整除。 PAGE:该段必须从页的边界开始,即段地址必须能被256整除。

②.组合类型(combine_type):说明程序连接时的段合并方法。它们可以是:

PRIVATE:该段为私有段(默认),在连接时将不与其它模块中的同名分段合并。 PUBLIC:该段连接时将与有相同名字的其它分段连接在一起。连接次序由LINK

指定。每一分段都从小段的边界开始,因此原有段之间有空隙。

COMMON:该段连接时与其它同名分段有相同的起始地址,所以会产生覆盖。

COMMON连接后的长度是各分段中长度最长的那个段的长度。

AT expression:使段起始地址是表达式计算出来的16位值。不能指定代码段。 MEMORY:与PUBLIC同义。

STACK:把不同模块中的同名段组合而形成一个堆栈段。其长度为原有段的长

度总和。栈顶可自动指向连接后形成的大堆栈段的栈顶。

③.使用类型(use_type):只适用于386及其后继机型,它用来说明使用16位寻址方式还是32位寻址方式。它们可以是:

USE16:使用16位寻址方式(默认)。段长不超过64KB,地址形式为16位段地

址和16位偏移地址。

USE32:使用32位寻址方式。段长可达4GB,地址形式为16位段地址和32位