• 汇编语言--寄存器(内存访问)


    本文主要从CPU如何执行指令的角度讲解了8086CPU的逻辑结构、形成物理地址的方法、相关的寄存器以及一些指令

    本文地址:http://www.cnblogs.com/archimedes/p/assembly-register-memory.html,转载请注明源地址。

    内存中字的存储

    在cpu中,用16位来存储一个字,高8位存放高字节,低8位存放低位字节。在内存中时,由于内存单元是字节单元,刚一个字要用2个地址连续的内存单元来存放,字的低位字节存在低地址单元. 

    字单元--存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成,高地址内存单元中存放字型数据的高字节,低地址内存单元存放单元中存放字型数据的低位字节

    0地址单元中存放的字节型数据为20H,0地址单元中存放的字型数据为4E20H,2地址单元中存放的字节型数据为12H,2地址单元中存放的字型数据为0012H,

    DS和[address]

    8086CPU中有一个DS寄存器,通常用来存放要访问数据的段地址。比如我们要读取10000H单元的内容,可以用如下的程序段进行:

    mov bx,1000H
    mov ds,bx
    mov al,[0]

    [……]表示一个内存单元,0表示内存单元的偏移地址

    字的传送

    8086CPU是16位结构,可以一次性的传送16位的数据,即一次性传送一个字。例如:

    mov bx,1000H
    mov ds,bx
    mov ax,[0]  ;1000:0处的字型数据送入ax
    mov [0],cx  ;cx中的16位数据送到1000:0

    问题1

    内存中的情况如下图,

    写出下面指令执行后寄存器ax,bx,cx中的值

    mov ax,1000H
    mov ds,ax
    mov ax,[0]
    mov bx,[2]
    mov cx,[1]
    add bx,[1]
    add cx,[2]

    mov ax,1000H 执行后,ax=1000H

    mov ds,ax 执行后,ds=1000H

    mov ax,[0] 执行后,ax=1123H

    mov bx,[2] 执行后,bx=6622H

    mov cx,[1] 执行后,cx=2211H

    add bx,[1] 执行后,bx=bx+[1]=6622H+2211H=8833H

    add cx,[2] 执行后,cx=6622H+2211H=8833H

    问题2

    内存中的情况如下图,

    写出下面指令执行后寄存器ax,bx,cx中的值

    mov ax,1000H
    mov ds,ax
    mov ax,11316
    mov [0],ax
    mov bx,[0]
    sub bx,[2]
    mov [2],bx

    mov ax,1000H 执行后,ax=1000H

    mov ds,ax 执行后,ds=1000H

    mov ax,11316 执行后,ax=2C34H

    mov [0],ax 执行后,1000:1存储2C,1000:0存储34

    mov bx,[0] 执行后,bx=2C34

    sub bx,[2] 执行后,bx=2C34-1122=1B12

    mov [2],bx 执行后,1000:2存储1B12

    指令执行结果如下:

    mov、add、sub指令

    mov指令有以下几种形式:

    mov 寄存器,数据

    mov 寄存器,寄存器

    mov 寄存器,内存单元

    mov 内存单元,寄存器

    mov 内存单元,段寄存器

    mov 段寄存器,寄存器

    mov 寄存器,段寄存器

    下面通过debug来验证一下"mov 寄存器,段寄存器"指令:

    验证"mov 内存单元,段寄存器"指令:

    mov ax,1000H
    mov ds,ax
    mov [0],cs

    add和sub指令同mov一样,都有两个操作对象,也可以有下面几种形式:

    add 寄存器,数据

    add 寄存器,寄存器

    add 寄存器,内存单元

    add 内存单元,寄存器

    sub 寄存器,数据

    sub 寄存器,寄存器

    sub 寄存器,内存单元

    sub 内存单元,寄存器

    数据段

    相关结论:

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

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

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

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

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

    CPU提供的栈机制

    在8086CPU编程的时候,可以将一段内存当做栈来使用,8086CPU提供2种栈的操作:push和pop,都是以字为单位进行操作

    在8086CPU中,提供2中寄存器分别栈顶地址:段寄存器SS和寄存器SP,任意时刻,SS:SP指向栈顶元素。入栈时,栈顶从高地址向低地址方向增长

    首先看一段代码:

    mov ax, 0123H
    push ax
    mov bx, 2266H
    push bx
    mov cx, 1122H
    push cx
    pop ax
    pop bx
    pop cx

    执行过程如下图:

    注意:字型数据用两个单元存放,高地址单元存放高8位,低地址单元存放低8位

    8086CPU中,有2个寄存器,段寄存器SS和寄存器SP,栈顶的段地址存放在SS中,偏移地址存放在SP中。任意时刻,SS:SP指向栈顶元素

    8086CPU不保证我们对栈的操作不会超界,我们在编程的时候要自己操心栈顶超界的问题

    push、pop指令

    push和pop指令是可以在寄存器和内存之间传送数据的,push和pop指令可以是如下的形式:

    push 寄存器 ;将一个寄存器中的数据入栈
    
    pop 寄存器 ;出栈,用一个寄存器接收出栈的数据
    
    push 段寄存器 ;将一个段寄存器中的数据入栈
    
    pop 段寄存器 ;出栈,用一个段寄存器接收出栈的数据
    
    ;push和pop指令也可以在内存单元和内存单元之间传送数据,还可以:
    
    push 内存单元 ;将一个内存单元处的字入栈(栈的操作都是以字为单位)
    
    pop 内存单元 ;出栈,用一个内存字单元接收出栈的数据

    比如下面的代码:

    mov ax, 1000H
    mov ds, ax ;内存单元的段地址要放在ds中
    push [0] ;将1000:0处的字入栈中
    pop [2]  ;出栈,出栈的数据送入1000:2处

    参考资料

    《汇编语言》--王爽

  • 相关阅读:
    顶级jQuery树插件
    jQuery 表格
    FlexiGrid使用手册
    gif动图快速制作方法(附工具)(转)
    Maven搭建SpringMVC+Hibernate项目详解(转)
    Gradle cookbook(转)
    Gradle入门系列(转)
    Gradle构建多模块项目(转)
    oracle中imp命令具体解释
    DisplayContent、StackBox、TaskStack笔记
  • 原文地址:https://www.cnblogs.com/wuyudong/p/assembly-register-memory.html
Copyright © 2020-2023  润新知