微機原理與系統設計筆記2 | 8086CPU結構與功能

来源:https://www.cnblogs.com/Roboduster/archive/2023/01/24/17066552.html
-Advertisement-
Play Games

打算整理彙編語言與介面微機這方面的學習記錄。本部分講解8086CPU的結構和基本功能以及特性。 參考資料 西電《微機原理與系統設計》周佳社 西交《微機原理與介面技術》 課本《彙編語言與介面技術》王讓定 小甲魚《彙編語言》 1. 微處理器的外部結構 1.1 引腳 外部結構就是封裝出來的輸入輸出引腳。8 ...



  • 打算整理彙編語言與介面微機這方面的學習記錄。本部分講解8086CPU的結構和基本功能以及特性。
  • 參考資料
    • 西電《微機原理與系統設計》周佳社
    • 西交《微機原理與介面技術》
    • 課本《彙編語言與介面技術》王讓定
    • 小甲魚《彙編語言》

1. 微處理器的外部結構

1.1 引腳

外部結構就是封裝出來的輸入輸出引腳。8086/8088有40個引腳。

  • 8086片內片外的數據匯流排都是16位
  • 8088片內16位,而片外8位

1

如此前緒論所說,部分引腳專用,部分引腳復用,復用部分需要掌握其時序。

CPU的這些引腳功能:

  1. 與存儲器之間交換信息
  2. 與I/O設備(介面)之間交換信息
  3. 輸入輸出必要的信息

1.2 控制引腳

舉個例子講解一下這些引腳:

  • 當CPU向外部(存儲器/IO介面)寫數據時,上圖的WR引腳應為有效(低電平)

    RD是讀信號。

  • 而區分操作存儲器和I/O介面的是M/IO引腳

  • 在此基礎上可以設計邏輯電路來控制更具體的事情,比如WR和M/IO連接一個或門,就能產生IOW信號等。

1.3 地址引腳

A. 定址空間

8086CPU有20條地址線A19A<sub>16</sub>、A<sub>15</sub>A0,可以定址\(2^{20}\)位元組的空間,也就是1M空間,地址空間大小為1MB。

B. IO埠的概念

  • 操作系統設計過程中,外設部分經常提及埠,這裡正經回憶一下。
  • 2
  • 外設的狀態存儲在介面電路中的埠寄存器,如果CPU沒有與介面通信,則埠寄存器保持高阻態,不向外/內輸出、輸入。
  • 當地址匯流排上的地址是某介面埠寄存器的地址(選中)時,其中信息通過數據匯流排流入CPU。

匯流排競爭:多個設備埠同時激活。

埠如下圖右下角部分所示:

  • 數據輸入埠
  • 命令埠
  • 狀態輸入埠
    3

具體而言,外設晶元是有手冊的,當我們操作顯卡,就要查VGA相關的手冊,滑鼠和鍵盤就有另一個晶元來管理。

手冊上會詳細說明埠的作用,在程式中用指令向埠賦值即可。

C. 統一編址與獨立編址

上面提到,一個IO埠至少占用一個IO地址----IO埠地址。根據埠地址和存儲器是否一起編址,有:

  • 統一編址

    • 缺點:浪費了存儲器的空間。
    • 優點:IO驅動程式編寫方便,靈活。
    • 例:51系列。
  • 獨立編製

    • 優點:節約存儲器的空間。
    • 缺點:要多記憶操作IO的指令,IO編程不靈活。
    • 例:8086。
    • x86的IO訪存指令為 in/out

    舉個例子

    某個I/O埠的地址為2000H,則訪問如果要輸出數據到該埠,彙編語言應該這樣寫:

    mov AL,01H
    ;這裡是要輸出的數據量,僅是一個參考
    ;該課程中這裡要點一個燈
    mov DX,2000H
    mov DX,AL
    ;註意這裡跟存儲器的並不同,沒有中括弧
    

2. 微處理器的內部結構

2.1 作用

4

2.2 結構

不論CPU型號如何,其內部基本都有以下結構:

5

  1. ALU:必須,算術邏輯運算

  2. 地址寄存器可以充當數據寄存器

    數據寄存器不能充當地址寄存器

  3. 控制器:負責取指令,放在指令寄存器中,解碼

  4. I/O控制邏輯:與外部I/O打交道,使得CPU可以響應I/O設備發出的中斷請求。

2.3 控制器講解

這部分要與其實跟計組沒多大差別了,要結合CPU"取指執行"的思想來理解。

6

學到這裡突然想複習 流水線 Verilog 什麼的了。

因為上面的圖還是很籠統,怎麼判斷、怎麼控制時序都還沒有涉及。先忍住,把介面部分學完。

上圖並不完整,如果從存儲器中取出的是數據data而不是指令 instructions ,則直接放入數據寄存器或者指定寄存器(也不屬於控制器的範疇了)

2.4 堆棧

來自計操的補充:

  • 說 堆 特指 堆
  • 說 堆棧 指的是 棧
  • 堆棧在存儲器空間中,大小和位置都是編程自定義的。

  • 8086中堆棧必須按字操作

  • 堆棧操作的代表性指令是

    push ax
    pop ax
    ;如果是8086的按字操作規定,目的寄存器就不能是AL
    
  • 堆棧基址寄存器:sp,初始置向棧底+1(也就是棧底再向下的一個存儲單元),這個位置是程式設定的。

  • 假如執行以下操作:

    push ax;第1步
    push bx;第2步
    

    第1步中,sp先-2空出一個字,然後AX分高低八位分別存入這個空字的高低存儲單元。

    第2步重覆第1步操作。

    如果要pop堆棧中的值,則是上述逆過程,先取出棧頂的值,再sp+2。

  • 堆棧溢出:

    • 當一直push,向堆棧區域增加數據,超過堆棧分配空間(超過最高棧頂),則溢出
    • 當一直pop,超過棧底,則溢出。
    • 堆棧溢出會造成系統crush。

3. 8086/8088CPU 內部結構

2.3節講解的是處理器的工作思路,或是說 “取指執行”的電腦思想。下麵介紹8086CPU的內部結構(仍然符合2.3節的大致思路)。

7

3.1 BIU

  • 有一個問題,地址匯流排20位,意味著可以定址1MB地址空間;而CPU內部寄存器只有16位。

    如何用16位寄存器存放20位的地址信息呢?

  • 8086的設計是:講存儲器分為邏輯段,一個寄存器負責定址段,一個寄存器負責定址段內空間,也就是一個段內最多64KB(\(2^{16}\)byte)空間。

  • 各種段基址寄存器以及指令寄存器就在上圖BIU右上角

  • 這裡的轉化的具體過程就是在上圖的地址產生與匯流排控制單元進行的。

  • 轉化公式為:

    CS:IP(CS左移4位+IP),也就是

    (CS << 4) + IP

  • BIU右下角的指令隊列充當的是2.3節的IR指令寄存器的角色,8086中有6個位元組,8088中4個位元組。

    這是兩個CPU內部結構唯一的區別。

總結,BIU負責外部存儲器取出指令、取出數據,並將取出的指令放入指令隊列,對應 “取指”。數據通過ALU匯流排直接送入EU。

3.2 EU

總結放在前面:負責從指令隊列中獲取指令,對該指令解碼並執行,對應“執行”。

這裡可以看出,指令隊列的存在,可以使得兩個部分的性能都得到提升。
8

而外部匯流排在上圖過程中始終處於忙狀態,匯流排的使用率也上升。

4. 8086的寄存器組織

8086內部共有14個16位寄存器:

  • 通用寄存器 (EU左上角)

    • 數據寄存器 4個
      • AX,BX,CX,DX
      • 各個寄存器又有特殊功能,但是給我的印象不深:
        • AX—累加器(特殊功能)| AH AL
        • BX—基址寄存器(特)—段內的–DS段的
        • CX—計數器
        • DX—數據寄存器(IO)
    • 它們又都可以分為XH和XL。
  • 地址指針寄存器與變址寄存器

    • 地址指針寄存器

      • SP:堆棧指針寄存器

      • BP:地址指針寄存器

        BP與BX在做地址指針時的區別:

        mov BX,002H
        mov BP,002H
        mov AL,34H
        mov [BX],AL;1
        mov [BP],AL;2
        

        1處AL值預設放到了數據段的BX偏移處,2處AL值預設放到了堆棧段的BP偏移處。

        如果要使它們不預設,可以將上面代碼表示地址的中括弧內加上它們的目的段基址寄存器如:

        mov SS:[BX],AL
        ;此時BX表示堆棧偏移
        mov DS:[BP],AL
        ;此時BP表示數據段偏移
        
    • 變址寄存器

      • SI:源變址寄存器

      • DI:目的變址寄存器

      • 找到的都是DS段的地址

      • 變址寄存器中“變”的概念來自於8086對字元串的處理。

        具體涉及8086指令系統中的字元串操作指令。

        如將字元串搬運到存儲器另一個位置,源字元串的位置需要定義在DS:SI,目的字元串的位置定義在DS:DI。

        DS:SI==(DS<<4)+SI

        當使用movsb或movsw(無操作數指令),自動從源字元串搬運到目的字元串。(兩者的區別是按位元組搬運和按字搬運)

        在這個字元串操作過程中,DI和SI是在自動增加的,所以其名字中的“變”不言而喻。

        當DI和SI像BP一樣進行普通數據段操作時,不會自己增加。

  • 段寄存器

    • 8086彙編程式結構分為若幹邏輯段,彙編後放到存儲器的不同段。

    • CS:代碼段基址寄存器

    • DS:數據段基址寄存器

    • ES:附加數據段基址寄存器

    • SS:堆棧段基址寄存器

    • 在代碼段開始時,賦值DS ES SS,使其符合自己安排的位置,而CS由操作系統安排。

      所以不會出現mov CS,AX

      突然感覺這個原理有點古董。

  • 控制寄存器

    • IP:指令指針寄存器,相當於2.3節的程式計數器PC

      代碼段的偏移地址

    • PSW:處理器狀態字寄存器,設置9個狀態位。

      6個狀態位表達ALU運算後的程式狀態。

      控制標誌:控制CPU的運行狀態

      • DF方向控制,在字元串操作中,DF0,變址寄存器SI DI自增;DF1,SI DI自減

        即控制SI DI的變化方向

      • IF中斷允許標誌,IF=1時,CPU可以響應可屏蔽中斷請求(也就是外部中斷);IF=0時,CPU不響應中斷請求。

        中斷是操作系統中很重要的概念,開中斷和閉中斷的指令為sti cli

      • TF陷阱標誌/單步標誌:TF=1時,CPU處於單步執行方式,每次執行一條指令自動執行一次特定的內部中斷,具體應用就是Debug。

    • 彙編語言中的pushF表示將PSW標誌寄存器壓棧,popF表示將棧頂出給PSW

5. 8086存儲器和IO組織地址空間

5.1 地址空間

  • 地址線:A19-A16,A15-A10,A9-A0

  • 8086給存儲器編址20根地址線,IO16根地址線(A0~A15)

  • 在早期IBM pc機中,給IO分配A9-A0地址線來定址1KB空間,

    • 前512B:為主板上的IO分配地址(000H-1FFH)
    • 後512B:給插件板上的IO分配地址(200H-3FFH)

5.2 數據存放格式

  • 三種格式:位元組型、字型、雙字型

  • 位元組型數據:

    一個位元組型數據對應一個地址單元。

    彙編語言設計中,位元組型數據定義在存儲器中的DS段,具體用DB這個偽指令來定義

    偽指令用於彙編器如何來翻譯彙編代碼。

  • 字型數據:

    對應兩個相鄰的地址單元。

    定義偽指令為DW,如將字型數據5678H放入存儲器0003H和0004H位置,則78H放在字的低地址0003H,56放在字的高地址0004H。

    這裡有一個對準和不對準的問題。如果字數據地址為奇地址,則稱為未對準,偶地址則對準(比如上面的例子就是未對準)

    對準的數據 進行 訪存指令花費時間更短。未對準會多花費一個時間周期,這與數據匯流排的傳輸機制有關。

    為了防止自己腦袋忘記,提示:對準情況下,高位元組對應高地址,地址單元為奇,走高八位數據線(一個是線,一個是位元組)

  • 雙字型數據:

    對應兩個字,也就是4個存儲單元。

    定義偽指令為DD。

在彙編語言中使用[BX /BP/ SI/ DI],是指寄存器所存的內容,也就是地址;使用BX BP SI DI—指的是寄存器本身

5.3 存儲器的分段與物理地址的形成

  • 為什麼要分段

    • 已經在前面提到過了:寄存器16位而地址線20根。
  • 如何分段:

    • 一個邏輯段最大64K,每個邏輯段的起始地址必須可以被16整除

      因此理論上講,1MB的地址空間,可以分64K(\(2^{16}\))個邏輯段,正好是16位寄存器可以描述的。

  • 物理地址

    • 這個上面3.1部分也提到過,要從段基址(段的起始地址)+段偏移的形式重新得到真實的物理地址。

    • 物理地址的唯一性:

      由於段相互有疊加(按照被16整除的判斷標準),所以一個單元的邏輯地址只是可能不同。但是物理地址一定不同,物理地址是站在存儲器全局為每個單元分配的門牌號。

      雖然段在理論上(按16整除)會重疊,但實際上,彙編源程式是自己定義的各個段,操作系統分別將其裝入記憶體,不會發生段覆蓋的情況。

    • 編程、調試都是邏輯地址

  • 物理地址(PA)的形成

    也就是上面3.1節的轉化公式。

    物理地址=段基址X16(16進位左移一位)+段內偏移地址(段內有效地址)。

  • 取指令

    • CPU如何實現取指令?

    • CS:IP

      即 CS(段基地址)X16+IP(段內偏移地址),取指令所存儲的物理地址

      接著8086按照計算後的物理地址去存儲器找指令取出。

      課程這裡(11講21分鐘時)提到了無條件跳轉,老師講的是代碼段間的無條件跳轉。

      據我所知,這部分比較複雜,老師估計是想強調一下cs:ip的存儲器取指特性,所以具體的後續再提。

      特性:CS和IP是用戶不可寫入的,CS是操作系統將代碼從磁碟放入記憶體後初始化的,IP不可寫入但是會改變,除了自增外還會跳轉。

    • 為了更明確說明物理地址的形成,再舉一個例子,存儲器寫操作:

      mov [bx],ax
      

      這就是將ax中的值寫入ds:bx中去,如果硬要扯一下第3部分EU BIU的知識,那就是EU先將16位地址BX沿內部數據匯流排傳送到BIU,BIU停下取指操作,配合EU去進行寫存儲器的操作,BIU將BX放到加法器中產生物理地址,輸出20位物理地址後放到地址線,AX值放到數據線。

      如果對齊,一個時間周期完成;如果不對齊,兩個時間周期。

    • 堆棧操作(SS:SP),跟上述過程相似。

5.4 各類指令的地址定址

這部分跟指令系統中的定址方式是分不開的,指令系統會在下一部分整理。

關於各種邏輯段偏移寄存器指定與不可指定的靈活性,下麵是一個小總結:

9

這個表裡總結了操作中的預設寄存器以及可以替代的寄存器,比如取指令CS必須與IP搭配,不得自己指定寄存器定址或者段地址。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • AOP 1.官方文檔 AOP講解:下載的spring文件-->spring-framework-5.3.8/docs/reference/html/core.html#aop AOP APIs:下載的spring文件-->spring-framework-5.3.8/docs/reference/h ...
  • RPC基本框架包括四個模塊:傳輸模塊、協議模塊、集群模塊以及Bootstrap模塊。 我們可以使用插件化架構的方法來擴展RPC基本框架,使其更加靈活適應將來可能得變更。 ...
  • 本次設計一個八位的SPI的介面模塊,可以修改輸出的頻率,也可以通過修改參數來設置通信模式。 本模塊是設定生成一個目標輸出頻率的二倍的計數器,然後通關計數的值來輸出響應的信號,從而進行SPI通信。 本模塊既可以發送數據也可以接收數據,給Send_en信號使開始發送數據,在接收到8位數據後會生成Read ...
  • 2023-01-23 一、network的命令 (1)關閉網路 systemctl stop network (2)查看網路狀態 systemctl status network (3)開啟網路 systemctl start network (4)重新啟動網路 systemctl start ne ...
  • System類 exit:退出當前程式。 arraycopy:複製數組元素,比較適合底層調用,一般使用Arrays.copyOF完成複製數組。 currentTimeMillens:返回當前時間距離 1970-1-1 的毫秒數。 gc:運行垃圾回收機制 System.gc(); public cla ...
  • 財務精度:BigInteger 與 BigDecimal 每博一文案 師父說: 人這一輩子,真地好難。 有些人,好著好著,忽然就變陌生了,有些手,牽著牽著,瞬間就放開了,有些路,走著走著,就失去了方向了。 懵懵懂懂,一眨眼,我們就長大了,愛過的人,一轉身,,青春就溜走了。以為有來日方長的,最後只剩人 ...
  • 2023-01-23 一、Linux 1、Liunx的簡介 Linux是一套免費使用和自用傳播的類Unix操作系統,是一個基於POSIX和UNIX的多用戶、多任務、支持多線程和多CPU的操作系統。Linux能運行主要的UNIX工具軟體、應用程式和網路協議。它支持32位和64位硬體。Linux繼承了U ...
  • Redhat 8 的安裝和初始配置 環境說明: 1.在VMWare Workstation上創建虛擬機安裝RHEL 8先決條件:自己的物理機(電腦/工作站/伺服器)的CPU的虛擬化功能要開啟。Intel的CPU:Virtualization Technology(VT-x)AMD的CPU:SVM M ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...