王爽之《汇编语言》学习重点六

时间:2020-12-24 19:22:38

第3章  寄存器(内存访问)

 

 

3.1  内存中字的存储

 

●CPU中用16位寄存器来存储一个字,高8位存放高位字节,低8位存放低位字节
字单元即存放一个字型数据的内存单元,由两个地址连续的内存单元组成;高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节
●将起始地址为N的字单元称为N地址字单元,比如:2地址字单元由2、3两个内存单元组成

 

3.2  DS和[address]

     CPU要读写一个内存单元的时候,必须先给出这个内存单元的地址,在8086PC中,内存地址由段地址和偏移地址组成。8086CPU中有一个DS寄存器,通常用来存放要访问的数据的段地址。比如我们要读取10000H单元的内容,可用以下程序段:

     mov bx,1000H

     mov ds,bx

     mov al,[0]

上面的三条指令将10000H(1000:0)中的数据读到al中。

 

下面详细说明指令的含义:

     mov al,[0]

 

     前面我们使用mov指令,可完成两种传送:(1)将数据直接送入寄存器;(2)将一个寄存器中的内容送入另一个寄存器。

     也可以使用mov指令将一个内存单元中的内容送入一个寄存器中。mov指令格式为: mov 寄存器名, 内存单元地址。

    “[]”表示一个内存单元,“[0]”中的0表示内存单元的偏移地址,段地址默认放在ds中。

     由于8086CPU硬件设计的问题,8086CPU不支持将数据直接送入段寄存器如mov ds,1000H是非法的。所以我们得使用一个寄存器进行中转,如上例:

(1).先将段地址1000H放入中转寄存器bx中,然后再放入ds
mov bx,1000H
mov ds,bx
(2).完成数据从1000:0单元到al的传送
mov al,[0]:“[]”表示一个内存单元,“[0]”中的0表示内存单元的偏移地址,段地址默认放在ds中。

 

问题3.2

      写几条指令,将al中的数据送入内存单元10000H中。

 

 

 


 

     因为8086CPU是16位结构,有16根数据线,所以可以一次性传送16位的数据即一个字。

内存情况如图:

  地址     数据                指令
10000H  23                  mov ax,1000H   
10001H  11                  mov ds,ax
10002H  22                  mov ax,[0]
10003H  66                  mov bx,[2]

                                  mov cx,[1]    

                                  add bx,[1]  

                                  add cx,[2]

 

分析:

 

指令            执行后相关寄存器内容  说明
mov ax,1000H  ax=1000H
mov ds,ax     ds=1000H  前两条指令的目的是将ds设为1000H
mov ax,[0]    ax=1123H  1000:0处存放的字型数据送入ax
{1000:0单元存放字型数据的低八位23H(送入al),1000:1单元存放字型数据的高八位11H(送入ah),1000:0处的字型数据是1123H}
mov bx,[2]    bx=6622H
mov cx,[1]    cx=2211H
add bx,[1]    bx=8833H  66+22=88,22+11=33
add cx,[2]    cx=8833H  22+66=22,22+11=33

 


 

问题3.4

     内存如图3.3所示,写出下面的指令执行后内存中的值。

 

  地址    数据               指令
10000H  23                mov ax,1000H
10001H  11                mov ds,ax 
10002H  22                mov ax,11316
10003H  11                mov [0],ax

                                mov bx,[0]     
                                sub bx,[2]

                                mov [2],bx      

分析:

指令         执行后相关寄存器或内存单元中内容  说明
mov ax,1000H    ax=1000H
mov ds,ax         ds=1000H   前两条指令的目的是将ds设为1000H
mov ax,11316    ax=2C34    十进制11316=十六进制2C34H
mov [0],ax        10000H 34  ax中的字型数据2C34送到1000:0处
                       10001H 2C  ah中的高八位2CH送入高地址1000:1单元
                       10002H 22  al中的低八位34H送入低地址1000:0单元
                       10003H 11
mov bx,[0]         bx=2C34H
sub bx,[2]          bx=1B12H   bx=bx中的字型数据-1000:2处的字型数据=2C34H-                                                                                    1122H=1B12H
mov [2],bx        10000H 34
                       10001H 2C
                       10002H 12
                       10003H 1B         

 

 3.4.mov,add,sub指令
mov 段寄存器,寄存器<--->mov 寄存器,段寄存器
mov 内存单元,寄存器<--->mov 内存单元,段寄存器<--->mov 段寄存器,内存单元

add 寄存器,数据
add 寄存器,寄存器
add 寄存器,内存单元
add 内存单元,寄存器
sub 寄存器,数据                  sub ax,bx    ax = ax - bx ;
sub 寄存器,寄存器
sub 寄存器,内存单元
sub 内存单元,寄存器

 

3.5.数据段


例五:
写几条指令,累加数据段123B0H--123BAH中的前3个字型数据
mov ax,123BH
mov ds,ax      (将123BH送入ds,作为数据段的段地址)
mov ax,0       (用ax存放累加结果)
add ax,[0]     (将数据段第一个字{偏移地址为0}加到ax中)
add ax,[2]     (将数据段第二个字{偏移地址为2}加到ax中)
add ax,[4]     (将数据段第三个字{偏移地址为4}加到ax中)
(一个字型数据占两个单元,所以偏移地址是0,2,4)

 

检测点一:
在Debug中,用“d 0:0 1f”查看内存,结果如下:
0000:0000 70 80 F0 30 EF 60 30 E2 00 80 80 12 66 20 22 60
0000:0010 62 26 E6 D6 CC 2E 3C 3B AB BA 00 00 26 06 66 88
下面的程序执行前,AX=0,BX=0,写出每条汇编指令执行完后相关寄存器中的值。
mov ax,1
mov ds,ax                  (ds=1,此时数据段地址为:0001×10+0000(偏移量)=00010)
mov ax,[0000]  AX=2662H    (数据表提供的是0000:0010,此时数据段的地址为:0000×10+0010=00010)
mov bx,[0001]  BX=E626H
mov ax,bx      AX=E626H
mov ax,[0000]  AX=2662H
mov bx,[0002]  BX=D6E6H
add ax,bx      AX=FD48H
add ax,[0004]  AX=2C14H
mov ax,0       AX=0000H
mov al,[0002]  AX=00E6H
mov bx,0       BX=0000H
mov bl,[000C]  BX=0026H
add al,bl      AX=000CH

 

●CS是告诉CPU,去哪个位置找内容当成指令去执行 
●DS是告诉CPU,去哪个位置找内容当成数据被使用
●CPU要执行CS中的指令,指令用到的数据可能就存放在DS中
●你可以把数据放到CS中,但是CPU并不把它当成数据来使用,你也可以把指令放到DS中,但是CPU根本不去DS里

读指令
●任何时候,程序运行的只能是cs:ip指向的内存中的指令


3.1~3.5   小结

(1)字在内存中存储时,要用两个地址连续的内存单元来存放,字的低位字节存放在低地址单元中,高位字节存放在高地址单元中。

(2)用mov指令要访问内存单元,可以在mov指令中只给出单元的偏移地址,此时,段地址默认在DS寄存器中。

(3)[address]表示一个偏移地址为address的内存单元。

(4)在内存和寄存器之间传送字型数据时,高地址单元和高8位寄存器、低地址单元和低8位寄存器相对应。

(5)mov、add、sub是具有两个操作对象的指令。jmp是具有一个操作对象的指令。

(6)可以根据自己的推测,在Debug中实验指令的新格式。


 检测点3.1


(1)Debug中用“d 0:0 1f”查看内存,结果如下:
   0000:0000 70 80 F0 30 EF 60 30 E2-00 80 80 12 66 20 22 60
   0000:0010 62 26 E6 D6 CC 2E 3C 3B-AB BA 00 00 26 06 66 88

   下面的程序执行前,AX=0,BX=0,写出每条汇编指令执行完后相关寄存器中的值。
   mov ax,1
   mov ds,ax
   mov ax,[0000]   AX=______ 2662H
   mov bx,[0001]   BX=______ E626H
   mov ax,bx          AX=______ E626H
   mov ax,[0000]   AX=______ 2662H
   mov bx,[0002]   BX=______ D6E6H
 
  add ax,bx          AX=______ FD48H
   add ax,[0004]   AX=______ 2C14H
   mov ax,0           AX=______ 0000H
   mov al,[0002]    AX=______ 00E6H
   mov bx,0           BX=______ 0000H
   mov bl,[000C]   BX=______ 0026H
   add al,bl            AX=______ 000CH


(2)mov ax,6622H
   jmp 0ff0:0100
   mov ax,2000H
   mov ds,ax
   mov ax,[0008]
   mov ax,[0002]

 

 

分析:

    (1)前面两条指令执行后,ds=0001H,而0001:0000等价于0000:0010H。所以,下面的指令读取的内存数据实际上是从0000:0010H开始的。