汇编_8086/8088寻址方式和指令系统

来源:互联网 发布:北大历史系知乎 编辑:程序博客网 时间:2024/05/18 15:51

注:参照中山大学汇编视频教学总结。

一、8086/8088寄存器组

      通用寄存器:数据寄存器、指针寄存器、变址寄存器,用于传送和暂存数据,保存算术逻辑运算中的操作数和运算结果

      数据寄存器:AX(AH,AL)累加器、BX(BH,BL)基址寄存器(可作为存储器指针)、CX(CH,CL(移位))字符串操作或循环操作、DX(DH,DL)32位的乘除法(存放被除数,存放余数),主要用于保存操作数和运算结果

      指针寄存器:堆栈指针(SP)栈顶地址、基址指针(BP),主要存放某个存储单元地址的偏移

      变址寄存器:源地址(SI)、目的地址(DI)

      控制寄存器:指令指针(IP)给出接着要执行的指令在代码段中的偏移、标志寄存器(FLAG)九个标志用于反映处理器的状态和运算结果的某些特征

      运算结果标志:进位标志CF(反映运算结果是否产生进位或借位)(FLAG的第0位),零标志ZF(反映运算结果是否为0)(FLAG的第6位),符号标志SF(反映运算结果的符号位)(FLAG的第7位),溢出标志OF(反映结算是否溢出)(FLAG的第11位),奇偶标志PF(反映运算结果中“1”的个数,“1”的个数为偶数个,OF为1)(FLAG的第2位),辅助进位标志AF(反映低半字节和高半字节是否进位或借位)(FLAG的第4位)

      状态控制标志:方向标志DF(1串操作按减方式)(FLAG的第10位),中断允许标志IF(决定CPU是否相应外部可屏蔽中断请求)(FLAG的第9位),追踪标志TF(主要用于程序调试)(FLAG的第8位)

      段寄存器:代码段(CS)(IP一起使用)、数据段(DS)、堆栈段(SS)(SP、BP一起使用)、附加段(ES)

 

二、存储器分段和地址的形成

      每个字节单元给以一个存储器的地址

      4号字节单元中存放的信息为34H,表示为(0004H)=34H

      一般机器字长为16位,存放在相继的两个字节单元,“高高低低”原则,比如4号字节单元中存放的信息为34H,5号字节单元中存放的信息为12H,则(0004H)=1234H

      如果存储器存放的是地址,比如4号字节单元中存放的信息为34H,5号字节单元中存放的信息为12H,1234号字节单元中存放的信息为12H,1235号字节单元中存放的信息为1AH,则4号字节单元中存放的实际信息为1A12H,表示为((0004))=1A12H

 

三、存储器分段及物理地址的形成

      采用存储器地址分段的方法将16位的地址扩展成20位的地址,段与段之间可以相连,也可以不相连,还可以部分重叠

      从0地址开始,每16个字节为一小段,首地址特征:在16进制表示的地址中,最低位为0,在20位地址中共有64K的首地址

      每一个存储单元都有唯一的一个20位的地址,这是该存储单元的物理地址,要访问的某一个存储单元总是属于某个段

      偏移:把存储单元的地址与所在段的起始地址的差称为段内偏移,用来指定要访问的存储单元,存储单元的物理地址等于段起始地址加上偏移

      逻辑地址:段值和偏移,表示方式:  段值:偏移

      物理地址=段值*16(相当左移4位)+偏移

      由于段可以重叠,所以一个物理地址可用多个逻辑地址表示

 

四、8086/8088的寻址方式

      计算机中的指令由操作码字段和操作数字码字段两部分组成

      寻址方式:表示指令中用于说明操作数所在的地址的方法

      立即寻址:操作数在指令中,是指令的一部分,可以是8位,可以是16位(采用“高高低低原则”),比如MOV AX,1234H,(AX)=1234H

      寄存器寻址:通用寄存器,比如MOV AX(目的数据),BX(源数据)  必须8位和8位,16位和16位操作

      直接寻址:操作数在寄存器中,指令直接包含有操作数的有效地址(偏移地址),操作数一般存放在数据段,所以操作数的地址由DS加上指令直接给出的16位偏移得到,比如MOV AX,[8054]  (DS)=2000H,(28054)=3050H,执行结果(AX)=3050H

      在汇编语言指令中,可以用符号地址代替数值地址,比如MOV AX,VALUE,VALUE为存放操作数单元的符号地址,也可以写成MOV AX,[VALUE]

      如果VALUE在附加段中,使用段超越前缀,应该写成MOV AX,ES:VALUE或MOV AX,ES:[VALUE]

      寄存器间接寻址:操作数有效地址在SI,DI,BX,BP

      如果有效地址在SI,DI,BX中,则以DS段寄存器的内容为段值,如果有效地址在BP中,则以SS段寄存器的内容为段值,比如MOV AX,[SI] (DS)=5000H,(SI)=1234H,物理地址=51234H,(AX)=(51234)

      寄存器相对寻址:操作数的有效地址是一个基址寄存器(BX,BP)或变址寄存器(SI,DI)内容加上指令中给定的8位或16位位移量之和,有效地址=(寄存器)+位移量,剩下的类似寄存器间接寻址,物理地址=(DS或SS)+有效地址,位移量采用补码表示,可能需要扩展,比如MOV AX,[DI+1223H],(DS)=5000H,(DI)=3678H,物理地址=5489BH

      MOV AX,[SI+3] 与 MOV AX,3[SI]等价

      基址加变址寻址:有效地址由基址寄存器之一的内容与变址寄存器之一的内容相加,这种寻址方式适合于数组或表格处理,用基址寄存器存放数组首地址,变址寄存器来定位数组中的各元素

      相对基址加变址寻址:有效地址由基址寄存器之一与变址寄存器之一的内容及指令中给定的位移量相加得到。计算有效地址超过FFFFH,就取64K的模。

 

五、8086/8088指令系统

      指令系统分为六个功能组:(1)数据传送(2)算术运算(3)逻辑运算(4)串操作(5)程序控制(6)处理器控制

      指令语句的一般格式:[标号:]指令助记符[操作数1[,操作数2]][;注释],标号只能被程序识别,与指令本身无关

      (1)数据传送

      传送指令

      MOV DST(目的操作数),SRC(源操作数),源操作数可以是累加器、寄存器、存储单元以及立即数,目的操作数可以是累加器、寄存器和存储单元,传送不改变源操作数。

      1.CPU内部寄存器之间的数据传送。

      源和目的操作数不能同时为段寄存器,代码段寄存器CS不能作为目的操作数,指令指针不能作为源操作数,也不能作为目的操作数。

      2.立即数传送至通用寄存器或存储单元

      立即数不能直接传送到段寄存器,立即数不能作为目的操作数

      3.寄存器与存储器间的数据传送

      注意:源操作数和目的操作数类型要一致,两个操作数必须有一个是寄存器(除立即寻址),比如把自变量X1的内容送到自变量X2里,MOV AX,X1  MOV X2,AX 

      比如MOV AL,'D'   MOV BX,将'D'的ASSIC码送到AL寄存器,OFFSET TABLE,将TABLE的偏移地址送到BX寄存器,其中OFFSET为属性操作数,加OFFSET是为了传送有效地址,不然传送对应地址的内容

      交换指令

      实现通用寄存器与通用寄存器或存储单元之间的数据交换

      XCHG OPRD1,OPRD2,此指令把操作数OPRD1的内容与操作数OPRD2的内容交换,操作数同时是字节或字,操作数中必须有一个寄存器(除立即寻址),OPRD1和OPRD2可以是通用存储器和存储单元,但不包括段存储器,也不能同时是存储单元,还不能是立即数,可采用各种存数器寻址方式来指定存储单元 

      地址传送指令

      指令LEA

      传送有效地址指令,LEA REG,OPRD 把操作数OPRD的有效地址传送到操作数REG,操作数OPRD必须是一个存储器操作数,操作数REG必须是一个16位的通用寄存器

      指令LDS

      段值和段内偏移构成32位的地址指针,LDS REG,OPRD 将OPRD的内容放到寄存器REG,OPRD+2的地址内容放到DS,把操作数OPRD中包含的一个32位地址指针的段值部分传送到数据段寄存器DS,把偏移部分传送到指令给出的通用寄存器REG,操作数OPRD必须是 一个32位的寄存器操作数,操作数REG可以是一个16位的通用寄存器,但往往是变址寄存器或指针寄存器

      指令LES

      LES REG,OPRD,将OPRD地址的内容存放到REG寄存器,将OPRD+2地址的内容存放到ES段寄存器里

      堆栈操作指令

      在8086/8088系统中,堆栈是一段RAM区域,称为栈底的一端地址较大,堆栈的段值在堆栈段寄存器SS中,堆栈指针寄存器SP始终指向栈顶,堆栈是以“后进先出”方式工作,必须以字为单位

      进栈指令PUSH

      PUSH SRC,把源操作数SRC压入堆栈,先把堆栈指针寄存器SP的值减2,然后将源操作数SRC送入由SP所指的栈顶。SRC可以是通用寄存器和段寄存器,也可以是字存储单元

      出栈指令POP

      POP DST,把栈顶弹出一个字数据到目的操作数DST,DST可以是通用寄存器和段寄存器(但CS例外),也可以是字存储单元

      PUSH和POP只能作字操作,不能把立即数作为操作数,POP不允许使用CS寄存器

      标志传送指令

      指令LAHF

      LAHF ,该指令将标志寄存器的低8位传送到寄存器AH的指定位,传送0,2,4,6,7位,其他不变

      指令SAHF

      SAHF ,该指令将寄存器AH的指定位传送到标志寄存器低8位

      指令PUSHF

      PUSHF ,该指令将标志寄存器压入堆栈

      指令POPF

      POPF ,该指令将栈顶的字送入标志寄存器

      标志位操作指令

      清进位标志CLC

      CLC ,CF=0

      置进位标志指令STC

      STC ,CF=1

      进位标志取反指令CMC

      CMC ,CF值取反

      清方向指令CLD

      CLD ,DF=0,地址递增

      置方向标志STD  

      STD ,DF=1

      清中断允许标志CLI

      CLI,IF=0,对屏蔽中断和内部中断没有影响

      置中断允许标志STI

      STI,IF=1

      (2)加减运算指令

      加法指令ADD

      ADD OPRD1(目的操作数),OPRD2(源操作数),结果送给目的操作数,加法指令影响标志位

      带进位的加法指令ADC

      ADC OPRD1,OPRD2,将CF也加进来,用于实现双精度数的计算,先计算低位,再计算高位,要考虑进位

      加1指令INC

      INC OPRD,将OPRD加1并将结果送回OPRD,主要用于调整地址指针和计数器

      DW,定义字节变量,RETURN DW 3

      减法指令SUB

      SUB OPRD1,OPRD2,将OPRD1-OPRD2送到OPRD1,此指令影响标识位CF说明无符号数相减的溢出,结果和减数符号相同则溢出,比如a-b,b是正数,结果是正数可能就溢出

      带借位的减法SBB

      SBB OPRD1,OPRD2,OPRD1-OPRD2-CF传送给OPRD1

      减1指令DEC

      DEC OPRD,OPRD减1,OPRD不能是立即数

      取补指令NEG

      NEG OPRD,相当于用零减去操作数OPRD,对-128取补,操作数不变,OF被置为1,其他均为0,对0取补,CF为0,其他都为1

      比较指令CMP

      CMP OPRD1,OPRD2,OPRD1-OPRD2,再判断结果,根据ZF判断是否相等,根据CF判断无符号数大小,根据SF和OF判断有符号数大小,目的操作数不能为立即数

      代码段寄存器CS不能作为目的操作数,PUSH CS 可以, POP CS不行

      双精度数中,一般AX放低位,DX放高位

      对双精度数求补,NEG DX     NEG AX    SBB DX,0

     (2)乘除运算指令

      乘法指令

      一个操作数总是隐含在寄存器AL或AX中,另一个操作数可以采用除立即数的方式外的任何方式

      无符号乘法指令MUL

      MUL OPRD ,目的操作数必须是累加器,两个8位相乘结果放在AX中,两个16位数相乘结果放在AX,DX中,如果结果中高半部分不为0,则CF=1,OF=1,否则都为0

      有符号数的乘法指令IUML

      IUML OPRD

      除法指令

      被除数总是隐含在寄存器AX中

      无符号除法指令DIV

      DIV OPRD ,字节数,AL放商,AH放余数,字数,AX放商,DX放余数,8位除数时商超过8位或者16位除时商超过16位,则认为除溢出,引起0号中断

      有符号数除法IDIV

      IDIV OPRD,当商太大太小时会引起0号中断

      符号扩展指令

      字节转换为字指令CBW

      CBW ,将寄存器AL的符号扩展到寄存器AH

      字转换为双字指令CWD

      CWD ,将寄存器AX中的符号扩展到寄存器DX中

      逻辑运算和移位指令

      逻辑运算指令

      否操作指令NOT

      NOT OPRD,将OPRD各位取反,OPRD不能是立即数

      与操作指令AND

      AND OPRD1,OPRD2,OPRD1和OPRD2相与,结果放到OPRD1

      或操作指令OR

      OR OPRD1,OPRD2,OPRD1和OPRD2相或,结果放到OPRD1

      异或操作指令

      XOR OPRD1,OPRD2,OPRD1和OPRD2相异或,结果放到OPRD1

      测试指令TEST

      TEST OPRD1,OPRD2,,OPRD1和OPRD2相与,根据ZF,PF,SF用来检测结果

      一般移位指令

      算术左移或逻辑左移SAL/SHL

      SAL OPRD,m,有符号数

      SHL OPRD,m,无符号数

      右边0补上,移出的最高位进入标志位CF,OF只有在移动一位时才可能为1,多位移动都为0

      算术右移指令SAR

      SAR OPRD,m 左边的符号位不变,移出的最低位进入到标志位CF,如果要移动多位一定要把位数放到AL中去,补上最高位相同的数,即补上符号位相同数

      逻辑右移指令SHR

      SHR OPRD,m 对于无符号数使用   ,补0

      循环移位指令

      移动多位,次数要放到CL寄存器里

      循环左移

      ROL OPRD,m,将左边的数放到右边,8位的数,移动8次回到原来的数

      循环右移

      ROR OPRD,m,将右边的数放到左边,类似左移

      带进位的循环左移

      RCL OPRD,m,CF也包括在内,8位数需要9次移动才能复原

      带进位的循环右移

      RCR OPRD,m,类似左移

      AX,DX中的双字左移4位,MOV CL,4   SHL DX,CL   MOV  BL,AH   SHL AX,CL  SHR BL,CL  OR  DL,BL

      转移指令

      无条件段内直接转移指令

      JMP  标号,比如NEXT:MOV AX,CX  JMP NEXT,指令格式还可以表示成指令操作码+地址差,地址差用字节表示,则称短转移,JMP SHORT 标号,用字表示,称近转移,JMP NEAR PTR 标号

      无条件段内间接转移指令

      JMP OPRD,OPRD给定的目标地址。可以是通用寄存器也可是字存储单元

      无条件段间直接转移指令

      JMP FAR PTR 标号,“FAR PTR”说明是段间转移,目标地址的段值置如CS,偏移置如IP

      无条件段间间接转移指令

      JMP OPRD,OPRD必须是双字的存储单元,比如JMP DWORD PTR [1234H],低字内容送给IP,高字的内容送给CS

      条件转移指令

      所有条件转移只能在段内转移,不影响标志

      有符号数的比较跳转,大于G,小于L,等于E,可以使用JGE,JG...

      无符号数的比较跳转,大于A,小于B,等于E,可以使用JAE,JE...

      两数相等由ZF标志反映

      无符号数的比较大小可以由CF反映

      有符号数的比较大小可以由SF和OF一起反映,SF和OF相等,a>b

      循环指令,通过IP上加一个地址差的方式实现转移

      计数循环指令LOOP

      LOOP 标号,CX放循环次数,CX等于0时跳转,CX会自动减1

      等于/全零循环指令LOOPE/LOOPZ

      LOOPE 标号/LOOPZ 标号,都是CX自动减1,LOOPE判断是否相等,LOOPZ判断是否为零

      AX累加器,BX基址寄存器,CX循环次数,DX双精度数

      不等于/非零循环LOOPNE/LOOPNZ

      LOOPNE 标号/LOOPNZ 标号,结果不为0不相等时,并且零标志ZF等于0,跳转,否则顺序执行

      跳转指令JCXZ

      JCXZ 标号,判断CX是否为0

      查表指令

      输入输出指令

      除了SAHF和POPF指令外,这组指令对各种标志没有影响