第三章 寄存器(內存訪問)

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指向了那裏。

相關文章
相關標籤/搜索