微机原理第五章知识点梳理:汇编程序设计与中断
*.EXE 文件与 *.COM 文件的主要区别
在DOS及8086汇编环境下,可执行文件主要存在.COM(Command)和.EXE(Executable)两种格式。它们在存储模型、加载机制及文件结构上存在本质差异:
-
内存模型与段结构(Memory Model)
-
COM文件:采用微模式(Tiny Model)。其本质是内存的纯二进制映像(Binary Image),文件在磁盘上的形式与加载到内存后的形式完全一致(字节对字节)。严苛限制代码段、数据段和堆栈段必须合并在同一个64KB的段内(即
CS = DS = SS = ES)。 -
EXE文件:采用多段模型。它拥有独立的文件头(Header),支持多个逻辑段(独立的代码段、数据段、堆栈段),程序大小仅受限于物理内存,可突破64KB限制。
-
加载过程与重定位(Loading & Relocation)
-
COM文件:无需重定位。加载器将其直接读入内存,指令指针(IP)固定指向偏移地址 100H 处(前256字节预留给程序段前缀PSP)。
-
EXE文件:必须重定位。加载器根据文件头中的重定位表(Relocation Table),在加载时动态计算并修改程序中涉及段地址的指令,初始化
CS:IP和SS:SP。 -
执行效率与体积
-
COM文件:文件紧凑(无文件头),加载极快,适合小型实用程序。
-
EXE文件:文件包含元数据头,体积稍大,加载过程涉及地址计算,但适合构建复杂的大型应用。
宏(Macro)模块与过程(Procedure)的特点及异同
宏与过程是实现程序模块化的两种核心技术,它们体现了计算机科学中经典的“时空权衡(Time-Space Tradeoff)”法则。
核心定义
- 宏:源程序级的文本替换。由汇编器在汇编阶段(Assembly Time)处理,将宏调用处的代码展开为宏定义体。
- 过程:机器码级的子程序。由CPU在运行阶段(Runtime)通过控制转移指令执行。
关键差异对比
| 比较维度 | 宏 (Macro) | 过程 (Procedure) |
|---|---|---|
| 处理机制 | 文本替换与展开(无控制转移)。 | CALL 跳转与 RET 返回。 |
| 内存占用 | 大。每调用一次,宏代码就在目标程序中重复生成一份副本。 | 小。内存中仅存一份代码实体,多次调用不增加代码体积。 |
| 执行速度 | 快。无跳转、返回及现场保护的额外指令周期开销。 | 较慢。涉及入栈/出栈及指令流水线刷新,有额外时间开销。 |
| 参数传递 | 形参替换。通过字符/符号直接替换,无需占用寄存器。 | 数据传递。需通过寄存器、堆栈或公共内存区传递数值。 |
| 适用场景 | 代码短小、执行频繁、参数形式灵活(如改变指令助记符)。 | 逻辑复杂、代码量大、需节省内存的功能模块。 |
中断向量写入的方法
中断向量表(IVT)位于内存物理地址 0000:0000 至 0000:03FF。修改中断向量即将自定义中断服务程序(ISR)的入口地址(CS:
IP)写入该表。主要有三种方法:
直接指令写入法(Direct Memory Access)
通过 MOV 指令直接操作内存。
- 步骤:将
DS设为0,根据中断类型码 计算偏移地址( 为IP位置, 为CS位置),分别写入ISR的偏移地址和段地址。 - 风险:操作非原子性,建议在写入前后使用
CLI(关中断)和STI(开中断)构建临界区,防止写入一半时发生中断导致系统崩溃。
串操作写入法
利用 STOSW 指令配合 ES:DI。
- 步骤:置
ES=0,DI=4n,CLD(地址递增)。先将ISR偏移地址存入AX执行STOSW,再将段地址存入AX执行STOSW。 - 注意:同样需要
CLI/STI进行保护。
DOS系统功能调用法(推荐规范)
使用 INT 21H 提供的标准接口,无需直接操作硬件内存,最为安全。
- 设置向量:使用功能号 AH=25H。
- 入口参数:
AL=中断类型码,DS:DX=ISR入口地址。 - 获取向量:使用功能号 AH=35H(修改前通常需先获取并保存旧向量)。
- 出口参数:
ES:BX=原ISR入口地址。
变量的三种属性
在汇编源程序中定义变量(如 VAR DW 1234H)时,汇编器会赋予该符号名三个静态属性:
- 段属性 (SEG / Segment)
- 表示该变量所在逻辑段的起始段基址(Segment Base Address)。
- 偏移属性 (OFFSET)
- 表示该变量单元距离其所在段起始地址的字节距离(即有效地址 EA)。
- 类型属性 (TYPE)
- 表示该变量分配内存时的数据宽度单位。例如:
BYTE(1字节),WORD(2字节),DWORD(4字节)。
中断服务子程序与普通子程序的差异
两者虽然都是代码跳转,但在触发机制、返回逻辑及现场保护上存在严格的学术区分。
调用与返回机制
- 普通子程序:
- 触发:同步触发。由主程序中的
CALL指令显式调用。 - 返回:使用
RET指令。仅从堆栈弹出 IP(近过程)或 CS:IP(远过程)。 - 中断服务子程序 (ISR):
- 触发:异步触发(外部中断)或异常触发。由硬件信号、内部异常或
INT指令引起。 - 返回:必须使用
IRET(Interrupt Return) 指令。其核心区别在于:IRET会依次弹出 IP、CS 和 FLAGS(标志寄存器) ,从而恢复中断前的处理器状态。
现场保护 (Context Saving)
- 普通子程序:
- 遵循调用约定(Calling Convention)。通常仅需保护子程序内部会修改且主程序后续仍需使用的通用寄存器。
- 通常不需要保护标志寄存器(FLAGS),除非特定逻辑需要。
- ISR:
- 强制全保护。由于中断可能在任何指令间隙发生,ISR对被中断程序必须是完全透明的。
- 必须保护ISR中使用的所有寄存器。
- 标志位保护:这是最大区别。CPU响应中断时会自动压入FLAGS,ISR返回时通过
IRET自动恢复。若不恢复FLAGS,原程序中的条件跳转逻辑(如JZ,JC)可能会因标志位改变而完全出错。