• 汇编语言:第三章 寄存器(内存访问)


    3.1内存中字的存储

    CPU中寄存器是16位的,可以用高低字节存储一个字,但是每个内存单元是8位的,只能存储一个字节,

    所以内存中用相邻2个内存单元存储一个字的高低字节

    如:20000数值(4E20H)在地址0的内存单元数值为20H,在地址1的内存单元数值为4EH

      两个内存单元存储一个字型数据叫做一个字单元,

      字单元的起始地址为N就叫N地址字单元,表示一个字的低字节在地址N的内存单元,高字节在地址N+1的内存单元

      任意连续的2个内存单元都可以组成一个字单元

    3.2 DS和 【address】

      CS寄存器用于存放下个指令所在内存单元的段地址。用jmp 1000:0 赋值 CS

      DS寄存器一般用于存放要访问的内存单元的段地址:

      如我们想把内存单元10000H(1000:0)的内容放到AL中:

      mov bx,1000H  将要访问的内存单元段地址放到bx中

      mov ds,bx    将bx放入ds段寄存器中

      mov al,[0]    将[0]代表的内存单元内容放到al中

      [0]: 表示一个内存单元,段地址是DS中的值,偏移地址是0,所以此时【0】表示1000:0内存单元的内容

      注意: mov ds,1000H是不行的,段寄存器是不可以直接赋值的,只能从其他寄存器转义到段寄存器

      相反:将AL写入10000H

      mov bx,1000H

      mov ds,bx

      mov [0],al

    3.3字的传送

      mov指令两个参数的位数相同,

      当mov在寄存器与内存进行数据交互时,寄存器的字节数决定了传送单个内存单元还是字单元。

      mov ax,[0] 会将该地址的字单元数据组合成16位传入ax寄存器,即传送了一个字

      问题 :

      

      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=8833H

      add cx,[2]      cx=8833H

    3.4 mov,add,suv指令

      mov 寄存器,数据   数据只能转移到寄存器,不能转移到段寄存器

      寄存器,段寄存器,内存单元在mov指令中的位置都是可以随意换的

      mov 寄存器,数据

      mov 寄存器,寄存器

      mov 寄存器,内存单元

      mov 内存单元,寄存器

      mov 内存单元,段寄存器

      mov 段寄存器,内存单元

      mov 段寄存器,寄存器

      mov 寄存器,段寄存器

      

      add,sub只能对数据,寄存器,内存单元操作,不能用于段寄存器

    3.5数据段:存放数据的连续内存单元形成一个数据段

      根据需要可以随意操作数据段中的数据

      如123B0H-123B9H是一个长度为10的数据段.

      1.累加前3个内存单元

      mov bx,123BH

      mov ds,bx

      add al,[0]

      add al,[1]

      add al,[2]

      2.累加前3个字型数据

      add ax,[0]

      add ax,[2]

      add ax,[4]

    检测点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 写出下列命令执行后相关寄存器中的值

      mox ax,1     AX=1

      mov ds,ax     DS=1

      mov ax,[0000]  AX=(16+0=10H)= 2662H

      mov bx,[0001]  BX=(16+1=11H)=E626H

      mov ax,bx    AX=E626H

      mov ax,[0000]  AX=2662H

      mov bx,[0002]  BX=(16+2=12H)=D6E6H

      add ax,bx     AX=FD48H

      add ax,[0004]  AX=2C14H  12C14

      mov ax,0     AX=0

      mov al,[0002]   AX=00E6H

      mov bx,0     BX=0

      mov bl,[000C]  BX=0026H

      add al,bl     AX=000CH

      2)内存情况如图所示:

      

      寄存器初始值: CS=2000H,IP=0,DS=1000H,AX=0,BX=0

        a.写出CPU执行顺序,及执行后相关寄存器值

          mov ax,6622H    ax=6622H

          jmp 0ff0:0100    

          mov ax,2000H    ax=2000H

          mov ds,ax      ds=2000H

          mov ax,[0008]    ax=C389

          mov ax,[0002]    ax=EA66

        

    3.6栈

      后进先出LIFO,栈就是一个有特殊访问方式的存储空间

      只有2种操作,入栈和出栈,并且有个指针总是指向栈顶元素

    3.7CPU提供的栈机制

      8086CPU提供PUSH和POP指令用于操作栈内存,PUSH和POP操作单位是字单元

      利用SS存储栈顶内存单元的段地址,SP存储栈顶内存单元的偏移地址.

      栈顶内存单元地址小,栈底内存单元地址大

      PUSH分两步: a.SP-2  b.写入/覆盖

      POP分两步  : a.读取     b.SP+2     内存单元的值依然存在,但是指针已经移到别处,再PUSH的时候就会覆盖原来值

    3.8栈顶越界问题

      CPU不会指针是否指向栈顶或者栈低,只会根据SS:SP进行PUSH或者POP,需要程序员自己控制

      栈为空时SS:SP指向栈底内存单元的下一个内存单元

    3.9 PUSH和POP指令

      PUSH和POP可以对寄存器、段寄存器、内存单元操作

    3.10栈段

      把一段起始地址是16整数倍的连续的内存单元看做一个栈,就是一个栈段

      栈段根据SS:SP的指向利用PUSH、POP操作

    段的综述数据段,段地址存放在DS中,add,sub,mov访问内存单元时候,CPU就把我们定义的数据段中的内容当做数据来操作

    代码段,段地址存放在CS中,段中第一条指令的偏移地址存放在IP中,这样CPU就能执行我们的代码段

    栈段   ,段地址存放在SS中,栈指针的偏移地址存放在SP中,CPU根据SS:SP进行PUSH,POP操作

    检测点3.2

    mov ax,1000H

    mov ds,ax

    mov bx,2000H

    mov ss,bx

    mov sp,10H

    push [0]

    push [2]

    push [4]

    push [6]

    push [8]

    push [A]

    push [C]

    push [E]

    2)补全下面的程序,使得10000H-1000FH逆向复制到20000H-2000FH中

    mov ax,2000H

    mov ds,ax

    mov ax,1000H

    mov ss,ax

    mov sp,0H

    pop [E]

    pop [C]

    pop [A]

    pop [8]

    pop [6]

    pop [4]

    pop [2]

    pop [0]

      

  • 相关阅读:
    关于商业智能(Business Intelligence,简称BI)的认识
    Python连接mysql数据库和关闭数据库的方法
    Python 列表list方法clear( )和直接list [ ]的区别
    截止今天学习大数据技术的笔记
    【已解决】hive导出mysql报错:Container [pid=3962,containerID=container_1632883011739_0002_01_000002] is running 270113280B beyond the 'VIRTUAL' memory limit.
    sqoop安装配置以及简单使用
    大数据相关常用命令行或操作
    阿里巴巴数据库设计规范
    【已解决】linux环境jps命令不显示进程
    【已解决】初始化 Hive 元数据库报错slf4j-log4j12-1.7.25.jar包冲突
  • 原文地址:https://www.cnblogs.com/superzhao/p/4602758.html
Copyright © 2020-2023  润新知