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

1.内存中字的存储编程

  CPU 中,用16位寄存器来存储一个字。高 8 位存放高位字节,低 8 位存放低位字节。在内存中存储时,因为内存单元是字节单元,则一个字要用两个地址连续的内存单元来存放,这个字的低位字节存放在低地址单元中,高位字节存放在高地址单元中。好比咱们从 0 地址开始存放 2000。spa

  提出了字单元的概念:字单元,即存放一个字型数据(16位)的内存单元,由两个地址连续的内存单元组成。高地址内存单元中存放字型数据的高位字节,低地址内存单元中存放字型数据的低位字节。对象

  老师在这里提出了小端法和大端法的概念:内存

  (1)小端法(Little-Endian)就是低位字节排放在内存的低地址端即该值的起始地址,高位字节排放在内存的高地址端。 
  (2)大端法(Big-Endian)就是高位字节排放在内存的低地址端即该值的起始地址,低位字节排放在内存的高地址端。it

通常来讲咱们采用小端法。程序

2.DS和【address】数据

CPU要读写一个内存单元的时候,必须先给出这个内存单元的地址。di

在8086PC中内存单元由2部分组成:push

(1)段地址错误

(2)偏移地址

8086CPU中有一个DS寄存器地址,一般用来存放数据的段地址。

好比咱们要读取10000H的单元内容,能够用以下的程序段进行。

 

mov bx,1000H

mov ds,bx

mov al,[0]

上面3条数据指令将10000H(1000:0)中的数据读到AL中

 mov al,[0]

咱们使用mov指令能够完成2种操做:

(1)将数据直接送入寄存器

(2)将一个寄存器中的数据送入到另一个寄存器。

也可使用mov指令将一个内存单元中的内容送入一个寄存器中。从哪一个内存单元送到哪个寄存器呢? 因此在指令中必须指明。寄存器用寄存器来指明,内存单元则用内存单元来指明。

 

[...] 表示一个内存单元。[...]中的0表示内存单元的便宜地址。咱们知道,只有偏移地址是不能定位一个内存单元的。那么内存单元的段地址是多少呢? 执行指令时,8086CPU会自动取DS中的数据为内存单元的段地址。

 

如何用MOV指令从10000H中读取数据呢? 10000H用段地址和偏移地址表示为1000:0. 咱们能够先讲1000H放入DS中。而后mov al,[0].就完成了传送。

mov 指令中[]表示操做的对象是一个内存单元。 [0]表示操做的是一个内存单元的偏移地址是0。它的段地址默认保存是放在ds中。执行指令时,CPU会自动从DS中取出。

 

如何把一个数据送入寄存器?

ds是一个短寄存器,8086CPU不支持将数据直接送入到短寄存器的操做。

那么如何将数据送入进去呢?

我能够在事前用通常的寄存器就行了。如bx,再将bx中的内容送入ds。

 

mov bx,1000H

mov ds,bx

mov al,[0]

以上三条指令能够实现将10000H(1000:0)中的数据读到al中。

 

mov bx,1000H

mov ds,bx

mov [0],al 则是将al中的数据送入内存单元10000H中。

 

mov 段寄存器, 寄存器      正确

mov 寄存器, 段寄存器      正确

3.字的传送

  前面咱们用mov指令在寄存器和内存之间进行字型数据的传送。由于8086CPU是16位结构,有16根数据线,因此,能够一次性传送16位的数据,也就是说能够一次性传送一个字。只要在mov指令中给出16位的寄存器就能够进行16位的数据传送了。

4 mov,add,sub指令

这三种指令都带有两个操做对象,有一下几种操做类型:

mov:寄存器,数据

mov:寄存器,寄存器

mov:寄存器,内存单元

mov:段寄存器,内存单元

mov:内存单元,寄存器

mov:内存单元,段寄存器

mov:段寄存器,寄存器

mov:寄存器,段寄存器

 

add:寄存器,数据

add:寄存器,寄存器

add:内存单元,寄存器

add:寄存器,内存单元

 

sub:寄存器,数据

sub:寄存器,寄存器

sub:内存单元,寄存器

sub:寄存器,内存单元

5.数据段

数据段:对于 8086PC 机,在编程时,能够根据须要,将一组内存单元定义为一个段。咱们能够将一组长度为 N(N<=64KB)、地址连续、起始地址为 16 的倍数的内存单元看成专门存储数据的内存空间,从而定义一个数据段。好比用 123BH~123B9H 这段内存空间来存放数据,咱们就能够认为,123B0H~123B9H 这段内存是一个数据段,它的段地址为 123BH,长度为10个字节。

6.栈

 

栈的特性: 后进先出

 

两个概念: 栈底、栈顶

 

两个操做: 入栈、出栈

 

栈段:对于 8086PC 机,在编程时,能够根据须要,将一组内存单元定义为一个段。咱们能够将长度为 N(N<=64KB)的一组地址连续、起始地址为 16 的倍数的内存单元,看成栈空间来用,从而定义了一个栈段。

 

 

 

栈的大小是靠咱们本身决定的,如何肯定这段内存为栈,就须要两个寄存器,段寄存器ss和存放偏移地址的寄存器sp,好比咱们决定10000-1000f为寄存器那么ss:sp一开始应该为 1000:0010执行栈有两个指令push,pop,push是入栈执行过程是先sp+2以后在把数据放进去,pop指令是先出栈,先将指令放进栈接着再sp-2。

任意时刻,SS:SP指向栈顶元素

 

 

注意:如下两种情形会发生「栈顶超界」问题:

 

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

 

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

栈顶超界是危险的,由于咱们既然将一段空间安排为栈,那么在栈空间以外的空间里极可能存放了具备其余用途的数据、代码等,这些数据、代码多是咱们本身程序中的,也多是别的程序中的。可是因为咱们在入栈出栈时的不当心,而将这些数据、代码意外地改写,将会引起一连串的错误。


7.段的综述

(1) 段是一个逻辑上的概念。

编程时,可根据须要指定一段内存区用做数据段、代码段或是栈段。

(2) 用做数据段时,要把段地址→DS

     用做栈段时,要把段地址→SS,栈顶偏移地址 → SP

 用做代码段时,段地址→CS,要取的指令偏移地址→IP。但CS和IP的值不能使用mov改变。

(3)  一段内存能够同时用做代码段、数据段、栈段。

     由编程时灵活肯定,不管咱们怎么安排,CPU将内存中的某段内容当作代码,是因CS:IP指向了那里;CPU将某段内存当作栈,是由于SS:SP指向了那里。

相关文章
相关标签/搜索