汇编语言课堂总结3——内存访问

内存中字的存储

  8086CPU中,用16位寄存器存储一个字,而在前面的学习中了解到内存是以字节为单位划分的,所以一个字要用两个地址连续的内存单元来存放,这就提出了字数据的存取原则(小端法):高—高,低—低,即,字数据的低位字节存放在低地址内存单元;字数据的高位字节存放在高地址内存单元;取低地址内存单元地址作为字数据地址。

ex.

  

  除此之外,还有一种存储方法叫做大端法,顾名思义,和小端法的存储方式正好相反。

DS[address]  and 字的传送

  DS,数据段寄存器,通常用来存放要访问的数据的段地址,在mov, add, sub等汇编指令中,访问内存单元时,默认情况下,指的是数据段。也就是说,我们可以通过改变DS中的值来访问指定的内存单元,但是8086CPU不允许直接将数据传入DS寄存器:

   

  所以需要通过一般寄存器来实现过渡,比如:

    MOV BX, 1000H

    MOV DS, BX     DS<-1000H

    MOV AL, [0]

  前两条mov指令完成了两种传送:①将数据直接送入寄存器;②将一个寄存器中的内容送入另一个寄存器。

  “[...]”表示一个内存单元,“[...]”中的数据0表示内存单元的偏移地址。所以这三条指令实现的功能就是将10000H ( 1000:0 ) 中的数据读到AL中。

  所以字的传送就是使用MOV指令通过16位寄存器在CPU和内存之间进行数据的传送,其中要使用数据段寄存器DS来访问内存单元。

ex.

   

MOV、ADD、SUB指令

  MOVADDSUB指令都有两个操作对象,操作对象可以是常数、寄存器、段寄存器和内存单元,但并不是任意两两组合都可以使用。

  mov指令:1、两个操作数长度要一致。

       2常数(立即数)不能作为第1个操作数(目的操作数);作第2个操作数(源操作数)时,如果最高位是十六进制的afAF,前面要加零。

       3两个内存单元之间不能直接传送数据。

       4不能使用mov指令修改CSIP的值。

       5两个段寄存器之间不能直接传送;不能把常数送到段寄存器。

   

  add指令:1、操作数不能同时是内存单元。

        2、操作数不能是段寄存器。

        3、操作数是内存单元时,指令中只给出「偏移地址」。默认,「段地址」在ds中。

   

  sub指令:1两个内存单元不能直接使用sub指令相减。

           2操作数不能是段寄存器。

           3操作数是内存单元时,指令中只给出「偏移地址」。默认,「段地址」在ds中。

   

  栈是一个逻辑上的概念,可以将一段内存空间当作栈来使用。栈有“后进先出”的特性。8086CPU中栈以字为存取单位。

  栈顶是最后入栈的字数据所对应的地址单元;栈底是固定的一端,栈区最高地址单元的前一个单元。8086CPU中有两个寄存器,SS(栈段段寄存器)和SP(栈指针寄存器),栈顶的段地址存放在SS中,偏移地址存放在SP中,任意时刻,SS:SP指向栈顶元素。

  栈有两种操作:入栈push和出栈pop

  push:第1步,栈顶上移两个单元,即:栈顶-2 → 栈顶;第2步,存入数据。

  pop:第1步,取出字数据5020H AX;第2步,栈顶下移两个单元,即:栈顶+2 → 栈顶。(栈为空时,栈顶指向栈底+2

  pushpop指令形式:

   

  注意:1、在push  内存单元和pop 内存单元中,指令中只需给出「偏移地址」。默认,段地址在DS中。

     2、8086CPU而言,pushpop的操作:入栈和出栈均以字为单元;操作对象不能是常数;pop 段寄存器中,段寄存器不能是CSSS

        3、利用栈「后入先出」特性,使用pushpop指令可以完成一些特殊处理。

栈顶越界问题

  当以下两种情形出现时会发生栈顶越界问题:

    ·当栈满的时候,再使用push指令入栈

    ·当栈空的时候,再使用pop指令出栈

  因为每次入栈或出栈改变的都是SP中的值,但是SP的范围只能在0000~FFFFH之间,也就是说一个栈空间最大只能有64kb,并且8086CPU不会自动考虑栈顶越界,所以容易发生越界的情况。

  越界情况发生后,也许不会有很大的影响,但也可能会访问到用户权限之外的内存,如果随意操作,可能会导致电脑出现故障;或者是在SPFFFF时继续执行了pop操作,这时可能会取到我们不需要的垃圾数据。

疑问

  在检测点3.1中有如下三条语句:

    mov ax, 1

    mov ds, ax

    mov ax, [0000]

  为什么执行完这三条语句后,AX中的值是0000:0010中的值,而不是0001:0000中的值呢?(有没有哪位大佬可以解答一下我的疑惑哇)

猜你喜欢

转载自www.cnblogs.com/lingana/p/9906116.html