惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
H
Help Net Security
G
Google Developers Blog
D
Docker
阮一峰的网络日志
阮一峰的网络日志
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
博客园 - 聂微东
Hugging Face - Blog
Hugging Face - Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Apple Machine Learning Research
Apple Machine Learning Research
云风的 BLOG
云风的 BLOG
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
腾讯CDC
T
The Blog of Author Tim Ferriss
Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
I
InfoQ
Engineering at Meta
Engineering at Meta
Stack Overflow Blog
Stack Overflow Blog
Google DeepMind News
Google DeepMind News

LanYunのBlog

优化macOS Dock栏的显示与隐藏 解决macOS全屏模式下某些情况显示原始鼠标指针的问题 Yarn从Classic迁移到Modern nginx自编译 用santa对二进制进行监控和授权 ESXI 8.0安装黑群晖DSM 7.x openwrt编译过程记录 编译monero For macOS ARM 自建busuanzi不蒜子平台统计平台 浅记博客更新日志 (机翻)Kubo配置文件 修改brew services中服务的启动参数 技术杂记📝 解决Surge模块不能同步问题 为Arch Linux配置邮件服务 自编译NutClient-ESXI,更改邮件逻辑 解决ESXI和群晖使用SSH密钥登录问题 为J4125软路由ESXI中群晖提供UPS服务 在arch linux上搭建rustdesk server 解决虚拟机扩容中GPT PMBR大小不符问题 搭建Tuic V5 优雅地为macOS提供python多版本的支持 修复root路径下文件权限问题 解决macOS 14上利用Whisky运行steam时有关问题 在macOS中用PhpStorm配置Xdebug调试 利用CloudFlare Workers快速自建一个IP获取器 如何自动续期证书? 从0开始速配VPS用于网站等 搭建一个基于ChatGPT的QQ机器人(Yunzai-Bot) For Mac 010 Editor For Mac 13.0.1 Crack 破解
CSAPP_Lab之BombLab
LanYun · 2022-07-02 · via LanYunのBlog

mov指令种类:

  • 普通的mov指令
  • 做符号(signed)扩展的movs
  • 做零(zero)扩展的movz

普通mov的种类有:

  • movb #完成1个字节(byte)的复制
  • movw #完成2个字节(=word 字)的复制
  • movl #完成4个字节(=dword 双字 无符号long型)的复制
  • movq #完成8个字节(=qword 四字)的复制

movs的种类:

  • movsbw #作符号扩展的1字节复制到2字节
  • movsbl #作符号扩展的1字节复制到4字节
  • movsbq #作符号扩展的1字节复制到8字节
  • movswl #作符号扩展的2字节复制到4字节
  • movswq #作符号扩展的2字节复制到8字节
  • movslq #作符号扩展的4字节复制到8字节

movz的种类:

  • movzbw #作0扩展的1字节复制到2字节
  • movzbl #作0扩展的1字节复制到4字节
  • movzbq #作0扩展的1字节复制到8字节
  • movzwl #作0扩展的2字节复制到4字节
  • movzwq #作0扩展的2字节复制到8字节
  • movzlq #作0扩展的4字节复制到8字节

jmp指令

无条件转移指令,可跳转到内存中任何程序段,

转移地址可在指令中给出,也可在寄存器中给出,或在存储器中给出.

可同时修改 CS(代码段寄存器) 和 IP(指令指针寄存器),或仅修改IP.

只修改IP称为段内转移:jmp ax 相当于 mov ax,ip

同时修改的称为 段间转移:jmp 1000:0

jmp 指令要给出两种信息:

  • 转移的目的地址
  • 转移的距离(段间转移、段内转移、段内近转移)

跳转指令分三类:

  • 无条件跳转: JMP;

  • 根据 CX、ECX 寄存器的值跳转: JCXZ(CX 为 0 则跳转)、JECXZ(ECX 为 0 则跳转);

  • 根据 EFLAGS 寄存器的标志位跳转

jmp指令需要:

  • 转移的目的地址
  • 转移的距离
    • 段间转移(远转移): jmp 2000:1000
    • 段内短转移: jmp short 标号 ; IP的修改范围为 -128~127,8位的位移
    • 段内近转移: jmp near ptr 标号 ; IP的修改范围为 -32768~32767,16位的位移

img

依据位移进行转移的jmp指令:

语法: jmp short 标号(转到标号处执行指令)

这种格式的 jmp 指令实现的是段内短转移

它对 IP 的修改范围为 -128~127

short 符号表示指令进行的是短转移

标号 指明了指令要转移的目的地

比如:

1
2
3
4
5
6
7
8
9
assume cs:codesg

codesg segment
start:mov ax,0
jmp short s
add ax,1
s:inc ax // inc功能功能:目标操作数+1.
codesg ends
end start

程序执行后,ax 中的值为 1

因为执行 jmp short s 后,越过了 add ax,1

IP 指向了 标号 s 处的 inc ax

也就是说,程序只进行了一次 ax1 操作

此种转移方式并没有转移的目的地址,而是相对于当前 IP 的转移位移

另外,近转移ip修改范围: -32768~32767

转移的目的地址在指令中的jmp指令:

语法: jmp far ptr 标号

这种实现的是 段间转移 ,又称为远转移

(CS)=标号所在段的段地址(IP)=标号在段中的偏移地址

far ptr 指明了指令用标号的段地址和偏移地址修改 CS 和 IP

比如:

1
2
3
4
5
6
7
8
9
10
11
assume cs:codesg

codesg segment
start:mov ax,0
mov bx,0
jmp far ptr s
db 256 dup (0)
s:add ax,1
inc ax
codesg ends
end start

转移地址在寄存器中的jmp指令:

指令格式: jmp 16 位 reg

功能: (IP)=(16 位 reg)

比如:

1
2
3
4
5
6
jmp ax

指令执行前: ax=1000H ,CS=2000H ,IP=0003H

指令执行后: ax=1000H ,CS=2000H ,IP=1000H
jmp ax ,相当于: mov IP,ax

转移地址在内存中的jmp指令:

转移地址在内存中的jmp指令有两种格式

(1) jmp word ptr 内存单元地址(段内转移)

功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址

内存单元地址可用寻址方式的任一格式给出。

比如:

1
2
3
4
5
mov ax,0123H

mov ds:[0],ax

jmp word ptr ds:[0]

执行后, (IP)=0123H

又比如:

1
2
3
4
5
mov ax,0123H

mov [bx],ax

jmp word ptr [bx]

执行后, (IP)=0123H

(2) jmp dword ptr 内存单元地址(段间转移)

功能:从内存单元地址处开始存放着两个字,

高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址

1
2
(CS) = (内存单元地址+2)
(IP) = (内存单元地址)

内存单元地址可用寻址方式的任一格式给出

比如:

1
2
3
4
5
6
7
mov ax,0123H

mov ds:[0],ax

mov word ptr ds:[2],0

jmp dword ptr ds:[0]

执行后, (CS)=0 ,(IP)=0123H ,CS:IP 指向 0000:0123

再比如:

1
2
3
4
5
6
7
mov ax,0123H

mov [bx],ax

mov word ptr [bx+2],0

jmp dword ptr [bx]

执行后, (CS)=0 ,(IP)=0123H ,CS:IP 指向 0000:0123

8086 转移指令分几类:

  1. 无条件转移指令: 如 jmp
  2. 条件转移指令: 如 jcxz
  3. 循环指令: 如 loop
  4. 过程
  5. 中断

jmp short 标号 功能为:段内短转移

(IP)=(IP)+8位位移

  1. 8位位移 = 标号处的地址 - jmp指令后的第一个字节地址
  2. short指明的此处是8位位移
  3. 8位位移的范围为-128-127,用补码表示
  4. 8位位移是编译程序时在编译时算出的

jmp near ptr 标号 功能为:段内近转移

(IP)=(IP)+16位位移

  1. 16位位移 = 标号处的地址 - jmp指令后的第一个字节地址
  2. short指明的此处是8位位移
  3. 16位位移的范围为-32768-32767,用补码表示
  4. 16位位移是编译程序时在编译时算出的

根据标志位跳转的指令:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
JE   ;等于则跳转
JNE ;不等于则跳转

JZ ;为 0 则跳转
JNZ ;不为 0 则跳转

JS ;为负则跳转
JNS ;不为负则跳转

JC ;进位则跳转
JNC ;不进位则跳转

JO ;溢出则跳转
JNO ;不溢出则跳转

JA ;无符号大于则跳转
JNA ;无符号不大于则跳转
JAE ;无符号大于等于则跳转
JNAE ;无符号不大于等于则跳转

JG ;有符号大于则跳转
JNG ;有符号不大于则跳转
JGE ;有符号大于等于则跳转
JNGE ;有符号不大于等于则跳转

JB ;无符号小于则跳转
JNB ;无符号不小于则跳转
JBE ;无符号小于等于则跳转
JNBE ;无符号不小于等于则跳转

JL ;有符号小于则跳转
JNL ;有符号不小于则跳转
JLE ;有符号小于等于则跳转
JNLE ;有符号不小于等于则跳转

JP ;奇偶位置位则跳转
JNP ;奇偶位清除则跳转
JPE ;奇偶位相等则跳转
JPO ;奇偶位不等则跳转
跳转相关的标志位:
11109876543210
OFDFIFTFSFZFAFPFCF
溢 出符 号未 用辅 助未 用奇 偶未 用进 位

如果程序运行在 32位 模式下,常用的寄存器(register)有以下8个。

  1. EAX,EAX 是 累加器 (accumulator), 它是很多加法乘法指令的缺省寄存器。
  2. EBX,EBX 是 基地址(base)寄存器, 在内存寻址时存放基地址。
  3. ECX,ECX 是 计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。
  4. EDX,EDX 总是被用来放整数除法产生的余数。
  5. EBP,EBP是 基址指针(BASE POINTER), 软件破解领域 经常用到这个 基址
  6. ESP ,ESP 是 堆栈指针(stack point)
  7. ESI/EDI,分别叫做 源/目标索引寄存器(source/destination index),因为在很多字符串操作指令中,DS:ESI 指向源串,而 ES:EDI 指向目标串.

一共有 8 个 通用 寄存器,什么是通用

就是 EAX 寄存器可以干 EBX 寄存器的活。他们其实都是同一种寄存器,CPU 提供的寄存器,只是从使用习惯上 EAX 叫 EAX

乘法指令能不能用 EBX 寄存器?也是可以的,只是使用习惯上没这么搞。

不熟悉 AT&T 汇编语法的可以先快速看一遍 官方文档 《Using as-The GNU Assembler》

相应的 X86 指令可以查 《英特尔® 64 位和 IA-32 架构开发人员手册》。

  1. 《英特尔® 64 位和 IA-32 架构开发人员手册:卷 1》
  2. 《英特尔® 64 位和 IA-32 架构开发人员手册:卷 2A》
1
.section .data

汇编程序中以.开头的名称并不是指令的助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为汇编指示(Assembler Directive)或伪操作(Pseudo-operation),由于它不是真正的指令所以加个“伪”字。.section指示把代码划分成若干个段(Section),程序被操作系统加载执行时,每个段被加载到不同的地址,操作系统对不同的页面设置不同的读、写、执行权限。.data段保存程序的数据,是可读可写的,相当于C程序的全局变量。本程序中没有定义数据,所以.data段是空的。

1
.section .text

.text段保存代码,是只读和可执行的,后面那些指令都属于.text段。

1
.globl _start

_start是一个符号(Symbol),符号在汇编程序中代表一个地址,可以用在指令中,汇编程序经过汇编器的处理之后,所有的符号都被替换成它所代表的地址值。在C语言中我们通过变量名访问一个变量,其实就是读写某个地址的内存单元,我们通过函数名调用一个函数,其实就是跳转到该函数第一条指令所在的地址,所以变量名和函数名都是符号,本质上是代表内存地址的。

.globl指示告诉汇编器,_start这个符号要被链接器用到,所以要在目标文件的符号表中标记它是一个全局符号。_start就像C程序的main函数一样特殊,是整个程序的入口,链接器在链接时会查找目标文件中的_start符号代表的地址,把它设置为整个程序的入口地址,所以每个汇编程序都要提供一个_start符号并且用.globl声明。如果一个符号没有用.globl声明,就表示这个符号不会被链接器用到。

1
_start:

这里定义了_start符号,汇编器在翻译汇编程序时会计算每个数据对象和每条指令的地址,当看到这样一个符号定义时,就把它后面一条指令的地址作为这个符号所代表的地址。而_start这个符号又比较特殊,它所代表的地址是整个程序的入口地址,所以下一条指令movl $1, %eax就成了程序中第一条被执行的指令。

可以参考CS216, University of Virginia

国外CS课程所用资料,篇幅简短,逻辑清晰,合适作为入门参考.以原理为主,有两个例子帮助理解.

翻译:[译] 简明 x86 汇编指南

1: 基本结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DATAS SEGMENT
;此处输入数据段代码
DATAS ENDS

STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS ;段寻址伪指令用来指明段与段寄存器的对应关系
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
MOV AH,4CH ;
INT 21H ; dos系统调用系统终端 执行AH程序中程序退出指令
CODES ENDS
END START ; 指定开始的地址

2:基本指令

一、数据传送指令

1、传送指令:MOV (move)

(1) CPU内部寄存器之间的数据传送,如:mov ah,al

(2) 立即数送至通用寄存器(非段寄存器)或存储单元,如:mov al,3 mov [bx],1234h

(3) 寄存器与存储器间的数据传送,如:mov ax,var mov ax,[bx]

二、堆栈操作指令

1、进栈指令:push

格式:push src
功能: 把16位数据src压入堆栈。
注: 源操作数src可以是通用寄存器和段寄存器,也可以是字存储单元

如: push si
push [si]
push var ;var是16位(字)变量
2、出栈指令:pop

格式:pop dst
功能:从堆栈弹出16位数据至dst
注: dst可以是通用寄存器和段寄存器,但不能是CS,可以是字存储单元

如: pop si
pop [si]
pop var ;var是字变量

三 加减运算指令

(1) add(Addtion)
格式:add OPRD1,OPRD2
功能:OPRD1 = OPRD1 + OPRD2
注: 影响FLAG

如:add al,5
add bl,var ;var是字节变量
add var,si ;var是字变量

(2) adc(add with Carry) ;带进位的加法
格式:adc OPRD1,OPRD2
功能:带进位的加法,OPRD1 = OPRD1 + OPRD2 + CF
注: 影响FLAG,主要用于多字节运算

如: adc al,[bx]
adc dx,ax
adc dx,var ;var是字变量

(3) inc(Increment)
格式:inc OPRD
功能:OPRD = OPRD + 1
注: 不影响CF

如:inc al
inc var ;var是字节变量,也可以是字变量
inc cx

2、减法指令:sub、sbb、dec、neg、cmp

(1) sub(Subtraction)
格式:sub OPRD1,OPRD2
功能:OPRD1 = OPRD1 - OPRD2

如: sub ah,12
sub bx,bp
sub al,[bx]
sub [BP],AX
sub AX,VAR ;VAR是字变量

(2) sbb(Sub with Borrow)
格式:sbb OPRD1,OPRD2
功能:OPRD1 = OPRD1 - OPRD2 - CF
注: 主要用于多字节数相减的情况

(3) dec(decrement)
格式:dec OPRD
功能:OPRD = OPRD - 1
注: 操作数OPRD可以是通用寄存器,也可以是存储单元。相减时把操作数作为一个无符号数对待,这条指令影响ZF、SP、OF、PF、AF,但不影响CF,该指令主要用于调整地址指针和计数器。

(4) neg(Negate)
格式:NEG OPRD
功能:对操作数取补,即OPRD = 0 - OPRD
注: 操作数可以是通用寄存器,也可以是存储单元。此指令结果影响CF、ZF、OF、AF、PF,一般会使CF为1,除非OPRD=0

(5) cmp(Compare)
格式:cmp OPRD1,OPRD2
功能:执行OPRD1 - OPRD2,但运算结果不运送到OPRD1
注: 该指令通过OPRD - OPRD2影响标志位CF、ZF、SF、OF、AF、PF来判断OPRD1和OPRD2的大小关系。通过ZF判断是否相等;如果是无符号数,通过CF可判断大小;如果是有符号数,通过SF和OF判断大小

四、乘除运算指令

(1) mul(Multiply) ;无符号数乘法指令
格式:MUL OPRD
功能:将OPRD与AX或AL中的操作数相乘,结果保存在DX:AX中或AX中
注: 无符号数相乘分为16位16位和8位8位,结果分别为32位和16位,保存在DX:AX中或AX中,其中结果为32位时,DX为高16位,AX为低16位;结果为16位时,AH为高8位,AL为低8位。

(2) imul(Signed Multiply) ;有符号数乘法指令
格式:IMUL OPRD
功能:把乘数和被乘数均作为有符号数进行乘法运算。其余与mul类似
注: 如果乘积结果的高位部分(DX或AH)不是低位的符号扩展,则CF=1,OF=1,否则CF=0,OF=0。即CF=1,OF=1表示AH或DX中含有结果的有效数。
如果除数为0,或8位数除时商超过8位,16位数除时商超过16位,则认为是除溢出,引起0号中断。除法指令对标志位的影响无定义。

2、除法指令:div、idiv

(1) div(Division) ;无符号数除法指令
格式:DIV OPRD
功能:OPRD为除数,被除数存放在DX:AX或AX中,做除法,结果存放在DX:AX(DX存放余数,AX存放商)或AX(AH余数,AL商)。
注: 8086中除法有32位除以16位和16位除以8位。前者被除数为32位,高位在DX中,低位在AX中,除数OPRD为16位通用寄存器或16位存储器操作数,结果为16位,其中16位余数存放在DX中,16位商存放在AX中;若为16位除以8位,被除数存放在AX中,OPRD为8位通用寄存器或存储器操作数,结果8位余数存放在AH中,8位商存放在AL中。

(2) idiv(Signed Division) ;有符号数除法指令
格式:IDIV OPRD
功能:把除数和被除数看做有符号数做除法,其余与div类似

3、符号扩展指令:cbw、cwd

(1) cbw(Convert Byte to Word)
格式:CBW
功能:把寄存器AL中的符号位扩展到寄存器AH

(2) cwd(Convert Word to Double Word)
格式:CWD
功能:把寄存器AX中的符号扩展到寄存器DX

五、逻辑运算和移位指令

(1) NOT
格式:NOT OPRD
功能:把操作数OPRD取反,然后送回OPRD。
注: OPRD可以是通用寄存器,也可以是存储器操作数,此指令对标志没有影响

(2) AND
格式:AND OPRD1,OPRD2
功能:对两个操作数进行按位逻辑“与”运算,结果送到OPRD1中
注: 该指令执行后,CF=0,OF=0,标志PF、ZF、SF反映运算结果,AF未定义。
某个操作数与自身相与,值不变,但可以使CF置0。

(3) OR
格式:OR OPRD1,OPRD2
功能:对两个操作数进行按位逻辑“或”运算,结果送到OPRD1中
注: 该指令执行后,CF=0,OF=0,标志PF、ZF、SF反映运算结果,AF未定义。
某个操作数与自身相或,值不变,但可以使CF置0。

(4) XOR
格式:XOR OPRD1,OPRD2
功能:对两个操作数进行按位逻辑“异或”运算,结果送到OPRD1中
注: 该指令执行后,CF=0,OF=0,标志PF、ZF、SF反映运算结果,AF未定义。

(5) TEST
格式:TEST OPRD1,OPRD2
功能:把OPRD1与OPRD2按位“与”,但结果不送到OPRD1中,仅影响标志位。
注: 该指令执行后,CF=0,OF=0,标志PF、ZF、SF反映运算结果。常用于检测某些位是否为1

2、一般移位指令:SAL/SHL,SAR/SHR

(1) SAL/SHL(Shift Arithmetic Left / Shift Logic Left) ;算术左移/逻辑左移
格式:SAL OPRD,m
SHL OPRD,m
功能:把操作数OPRD左移m位,每移动一位,右边用0补足1位,移出的最高位进入标志位CF
注: 算术左移和逻辑左移进行相同的动作,为了方便提供了两个助记符。

(2) SAR(Shift Arithmetic Right) ;算数右移指令
格式:SAR OPRD,m
功能:操作数右移m位,同时每移1位,左边的符号位保持不变,移出的最低位进入标志位CF
注: 对有符号数和无符号数,算数右移1位相当于除以2

(3) SHR(Shift Logic Right) ;逻辑右移指令
格式:SHR OPRD,m
功能:操作数右移m位,同时每移1位,左边用0补足,移出的最低位进入标志位CF
注: 对无符号数,逻辑右移1位相当于除以2

3、循环移位指令:ROL、ROR、RCL、RCR

4 、循环指令:LOOP、LOOPE/LOOPZ、LOOPNE/LOOPNZ、JCXZ

(1) Loop ;计数循环指令
格式:loop 标号
功能:使转移标号与Loop指令间的指令循环执行CX次
原理:指令执行至loop时,cx减1,如果cx不为0,则跳转至标号处,否则继续执行下一条指令
即:DEC CX
JNZ 标号

(2) LOOPE/LOOPZ ;等于/全零循环指令
格式:LOOPE 标号
LOOPZ 标号
功能:该指令使CX自减1,若结果不为0,并且ZF=1,则转移至标号,否则顺序执行。注意指令本身实施的CX自减1操作不影响标志

(3) LOOPNE/LOOPNZ ;不等于/非零循环指令
格式:LOOPNE 标号
LOOPNZ 标号
功能:该指令使CX自减1,若结果不为0,并且ZF=0,则转移至标号,否则顺序执行。注意指令本身实施的CX自减1操作不影响标志

(4) JCXZ ;跳转指令
格式:JCXZ 标号
功能:当寄存器CX的值为0时跳转到标号,否则顺序执行

跳转指令汇总:

助记符说明标志位/寄存器助记符说明标志位/寄存器
JZ为零跳转ZF=1JNO无溢出跳转OF=0
JNZ非零跳转ZF=0JS有符号跳转SF=1
JC进位跳转CF=1JNS无符号跳转SF=0
JNC无进位跳转CF=0JP偶校验跳转PF=1
JO溢出跳转OF=1JNP奇校验跳转PF=0
助记符说明
JE相等跳转 (leftOp=rightOp)
JNE不相等跳转 (leftOp M rightOp)
JCXZCX=0 跳转
JECXZECX=0 跳转
JRCXZRCX=0 跳转(64 位模式)
助记符说明助记符说明
JA大于跳转(若 leftOp > rightOp)JB小于跳转(若 leftOp < rightOp)
JNBE不小于或等于跳转(与 JA 相同)JNAE不大于或等于跳转(与 JB 相同)
JAE大于或等于跳转(若 leftOp ≥ rightOp)JBE小于或等于跳转(若 leftOp ≤ rightOp)
JNB不小于跳转(与 JAE 相同)JNA不大于跳转(与 JBE 相同)
助记符说明助记符说明
JG大于跳转(若 leftOp > rightOp)JL小于跳转(若 leftOp < rightOp)
JNLE不小于或等于跳转(与 JG 相同)JNGE不大于或等于跳转(与 JL 相同)
JGE大于或等于跳转(若 leftOp ≥ rightOp)JLE小于或等于跳转(若 leftOp ≤ rightOp)
JNL不小于跳转(与 JGE 相同)JNG不大于跳转(与 JLE 相同)

3:通用寄存器用途

通用寄存器的主要用途

寄存器的分类寄存器主 要 用 途
通用寄存器数据 寄存器AX乘、除运算,字的输入输出,中间结果的缓存
AL字节的乘、除运算,字节的输入输出,十进制算术运算
AH字节的乘、除运算,存放中断的功能号
BX存储器指针
CX串操作、循环控制的计数器
CL移位操作的计数器
DX字的乘、除运算,间接的输入输出
变址 寄存器SI存储器指针、串指令中的源操作数指针
DI存储器指针、串指令中的目的操作数指针
变址 寄存器BP存储器指针、存取堆栈的指针
SP堆栈的栈顶指针
指令指针IP/EIP
标志位寄存器Flag/EFlag
32位CPU的段寄存器16位CPU的段寄存器ES附加段寄存器
CS代码段寄存器
SS堆栈段寄存器
DS数据段寄存器
新增加的 段寄存器FS附加段寄存器
GS附加段寄存器

4:常用DOS指令表

表:DOS系统功能调INT 21H

AH功能调用参数返回参数
00程序终止(同INT 20H)CS=程序段前缀
01键盘输入并回显AL=输入字符
02显示输出DL=输出字符
03异步通迅输入AL=输入数据
04异步通迅输出DL=输出数据
05打印机输出DL=输出字符
06直接控制台I/ODL=FF(输入) DL=字符(输出)AL=输入字符
07键盘输入(无回显)AL=输入字符
08键盘输入(无回显) 检测Ctrl-BreakAL=输入字符
09显示字符串DS:DX=串地址 ‘$’结束字符串
0A键盘输入到缓冲区DS:DX=缓冲区首地址 (DS:DX)=缓冲区最大字符数(DS:DX+1)=实际输入的字符数
0B检验键盘状态AL=00 有输入 AL=FF 无输入
0C清除输入缓冲区并 请求指定的输入功能AL=输入功能号 (1,6,7,8,A)
0D磁盘复位清除文件缓冲区
0E指定当前缺省的磁盘驱动器DL=驱动器号 0=A,1=B,…AL=驱动器数
0F打开文件DS:DX=FCB首地址AL=00 文件找到 AL=FF 文件未找到
10关闭文件DS:DX=FCB首地址AL=00 目录修改成功 AL=FF 目录中未找到文件
11查找第一个目录项DS:DX=FCB首地址AL=00 找到 AL=FF 未找到
12查找下一个目录项DS:DX=FCB首地址 (文件中带有*或?)AL=00 找到 AL=FF 未找到
13删除文件DS:DX=FCB首地址AL=00 删除成功 AL=FF 未找到
14顺序读DS:DX=FCB首地址AL=00 读成功 =01 文件结束,记录中无数据 =02 DTA空间不够 =03 文件结束,记录不完整
15顺序写DS:DX=FCB首地址AL=00 写成功 =01 盘满 =02 DTA空间不够
16建文件DS:DX=FCB首地址AL=00 建立成功 =FF 无磁盘空间
17文件改名DS:DX=FCB首地址 (DS:DX+1)=旧文件名 (DS:DX+17)=新文件名AL=00 成功 AL=FF 未成功
19取当前缺省磁盘驱动器AL=缺省的驱动器号 0=A,1=B,2=C,…
1A置DTA地址DS:DX=DTA地址
1B取缺省驱动器FAT信息AL=每簇的扇区数 DS:BX=FAT标识字节 CX=物理扇区大小 DX=缺省驱动器的簇数
1C取任一驱动器FAT信息DL=驱动器号同上
21随机读DS:DX=FCB首地址AL=00 读成功 =01 文件结束 =02 缓冲区溢出 =03 缓冲区不满
22随机写DS:DX=FCB首地址AL=00 写成功 =01 盘满 =02 缓冲区溢出
23测定文件大小DS:DX=FCB首地址AL=00 成功(文件长度填入FCB) AL=FF 未找到
24设置随机记录号DS:DX=FCB首地址
25设置中断向量DS:DX=中断向量 AL=中断类型号
26建立程序段前缀DX=新的程序段前缀
27随机分块读DS:DX=FCB首地址 CX=记录数AL=00 读成功 =01 文件结束 =02 缓冲区太小,传输结束 =03 缓冲区不满
28随机分块写DS:DX=FCB首地址 CX=记录数AL=00 写成功 =01 盘满 =02 缓冲区溢出
29分析文件名ES:DI=FCB首地址 DS:SI=ASCIIZ串 AL=控制分析标志AL=00 标准文件 =01 多义文件 =02 非法盘符
2A取日期CX=年 DH:DL=月:日(二进制)
2B设置日期CX:DH:DL=年:月:日AL=00 成功 =FF 无效
2C取时间CH:CL=时:分 DH:DL=秒:1/100秒
2D设置时间CH:CL=时:分 DH:DL=秒:1/100秒AL=00 成功 =FF 无效
2E置磁盘自动读写标志AL=00 关闭标志 AL=01 打开标志
2F取磁盘缓冲区的首址ES:BX=缓冲区首址
30取DOS版本号AH=发行号,AL=版本
31结束并驻留AL=返回码 DX=驻留区大小
33Ctrl-Break检测AL=00 取状态 =01 置状态(DL) DL=00 关闭检测 =01 打开检测DL=00 关闭Ctrl-Break检测 =01 打开Ctrl-Break检测
35取中断向量AL=中断类型ES:BX=中断向量
36取空闲磁盘空间DL=驱动器号 0=缺省,1=A,2=B,…成功:AX=每簇扇区数 BX=有效簇数 CX=每扇区字节数 DX=总簇数 失败:AX=FFFF
38置/取国家信息DS:DX=信息区首地址BX=国家码(国际电话前缀码) AX=错误码
39建立子目录(MKDIR)DS:DX=ASCIIZ串地址AX=错误码
3A删除子目录(RMDIR)DS:DX=ASCIIZ串地址AX=错误码
3B改变当前目录(CHDIR)DS:DX=ASCIIZ串地址AX=错误码
3C建立文件DS:DX=ASCIIZ串地址 CX=文件属性成功:AX=文件代号 错误:AX=错误码
3D打开文件DS:DX=ASCIIZ串地址 AL=0 读 =1 写 =3 读/写成功:AX=文件代号 错误:AX=错误码
3E关闭文件BX=文件代号失败:AX=错误码
3F读文件或设备DS:DX=数据缓冲区地址 BX=文件代号 CX=读取的字节数读成功: AX=实际读入的字节数 AX=0 已到文件尾 读出错:AX=错误码
40写文件或设备DS:DX=数据缓冲区地址 BX=文件代号 CX=写入的字节数写成功: AX=实际写入的字节数 写出错:AX=错误码
41删除文件DS:DX=ASCIIZ串地址成功:AX=00 出错:AX=错误码(2,5)
42移动文件指针BX=文件代号 CX:DX=位移量 AL=移动方式(0:从文件头绝对位移,1:从当前位置相对移动,2:从文件尾绝对位移)成功:DX:AX=新文件指针位置 出错:AX=错误码
43置/取文件属性DS:DX=ASCIIZ串地址 AL=0 取文件属性 AL=1 置文件属性 CX=文件属性成功:CX=文件属性 失败:CX=错误码
44设备文件I/O控制BX=文件代号 AL=0 取状态 =1 置状态DX =2 读数据 =3 写数据 =6 取输入状态 =7 取输出状态DX=设备信息
45复制文件代号BX=文件代号1成功:AX=文件代号2 失败:AX=错误码
46人工复制文件代号BX=文件代号1 CX=文件代号2失败:AX=错误码
47取当前目录路径名DL=驱动器号 DS:SI=ASCIIZ串地址(DS:SI)=ASCIIZ串 失败:AX=出错码
48分配内存空间BX=申请内存容量成功:AX=分配内存首地 失败:BX=最大可用内存
49释放内容空间ES=内存起始段地址失败:AX=错误码
4A调整已分配的存储块ES=原内存起始地址 BX=再申请的容量失败:BX=最大可用空间 AX=错误码
4B装配/执行程序DS:DX=ASCIIZ串地址 ES:BX=参数区首地址 AL=0 装入执行 AL=3 装入不执行失败:AX=错误码
4C带返回码结束AL=返回码
4D取返回代码AX=返回代码
4E查找第一个匹配文件DS:DX=ASCIIZ串地址 CX=属性AX=出错代码(02,18)
4F查找下一个匹配文件DS:DX=ASCIIZ串地址 (文件名中带有?或*)AX=出错代码(18)
54取盘自动读写标志AL=当前标志值
56文件改名DS:DX=ASCIIZ串(旧) ES:DI=ASCIIZ串(新)AX=出错码(03,05,17)
57置/取文件日期和时间BX=文件代号 AL=0 读取 AL=1 设置(DX:CX)DX:CX=日期和时间 失败:AX=错误码
58取/置分配策略码AL=0 取码 AL=1 置码(BX)成功:AX=策略码 失败:AX=错误码
59取扩充错误码AX=扩充错误码 BH=错误类型 BL=建议的操作 CH=错误场所
5A建立临时文件CX=文件属性 DS:DX=ASCIIZ串地址成功:AX=文件代号 失败:AX=错误码
5B建立新文件CX=文件属性 DS:DX=ASCIIZ串地址成功:AX=文件代号 失败:AX=错误码
5C控制文件存取AL=00封锁 =01开启 BX=文件代号 CX:DX=文件位移 SI:DI=文件长度失败:AX=错误码
62取程序段前缀BX=PSP地址