0.指令格式
   
为了理解相关的寻址方式,首先对指令的格式进行简单的说明。(需要注意的是下面的说明只是从所包含的信息角度进行的说明,实际指令码的格式要复杂得多)
    
    
    0.1 指令信息
   
一个指令需要包含下面四个方面的信息:
- 
指令操作码 指示完成的功能。如 
 
 MOV
 
 指令用来进行数据传送。
- 
操作数地址 指令中指出操作数的地址从而处理器可以获得操作数。而操作数的地址有多种形式,常见的有: - 存储单元
- I/O接口
- CPU内部寄存器
 
- 
操作结果的存放地址 对操作数进行相关处理后,处理结果可能会存放在某处,存放地址和操作数地址类似,常见的有: - 存储单元
- I/O接口
- CPU内部寄存器
 
- 
下一条指令的地址 程序顺序执行时,下一条指令的地址由CPU中的程序计数器(PC)给出。如果遇到程序转移或者调用子程序时,下一条地址由指令给出。 
    上述的4种信息
    
     不一定在一条指令中都存在
    
    ,具体有哪些信息由具体指令而定。示意图如下:
   
     
   
这里将示意图画成上图所示,并不代表指令的真实构成就是上面信息的直译形式。实际上,一条指令码的构成格式要比上图要复杂得多。上图只是从包含信息的角度,说明了指令包含哪些必要信息。
    
    
    0.2 指令格式
   
常见指令格式有如下几种:
    
    
    0.2.1 三地址指令
   
    
     OP A1 A2 A3
    
- 
     
 A1
 
 :存放结果的地址
- 
     
 A2, A3
 
 :两个操作数的地址
    含义为:
    
     (A1) OP (A2)
    
    
     
      
       → 
        \rightarrow
      
      
       
        
        
        
         →
        
       
      
     
    
    
     A3
    
    ,即将A1 OP A2的结果放在
    
     A3
    
    处。
   
     
   
这里A1 A2 A3的地址形式可以是上述说明的存储单元,I/O接口和CPU内部寄存器中的一种。
    
    
    0.2.2 二地址指令
   
    
     OP A1 A2
    
    ,含义为:
    
     (A1) OP (A2) → A1
    
    。A1 A2可以是存储单元,I/O接口和CPU内部寄存器中的一种。
   
     
   
    如:
    
     MOV DX, A2
    
    ,即将内存地址单元
    
     A2
    
    的内容传送到
    
     DX
    
    中,这里的
    
     DX
    
    相当于
    
     A1
    
    。
   
    
    
    0.2.3 一地址指令
   
    简单可以猜到形式如下:
     
   
    例子:
    
     INC AX;
    
    意为将AX中的内容加1。
   
    
    
    0.2.4 零地址指令
   
    
     OP
    
    ,比较特殊,这种指令只有操作码,没有地址码。形式如下:
   
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dl6Gtssm-1665668906523)(https://cdn.jsdelivr.net/gh/Holmes233666/blogImage@main/img/image-20221013191442338.png)]
    常见的有停机指令,处理器暂停指令
    
     HLT
    
    等。
   
    
    
    8086CPU的寻址方式
   
    以下的寻址方式以8086处理器为例。其中寻址方式包括:决定操作数地址的寻址方式和决定转移地址的寻址方式:
    
    
     
      
       
        寻址方式 
{
决定操作数地址:
e
.
g
.
mov xxx, xxx
决定转移地址:
e
.
g
.
jmp xxx, xxx
         寻址方式\begin{cases}决定操作数地址:e.g. \text{ mov xxx, xxx}\\ 决定转移地址:e.g. \text{ jmp xxx, xxx}\end{cases}
       
       
        
         
         
         
          寻址方式
         
         
         
         
          
           
            {
            
           
          
          
           
            
             
              
               
                
                 
                 
                 
                  
                   决定操作数地址:
                  
                  
                   e
                  
                  
                   .
                  
                  
                   g
                  
                  
                   .
                  
                  
                   
                    mov xxx, xxx
                   
                  
                 
                
                
                 
                 
                 
                  
                   决定转移地址:
                  
                  
                   e
                  
                  
                   .
                  
                  
                   g
                  
                  
                   .
                  
                  
                   
                    jmp xxx, xxx
                   
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
           
          
          
          
         
        
       
      
     
    
   
即,mov指令是决定操作数地址的寻址方式。
另外,补充一点寻址是在何时进行的。这里涉及到一条指令的执行过程:首先CPU根据程序计数器PC访问内存,在内存中取出待执行的指令,接着该指令被译码(指令译码:CPU需要理解这条指令到底是要做什么,对它进行翻译,根据指令含义获得相关的操作数),译码后,指令正式执行。
    具体的,译码过程中获得操作数的过程涉及寻址,
    
     必要的话
    
    要进行访存,找到源操作数,目的操作数等。至于为什么说“必要的话”,因为有些指令不需要访存就可以得到操作数,如下面要说的立即寻址:两个操作数一个直接包含在指令中,另一个是寄存器中的值,都不需要访存就可以获得。这点在
    
     1.1高亮部分
    
    也有说明。
   
    指令执行的基本过程有下面的几种形式:
    
    
     
      
       
        基本过程 
{
取指令
,
执行
取指令
,
取操作数
,
执行
取指令
,
取操作数
,
执行
,
写结果
         基本过程\begin{cases}取指令,执行\\ 取指令,取操作数,执行\\ 取指令,取操作数,执行,写结果\end{cases}
       
       
        
         
         
         
          基本过程
         
         
         
         
          
           
            
             
              
               
                
                
                
                 
                  ⎩
                 
                
               
               
                
                
                
                 
                
               
               
                
                
                
                 
                  ⎨
                 
                
               
               
                
                
                
                 
                
               
               
                
                
                
                 
                  ⎧
                 
                
               
              
              
               
              
             
             
              
               
               
              
             
            
           
          
          
           
            
             
              
               
                
                 
                 
                 
                  
                   取指令
                  
                  
                   ,
                  
                  
                  
                  
                   执行
                  
                 
                
                
                 
                 
                 
                  
                   取指令
                  
                  
                   ,
                  
                  
                  
                  
                   取操作数
                  
                  
                   ,
                  
                  
                  
                  
                   执行
                  
                 
                
                
                 
                 
                 
                  
                   取指令
                  
                  
                   ,
                  
                  
                  
                  
                   取操作数
                  
                  
                   ,
                  
                  
                  
                  
                   执行
                  
                  
                   ,
                  
                  
                  
                  
                   写结果
                  
                 
                
               
               
                
               
              
              
               
                
                
               
              
             
            
           
          
          
          
         
        
       
      
     
    
   
    
    
    1.1决定操作数的寻址方式
   
细致分类有下面几种:
   
    
     为什么说是内存寻址,是因为这类寻址的指令对应的操作数是存储在存储器中的。在执行指令的过程中包含的对指令进行译码,取操作数的过程是需要访存取出操作数的,不像上面的寄存器寻址,操作数直接就在寄存器中,不需要访存。
    
   
    
    
    1.1.1 立即寻址
   
    特点:操作数直接包含在指令中,是和操作码一起放在代码区域中的;操作数可以是
    
     8位或者16位
    
    。
   
如:
    
     MOV AL, 05H
    
    
     MOV DX, 8000H
    
在计算机中,以第二条指令为例,这条指令在内存中的存储方式为:
   
这里你可能会好奇,DX并没有在这里存储,指令是怎么知道另一个操作数是DX的?这里涉及到指令码构成格式的问题,因为过程比较复杂,这里就不过多展开了。可以简单认为指令中会存放寄存器的编号,根据编号译码得出是哪个寄存器。
    
    
    1.1.2 寄存器寻址
   
操作数包含在CPU的内部寄存器中,例如:
    
     MOV DS, AX
    
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2JYb09vA-1665668906523)(https://cdn.jsdelivr.net/gh/Holmes233666/blogImage@main/img/image-20221013202418041.png)]
    
    
    1.1.3 直接寻址
   
    在直接寻址中,
    
     操作数存放在存储器中
    
    ,而操作数的16位段内偏移地址直接包含在指令中,它与操作码一起放在代码段区域。
   
操作数一般在数据段区域,他的地址为数据段寄存器DS加上这16位的段内偏移地址。
详细说明一下这一段的意思:我们需要区分的是
操作数
和
操作数地址
的概念。在直接寻址中,指令中直接给出的是操作数的地址的部分信息(即上述的16位段内偏移地址,另一部分信息即
段地址
存储在DS寄存器中),我们在指令译码阶段,会根据指令中的操作数地址进行访存,在内存中的数据段区域相应地址处找到该操作数,并取出。
    例子:
    
     MOV AX, [2000H]
    
那么操作数的地址可以由下面的计算得出:
   
即操作数的地址是32000H,译码时需要从地址32000H和32001H中取出实际的操作数放入由AH和AL组成的寄存器AX中。
    
    
    1.1.4 寄存器间接寻址
   
    在寄存器间接寻址方式中,
    
     操作数放在存储器中
    
    ,操作数的16位段内偏移地址放在SI, DI, BP, BX这四个寄存器之一。
   
SI, DI, BP, BX四个寄存器对应的段寄存器是不同的,其中若使用寄存器BP进行间接寻址,那么操作数存放在堆栈段区域;否则使用其他三个寄存器寻址,那么操作数存放在数据段中。
    例子:
    
     MOV AX, [SI]
    
    例子:
    
     MOV AX, [BP]
    
计算的形式如下:
     
   
    
    
    1.1.5 寄存器相对寻址
   
在寄存器相对寻址方式中,操作数存放在存储器中,操作数的16位段内偏移地址是由SI, DI, BX, BP之一的内容,再加上指令中所指出的8位或者16位相对地址偏移量而得到的。
与寄存器间接寻址类似,在一般情况下,若用SI、DI或者BX进行寻址时,以数据段寄存器DS作为基址;使用BP寻址时,使用堆栈寄存器SS作为基址。
    例子:
    
     MOV AX, DISP[SI]
    
    
    
    1.1.6 基址、变址寻址
   
    在8086/8088中,通常把BX,BP作为
    
     基址寄存器
    
    ,而把SI、DI作为
    
     变址寄存器
    
    。将这两种寄存器联合起来进行的寻址就称为基址、变址寻址。
   
    在基址、变址寻址方式中,
    
     操作数存放在存储器中
    
    ,操作数的16位段内偏移地址是由基址寄存器内容(BX或BP内容),再加上变址寄存器内容(SI或DI内容)而得到的。
   
   
同理,若使用BX作为基址,那么DS作为段址寄存器;如果使用BP作为基址,那么SS作为段址寄存器。
    
    
    1.1.7 基址、变址、相对寻址
   
    基址、变址、相对寻址方式实际上是基址、变址寻址方式的扩充。即
    
     操作数存放在存储器
    
    中,操作数的16位段内偏移地址是由基址、变址方式得到的地址再加上由指令指明的8位或16位的相对偏移地址而得到的。
   
     
   
    
    
    1.1.8 隐含寻址
   
在有些指令的指令码中,不仅包含有操作码信息,而且还隐含了操作数地址的信息。例如乘法指令MUL的指令码中只需指明一个乘数的地址,另一个乘数和积的地址是隐含固定的。这种将操作数的地址隐含在指令操作码中的寻址方式称为隐含寻址。
     
   
 
