3.10 中断指令

2024-09-13 13:16:00 浏览数 (2)

3.10 中断指令

在汇编语言中,中断机制是控制程序流程和处理异步事件的重要手段。有软中断指令 (INT n)和中断返回指令 (IRET)

1. 软中断指令 (INT n)
定义与格式
  • 指令格式
代码语言:javascript复制
INT n
代码语言:javascript复制
- `n`:中断类型码,取值范围为 `0` 到 `0FFH`(即 0 到 255),总共有 256 种不同的中断类型。
功能与工作原理
  • 中断矢量表
    • 中断类型码 n 对应于中断矢量表中的第 n 项。
    • 每个中断类型码在中断矢量表中占用 4 个字节:
      • 前两个字节:存放中断服务程序(Interrupt Service Routine, ISR)的入口地址偏移量(Offset)。
      • 后两个字节:存放中断服务程序的段基址(Segment Address)。
  • 执行过程
    1. 保存标志寄存器
      • INT n 指令执行时,首先将当前的标志寄存器(Flags Register, FR)的内容压入堆栈,以保存当前的状态。
    2. 清除特定标志位
      • 清除中断标志位(Interrupt Flag, IF)和陷阱标志位(Trap Flag, TF),以防止嵌套中断或单步调试中断。
    3. 保存程序断点
      • 将当前程序计数器(即下一条指令的地址)的段基址和偏移地址压入堆栈,以便中断服务程序执行完毕后能够返回。
    4. 跳转到中断服务程序
      • 从中断矢量表中获取与中断类型码 n 对应的 4 个字节内容:
        • 偏移地址(Offset):加载到指令指针寄存器(IP)中。
        • 段基址(Segment Address):加载到代码段寄存器(CS)中。
      • 这样,CPU 会跳转到指定的中断服务程序执行。
示例

假设我们有一个中断类型码为 0x21(常用于DOS的中断服务),使用 INT 21H 来调用DOS功能:

代码语言:javascript复制
MOV AH, 09H       ; DOS功能号 09H:显示字符串
MOV DX, OFFSET msg ; DS:DX 指向要显示的字符串
INT 21H           ; 调用DOS中断
...
msg DB 'Hello, World!$' ; DOS字符串以 '$' 结尾
解释
  • 这里,INT 21H 调用了DOS提供的功能,通过设置 AHDX 寄存器来指定具体的操作(显示字符串)。
再看一个例子
代码语言:javascript复制
section .text
    org 100h               ; 设置程序起始地址(一般用于COM程序)

start:
    ; 假设 AX 中已经有了要计算的数值
    int 7Ch                ; 调用自定义的中断 7Ch,计算 AX 中的数据的平方

    ; 示例计算:2 * 3456^2
    mov ax, 3456h          ; 初始化 AX = 3456h
    int 7Ch                ; 计算 3456h 的平方

    ; 结果存储在 DX:AX 中
    ; 此时 DX 中存放高16位,AX 中存放低16位
    add ax, ax             ; 结果乘以2,更新 AX
    adc dx, dx             ; 结果乘以2,更新 DX

    mov ax, 4C00h          ; 正常结束程序
    int 21h

; 中断例程 - 中断7Ch: 计算AX中数值的平方
isr_7ch:
    pusha                  ; 保存所有通用寄存器

    ; 计算 AX 的平方,并将结果存入 DX:AX 中
    mov dx, ax             ; 将 AX 复制到 DX 中
    mul dx                 ; AX * DX -> DX:AX,AX 中低16位,DX 中高16位

    popa                   ; 恢复所有通用寄存器
    iret                   ; 返回到调用程序

section .data

软中断指令 (INT n)有哪些,都能做什么?

在 x86 汇编语言中,软中断指令 INT n 用于生成一个软件中断,通过调用操作系统或BIOS提供的服务。软中断允许程序在运行时请求操作系统或BIOS执行某些功能,类似于调用系统函数。

软中断指令概述
  • 语法: INT n
    • n 是中断向量号,指定了中断处理程序的入口点。
常见的软中断指令及其功能
  1. INT 10h: 视频服务中断
    • 用途: 提供视频功能,包括显示模式设置、光标控制、字符显示等。
    • 功能示例:
      • INT 10h 使得可以设置屏幕模式、显示光标、打印字符等。
      • AH = 0x02: 设置光标位置。
      • AH = 0x0E: 显示字符。
  2. INT 13h: 磁盘服务中断
    • 用途: 提供磁盘操作服务,如读取和写入磁盘扇区。
    • 功能示例:
      • INT 13h 用于访问硬盘和软盘。
      • AH = 0x02: 读扇区。
      • AH = 0x03: 写扇区。
  3. INT 14h: 串行端口服务中断
    • 用途: 提供串行端口操作服务。
    • 功能示例:
      • INT 14h 用于串行通信。
      • AH = 0x00: 初始化串行端口。
      • AH = 0x01: 发送字符。
  4. INT 15h: 扩展服务中断
    • 用途: 提供系统扩展服务,例如内存管理和电源管理。
    • 功能示例:
      • INT 15h 用于获取系统内存信息和电源管理。
      • AH = 0xE820: 获取系统内存范围。
  5. INT 16h: 键盘服务中断
    • 用途: 提供键盘操作服务。
    • 功能示例:
      • INT 16h 用于键盘输入。
      • AH = 0x00: 获取键盘按键。
      • AH = 0x01: 检测键盘按键是否被按下。
  6. INT 21h: DOS 系统调用中断
    • 用途: 提供大量的操作系统服务,如文件操作、内存分配、程序退出等。
    • 功能示例:
      • INT 21h 提供多种 DOS 服务。
      • AH = 0x01: 读取字符。
      • AH = 0x09: 打印字符串。
      • AH = 0x4Ch: 退出程序。
示例代码

下面是一个使用 INT 21h 打印字符串的示例:

代码语言:javascript复制
ORG 100h          ; 设定起始地址为 100h

MOV AH, 09h       ; 功能号:打印字符串
MOV DX, OFFSET MSG ; 设置字符串地址
INT 21h           ; 调用 DOS 中断

MOV AH, 4Ch       ; 功能号:退出程序
INT 21h           ; 调用 DOS 中断

MSG DB 'Hello, World!$', 0

当然,以下是将这段汇编代码整合到一起,并进行详细解释的内容:

代码语言:javascript复制
ORG 100h          ; 设定起始地址为 100h

MOV AH, 09h       ; 功能号:打印字符串
MOV DX, OFFSET MSG ; 设置字符串地址
INT 21h           ; 调用 DOS 中断

MOV AH, 4Ch       ; 功能号:退出程序
INT 21h           ; 调用 DOS 中断

MSG DB 'Hello, World!$', 0
代码解释
  1. ORG 100h
    • 含义: 指定程序的起始地址为 100h。
    • 作用: 在 DOS 执行的 .COM 文件中,代码通常从内存地址 100h 开始,因为前面 100h 字节的空间用于存储程序的 PSP(程序控制块)。这个伪指令告诉汇编器生成的机器代码从地址 100h 开始。
  2. 打印字符串部分
代码语言:javascript复制
MOV AH, 09h       ; 功能号:打印字符串
MOV DX, OFFSET MSG ; 设置字符串地址
INT 21h           ; 调用 DOS 中断
代码语言:javascript复制
- `MOV AH, 09h`: 将 09h 放入 AH 寄存器中。09h 是 DOS 中断 21h 的一个功能号,表示打印以 `$` 结束的字符串。
- `MOV DX, OFFSET MSG`: 将 `MSG` 标签的地址放入 DX 寄存器中。`<font style="color:#DF2A3F;">OFFSET MSG</font>` 计算 `<font style="color:#DF2A3F;">MSG</font>` 数据的<font style="color:#DF2A3F;">起始地址</font>。DX 寄存器现在包含了字符串的地址。
- `INT 21h`: 调用 DOS 中断 21h。由于 AH 寄存器中包含 09h,这次中断调用会打印 DX 寄存器中指定的字符串(即 `MSG`)。
  1. 退出程序部分
代码语言:javascript复制
MOV AH, 4Ch       ; 功能号:退出程序
INT 21h           ; 调用 DOS 中断
代码语言:javascript复制
- `MOV AH, 4Ch`: 将 4Ch 放入 AH 寄存器中。4Ch 是 DOS 中断 21h 的功能号,表示正常退出程序。
- `INT 21h`: 调用 DOS 中断 21h。由于 AH 寄存器中包含 4Ch,这次中断调用会结束程序的执行并返回到 DOS 命令行。
  1. 字符串数据定义
代码语言:javascript复制
MSG DB 'Hello, World!$', 0
代码语言:javascript复制
- `MSG DB 'Hello, World!$', 0`: 定义一个名为 `MSG` 的数据字节(DB),内容是字符串 `'Hello, World!'` 以 `$` 结束,`0` 作为字符串结束符。虽然 `$` 已经足够标识字符串的结束,`0` 是为了避免潜在的字符串结束问题(尤其是对其他功能)。
整体流程
  1. 程序开始:
    • 从地址 100h 开始执行代码。
  2. 打印字符串:
    • 设置 AH 寄存器为 09h,准备调用打印字符串的功能。
    • 将字符串的地址放入 DX 寄存器。
    • 调用 INT 21h,执行打印操作,将 “Hello, World!” 显示在屏幕上。
  3. 退出程序:
    • 设置 AH 寄存器为 4Ch,准备调用退出程序的功能。
    • 调用 INT 21h,正常退出程序,返回到 DOS 命令行。

这个程序展示了如何在 DOS 环境下使用汇编语言打印字符串并正常退出,适用于简单的 DOS .COM 文件编程。

总结
  • INT** 指令**: 通过调用软件中断,程序可以请求操作系统或 BIOS 执行特定任务。
  • INT** 指令的功能**: 包括视频服务、磁盘操作、串行通信、键盘输入、系统服务等。

通过不同的 INT n 指令和相关功能号,汇编语言程序可以访问底层硬件或操作系统提供的功能,执行各种系统级任务。

2. 中断返回指令 (IRET)
定义与格式
  • 指令格式
代码语言:javascript复制
IRET
功能与工作原理
  • 作用**<font style="color:#DF2A3F;">IRET</font>** 指令用于从中断服务程序返回到被中断的主程序,恢复中断前的执行状态。
  • 执行过程
    1. 恢复标志寄存器
      • 从堆栈中弹出一个字(通常是 16 位),并将其加载到标志寄存器(FR)中,恢复中断前的标志状态。
    2. 恢复代码段和指令指针
      • 从堆栈中依次弹出两个字(各 16 位),将其加载到代码段寄存器(CS)和指令指针寄存器(IP)中,恢复中断前的程序计数器。
    3. 继续执行
      • 程序控制权返回到被中断的主程序,继续执行 CALLINT 指令之后的下一条指令。
  • 重要性
    • 必须性:在中断服务程序的最后,必须使用 IRET 指令来确保程序能够正确返回到中断前的位置。如果没有 IRET,程序将无法恢复到中断前的状态,导致程序执行混乱或崩溃。
示例
代码语言:javascript复制
; 主程序
MAIN:
    ; 一些主程序代码
    INT 21H           ; 调用DOS中断
    ; 中断返回后继续执行
    ...

; 中断服务程序(假设自定义中断)
ISR:
    ; 中断服务程序的代码
    ...
    IRET             ; 返回到主程序
解释
  • INT 指令被执行时,CPU 跳转到对应的中断服务程序(如 ISR)。
  • 中断服务程序执行完毕后,通过 IRET 指令返回到主程序的 INT 指令之后的位置,继续执行主程序的后续代码。
再看一个例子
代码语言:javascript复制
section .text
    org 100h               ; 设置程序起始地址(一般用于COM程序)

start:
    ; 假设 AX 中已经有了要计算的数值
    int 7Ch                ; 调用自定义的中断 7Ch,计算 AX 中的数据的平方

    ; 示例计算:2 * 3456^2
    mov ax, 3456h          ; 初始化 AX = 3456h
    int 7Ch                ; 计算 3456h 的平方

    ; 结果存储在 DX:AX 中
    ; 此时 DX 中存放高16位,AX 中存放低16位
    add ax, ax             ; 结果乘以2,更新 AX
    adc dx, dx             ; 结果乘以2,更新 DX

    mov ax, 4C00h          ; 正常结束程序
    int 21h

; 中断例程 - 中断7Ch: 计算AX中数值的平方
isr_7ch:
    pusha                  ; 保存所有通用寄存器

    ; 计算 AX 的平方,并将结果存入 DX:AX 中
    mov dx, ax             ; 将 AX 复制到 DX 中
    mul dx                 ; AX * DX -> DX:AX,AX 中低16位,DX 中高16位

    popa                   ; 恢复所有通用寄存器
    iret                   ; 返回到调用程序

section .data

总结
  • 软中断指令 (INT n)
    • 用于调用中断服务程序,处理特定的服务或事件。
    • 通过中断类型码 n 来选择具体的中断服务。
    • 执行 INT 指令时,CPU 会保存当前状态并跳转到对应的中断服务程序。
  • 中断返回指令 (IRET)
    • 用于从中断服务程序返回到被中断的主程序。
    • 恢复中断前的程序状态,确保程序能够继续正常执行。
    • 必须在中断服务程序的末尾使用,以确保程序流程的正确性。

应用场景

  • 操作系统服务调用:如DOS中断 INT 21H 提供了文件操作、设备控制等功能。
  • 硬件中断处理:例如键盘输入、定时器中断等,通过中断服务程序来处理异步事件。
  • 软件异常处理:如断点调试、非法操作处理等。

通过正确使用 INTIRET 指令,汇编程序能够有效地管理程序流程、处理事件和调用系统服务,实现复杂的功能和响应外部事件。

0 人点赞