第二章從寄存器的邏輯結構和CPU尋址開始,到後面再講到CPU是如何進行執行代碼(涉及CS和IP兩個寄存器),最後介紹了一個實驗,說實在的,前面的講解真的很具體,做了實驗才出了一些問題。 寄存器 register
細細回憶一下。
====================================
首先,寄存器是可以存放多位二進制數的邏輯結構。8086中,一個寄存器隻能存16位二進制數。16位是2個位元組,但是規定16位是1個字。也就是說,一個寄存器可以放1個字。1個字可以分為高位和低位,分别是1個位元組。這樣一個16位的寄存器就又可以被拆為高8位和低8位兩個寄存器。這樣,我就大緻對寄存器有了概念。
下面是我的了解圖。
AX--通用寄存器之一
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
【0】【0】【0】【0】【0】【0】【0】【0】【0】【0】【1】【0】【0】【1】【0】【0】
7 6 5 4 3 2 1 0 || 7 6 5 4 3 2 1 0
AH || AL
======================================
然後,就是CPU尋址。
CPU是先形成實體位址再來尋找位址的。實體位址的形成是依賴一個段加偏移的邏輯算法。這裡有個問題,為什麼CPU的設計要這樣,寄存器是16
位,而位址總線要弄20這樣的值?
對于段加偏移,書上的比喻讓我們了解很恰當。不過我覺得這樣了解會更好。
比如我們在用谷歌地圖手動找一個城市。首先我們明白地球上有很多國家,有很多城市。我們顯然不會忽略國家的概念而直接去找城市,因為那樣很困難。假設我們要找重慶,我們就先找到中國,然後在想辦法找到重慶。這裡的國家的位置就相當于“段”,城市的位置就相當于“偏移”
。是以在用CPU尋址的時候,我們首先要明白有很多段和很多偏移,然後還要知道“段”是我們自定義的,這不像現在的國家基本固定,這樣我們就可以自由定位了。
段位址*16+偏移位址=實體位址
對二進制而言,這裡的段位址和偏移位址都是16位的,因為它們都是通過寄存器處理的。這裡的段位址*16即段位址向左移4位,後邊的位數用0補上,這樣就形成了一個20位的資料。偏移位址是任意的16位,故可以偏移64K大小的位置,也就是隻有16根位址總線時能尋址的範圍大小。這樣隻需要16個段位址就可以覆寫20位位址總線能夠尋址範圍。而段位址的自定義性,更是可以大大加大了尋址的靈活性。
=====================================
接下去,介紹的是CS和IP兩個寄存器。它們的組合實作了CPU對代碼段的尋址(我們很自然的就明白了這兩個分别代表了段和偏移)。CS-Code Segment IP-Instruction Pointer(自己認為的原英文詞)。
這裡需要說明一下,段寄存器有4種,其中CS是代碼段寄存器。也許到這裡,我可以大概明白了上面自己提出的問題,為什麼CPU要弄個段加偏移的尋址方式?有了段就可以對記憶體中不同的資料内容進行分類。就像CS段隻指向代碼段。而且很顯然段加偏移的概念應該跟位址總線的數量無關。
在這一部分又強調了 記憶體中,指令和資料沒有任何差別。也就是說CPU必須應該能夠在一大堆1和0中知道哪些是代碼,哪些是資料。于是寄存器又在這裡發揮作用了,有專門的寄存器來參與實作代碼段實體位址的形成。CS-代碼段寄存器,提供段位址。IP-指令指針寄存器,提供偏移位址。
=====================================
最後是一個實驗
先總結一下操作方法:
* R-檢視、改變CPU寄存器的内容
* D-檢視記憶體中的内容
* E-改寫記憶體中的内容
* U-将記憶體中的機器指令翻譯成彙編指令
* T-執行一條機器指令
* A-以彙編指令的格式在記憶體中寫入一條機器指令
-r 檢視寄存器的内容
-r ax 修改ax的内容 鍵入回車後 出現“:”在其後填入要賦予的值
-d 1000:1 檢視從1000:1開始的128個位元組的内容 每行16個共8行
-d 1000:0 9 檢視10000到10009的10個位元組
-e 1000:0 1 2 3 4 5 6 7 8 9 修改從10000開始的10個位元組的資料
-e 1000:0 輸回車 可以一個一個修改 按空格跳到下一個
-e 1000:0 “adfasf” 2 ‘a’ 可以輸字元串 字元 數字
-u 1000:0 檢視1000:0開始的機器指令和對應的彙編指令
-a 1000:0 從1000:0位置開始寫彙編指令 很友善
-t 執行目前CS:IP位置的機器指令
做實驗過程中,我開了好幾個cmd視窗,竟然發現對其中的修改竟然互不影響。後來才明白我是在虛拟下運作的。虛拟8086模式,确實是一個不錯的想法。