汇编(四)字的存储、DS和[address]、字的传送、mov、add、sub指令、数据段

寄存器(内存访问)

3.1 内存中字的存储

  • 把0地址开始存放 4e20
  • 0号单元是低地址单元,1号单元是高地址单元
0 20
1 4e
2 12h
  • 任何两个地址连续的内存单元,n号单元和n+1号单元,可以将他们看成两个内存单元,也可以看成一个地址为n的字单元中的高位字节单元和低位字节单元

    • 高位单元:n+ 低位单元:n

3.2 DS和[Address]

  • CPU要赌气一个内存单元的时候,必须先给出这个内存单元的地址
  • 内存地址是由:段地址和偏移地址组成的
  • CPU中有一个DS寄存器,通常用来存放要访问的数据的段地址
  mov bx, 1000
  mov ds, bx
  mov al, [0]
  • 上面三条指令将10000(1000:0)中的数据读到al中
mov al, [0]
  • 已知的mov指令可以用完成两种传送功能
    1. 将数据直接送入寄存器
    2. 将寄存器中的内容送入另一个寄存器中
  • 除此之外,mov指令还可以将一个内存单元中的内容送入一个寄存器

    *上面就是 将内存偏移地址为0的内容送入ax低八位(al)寄存器

  • mov指令格式:

    • mov 寄存器,内存单元地址
    • […]表示一个内存单元,”[…]“中的0表示内存单元的偏移地址
    • 执行指令时 CPU会自动取DS中的数据为内存单元的段地址
      1. 将1000放入ds ,但是不会能直接放入到ds,ds是一个段寄存器 不是通用寄存器,不支持将数据直接送入 需要借助通用寄存器
      2. 用mov al, [0] 完成传送 (mov指令中的【】说明操作对象是一个内存单元的偏移地址,是0 它的段地址默认放在ds中
    • 数据 -> 通用寄存器 -> 段寄存器
  • Mov bx, 1000 为将数据送入寄存器
  • mov bx, 1000; mov ds, bx; mov [0], al; 将数据从寄存器送入内存单元 最终的结果:就是把al寄存器中的内容送入[0](1000:0)内存单元中
  • mov bx, 1000; mov ds, bx; mov al, [0]; 将内存单元送入寄存器 最终结果:就是把[0](1000:0)内存单元送入al寄存器

3.3 字的传送

  • 16结构的从CPU 有16根数据线,所以一次性传送16位的数据,也就是一次性传送一个字
  •   mov bx, 1000
      mov ds, bx
      # 上面为:将1000送入到ds中  设置默认段地址为:1000
      mov ax, [0]  # 将1000:0处的字型数据送入 ax, 因为是ax 16位寄存器 所以是字数据,al为8位寄存器就是直接数据 也可以称为16个字节数据或一个字数据
      mov [0], cx  # 将cx中的16位数据送到1000:0处

    汇编(四)字的存储、DS和[address]、字的传送、mov、add、sub指令、数据段

    汇编(四)字的存储、DS和[address]、字的传送、mov、add、sub指令、数据段

  • 答案:执行步骤详解

    mov ax, 1000  # 将1000赋值给ax  ax=1000
    mov ds, ax    # 将ax赋值给ds为默认段地址  ds=1000
    mov ax, [0]   # 将 ds:0(23) 赋值给ax  因为ds:0是字节单元 而ax是字单元 所以自动会把高八位ds:1(11)拉出来  所以ax=1123
    mov bx, [2]   # 将 ds:2(22) 赋值给bx 拖一个高地址  bx=6622
    mov cx, [1]   # 将 ds:1(11) 赋值给cx 拖一个告地状  cx=2211
    add bx, [1]   # 将 ds:1(11) 拖一个高地址 2211加上bx(6622)  bx=8833
    add cx, [2]   # 将 ds:2(22) 6622+2211  cx=8833
    mov al, [1]   # 如果是赋值给字节寄存器  那么 al的值为 ds:1(11)  ax 8811
  • 第二题答案:

  • 汇编(四)字的存储、DS和[address]、字的传送、mov、add、sub指令、数据段
  • 汇编(四)字的存储、DS和[address]、字的传送、mov、add、sub指令、数据段

    mov ax, 1000  # 将ax设置为 1000
    mov ds, ax    # 将段地址设置为 ax=1000
    mov ax, 2c34  # 将ax 设置为2c34  十进制:11316
    mov [0], ax   # 将1000:0 设置为ax    mov 10000:0, ax
    mov bx, [0]   # 将bx 设置为  1000:0 = ds:0 = 2c34
    sub bx, [2]   # bx = bx-ds:2  拖一位高地址 ds:2 = 1122    bx = 2c34 - 1122 = 1b12
    mov [2], bx   # 将ds:2的值设置为  bx  1b12

    3.4 mov、add、sub指令

  • mov指令的几种形式

    1. mov 寄存器, 数据 # 这里的寄存器为通用寄存器
    2. mov 寄存器,寄存器
    3. mov 寄存器,内存单元
    4. mov 内存单元,寄存器
    5. mov 段寄存器,寄存器
    6. mov 寄存器,段寄存器
  • add sub 是一样的

  • 汇编(四)字的存储、DS和[address]、字的传送、mov、add、sub指令、数据段

    3.5 数据段

  • 我们可以根据需要将一组内存单元定义为一个段(可以是代码段、数据段等)
  • 我么可以将一组数据长度为n(n<=64)、地址连续、起始地址为16的倍数的内存单元当做专门存数据的内存空间,从而定义了一个数据段。
  • 比如123B0~123B9这个空间来存放数据:

    • 段地址:123B
    • 长度:10字节 (0~9 十个字节)
  • 如何访问数据段中的数据?

    • 将一段内存当做数段,是我们在编程的时候的一种安排,我们可以在具体操作的时候,用ds存放数据段的段地址,在根据需要,用相关指令访问数据段中的具体单元
  • 要累加这个数据段中的前3个单元中的数据,代码如下:
  • mov ax, 123b
    mov ds, ax
    mov al, [0]  # 只有用8位字节寄存器(al)才可以,不然会拖一个高地址内存单元过来
    add al, [1]
    add al, [2]
  • 要累加这个数据段中前3个字型数据,代码如下:

    mov ax, 123b
    mov ds, ax
    mov ax, [0]  # 一个字型数据 占两个内存单元,所以便宜地址是0,2,4
    add ax, [2]
    add ax, [4]

小结:

  1. 字在内存中存储时,要用两个连续的内存单元来存放,字的地位字节存放在低地址单元中。高位字节存放在高地址单元中
  2. 用mov 指令要访问内存单元,可以在mov指令中给出单元的偏移地址,此时段地址默认在ds寄存器中
  3. [address] 表示一个 段地址为ds 偏移地址为address的内存单元
  4. 在内存和寄存器之间传送字型数据时。高地址单元和高8位寄存器、低地址单元和低8位寄存器相对应。
  5. mov、add、sub 是具有两个操作队形的指令 、jmp(无条件跳转)是具有一个操作对象的指令
  6. 可以根据自己的推测在 debug中实验指令的格式是否正确 以及结果
上一篇:Linux系统CentOS8 检测USB、创建挂载点、挂载、存取USB数据、取消挂载


下一篇:汇编(二) 内存地址空间、寄存器、物理地址以及物理地址的计算