8086中断指令列表

注意:列表列出的中断(interrupt)现在都由仿真程序提供支持。这些中断应该在IBM PC和全系x86架构芯片、Intel 8086AMD compatible microprocessors兼容。不过,Windows XP系统可能重写了一些原生的中断。

快速导航:

INT 10H/00H

INT 10H/01H

INT 10H/02H

INT 10H/03H

INT 10H/05H

INT 10H/06H

INT 10H/07H

INT 10H/08H

INT 10H/09H

INT 10H/0AH

INT 10H/0CH

INT 10H/0DH

INT 10H/0EH

INT 10H/13H

INT 10H/1003H

INT 11H

INT 12H

INT 13H/00H

INT 13H/02H

INT 13H/03H

INT 15H/86H

INT 16H/00H

INT 16H/01H

INT 19H

INT 1AH/00H

INT 20H

INT 21H

INT 21H/01H

INT 21H/02H

INT 21H/05H

INT 21H/06H

INT 21H/07H

INT 21H/09H

INT 21H/0AH

INT 21H/0BH

INT 21H/0CH

INT 21H/0EH

INT 21H/19H

INT 21H/25H

INT 21H/2AH

INT 21H/2CH

INT 21H/35H

INT 21H/39H

INT 21H/3AH

INT 21H/3BH

INT 21H/3CH

INT 21H/3DH

INT 21H/3EH

INT 21H/3FH

INT 21H/40H

INT 21H/41H

INT 21H/42H

INT 21H/47H

INT 21H/4CH

INT 21H/56H

INT 33H/0000H

INT 33H/0001H

INT 33H/0002H

INT 33H/0003H

INT 10H / AH = 0 设置图形(video)格式

输入:

AL = 希望的图形(video)模式

00H 文本模式 40 * 25 16色 8页

03H 文本模式 80 * 25 16色 8页

13H 图形模式 40 * 25 256色 320 * 200 像素 1页

示例:

MOV		AL, 13H
MOV		AH, 0
INT		10H

INT 10H / AH = 01H 设置文本模式光标形状

输入:

CH = 0-4位为光标开始线,5-7位为选项

CL = 0-4位底部光标线

CH 的第 5 位置为 0 光标可用,置为 1 时光标不可用。

示例:

; 隐藏闪烁的文本光标
	MOV		CH,		32
	MOV		AH,		1
	INT		10H
	
; 显示标准闪烁文本光标
	MOV		CH,		6
	MOV		CL,		7
	MOV		AH,		1
	INT		10H
	
; 显示箱状闪烁文本光标
	MOV		CH,		0
	MOV		CL,		7
	MOV		AH,		1
	INT		10H
	
; 注意:一些 BIOS 要求 CL >= 7 否则会显示错误的光标形状

INT 10H / AH = 02H 设置光标位置

输入:

DH = 行

DL = 列

BH = 页数(0-7)

示例:

; 将光标位置设置在 0 页 10 行 20 列
MOV		DH,		10
MOV		DL,		20
MOV		BH,		0
MOV		AH,		2
INT		10H

INT 10H / AH = 03H 取得光标位置和尺寸

输入:

BH = 页数(0-7)

返回:

DH = 行

DL = 列

CH = 光标开始线

CL = 光标底部线

INT 10H / AH = 05H 设置活跃图形(video)页

输入:

AL = 新页数(0-7)

被激活的页面将会被显示。

INT 10H / AH = 06H(07H) 上(下)滚动窗口

输入:

AL = 想要滚动的行数(00H则清除整个窗口)

BL = 用于写窗口底部空白行的属性

CH, CL = 窗口左上角的行和列

DH, DL = 窗口右下角的行和列

INT 10H / AH = 08H 读取光标位置的字符和属性

输入:

BH = 页数

返回:

AH = 属性

AL = 字符

INT 10H / AH = 09H 将字符和属性写入光标位置

输入:

AL = 显示的字符

BH = 页数

BL = 属性

CX = 字符要写入的次数

INT 10H / AH = 0CH 对单一像素改变颜色

输入:

AL = 像素颜色

CX = 列

DX = 行

示例:

; 将图形(video)模式设置为图像模式
MOV		AL,		13H
MOV		AH,		0
INT		10H

; 将像素(20,10)颜色设置为 0CH
MOV		AL,		0CH
MOV		CX,		10
MOV		DX,		20
MOV		AH,		0CH
INT		10H

INT 10H / AH = 0DH 得到单个像素的颜色

输入:

CX = 列

DX = 行

返回:

AL = 像素颜色

INT 10H / AH = 0EH 电传打字机(teletype)输出

输入:

AL = 要写入的字符

这个中断在屏幕上显示字符,根据需要推动光标或滚动屏幕。通常都会显示在当前活跃页面。

示例:

MOV		AL,		'a'
MOV		AH,		0EH
INT		10H

; 注意:一些系统中这个中断在图形模式下不支持

INT 10H / AH = 13H 写入字符串

输入:

AL = 写入模式(第 0 位写入后更新光标;第 1 位字符中含有属性)

BH = 页数

BL = 如果字符串中只有字符的属性(AL第 1 位为0)

CX = 字符串中字符个数(属性不计算在内)

DL, DH = 开始写入的列,行

ES:BP = 要写入字符串的地址

示例:

MOV		AL,		1
MOV		BH,		0
MOV		BL,		3BH
MOV		CX,		MSGEND - OFFSET MSG1	; 计算字符串长度
MOV		DL,		10
MOV		DH,		7
PUSH	CS
POP		ES
MOV		BP,		OFFSET	MSG1
MOV		AH,		13H
INT		10H
JMP		MSGEND
MSG1	DB		"HELLO WORLD"
MSG1END:

INT 10H / AX = 1003H 常亮/闪烁 切换

输入:

BL = 写入模式(0为常亮模式,1为闪烁模式)

BH = 0(为了防止在一些适配器上出现问题)

示例:

MOV		AX,		1003H
MOV		BX,		0
INT		10H

位颜色表

字符属性是一个8位值,低四位前部颜色,高四位设置背景颜色。

注意:仿真器和 Windows 命令行不支持背景闪烁,然而为了使颜色在DOS和全屏环境下观感一致,还是要通过命令关闭背景闪烁。

HEXBINCOLOR
00000黑色
10001蓝色
20010绿色
30011青色
40100红色
50101洋红色
60110棕色
70111亮灰色
81000暗灰色
91001亮蓝色
A1010亮绿色
B1011亮青色
C1100亮红色
D1101亮洋红色
E1110黄色
F1111白色

注意:

; 使用这段代码保证DOS/CMD 全屏模式下的兼容性
MOV		AX,		1003H
MOV		BX,		0		; 停止闪烁
INT		10H

INT 11H 取得BIOS设备列表

返回:

AX = BIOS 设备列表 字(word),事实上这个中断返回位于0040H:0010H的字的内容。

现今这个中断常用来确定设备安装的软盘个数。

各位代表 BIOS 检测 已安装硬件如下:

15-14 并行设备数量

13 预留

12 已安装游戏端口(用于连接卡带,手柄等游戏设备)

11-9 串行设备数量

8 预留

7-6 软盘数量(-1,即若为01,则有两个软盘)

5-4 初始图形(video)模式

​ 00 EGA, VGA, PGA, 或其他在BIOS板的图形卡

​ 01 40x25 CGA 彩色显示

​ 10 80x25 CGA 彩色显示(默认)

​ 11 80x25 纯文字(mono text)

3 预留

2 PS/2 接口的鼠标

1 已安装数学协处理器

0 当从软盘启动时设置(Set when booted from floppy)

例如,当DOSBOX执行INT 11H命令时,AX = D426H = 1101 0100 0010 0110B。则对于该虚拟机,有 3个并行设备,已安装 1 个游戏设备,两个串行设备,1个软盘,80x25 CGA 彩色显示,安装 PS/2 鼠标,安装数学协处理器,从软盘启动。

INT 12H 得到主存大小

返回

AX = 从绝对地址00000H处开始的相邻地址大小,以KB为单位,中断返回的是位于0040H:0013H处字的内容。

软盘通过使用 FLOPPY_0(..3) 文件仿真。

INT 13H / AH = 00H 重置磁盘系统

INT 13H / AH = 02H 将磁盘扇区读入主存

INT 13H / AH = 03H 写入磁盘扇区

输入:

AL = 需要读或写的扇区数(必须不为0)

CH = 柱面数(0-79)

CL = 扇区数(1-18)

DH = 磁头数(0-1)

DL = 驱动数(0-3,对于仿真器来说取决于 FLOPPY_file 的编号)

ES:BX = 数据缓冲区的地址

返回:

CF = 错误置1

CF = 成功置0

AH = 状态( 0 为成功)

AL = 转移的扇区数

由软盘的标准,一个扇区必须为 512B。

INT 15H / AH = 86H BIOS 等待中断

输入:

CX:DX = 以微秒为单位的间隔

返回:

CF = 0则成功(等待时间间隔流逝)

CF = 1则发送错误或等待中断已在进程

注意:在许多系统,等待时间的分辨率为977微秒(100万微妙-1秒)

Windows XP 系统不支持该中断(系统默认将CF恒置为1)

INT 16H / AH = 00H 从键盘取得按键(无回应)

返回:

AH = BIOS 扫描码

AL = ASCII 字符 (如果存在一个按键,将其从键盘缓冲区中移除)

INT 16H / AH = 01H 检查键盘缓冲区的按键

返回:

ZF = 1 若按键可用

ZF = 0 若按键不可用

AH = BIOS 扫描码

AL = ASCII 字符 (如果存在一个按键,将其从键盘缓冲区中移除)

INT 19H 系统重启

通常,BIOS会尝试从A盘读取0磁头,0磁道,1扇区0000H:7C00H。仿真器仅停止其执行,从virtual drive -> boot from floppy菜单中选取的软盘启动。

INT 1AH / AH = 00H 得到系统时间

返回:

CX:DX = 从午夜(00:00)开始计算度过的时钟数

AL = 午夜计数器,每当度过一次午夜增加1

注意:一秒大约有18.24608个时钟周期,每天有1800B0H个时钟周期,AL不是由仿真器设置的。

示例:

MOV		AH,		00H
INT		1AH

14:40时执行该程序,得到CX:DX=000EH:AA8BH,其值化为十进制为43883,化为分钟后约为40分钟。对于 DOSBOX 仿真器来说,午夜设置在了14:00

INT 20H 退出操作系统

INT 21H MS-DOS 中断

DOS 的文件系统C:\emu8086\vdrive\x中仿真,这里的x是磁盘号。如果没有特殊指定磁盘号并且当前文件目录未设置,那么默认使用C:\emu8086\Mybuild\。FLOPPY_0, 1, 2, 3 文件从 DOS 文件系统独立仿真。

对于仿真器,物理磁盘A:为如下文件C:\emu8086\FLOPPY_0(支持 BIOS 中断 13H 并且启动)

对于 DOS 中断(INT 21H)A盘位于C:\emu8086\vdrive\a\仿真。

注意:DOS 文件系统限制文件和文件夹路径最多8字符,拓展名最多3字符;

例如如下有效1文件名myfile.txt 。拓展名写在点后,且不能有点。

INT 21H / AH = 01H 从标准输入读取字符,有回应,结果存在 AL。若键盘缓冲区无字符,中断等待直到有键被按下。

示例:

MOV		AH,		01H
INT		21H

INT 21H / AH = 02H 写字符到标准输出

输入:

DL = 要写入的字符,执行后 AL = DL

示例:

MOV		AH,		02H
MOV		DL,		'a'
INT		21H

INT 21H / AH = 05H 输出字符到打印器

输入:

DL = 要打印的字符,执行后AL = DL

示例:

MOV		AH,		05H
MOV		DL,		'a'
INT		21H

INT 21H / AH = 06H 直接控制台输入/输出

输入:

DL = 输出 0-254(ASCII 码) 输入 255

返回:

输出时 AL = DL

输入时 若无字符可用则 ZF = 1 且 AL = 00H,若有字符可用则 ZF = 0

AL = 读取的字符;缓存区清除

示例:

; 输出字符
MOV		AH,		06H
MOV		DL,		'a'
INT		21H

; 从键盘缓冲区取得字符或置 ZF = 1
MOV		AH,		06H
MOV		DL,		255
INT		21H

INT 21H / AH = 07H 无回应输入字符到 AL

如果键盘缓冲区没有字符,则中断在有按键前等待

示例:

MOV		AH,		07H
INT		21H

INT 21H / AH = 09H 输出位于DS:DX处的字符串,字符串必须由$终止

示例:

ORG		100H
MOV		DX,		OFFSET MSG
MOV		AH,		09H
INT 21H
RET
MSG		DB		"hello world$"

INT 21H / AH = 0AH 输入一个字符到DS:DX,第一个字节为缓冲区大小,第二个字节是实际读取的字符数

这个中断不需要在字符串结尾加$。而用上一个中断必须要在结尾加入$并且从DS:DX + 2开始打印。

示例:

ORG		100H
MOV		DX,		OFFSET BUFFER
MOV		AH,		0AH
INT		21H
JMP PRINT
BUFFER	DB	10, ?, 10 DUP(' ')
PRINT:
XOR		BX,		BX		; BX = 0
MOV		BL,		BUFFER[1]
MOV		BUFFER[BX+2]		'$'
; 从 DS:DX + 2 处开始打印
MOV		DX,		OFFSET BUFFER + 2
MOV		AH,		09H
INT		21H
RET

该中断不允许超出指定缓冲区大小字符进入。

INT 21H / AH = 0BH 取得输入状态

返回:

AL = 00H 如果没有字符可用;FFH如果有字符可用

INT 21H / AH = 0CH 清空键盘缓冲区并读取标准输入

输入:

AL = 清空缓存区后执行的输入中断编号(01H, 06H, 07H, 08H, 0AH,对其他值缓存区会被清空但不会有输入)

其他寄存器按照 AL 确定的中断进行设置。

INT 21H / AH = 0EH 选择默认磁盘

输入:

DL = 新的默认磁盘(0 对应A:\,1 对应B:\,...)

返回:

AL = 潜在有效盘符个数

注意:返回值是最高磁盘代表值(The highest drive present)

INT 21H / AH = 19H 取得现在默认磁盘

返回:

AL = 盘符(0 对应A:\,1 对应B:,...)

INT 21H / AH = 25H 设置中断向量

输入:

AL = 中断数

DS:DX = 新的中断执行句柄

INT 21H / AH = 2AH 取得系统时间

返回:

CX = 年(1980-2099)

DH = 月

DL = 日

AL = 星期(00H代表星期天)

INT 21H / AH = 2CH 取得系统时间

返回:

CH = 小时

CL = 分钟

DH = 秒

DL = 0.01秒

INT 21H / AH = 35H 取得中断向量

输入:

AL = 中断数

返回:

ES:BX = 现在中断句柄

INT 21H / AH = 39H 新建文件夹

输入:

DS:DX = ASCII 文件路径,最后以0结束字符串

返回:

CF = 0 则成功创建 AX 销毁,CF = 1 则发生错误,AX = 错误码

注意:除了最后一个路径可以不存在其他的必须存在

示例:

ORG		100H
MOV		DX,		OFFSET FILEPATH
MOV		AH,		39H
INT		21H

RET

FILEPATH  DB  "C:\mydir", 0
END

上述代码如果在仿真器运行回创建C:\emu8086\vdrive\C\mydir文件夹。

INT 21H / AH = 3AH 删除文件夹

输入:

DS:DX = 要删除的文件夹路径,以0结束字符串

返回:

CF = 0 则成功删除 AX 销毁,CF = 1 则发生错误,AX = 错误码

要删除的文件夹必须存在且为空

INT 21H / AH = 3BH 设置当前路径

输入:

DS:DX = 要前往的路径(最大 64 字节)

返回:

CF = 0 成功,AX 销毁,CF = 1 发生错误,AX = 错误码

注意:即使新路径中包含盘符名,默认盘符也不会改变,只能前往该盘符下的路径

INT 21H / AH = 3CH 创建或删除(truncate)文件

输入:

MOV		CX,		0		; 正常,无属性
MOV		CX,		1		; 只读
MOV		CX,		2		; 隐藏
MOV		CX,		4		; 仅系统
MOV		CX,		7		; 只读,隐藏且仅系统
MOV		CX,		16		; 归档

DS:DX = 文件路径

返回:

CF = 0 则成功, AX = 文件句柄,CF = 1 发生错误,AX = 错误码

注意:若特定文件存在将会被不加警告地删除

示例:

ORG		100H
MOV		AH,		3CH
MOV		CX,		0
MOV		DX,		OFFSET FILENAME
MOV		AH,		3CH
INT		21H
JC		ERR
MOV		HANDLE,		AX
JMP		K
FILENAME  DB  "myfile.txt", 0
HANDLE  DW  ?
ERR:
; ...
K:
RET

INT 21H / AH = 3DH

输入:

AL = 访问及共享模式

MOV		AL,		0		; 只读
MOV		AL,		1		; 只写
MOV		AL,		2		; 读写

DS:DX = 文件路径

返回:

CF = 0 则成功, AX = 文件句柄,CF = 1 发生错误,AX = 错误码

注意:文件指针会设置在文件开头;文件必须存在

示例:

ORG		100H
MOV		AL,		2
MOV		DX,		OFFSET FILENAME
MOV		AH,		3DH
INT		21H
JC		ERR
MOV		HANDLE,		AX
JMP		K
FILENAME  DB  "myfile.txt", 0
HANDLE  DW  ?
ERR:
; ...
K:
RET

INT 21H / AH = 3EH 关闭文件

输入:

BX = 文件句柄

返回:

CF = 0 则成功, AX = 文件句柄,CF = 1 发生错误,AX = 错误码(06H)

INT 21H / AH = 3FH 从文件读取

输入:

BX = 文件句柄

CX = 读取字节数

DS:DX = 数据缓冲区

返回:

CF = 0 则成功, AX = 实际读取字节数,AX = 0 调用前在EOF处

CF = 1 则发生错误,AX = 错误码

注意:数据从当前文件位置开始读取,并且在一次成功读取后文件位置会更新,如果发生局部分读取返回的 AX 可能比请求的字节数 CX 少

INT 21H / AH = 40H 写入文件

输入:

BX = 文件句柄

CX = 写入字节数

DS:DX = 要写入的数据

返回:

CF = 0 则成功, AX = 实际写入字节数,CF = 1 发生错误,AX = 错误码

若 CX = 0,没有数据写入,并且文件被缩短或扩展到当前位置数据,并且文件位置在成功写入后更新。通常使AX < CX的原因是磁盘已满

INT 21H / AH = 41H 删除文件(未连接的)

输入:

DS:DX = 文件路径(不能有通配符,请见注意)

返回:

CF = 0 则成功, AX 销毁,AL 为已删除文件的驱动,CF = 1 发生错误,AX = 错误码

注意:DOS不会擦除文件数据,仅变为不可访问。因为删除当前打开的文件时清除 FAT 链可能导致文件系统出错

INT 21H / AH = 42H 查找 设置当前文件位置

输入:

AL = 初始移动: 0 文件开始 1 当前文件位置 2 文件结束

BX = 文件句柄

CX:DX = 初始到新文件位置的偏移

返回:

CF = 0 则成功, DS:AX = 新文件位置(从问文件开始,以字节为单位),CF = 1 发生错误,AX = 错误码

这主意:对于初始的 1 和 2,指针可能指向文件开始之前;在这种状态下没有错误会被返回,但是虽有尝试读写文件会发生错误。若新的位置超过当前文件结尾,文件在下次写入时会被拓展(见 AH = 40H)

示例:

ORG		100H
; 创建文件
MOV		AH,		3CH
MOV		CX,		0
MOV		DX,		OFFSET FILENAME
MOV		AH		3CH
INT		21H

; 写入文件
MOV		BX,		HANDLE
MOV		DX,		OFFSET DATA
MOV		CX,		DATA_SIZE
MOV		AH,		40H
INT		21H

; 查找
MOV		AL,		0
MOV		BX,		HANDLE
MOV		CX,		0
MOV		DX,		7
MOV		AH,		42H
INT		21H

; 读取文件
MOV		BX,		HANDLE
MOV		DX,		OFFSET BUFFER
MOV		CX,		4
MOV		AH,		3FH
INT 21H

; 关闭文件
MOV		BX,		HANDLE
MOV		AH,		3EH
INT		21H
RET

FILENAME  DB  "myfile.txt", 0
HANDLE  DW  ?
DATA  DB  "hello files!"
DATA_SIZE = $ - OFFSET DATA
BUFFER  DB  4 DUP(' ')

INT 21H / AH = 47H 取得当前文件夹

输入:

DL = 盘符号(00H = 默认,01H = A:,...)

DS:SI = 用于存放路径的64位缓冲区去

返回:

CF = 0 则成功,CF = 1 发生错误,AX = 错误码(0FH)

返回的路径不包括盘符和初始反斜线

INT 21H / AH = 4CH 控制权交还操作系统(停止程序)

INT 21H / AH = 56H 移动/重命名文件

输入:

DS:DX = 已存在文件文件名

ES:DI = 新文件名

返回:

CF = 0 则成功,CF = 1 发生错误,AX = 错误码

注意:只允许在同一逻辑盘内移动;已打开文件不能重命名

INT 33H / AX = 0000 鼠标初始化,任何之前鼠标指针被隐藏

返回:

成功:AX = 0FFFFH BX = 鼠标按键个数

失败:AX = 0

示例:

MOV		AX,		0
INT		33H

INT 33H / AX = 0001 显示鼠标指针

示例:

MOV		AX,		1
INT		31H

INT 33H / AX = 0002 隐藏可见鼠标指针

示例:

MOV		AX,		2
INT		33H

INT 33H / AX = 0003 取得鼠标位置和按键状态

返回:

若左键被按下,BX = 1

若右键被按下,BX = 2

若左键右键同时按下,BX = 3

CX = x

CY = y

示例:

; 注意:在 320x200 图形模式 CX 的值将加倍。

MOV		AX,		3
INT		33H