音无结弦之时,天使跃动之心。立于浮华之世,奏响天籁之音。.|

次林梦叶

园龄:3年3个月粉丝:22关注:3

8086指令系统

 《8086寻址方式》

  寻址主要可以分为3类:

    数据寻址

    程序转移地址寻址(即查找下一条指令的地址)

    端口寻址

  解释一下端口:

    

 

       端口也要编址,其编址方式有两种:

      1.集中编址

      

 

 

           即端口在内存中,占内存的空间进行编址

     2.独立编址

      

 

 

           端口独立与内存之外

      这样有个好处是内存的空间更大了

      但是在寻址的时候为了区分是端口的地址还是内存地址

      我们要单独地再添加两条指令(在8086中就是IN与OUT)

      其作用就是访问端口

      与访问内存的指令区分开来

  《寻址方式的划分》

    根据数据的位置可以分为:

    立即寻址(数据在指令中)

    寄存器寻址(数据在寄存器中)

    内存寻址(数据在内存中)

 

   如果用寄存器进行间接寻址,那么能够使用的寄存器只有

    SI 源变址寄存器

    DI 目的变址寄存器

    BX 基址寄存器

    BP 基址指针寄存器

      计算物理地址时,如果使用的是BX,SI,DI,则段基值隐含由DS提供

    BP,由SS提供

     

  《基址变址寻址》

    操作数的偏移地址EA 为指令中基址寄存器 BR 内容 和 变址寄存器 IR 内容 之和

    即[BR][IR]

    注意 基址寄存器只有 BX BP

       变址寄存器只有 SI DI
     然后两两组合
   

 

 

 

《程序转移地址的寻址方式》

  首先回顾一下 指令指针寄存器IP,用于存放下一条执行指令

  这里直接寻址是指直接给出数据,

  这里间接寻址是指用了寄存器来给出数据

 

 

  在汇编语言上会看到这样的代码:

    JMP WORD PTR [BX]

  这里说明一下 PTR 与 WORD:

    具体看此博客<-------

    

 

 

         

 

 

 

 

  《段内寻址》

 

 

    段内直接寻址 JMP SHORT NEXT(NEXT 为变量或者是标注,名字可变)

            ....

            ....

          NEXT:ADDAL,[BX]

    这个就是直接跳转到了 这里

 

 

 

     

 

    段内间接寻址 JMP WORD PTR TABLE[BX] (TABLE 也是变量)

 

   比如

 

 

        TABLE[BX] 计算出的 物理地址为232F8H 

    其中的数据为3280H 这个数据直接给 IP

 

 

  《段间寻址》

    用指令中提供的转向段地址 和 偏移地址 取代原先的CS 和 IP

    即运用在不同两段代码之间的跳转

    由于需要 新的CS和IP (均为16位的数据,即要两个16位的数据),而寄存器只有一个16位

    所以到寄存器中寻找数据是不行的

    一定是在内存中找数据

 

    如段间间接寻址:

      JMP DWORD PTR [INTERS+BX]

      这里DWORD是双字,低位字给IP,高位字给CS

    具体看书P25

    

    

 

《8086的指令系统》

 《数据传送类指令》

 具体看书P26

  偏移地址(Offset Address)或有效地址(EA,Effective Address)
  段地址 PA
  
  逻辑地址:PA:EA
  物理地址:PA*16+EA
  
  知道了上面这些来看下如下几个指令:
 
    MOV  BP  3[BX+SI]
    这个指令的含义为:将 DS:[BX+SI+3] 这个逻辑地址转化为物理地址后
    将其保存的数据copy到寄存器BP中

 

   
       

   地址传送指令

  (1)传送偏移地址指令 LEA

    LEA  OPD  OPS

    指令含义为将偏移地址送入指定寄存器

    如:

      MOV  BX, 0100H

      MOV  SI, 0210H

      LEA  BX,1234[BX+SI]

    本来我们是要将 DS:[BX+SI+1234]这个逻辑地址转化为物理地址后,将其中保存的数放到BX中

    但是这里这条指令LEA (注意后面EA,即偏移地址)

    就是要将偏移地址放到指定寄存器中(这里即为BX)

    所以我们不要转化 直接将 (BX+SI+1234)算出的结果放到 BX中

 

 

    输入/输出指令

    输入指令IN,输出指令OUT

    IN AL, PORT

    这条指令的含义为将端口号为PORT的这个端口中的内容交给AL这个寄存器

    需要注意的是:

      端口地址在0000h~00FFh范围内时,用8位地址值直接寻址即可;

      只有端口地址在0100h~FFFFh范围内时,才必须通过DX寄存器间接寻址。

  

    如:

    MOV DX , 383H

    IN  AX,DX

    383H 是16位的(其实他省略了前面的0,其实是0383H)

    其要先将值交给DX,再用DX当做端口号,将端口的值输入到AX中

 

    在0000h~00FFh范围内,端口地址使用8位地址值直接寻址即可,因为这个范围是I/O端口的常用地址范围。

    这种直接寻址方式又被称为“端口地址空间”。

 

    由于端口地址不属于内存地址空间,不能像访问内存一样直接寻址。

    相反,需要通过DX寄存器来进行间接寻址。

    具体来说,在执行IN或OUT指令时,DX寄存器中存储的值会被用作端口地址,从而实现对I/O端口的读写操作。

 

《算术运算类指令》

  《加法指令》

  这里重点说明如下几个问题:

  1.INC为何不影响CF标志位?

    因为其只是简单地对目的操作数+1,如果有进位会当做看不见

    所以其不影响CF

    

  2.什么叫做不带进位和带进位?

    如ADD 为不带进位的加指令

    如ADC 为带进位的加指令

   即在进行加操作时,看是否加上CF

 

  《减运算指令》

  

   DEC也不影响CF,原因与上面一样

   需要注意的是 求补指令NEG 

   NEG影响标志位同SUB指令,因为本质上其是个减指令

   同理比较指令 CMP

 

  《乘运算指令》

   首先说明一下:

    字节数*字节数 得到 字数据

    这是因为字节有8位

    在8086中字为16位

    8位*8位 其 <16位 但>8位

    一旦超过了8位但小于16位就要用字来装了

    

    同理 字*字==双字  

 

   还有个问题:

    有符号乘是如何计算的?

    以书上的案例:

    有符号数相乘 0B4H*11H为何得到 0FAF4H?

         首先解释一下有符号数

      即最高位其被当做符号位

     0B4H*11H 的过程是:

      

 

 

      除法指令与符号扩展指令也可以按上面这样理解

 

《十进制调整指令》

  BCD码(Binary-Coded Decimal)是一种用于将十进制数字转换为二进制数字的编码方式。它使用4位二进制数来表示1位十进制数中的0-9这10个数码,因此可以直接用计算机来处理和存储数字。

  BCD码可分为有权码和无权码两类。有权BCD码有8421码、2421码、5421码,其中8421码是最常用的BCD码;无权BCD码有余3码,余3循环码等。其中,8421码是将十进制数的每一位数都分别用4位二进制数来表示的方式,例如数字5的8421码为0101。

  这种编码方式广泛应用于数字显示、计数器、电子时钟等领域。

  

  我们知道BCD在进行加减运算时都是按照16进制的方式运算(因为4位二机制数表示)

  但是我们用BCD码表示的是十进数

  

  在加法上 BCD码本来是要逢十进一,但是计算机会逢十六进一

  相差了6

  所以在进行加法时,如果BCD码的位上表示的数在进行加操作时没>9,则啥也不做

  但是>9了,则会进行+6操作进行补正

 

 

  在减法上同理,计算机在减法向高位借位时,借一位就是16

  但是在十进制上借一位是10

  则相差了6

  如果发生了借位(高四位看CF标志位,低四位看AF ,如果有借位(进位)其值为1)则要-6进行补正

 

  上面都是如果AF=1(有进位/借位)或低四位>9 (对于减法,BCD码的4位二级制数最大只能表示9,如果>9则说明一定是借位是上的问题)

  就AL=AL-6

  如果CF=1(有进位/借位)或 AL>=0A0H(说明高四位发生了进位/借位)

  那么相对应地+-6

  

  

    

 《DOSBOX和MASM下的实验》

  回答一下:

  MASM是什么?

   

  DOSBOX是什么?

 

 首先要知道 

  .asm是汇编源文件(相当于linux下的.s)

  .obj是目标文件(相当于linux下的.o)

  

 那么如何在windows下运用DOSBOX和MASM

  来由.asm得到.obj文件呢?

    输入masm

    然后他会友好地向你提供提示

   当然可以使用dir 命令查看当前文件夹的文件

 

  得到.obj文件之后又如何得到可执行文件呢?(快想想在linux中学习的东西!)

 

  当然是链接了!!! 

  linux中是ld指令

  那么在windows的这两款软件下呢?

    很简单,直接用输入 link

   下面就是输入你要链接的.obj文件了

 

  然后debug xxx.exe

  就是调试你生成的可执行文件了

  不错的DEBUG 命令 大全(其实不全)

     

  等等,前提呢?.asm文件咋来?

    当然是在笔记本(或者其他)下

    写入汇编代码了

  我现在已知的可运行的汇编代码如下:

复制代码
assume cs:codesg

codesg segment
    
    mov ax,00001
    add ax,ax

codesg ends

end
复制代码

 

 

 

 

《习题感悟》  

1.常常看到数据段这个名词,那么数据段到底是什么?

  这个问题牵扯到代码的编译->目标文件的过程,具体看计算机系统基础

  我们知道目标文件分为两种:

    1.可重定位可链接目标文件,即还没链接过

    2.可执行目标文件

   他们都可以用ELF的文件格式进行描述:

   对应地有两种视图:

  在执行视图上:

可以看到:Data段也就是我们说的数据段

 

2.在写指令时什么时候要加上如: WORD PTR 的描述?

  可以知道:

  当需要指明操作的数据是什么数据类型时必须要加上

  再如:  

    JMP DWORD PTR [BX]

  在程序转移地址寻址中,有段内(在同一段地址,由DS指出)和段间(在不同地址)寻址

    其是寻找下一条需要执行的指令,所以伴随着是IP的改变

  即 DS 与 IP一起指出物理地址

  当 JMP WORD PTR [BX]时是段内寻址,只是IP变成了 [BX]的数据

  当 JMP DWORD PTR [BX] 时是段间寻址,这个时候CS 和 IP 的值 被 [BX]的接下来两个字分别刷新了

  所以可以看出 加上类似 WORD PTR 描述的重要性

 

 3.指令中指定要使用的寄存器们

  1.在输入输出指令中:外设信息送到累加器中(AX[AH,AL]), 当端口号>=256 端口号要先放到 DX中

  2.在乘运算指令中:是用累加器(AX[AH,AL])来当被乘数,结果放到AX中,

    双字结果:高位放DX,低位放AX

    3.位移指令中:CL用来放指定位移次数,CF放位移掉的数据

     4.串操作指令中:DS:SI来寻找源串,ES:DI来寻找目的串

  

 

本文作者:次林梦叶

本文链接:https://www.cnblogs.com/cilinmengye/p/17296960.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   次林梦叶  阅读(255)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起