jjzjj

8086指令系统(8086基本知识点)

哆啦BCD梦 2023-05-21 原文

目录

一.指令的寻址

1 操作数寻址

1.1 立即数寻址

1.2 寄存器寻址

1.3 直接寻址

1.4 寄存器间接寻址

1.5 寄存器相对寻址

1.6 隐含寄存器的操作数

2 指令地址寻址

二.8086指令系统

1 数据传送指令

1.1通用传送指令MOV

1.2堆栈操作指令PUSH与POP

1.3交换指令 XCHG

1.4换码指令 XLAT(Translate)

1.5输入输出指令IN与OUT

2地址传送指令

2.1LEA(Load Effective Address)

2.2LDS(LOAD into DS)

2.3LES(LOAD into ES)

3 标志传送指令

3.1 LAHF(Load AH with Flags)

3.2 SAHF(Store AH onto Flags)

3.3 PUSHF

3.4 POPF

4 算数运算指令

4.1加法指令(不带进位位)ADD

4.2加法指令(带进位位)ADC(ADD with Carry)

4.3 增量指令INC(Increasment)

4.4 减法指令(不考虑借位)SUB(Substract)

4.5 减法指令(考虑借位)SBB(Substract with Borrow)

4.6 减量指令(DEC)

4.7 求补指令NEG(Negate)

4.8 比较指令CMP

4.9 无符号数乘法指令MUL

4.10 有符号数乘法指令IMUL

4.11 无符号数除法指令DIV

4.12 有符号数除法指令IDIV

4.13 BCD码加法调整指令DAA(Decimal Adjust for Addition)

4.14 BCD码减法调整指令DAS(Decimal Adjust for Substraction)

4.15 非组合BCD码的调整

5 逻辑运算指令

5.1 逻辑与指令AND

5.2 逻辑或指令OR

5.3 逻辑异或指令XOR

5.4 逻辑非指令NOT

5.5 测试指令TEST

6 移位指令

6.1 非循环移位指令

6.2 循环移位指令

7 串操作指令

7.1 字符串传送指令MOVSB(Move String Byte)与MOVSW

7.2 字符串比较指令CMPSB与CMPSW

7.3 字符串检索指令SCASB(Scan String Byte)与SCASW

7.4 字符串转移指令LODSB(Load String Byte)与LODSW

7.5 存字符串指令STOSB与STOSW

8 控制转移指令

8.1 指令寻址方式

8.2 子程序调用及返回指令CALL

8.3 子程序返回指令RET

8.4  无条件转移指令JMP及各种条件转移指令

8.5 循环控制指令LOOP,LOOPZ/LOOPE,LOOPNZ/LOOPNE

8.6 中断指令与中断返回指令INT(Interrupt)

8.7 处理器控制指令(不影响任何标志)


一.指令的寻址

1 操作数寻址

1.1 立即数寻址

MOV CL,05H

1.2 寄存器寻址

MOV AX,BX

1.3 直接寻址

MOV AX,[3100H]

1.4 寄存器间接寻址

寄存器可以为BX,BP,SI,DI,BP的默认段为SS,BP中存放的一般是要访问数据的偏移量,其余默认段为DS ,需要修改段需要加前缀说明

MOV BX,[DI]

1.5 寄存器相对寻址

有效地址EA由寄存器加偏移量产生,寄存器同上可以为BX,BP,SI,DI

例如假设表格首地址为COUNT(BX为基址寄存器,SI为变址寄存器)

MOV SI,n-1

-------------------------------------

MOV AL,[SI+COUNT]

或者

MOV BX COUNT

MOV AX,[SI][BX]

可以用来定位表格第n项元素

假设MASK为栈首地址道数组首地址的位移量,可以利用MASK+BP+SI(BP里存放栈顶值,SI中存放栈顶偏移量,栈底到栈顶地址逐渐减小)

1.6 隐含寄存器的操作数

例如乘法指令

MUL CL

隐含AL寄存器,结果存放在AX中

2 指令地址寻址

如无条件转移指令JMP

二.8086指令系统

1 数据传送指令

1.1通用传送指令MOV

两个操作数可以都是寄存器,一个寄存器一个内存地址,或者源操作数是立即数,目的操作数是寄存器或者内存地址

特殊情况:

CS:IP指向下一条将要执行的指令,二者不能作为目的操作数,只能作为源操作数

不能将立即数传给段寄存器,段寄存器之间也不能直接互相传值,中间需要某个通用寄存器过渡

内存单元不能同时作为源操作数与目的操作数

1.2堆栈操作指令PUSH与POP

两个指令后直接加操作数,压栈与弹栈都是按照字节操作,压栈与弹栈影响SP的值,压栈SP-2,弹栈SP+2

特殊情况:

CS值可以压栈,栈中除断点以外的值不能弹入CS

1.3交换指令 XCHG

XCHG OP1,OP2

特殊情况:

二者不能同时为内存单元地址,不能为段寄存器,不能为立即数

不能出现CS与IP

目的操作数与源操作数的位数相同

1.4换码指令 XLAT(Translate)

该指令在内存中有码表的情况下对AX与BX进行操作,BX存码表首地址,AX存偏移量,结果存入AX中

首先给AX与BX传入数据(DISP_TABLE为表的标号)

MOV BX,OFFSET DISP_TABLE

MOV AL,5

然后直接写出语句即可

XLAT

1.5输入输出指令IN与OUT

只能使用累加器作为传送数据的寄存器,AL供8位端口传送,AX供16位端口(可以理解为接口中的寄存器)传送,每个8位端口都有一个地址,被称为端口号,相邻两个8位端口组成16位端口,PC机仅用10位地址线(A0~A9)译码,A9为0(000H~1FFH)用作主机板IO译码,A9为1(200H~3FFH)用作扩展板IO译码,如硬盘适配器内部的寄存器编码

端口号在00H~FFH范围内的端口,采用直接输入输出指令,例如:

IN AL,44H

端口号在FFH以上的端口,采用间接输入输出指令,只用DX作为间接寻址的寄存器,可以扩大寻址范围,例如:

MOV DX,3FCH

IN AX,DX

2地址传送指令

2.1LEA(Load Effective Address)

将某一内存单元的地址送入某一寄存器,例如:

MOV BX,OFFSET DISP_TABLE

LEA BX,DISP_TABLE

2.2LDS(LOAD into DS)

将4B的内存单元低两个字节作为偏移量送入某一个寄存器,高两个字节作为段地址送入DS,例如:

LDS DI,[2130H]

2.3LES(LOAD into ES)

与上一条指令同理,只不过将高两位字节作为段地址送入ES,例如:

LES ES,[2130H]

3 标志传送指令

标志寄存器内部重要位的意义:

 

 CF,PF,AF,ZF,SF,OF为状态标志,TF,IF,DF为控制标志,是人为设置的

标志寄存器总共16位,有七位没有用到,剩下9位的意义如下:

CF(Carry Flag):进位标志

PF(Parity Flag):运算结果低8位是否为偶数

AF(Auxiliary Carry Flag):辅助进位标志,表示前四位是否对后四位有进位,用于BCD码调整

ZF(Zero Flag):零标志

SF(Sign Flag):运算结果的最高位

OF(Overflow Flag):溢出标志

DF(Direction Flag):控制串操作方向的标志,DF为0自增

IF(Intrrupt Flag):可屏蔽中断标志,IF=1允许中断

TF(Trap Flag):跟踪标志,为1的话CPU以跟踪方式运行,用于程序调试

3.1 LAHF(Load AH with Flags)

3.2 SAHF(Store AH onto Flags)

3.3 PUSHF

用于子程序和标志处理子程序保护标志寄存器的过程

3.4 POPF

4 算数运算指令

4.1加法指令(不带进位位)ADD

ADD OP1,OP2

有符号数与无符号数的加减运算可以使用同一套指令系统

有符号数溢出用OF位判断,无符号数溢出用CF位判断

4.2加法指令(带进位位)ADC(ADD with Carry)

OP2+OP1+CF->OP1

例:进位加法

MOV SI,2000H

MOV AX,[SI]

MOV DI,3000H

ADD AX,[DI]

MOV [SI],AX

MOV AX,[SI+2]

ADC AX,[DI+2]

MOV [SI+2],AX

4.3 增量指令INC(Increasment)

例如:

INC BYTE PTR [BX+DI+500]

4.4 减法指令(不考虑借位)SUB(Substract)

SUB OP1,OP2

例如:

SUB WORD PTR [DI],1000H

4.5 减法指令(考虑借位)SBB(Substract with Borrow)

4.6 减量指令(DEC)

例如:

DEC AX

4.7 求补指令NEG(Negate)

0-OP->OP

除非OP为1,否则0-OP必须借位,导致CF位一般为1

4.8 比较指令CMP

本质上是减法指令,但是结果不回送,只影响标志位

例如:

CMP OP1,OP2

若OP1=OP2

ZF位为0

无符号数判定大小,相减后观察CF标志

有符号数同号数相减后观察SF位

有符号数异号数相减后观察OF位与SF位,若OF=0,没有溢出的情况下,SF=0,OP1>OP2,反之OP1<OP2,若OF=1,在溢出情况下,SF=1,说明是正数减负数向正方向溢出,OP1>OP2,反之OP1<OP2,综上SF与OF相等时,OP1>OP2,SF与OF不等时,OP1<OP2

4.9 无符号数乘法指令MUL

两个8位操作数相乘,结果存入AX中

两个16位操作数相乘,结果存入AX与DX中

4.10 有符号数乘法指令IMUL

IMUL OP(另一个操作数隐含入AL或者AX中)

4.11 无符号数除法指令DIV

除法指令使用原则:

①除数必须为被除数一半长,被除数的位数不足时进行扩展

CBW(Convert Byte to Word)

CWD(Convert Word to Double Word)

②被除数放入AX中或者AX与DX中,DX为AX的扩展

③商放入AL/AX中,余数放入AH/DX中

④8086规定余数的符号与被除数相同

⑤商超过8位产生0中断

例如:DIV OP

4.12 有符号数除法指令IDIV

4.13 BCD码加法调整指令DAA(Decimal Adjust for Addition)

调整方法:将不正确的四位加0110B

调整对象:AF=1或CF=1或出现无效码

4.14 BCD码减法调整指令DAS(Decimal Adjust for Substraction)

4.15 非组合BCD码的调整

非组合BCD码:高四位为0,低四位表示十进制数

假如两位十进制数相加结果分别存放于AH与AL中,需要根据进位标志或者无效码决定是否给AL加上0000 0110B,是否给AH加进位值,如果AL经过调整,还需要将高四位置0,即AL&0FH

指令:

AAA(ASCII Adjust for Addition)

AAS(ASCII Adjust for Substract)

AAM(ASCII Adjust for Multiplication)

AAD(ASCII Adjust for Division)

5 逻辑运算指令

除了NOT指令外,其余的逻辑指令都会让CF与OF位清零,AF的值不变,并对SF,PF,ZF产生影响

5.1 逻辑与指令AND

AND OP1,OP2

5.2 逻辑或指令OR

OR OP1,OP2

5.3 逻辑异或指令XOR

XOR OP1,OP2

5.4 逻辑非指令NOT

NOT OP

5.5 测试指令TEST

TEST指令与AND指令执行相同的操作,只不过只改变标志位,后面一般接JNZ或者JZ指令,根据ZF的值判断是否转移

6 移位指令

移位指令只有移位次数为1时OF才有意义,移位后CF与最高位不同OF=1,否则OF=0

移位次数要么为1,要么放入CL中,例如

SAL AL,3

SAL AL,BL

都是无效指令

6.1 非循环移位指令

SAL(Shift Arithmetic Left)

SHL(Shift Logic Left)

SAR

SAR与IDIV指令的区别是SAR对负数向上舍入,IDIV对负数向下舍入

SHR

6.2 循环移位指令

ROL(Rotate Left)

RCL(Rotate Through CF Left)

ROR

RCR

 例如:将1000H内存单元中的非组合BCD码转换为组合BCD码

MOV CL,4

MOV SI,1000H

MOV AX,WORD PTR[SI]

SHL AL,CL

SHR AX,CL

7 串操作指令

串操作指令是唯一一个允许源操作数与目的操作数都在内存中的一组指令

默认以SI作为源操作数指针寄存器,默认段为DS段

默认以DI作为目的操作数指针寄存器,默认段为ES段

串操作方向与DF有关,0增1减

字符串操作SI与DI加减1,字串操作SI与DI加减2

7.1 字符串传送指令MOVSB(Move String Byte)与MOVSW

MOV SI,1000H

MOV DI,2000H

MOV CX,100

CLD

K:MOVSB

DEC CX

JNZ K

7.2 字符串比较指令CMPSB与CMPSW

用于比较两个字符串

前缀1:REPE(Repeat Equal)或者REPZ,CX≠0并且ZF=1继续比较,寻找第一个不等元素

前缀2:REPNE或者REPNZ,CX≠0并且ZF=0继续比较,寻找第一个相等元素

例:

LEA SI,STR2

LEA DI,STR1

MOV CX,3

CLD

REPZ CMPSB

JZ MATCH

AND AL,0

HLT

MATCH:MOV AL,1

HLT

7.3 字符串检索指令SCASB(Scan String Byte)与SCASW

用于检索AL中的字符在串STR中的位置

前缀1:REPE(Repeat Equal)或者REPZ,CX≠0并且ZF=1继续比较,寻找第一个不等元素

前缀2:REPNE或者REPNZ,CX≠0并且ZF=0继续比较,寻找第一个相等元素

例:

LEA DI,STR

CLD

MOV CX,4

MOV BX,4

REPNZ SCANSB

JZ FND

OR BX,FFFFH

HLT

FND:SUB BX,CX

HLT

7.4 字符串转移指令LODSB(Load String Byte)与LODSW

功能是将DS:SI所指示的内存单元存入AL或者AX中

例:

CLD

MOV CL,5

MOV SI,0700H

MOV DI,SI

LI:LODSB

PUSH CX

处理过程(处理过程可能会影响CS寄存器,所以要压栈)

POP CX

DEC CX

MOV [DI],AL

JNZ LI

7.5 存字符串指令STOSB与STOSW

功能是将AL或者AX寄存器中的内容存入ES:DI对应的存储单元中

8 控制转移指令

8.1 指令寻址方式

段内直接转移:当前IP加位移量

段内简介转移:IP=寄存器内容所对应的内存单元

段间直接转移:需要同时指出CS值与IP值

段间间接转移:寄存器对应内存单元存放着新的段地址与段内偏移量

8.2 子程序调用及返回指令CALL

可以使用上述任何一种指令寻址方式,与RET指令配合使用,将CALL的下一条指令地址压入栈中,子程序出口使用RET语句弹出

例如:

CALL DWORD PTR[DI]

涉及4B一定是段间间接转移

8.3 子程序返回指令RET

RET后可以加参数n,n为偶数,返回后SP+n,因为子程序可能用到堆栈产生无用值

8.4  无条件转移指令JMP及各种条件转移指令

JE/JZ(ZF=1)

JNE/JNZ(ZF=0)

有符号数:(Greater and Less)(前有CMP指令)

JG/JNLE

JNG/JLE

JL/JNGE

JNL/JGE

无符号数:(Above and Below)

JB/JNAE

JNB/JAE

JA/JNBE

JNA/JBE

JS(SF==1)

JNS

JO(OF==1)

JNO

JP(PF==1)

JNP

例:

GETMAX:MOV BX,2000H

MOV AL,[BX]

MOV CX,14H

P1:INC BX

CMP AL,[BX]

JAE P2

MOV AL,[BX]

P2:DEC CX

JNZ P1

MOV BX,[2000H]

MOV [BX],AL

8.5 循环控制指令LOOP,LOOPZ/LOOPE,LOOPNZ/LOOPNE

只能使用段内直接转移,位移量只能是8位

LOOP BEGIN

DEC CX

JNZ BEGIN

等效

LOOPZ 指令在CX≠0且ZF=1的情况下循环

JCXZ指令可以用于跳过循环

例:

MOV CX,N

FND:REPNZ SCANSB

JE OK

JCXZ ENDF

OK:.....

JMP FND

ENDF:......

8.6 中断指令与中断返回指令INT(Interrupt)

INT n

n必须为立即数,对应内存中中断向量表里的中断向量(CS/IP)

终端处理程序最后一条指令为IRET,能正确地恢复断点与标志寄存器的值

中断向量表为000H到3FEH,一个类型占4B,分别为CS值与IP值

5个内部中断为专用中断向量

① 除数为0

②单步中断(程序调试)

③非可屏蔽中断

④断点中断(程序调试)

⑤溢出中断

8.7 处理器控制指令(不影响任何标志)

(1)HLT

CS:IP指向HLT的下一条指令,直到出现硬件中断或者复位操作才退出暂停状态

(2)空操作指令NOP(No Operate)

可以用作延时操作

(3)标志位操作指令

STC(Set Carry Flag):CF=1

CLC(Clear Carry Flag):CF=0

CMC(Complete Carry Flag):CF求反

STD(字符串处理方向)

CLD

STI(中断允许位)

CLI

(4)交权指令

ESC

启动协处理器工作,交给8087处理

(5)等待指令WAIT

TEST引脚有效,CPU结束等待状态执行下一条指令

(6)总线封锁指令LOCK

可以作为任何指令的前缀使得CPU的LOCK引脚有效,从而独占总线

有关8086指令系统(8086基本知识点)的更多相关文章

  1. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  2. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  3. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  4. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  5. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  6. ruby-on-rails - 使用 HTTParty 的非常基本的 Rails 4.1 API 调用 - 2

    Rails相对较新。我正在尝试调用一个API,它应该向我返回一个唯一的URL。我的应用程序中捆绑了HTTParty。我已经创建了一个UniqueNumberController,并且我已经阅读了几个HTTParty指南,直到我想要什么,但也许我只是有点迷路,真的不知道该怎么做。基本上,我需要做的就是调用API,获取它返回的URL,然后将该URL插入到用户的数据库中。谁能给我指出正确的方向或与我分享一些代码? 最佳答案 假设API为JSON格式并返回如下数据:{"url":"http://example.com/unique-url"

  7. ruby - 在没有基准或时间的情况下用 Ruby 测量用户时间或系统时间 - 2

    因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实

  8. ruby - 以毫秒为单位获取当前系统时间 - 2

    在Ruby中,以毫秒为单位获取自纪元(1970)以来的当前系统时间的正确方法是什么?我试过了Time.now.to_i,好像不是我想要的结果。我需要结果显示毫秒并且使用long类型,而不是float或double。 最佳答案 (Time.now.to_f*1000).to_iTime.now.to_f显示包含十进制数字的时间。要获得毫秒数,只需将时间乘以1000。 关于ruby-以毫秒为单位获取当前系统时间,我们在StackOverflow上找到一个类似的问题:

  9. ruby-on-rails - Rails 基本 Base64 身份验证 - 2

    我正在尝试复制此GETcurl请求:curl-D--XGET-H"Authorization:BasicdGVzdEB0YXByZXNlYXJjaC5jb206NGMzMTg2Mjg4YWUyM2ZkOTY2MWNiNWRmY2NlMTkzMGU="-H"Content-Type:application/json"http://staging.example.com/api/v1/campaigns在Ruby中,通过电子邮件+apikey生成身份验证:auth="Basic"+Base64::encode64("test@example.com:4c3186288ae23fd9661c

  10. ruby-on-rails - 如何构建复杂的 Rails 系统 - 2

    关闭。这个问题需要更多focused.它目前不接受答案。想改进这个问题吗?更新问题,使其只关注一个问题editingthispost.关闭8年前。Improvethisquestion我们有以下(以及更多)系统,我们将数据从一个应用推送/拉取到另一个:托管CRM(InsideSales.com)Asterisk电话系统(内部)横幅广告系统(openx,我们托管)潜在客户生成系统(自行开发)电子商务商店(spree,我们托管)工作板(本土)一些工作网站抓取+入站工作提要电子邮件传送系统(如Mailchimp,自主开发)事件管理系统(如eventbrite,自主开发)仪表板系统(大量图表和

随机推荐