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