王爽匯編語言第二版(全部)課件.ppt
《王爽匯編語言第二版(全部)課件.ppt》由會員分享,可在線閱讀,更多相關《王爽匯編語言第二版(全部)課件.ppt(1290頁珍藏版)》請在裝配圖網(wǎng)上搜索。
第1章基礎知識 1 1機器語言1 9數(shù)據(jù)總線1 2匯編語言的產(chǎn)生1 10控制總線1 3匯編語言的組成1 11內(nèi)存地址空間 概述 1 4存儲器1 12主板1 5指令和數(shù)據(jù)1 13接口卡1 6存儲單元1 14各類存儲器芯片1 7CPU對存儲器的讀寫1 15內(nèi)存地址空間1 8地址總線 引言 匯編語言是直接在硬件之上工作的編程語言 首先要了解硬件系統(tǒng)的結構 才能有效的應用匯編語言對其編程 在本章中 對硬件系統(tǒng)結構的問題進行一部分的探討 以使后續(xù)的課程可在一個好的基礎上進行 引言 當課程進行到需要補充新的基礎知識 關于編程結構或其他的 時候 再對相關的基礎知識進行介紹和探討 本書的原則是 以后用到的知識 以后再說 引言 匯編課程的研究重點放在如何利用硬件系統(tǒng)的編程結構和指令集有效靈活的控制系統(tǒng)進行工作 1 1機器語言 機器語言是機器指令的集合 機器指令展開來講就是一臺機器可以正確執(zhí)行的命令 1 1機器語言 指令 01010000 PUSHAX 電平脈沖 1 1機器語言 以后我們提到的計算機是指由CPU和其他受CPU直接或間接控制的芯片 器件 設備組成的計算機系統(tǒng) 比如我們最常見的PC機 1 1機器語言 程序員們將0 1數(shù)字編程的程序代碼打在紙帶或卡片上 1打孔 0不打孔 再將程序通過紙帶機或卡片機輸入計算機 進行運算 示例應用8086CPU完成運算 S 768 12288 1280 1 1機器語言 S 768 12288 1280機器碼 101100000000000000000011000001010000000000110000001011010000000000000101假如將程序錯寫成以下這樣 請找處錯誤 101100000000000000000011000001010000000000110000000101101000000000000101 1 1機器語言 在顯示器上輸出 welcometomasm 機器碼看到這樣的程序 你會有什么感想 如果程序里有一個 1 被誤寫為 0 又如何去查找呢 1 2匯編語言的產(chǎn)生 匯編語言的主體是匯編指令 匯編指令和機器指令的差別在于指令的表示方法上 匯編指令是機器指令便于記憶的書寫格式 匯編指令是機器指令的助記符 1 2匯編語言的產(chǎn)生 機器指令 1000100111011000操作 寄存器BX的內(nèi)容送到AX中匯編指令 MOVAX BX這樣的寫法與人類語言接近 便于閱讀和記憶 寄存器 寄存器 簡單的講是CPU中可以存儲數(shù)據(jù)的器件 一個CPU中有多個寄存器 AX是其中一個寄存器的代號 BX是另一個寄存器的代號 更詳細的內(nèi)容我們在以后的課程中將會講到 1 2匯編語言的產(chǎn)生 計算機能讀懂的只有機器指令 那么如何讓計算機執(zhí)行程序員用匯編指令編寫的程序呢 用匯編語言編寫程序的工作過程 1 3匯編語言的組成 匯編語言由以下3類組成 1 匯編指令 機器碼的助記符 2 偽指令 由編譯器執(zhí)行 3 其它符號 由編譯器識別 匯編語言的核心是匯編指令 它決定了匯編語言的特性 1 4存儲器 CPU是計算機的核心部件 它控制整個計算機的運作并進行運算 要想讓一個CPU工作 就必須向它提供指令和數(shù)據(jù) 指令和數(shù)據(jù)在存儲器中存放 也就是平時所說的內(nèi)存 1 4存儲器 在一臺PC機中內(nèi)存的作用僅次于CPU 離開了內(nèi)存 性能再好的CPU也無法工作 1 4存儲器 磁盤不同于內(nèi)存 磁盤上的數(shù)據(jù)或程序如果不讀到內(nèi)存中 就無法被CPU使用 1 5指令和數(shù)據(jù) 指令和數(shù)據(jù)是應用上的概念 在內(nèi)存或磁盤上 指令和數(shù)據(jù)沒有任何區(qū)別 都是二進制信息 1 5指令和數(shù)據(jù) 二進制信息 1000100111011000 89D8H 數(shù)據(jù) 1000100111011000 MOVAX BX 程序 1 6存儲單元 存儲器被劃分為若干個存儲單元 每個存儲單元從0開始順序編號 例如 一個存儲器有128個存儲單元 編號從0 127 如右圖示 1 6存儲單元 對于大容量的存儲器一般還用以下單位來計量容量 以下用B來代表Byte 1KB 1024B1MB 1024KB1GB 1024MB1TB 1024GB磁盤的容量單位同內(nèi)存的一樣 實際上以上單位是微機中常用的計量單位 1 7CPU對存儲器的讀寫 CPU要想進行數(shù)據(jù)的讀寫 必須和外部器件 標準的說法是芯片 進行三類信息的交互 存儲單元的地址 地址信息 器件的選擇 讀或?qū)懨?控制信息 讀或?qū)懙臄?shù)據(jù) 數(shù)據(jù)信息 1 7CPU對存儲器的讀寫 那么CPU是通過什么將地址 數(shù)據(jù)和控制信息傳到存儲芯片中的呢 電子計算機能處理 傳輸?shù)男畔⒍际请娦盘?電信號當然要用導線傳送 1 7CPU對存儲器的讀寫 在計算機中專門有連接CPU和其他芯片的導線 通常稱為總線 物理上 一根根導線的集合 邏輯上劃分為 地址總線數(shù)據(jù)總線控制總線圖示 1 7CPU對存儲器的讀寫 總線在邏輯上劃分的圖示 1 7CPU對存儲器的讀寫 CPU在內(nèi)存中讀或?qū)懙臄?shù)據(jù)演示 讀演示寫演示從上面我們知道CPU是如何進行數(shù)據(jù)讀寫的 可是我們?nèi)绾蚊钣嬎銠C進行數(shù)據(jù)的讀寫呢 1 7CPU對存儲器的讀寫 1 7CPU對存儲器的讀寫 1 7CPU對存儲器的讀寫 對于8086CPU 下面的機器碼能夠完成從3號單元讀數(shù)據(jù) 機器碼 101000000000001100000000含義 從3號單元讀取數(shù)據(jù)送入寄存器AXCPU接收這條機器碼后將完成上面所述的讀寫工作 1 7CPU對存儲器的讀寫 機器碼難于記憶 用匯編指令來表示 情況如下 機器碼 101000000000001100000000對應的匯編指令 MOVAX 3 含義 傳送3號單元的內(nèi)容到AX 1 8地址總線 CPU是通過地址總線來指定存儲單元的 地址總線上能傳送多少個不同的信息 CPU就可以對多少個存儲單元進行尋址 1 8地址總線 地址總線發(fā)送地址信息演示 1 8地址總線 1 8地址總線 一個CPU有N根地址總線 則可以說這個CPU的地址總線的寬度為N 這樣的CPU最多可以尋找 的N次方個內(nèi)存單元 1 9數(shù)據(jù)總線 CPU與內(nèi)存或其它器件之間的數(shù)據(jù)傳送是通過數(shù)據(jù)總線來進行的 數(shù)據(jù)總線的寬度決定了CPU和外界的數(shù)據(jù)傳送速度 1 9數(shù)據(jù)總線 我們來分別看一下它們向內(nèi)存中寫入數(shù)據(jù)89D8H時 是如何通過數(shù)據(jù)總線傳送數(shù)據(jù)的 8088CPU數(shù)據(jù)總線上的數(shù)據(jù)傳送情況8086CPU數(shù)據(jù)總線上的數(shù)據(jù)傳送情況 1 9數(shù)據(jù)總線 8位數(shù)據(jù)總線上傳送的信息 1 9數(shù)據(jù)總線 16位數(shù)據(jù)總線上傳送的信息 1 10控制總線 CPU對外部器件的控制是通過控制總線來進行的 在這里控制總線是個總稱 控制總線是一些不同控制線的集合 有多少根控制總線 就意味著CPU提供了對外部器件的多少種控制 所以 控制總線的寬度決定了CPU對外部器件的控制能力 控制總線上發(fā)送的控制信息 1 10控制總線 1 10控制總線 前面所講的內(nèi)存讀或?qū)懨钍怯蓭赘刂凭€綜合發(fā)出的 其中有一根名為讀信號輸出控制線負責由CPU向外傳送讀信號 CPU向該控制線上輸出低電平表示將要讀取數(shù)據(jù) 有一根名為寫信號輸出控制線負責由CPU向外傳送寫信號 1 1節(jié) 1 10節(jié)小結 1 匯編指令是機器指令的助記符 同機器指令一一對應 2 每一種CPU都有自己的匯編指令集 1 1節(jié) 1 10節(jié)小結 3 CPU可以直接使用的信息在存儲器中存放 4 在存儲器中指令和數(shù)據(jù)沒有任何區(qū)別 都是二進制信息 1 1節(jié) 1 10節(jié)小結 5 存儲單元從零開始順序編號 6 一個存儲單元可以存儲8個bit 用作單位寫成 b 即8位二進制數(shù) 7 1B 8b1KB 1024B1MB 1024KB1GB 1024MB 1 1節(jié) 1 10節(jié)小結 續(xù) 8 每一個CPU芯片都有許多管腳 這些管腳和總線相連 也可以說 這些管腳引出總線 一個CPU可以引出三種總線的寬度標志了這個CPU的不同方面的性能 地址總線的寬度決定了CPU的尋址能力 數(shù)據(jù)總線的寬度決定了CPU與其它器件進行數(shù)據(jù)傳送時的一次數(shù)據(jù)傳送量 控制總線寬度決定了CPU對系統(tǒng)中其它器件的控制能力 1 1節(jié) 1 10節(jié)小結 續(xù) 在匯編課程中 我們從功能的角度介紹了這三類總線 對實際的連接情況不做討論 特別提示 特別提示 檢測點1 1 Page8 沒有通過檢測點請不要向下學習 1 11內(nèi)存地址空間 概述 什么是內(nèi)存地址空間呢 一個CPU的地址線寬度為10 那么可以尋址1024個內(nèi)存單元 這1024個可尋到的內(nèi)存單元就構成這個CPU的內(nèi)存地址空間 下面深入討論 首先需要介紹兩部分基本知識 主板和接口卡 1 12主板 在每一臺PC機中 都有一個主板 主板上有核心器件和一些主要器件 這些器件通過總線 地址總線 數(shù)據(jù)總線 控制總線 相連 1 13接口卡 計算機系統(tǒng)中 所有可用程序控制其工作的設備 必須受到CPU的控制 CPU對外部設備不能直接控制 如顯示器 音箱 打印機等 直接控制這些設備進行工作的是插在擴展插槽上的接口卡 1 14各類存儲器芯片 從讀寫屬性上看分為兩類 隨機存儲器 RAM 和只讀存儲器 ROM 從功能和連接上分類 隨機存儲器RAM裝有BIOS的ROM接口卡上的RAMPC機中各類存儲器的邏輯連接情況 1 14各類存儲器芯片 裝有BIOS的ROMBIOS BasicInput OutputSystem 基本輸入輸出系統(tǒng) BIOS是由主板和各類接口卡 如 顯卡 網(wǎng)卡等 廠商提供的軟件系統(tǒng) 可以通過它利用該硬件設備進行最基本的輸入輸出 在主板和某些接口卡上插有存儲相應BIOS的ROM 1 15內(nèi)存地址空間 上述的那些存儲器在物理上是獨立的器件 但是它們在以下兩點上相同 1 都和CPU的總線相連 2 CPU對它們進行讀或?qū)懙臅r候都通過控制線發(fā)出內(nèi)存讀寫命令 1 15內(nèi)存地址空間 將各各類存儲器看作一個邏輯存儲器 所有的物理存儲器被看作一個由若干存儲單元組成的邏輯存儲器 每個物理存儲器在這個邏輯存儲器中占有一個地址段 即一段地址空間 CPU在這段地址空間中讀寫數(shù)據(jù) 實際上就是在相對應的物理存儲器中讀寫數(shù)據(jù) 1 15內(nèi)存地址空間 假設 上圖中的內(nèi)存空間地址段分配如下 地址0 7FFFH的32KB空間為主隨機存儲器的地址空間 地址8000H 9FFFH的8KB空間為顯存地址空間 地址A000H FFFFH的24KB空間為各個ROM的地址空間 1 15內(nèi)存地址空間 不同的計算機系統(tǒng)的內(nèi)存地址空間分配情況是不同的 8086PC機內(nèi)存地址空間分配的基本情況 8086PC機的內(nèi)存地址空間分配 1 15內(nèi)存地址空間 內(nèi)存地址空間 最終運行程序的是CPU 我們用匯編編程的時候 必須要從CPU角度考慮問題 對CPU來講 系統(tǒng)中的所有存儲器中的存儲單元都處于一個統(tǒng)一的邏輯存儲器中 它的容量受CPU尋址能力的限制 這個邏輯存儲器即是我們所說的內(nèi)存地址空間 小結 匯編語言 課件 王爽著 清華大學出版社 制作工具 MicrosoftPowerPoint2003 本課件由匯編網(wǎng) 制作提供 第2章寄存器 CPU工作原理 2 1通用寄存器2 2字在寄存器中的存儲2 3幾條匯編指令2 4物理地址2 516位結構的CPU2 68086CPU給出物理地址的方法 2 7 段地址 16 偏移地址 物理地址 的本質(zhì)含義2 8段的概念2 9段寄存器2 10CS和IP2 12代碼段 CPU概述 一個典型的CPU由運算器 控制器 寄存器等器件組成 這些器件靠內(nèi)部總線相連 內(nèi)部總線實現(xiàn)CPU內(nèi)部各個器件之間的聯(lián)系 外部總線實現(xiàn)CPU和主板上其它器件的聯(lián)系 寄存器概述 8086CPU有14個寄存器它們的名稱為 AX BX CX DX SI DI SP BP IP CS SS DS ES PSW 這些寄存器以后會陸續(xù)介紹 2 1通用寄存器 8086CPU所有的寄存器都是16位的 可以存放兩個字節(jié) AX BX CX DX通常用來存放一般性數(shù)據(jù)被稱為通用寄存器 下面以AX為例 我們看一下寄存器的邏輯結構 一個16位寄存器可以存儲一個16位的數(shù)據(jù) 數(shù)據(jù)的存放情況 一個16位寄存器所能存儲的數(shù)據(jù)的最大值為多少 答案 216 1 2 1通用寄存器 16位數(shù)據(jù)在寄存器中的存放情況 數(shù)據(jù) 18二進制表示 10010在寄存器AX中的存儲 16位數(shù)據(jù)在寄存器中的存放情況 數(shù)據(jù) 20000二進制表示 0100111000100000在寄存器AX中的存儲 2 1通用寄存器 8086上一代CPU中的寄存器都是8位的 為保證兼容性 這四個寄存器都可以分為兩個獨立的8位寄存器使用 AX可以分為AH和AL BX可以分為BH和BL CX可以分為CH和CL DX可以分為DH和DL 8086CPU的8位寄存器存儲邏輯 2 1通用寄存器 以AX為例 8086CPU的16位寄存器分為兩個8位寄存器的情況 2 1通用寄存器 AX的低8位 0位 7位 構成了AL寄存器 高8位 8位 15位 構成了AH寄存器 AH和AL寄存器是可以獨立使用的8位寄存器 8086CPU的8位寄存器數(shù)據(jù)存儲情況一個8位寄存器所能存儲的數(shù)據(jù)的最大值是多少 答案 28 1 2 1通用寄存器 2 2字在寄存器中的存儲 一個字可以存在一個16位寄存器中 這個字的高位字節(jié)和低位字節(jié)自然就存在這個寄存器的高8位寄存器和低8位寄存器中 關于數(shù)制的討論 由于一個內(nèi)存單元可以存放8位數(shù)據(jù) CPU中的寄存器又可存放n個8位數(shù)據(jù) 也就是說 計算機中的數(shù)據(jù)大多是由1 N個8位數(shù)據(jù)構成的 用十六進制來表示數(shù)據(jù)可以直觀的看出這個數(shù)據(jù)是由哪些8位數(shù)據(jù)構成的 示例 2 3幾條匯編指令 匯編指令不區(qū)分大小寫 2 3幾條匯編指令 CPU執(zhí)行下表中的程序段的每條指令后 對寄存器中的數(shù)據(jù)進行的改變 2 3幾條匯編指令 2 3幾條匯編指令 這里的丟失 指的是進位制不能在8位寄存器中保存 但是CPU不是并真的不丟棄這個進位值 這個問題會在后面的課程中討論 特別提示 檢測點2 1 Page18 沒有通過檢測點請不要向下學習 2 4物理地址 CPU訪問內(nèi)存單元時要給出內(nèi)存單元的地址 所有的內(nèi)存單元構成的存儲空間是一個一維的線性空間 每一個內(nèi)存單元在這個空間中都有唯一的地址 這個唯一的地址稱為物理地址 2 516位結構的CPU 概括的講 16位結構描述了一個CPU具有以下幾個方面特征 1 運算器一次最多可以處理16位的數(shù)據(jù) 2 寄存器的最大寬度為16位 3 寄存器和運算器之間的通路是16位的 2 68086CPU給出物理地址的方法 8086有20位地址總線 可傳送20位地址 尋址能力為1M 8086內(nèi)部為16位結構 它只能傳送16位的地址 表現(xiàn)出的尋址能力卻只有64K 2 68086CPU給出物理地址的方法 8086CPU采用一種在內(nèi)部用兩個16位地址合成的方法來形成一個20位的物理地址 8086CPU相關部件的邏輯結構 在8086CPU內(nèi)部用兩個16位地址合成的方法來形成一個20位的物理地址 地址加法器 地址加法器合成物理地址的方法 物理地址 段地址 16 偏移地址例如 8086CPU訪問地址為123C8H的內(nèi)存單元由段地址 16引發(fā)的討論 觀察移位次數(shù)和各種形式數(shù)據(jù)的關系 1 一個數(shù)據(jù)的二進制形式左移1位 相當于該數(shù)據(jù)乘以2 2 一個數(shù)據(jù)的二進制形式左移N位 相當于該數(shù)據(jù)乘以2的N次方 3 地址加法器如何完成段地址 16的運算 以二進制形式存放的段地址左移4位 由段地址 16引發(fā)的討論 2 7 段地址 16 偏移地址 物理地址 的本質(zhì)含義 兩個比喻說明 說明 基礎地址 偏移地址 物理地址 的思想 第一個比喻說明 段地址 16 偏移地址 物理地址 的思想 第二個比喻8086CPU就是這樣一個只能提供兩張3位數(shù)據(jù)紙條的CPU 基礎地址 偏移地址 物理地址 比如說 學校 體育館同在一條筆直的單行路上 學校位于路的起點0米處 讀者在學校 要去圖書館 問我那里的地址 我可以用幾種方式描述這個地址 基礎地址 偏移地址 物理地址 1 從學校走2826m到圖書館 這2826可以認為是圖書館的物理地址 2 從學校走2000m到體育館 從體育館再走826m到圖書館 第一個距離2000m是相對于起點的基礎地址 第二個距離826m是將對于基礎地址的偏移地址 段地址 16 偏移地址 物理地址 比如我們只能通過紙條來通信 讀者問我圖書館的地址 我只能將它寫在紙上告訴讀者 顯然我必須有一張可以容納4位數(shù)據(jù)的紙條才能寫下2826這個數(shù)據(jù) 段地址 16 偏移地址 物理地址 不巧的是 沒有能容納4位數(shù)據(jù)的紙條 僅有兩張可以容納3位數(shù)據(jù)的紙條 這樣我只能以這種方式告訴讀者2826這個數(shù)據(jù) 2 8段的概念 錯誤認識 內(nèi)存被劃分成了一個一個的段 每一個段有一個段地址 其實 內(nèi)存并沒有分段 段的劃分來自于CPU 由于8086CPU用 段地址 16 偏移地址 物理地址 的方式給出內(nèi)存單元的物理地址 使得我們可以用分段的方式來管理內(nèi)存 2 8段的概念 我們可以認為 地址10000H 100FFH的內(nèi)存單元組成一個段 該段的起始地址 基礎地址 為10000H 段地址為1000H 大小為100H 2 8段的概念 我們也可以認為地址10000H 1007FH 10080H 100FFH的內(nèi)存單元組成兩個段 它們的起始地址 基礎地址 為10000H和10080H 段地址為 1000H和1008H 大小都為80H 2 8段的概念 以后 在編程時可以根據(jù)需要 將若干地址連續(xù)的內(nèi)存單元看作一個段 用段地址 16定位段的起始地址 基礎地址 用偏移地址定位段中的內(nèi)存單元 兩點需要注意內(nèi)存單元地址小結特別提示 兩點需要注意 1 段地址 16必然是16的倍數(shù) 所以一個段的起始地址也一定是16的倍數(shù) 2 偏移地址為16位 16位地址的尋址能力為64K 所以一個段的長度最大為64K 內(nèi)存單元地址小結 CPU訪問內(nèi)存單元時 必須向內(nèi)存提供內(nèi)存單元的物理地址 8086CPU在內(nèi)部用段地址和偏移地址移位相加的方法形成最終的物理地址 思考兩個問題 1 觀察下面的地址 讀者有什么發(fā)現(xiàn) 結論 CPU可以用不同的段地址和偏移地址形成同一個物理地址 內(nèi)存單元地址小結 內(nèi)存單元地址小結 2 如果給定一個段地址 僅通過變化偏移地址來進行尋址 最多可以定位多少內(nèi)存單元 結論 偏移地址16位 變化范圍為0 FFFFH 僅用偏移地址來尋址最多可尋64K個內(nèi)存單元 比如 給定段地址1000H 用偏移地址尋址 CPU的尋址范圍為 10000H 1FFFFH 內(nèi)存單元地址小結 在8086PC機中 存儲單元的地址用兩個元素來描述 即段地址和偏移地址 數(shù)據(jù)在21F60H內(nèi)存單元中 對于8086PC機的兩種描述 a 數(shù)據(jù)存在內(nèi)存2000 1F60單元中 b 數(shù)據(jù)存在內(nèi)存的2000段中的1F60H單元中 可根據(jù)需要 將地址連續(xù) 起始地址為16的倍數(shù)的一組內(nèi)存單元定義為一個段 特別提示 檢測點2 2 Page23 沒有通過檢測點請不要向下學習 2 9段寄存器 段寄存器就是提供段地址的 8086CPU有4個段寄存器 CS DS SS ES當8086CPU要訪問內(nèi)存時 由這4個段寄存器提供內(nèi)存單元的段地址 2 10CS和IP CS和IP是8086CPU中最關鍵的寄存器 它們指示了CPU當前要讀取指令的地址 CS為代碼段寄存器 IP為指令指針寄存器 8086PC讀取和執(zhí)行指令相關部件 8086PC讀取和執(zhí)行指令演示8086PC工作過程的簡要描述 8086PC工作過程的簡要描述 1 從CS IP指向內(nèi)存單元讀取指令 讀取的指令進入指令緩沖器 2 IP IP 所讀取指令的長度 從而指向下一條指令 3 執(zhí)行指令 轉到步驟 1 重復這個過程 8086PC工作過程的簡要描述 在8086CPU加電啟動或復位后 即CPU剛開始工作時 CS和IP被設置為CS FFFFH IP 0000H 即在8086PC機剛啟動時 CPU從內(nèi)存FFFF0H單元中讀取指令執(zhí)行 FFFF0H單元中的指令是8086PC機開機后執(zhí)行的第一條指令 2 10CS和IP 內(nèi)存中指令和數(shù)據(jù)沒有任何區(qū)別 都是二進制信息 CPU在工作的時候把有的信息看作指令 有的信息看作數(shù)據(jù) CPU根據(jù)什么將內(nèi)存中的信息看作指令 CPU將CS IP指向的內(nèi)存單元中的內(nèi)容看作指令 2 10CS和IP 在任何時候 CPU將CS IP中的內(nèi)容當作指令的段地址和偏移地址 用它們合成指令的物理地址 到內(nèi)存中讀取指令碼 執(zhí)行 如果說 內(nèi)存中的一段信息曾被CPU執(zhí)行過的話 那么 它所在的內(nèi)存單元必然被CS IP指向過 2 11修改CS IP的指令 在CPU中 程序員能夠用指令讀寫的部件只有寄存器 程序員可以通過改變寄存器中的內(nèi)容實現(xiàn)對CPU的控制 CPU從何處執(zhí)行指令是由CS IP中的內(nèi)容決定的 程序員可以通過改變CS IP中的內(nèi)容來控制CPU執(zhí)行目標指令 我們?nèi)绾胃淖僀S IP的值呢 2 11修改CS IP的指令 8086CPU必須提供相應的指令先回想我們?nèi)绾涡薷腁X中的值 mov指令不能用于設置CS IP的值 8086CPU沒有提供這樣的功能 8086CPU為CS IP提供了另外的指令來改變它們的值 轉移指令 如何修改AX中的值 mov指令如 movax 123mov指令可以改變8086CPU大部分寄存器的值 被稱為傳送指令 能夠通過mov指令改變CS IP的值嗎 2 11修改CS IP的指令 同時修改CS IP的內(nèi)容 jmp段地址 偏移地址jmp2AE3 3jmp3 0B16功能 用指令中給出的段地址修改CS 偏移地址修改IP 2 11修改CS IP的指令 僅修改IP的內(nèi)容 jmp某一合法寄存器jmpax 類似于movIP ax jmpbx功能 用寄存器中的值修改IP 內(nèi)存中存放的機器碼和對應匯編指令情況 初始 CS 2000H IP 0000H 請寫出指令執(zhí)行序列 問題分析 問題分析結果 1 movax 6622 2 jmp1000 3 3 movax 0000 4 movbx ax 5 jmpbx 6 movax 0123H 7 轉到第 3 步執(zhí)行 2 12代碼段 對于8086PC機 在編程時 可以根據(jù)需要 將一組內(nèi)存單元定義為一個段 可以將長度為N N 64KB 的一組代碼 存在一組地址連續(xù) 起始地址為16的倍數(shù)的內(nèi)存單元中 這段內(nèi)存是用來存放代碼的 從而定義了一個代碼段 例如 2 12代碼段 這段長度為10字節(jié)的字節(jié)的指令 存在從123B0H 123B9H的一組內(nèi)存單元中 我們就可以認為 123B0H 123B9H這段內(nèi)存單元是用來存放代碼的 是一個代碼段 它的段地址為123BH 長度為10字節(jié) 2 12代碼段 如何使得代碼段中的指令被執(zhí)行呢 將一段內(nèi)存當作代碼段 僅僅是我們在編程時的一種安排 CPU并不會由于這種安排 就自動地將我們定義得代碼段中的指令當作指令來執(zhí)行 CPU只認被CS IP指向的內(nèi)存單元中的內(nèi)容為指令 所以要將CS IP指向所定義的代碼段中的第一條指令的首地址 CS 123BH IP 0000H 2 9節(jié) 2 12節(jié)小結 1 段地址在8086CPU的寄存器中存放 當8086CPU要訪問內(nèi)存時 由段寄存器提供內(nèi)存單元的段地址 8086CPU有4個段寄存器 其中CS用來存放指令的段地址 2 CS存放指令的段地址 IP存放指令的偏移地址 8086機中 任意時刻 CPU將CS IP指向的內(nèi)容當作指令執(zhí)行 2 9節(jié) 2 12節(jié)小結 續(xù) 3 8086CPU的工作過程 1 從CS IP指向內(nèi)存單元讀取指令 讀取的指令進入指令緩沖器 2 IP指向下一條指令 3 執(zhí)行指令 轉到步驟 1 重復這個過程 4 8086CPU提供轉移指令修改CS IP的內(nèi)容 特別提示 檢測點2 3 Page33 沒有通過檢測點請不要向下學習 小結 匯編語言 課件 王爽著 清華大學出版社 制作工具 MicrosoftPowerPoint2003 本課件由匯編網(wǎng) 制作提供 第3章寄存器 內(nèi)存訪問 3 1內(nèi)存中字的存儲3 2DS和 address 3 3字的傳送3 4mov add sub指令3 5數(shù)據(jù)段3 6棧3 7CPU提供的棧機制3 8棧頂超界的問題3 9push pop指令3 10棧段 引言 在第2章中 我們主要從CPU如何執(zhí)行指令的角度講解了8086CPU的邏輯結構 形成物理地址的方法 相關的寄存器以及一些指令 這一章中 我們從訪問內(nèi)存的角度繼續(xù)學習幾個寄存器 在0地址處開始存放20000 0號單元是低地址單元 1號單元是高地址單元 3 1內(nèi)存中字的存儲 3 1內(nèi)存中字的存儲 問題 1 0地址單元中存放的字節(jié)型數(shù)據(jù)是多少 2 0地址字單元中存放的字型數(shù)據(jù)是多少 3 2地址字單元中存放的字節(jié)型數(shù)據(jù)是多少 3 1內(nèi)存中字的存儲 問題 續(xù) 4 2地址單元中存放的字型數(shù)據(jù)是多少 5 1地址字單元中存放的字型數(shù)據(jù)是多少 結論 3 1內(nèi)存中字的存儲 結論 任何兩個地址連續(xù)的內(nèi)存單元 N號單元和N 1號單元 可以將它們看成兩個內(nèi)存單元 也可以看成一個地址為N的字單元中的高位字節(jié)單元和低位字節(jié)單元 3 2DS和 address CPU要讀取一個內(nèi)存單元的時候 必須先給出這個內(nèi)存單元的地址 在8086PC中 內(nèi)存地址由段地址和偏移地址組成 8086CPU中有一個DS寄存器 通常用來存放要訪問的數(shù)據(jù)的段地址 例如 3 2DS和 address 例如 我們要讀取10000H單元的內(nèi)容可以用如下程序段進行 movbx 1000Hmovds bxmoval 0 上面三條指令將10000H 1000 0 中的數(shù)據(jù)讀到al中 3 2DS和 address moval 0 已知的mov指令可完成的兩種傳送功能 1 將數(shù)據(jù)直接送入寄存器 2 將一個寄存器中的內(nèi)容送入另一個寄存器中 mov指令還可以將一個內(nèi)存單元中的內(nèi)容送入一個寄存器 3 2DS和 address 從哪個內(nèi)存單元送到哪個寄存器中呢 mov指令的格式 mov寄存器名 內(nèi)存單元地址 表示一個內(nèi)存單元 中的0表示內(nèi)存單元的偏移地址 那么內(nèi)存單元的段地址是多少呢 3 2DS和 address 執(zhí)行指令時 8086CPU自動取DS中的數(shù)據(jù)為內(nèi)存單元的段地址 如何用mov指令從10000H中讀取數(shù)據(jù) 10000H表示為1000 0 段地址 偏移地址 將段地址1000H放入ds用moval 0 完成傳送 mov指令中的 說明操作對象是一個內(nèi)存單元 中的0說明這個內(nèi)存單元的偏移地址是0 它的段地址默認放在ds中 如何把1000H送入ds 3 2DS和 address 如何把1000H送入ds 傳送指令movax 1相似的方式movds 1000H 8086CPU不支持將數(shù)據(jù)直接送入段寄存器的操作 ds是一個段寄存器 硬件設計的問題 movds 1000H是非法的 數(shù)據(jù) 一般的寄存器 段寄存器 3 2DS和 address 問題 寫幾條指令 將al中的數(shù)據(jù)送入內(nèi)存單元10000H 思考后分析 分析問題本質(zhì) 怎樣將數(shù)據(jù)從寄存器送入內(nèi)存單元 結論 movbx 1000Hmovds bxmov 0 al 一種合理的回答 3 3字的傳送 因為8086CPU是16位結構 有16根數(shù)據(jù)線 所以 可以一次性傳送16位的數(shù)據(jù) 也就是一次性傳送一個字 問題3 3 內(nèi)存中的情況如右圖 寫出下面指令執(zhí)行后寄存器ax bx cx中的值 思考后看分析 單步跟蹤 3 3字的傳送 問題3 3分析 問題3 4 內(nèi)存中的情況如右圖 寫出下面指令執(zhí)行后寄存器ax bx cx中的值 思考后看分析 單步跟蹤 3 3字的傳送 問題3 4分析 3 4mov add sub指令 已學mov指令的幾種形式 mov寄存器 數(shù)據(jù)mov寄存器 寄存器mov寄存器 內(nèi)存單元mov內(nèi)存單元 寄存器mov段寄存器 寄存器根據(jù)已知指令進行推測 3 4mov add sub指令 根據(jù)已知指令進行推測 mov段寄存器 寄存器 mov寄存器 段寄存器 驗證 mov內(nèi)存單元 寄存器 mov內(nèi)存單元 段寄存器 mov段寄存器 內(nèi)存單元 驗證 Debug mov段寄存器 寄存器 mov寄存器 段寄存器 add和sub指令同mov一樣 都有兩個操作對象 它們可以對段寄存器進行操作嗎 請自行在Debug中試驗 3 4mov add sub指令 3 5數(shù)據(jù)段 前面講過 對于8086PC機 我們可以根據(jù)需要將一組內(nèi)存單元定義為一個段 我們可以將一組長度為N N 64K 地址連續(xù) 起始地址為16的倍數(shù)的內(nèi)存單元當作專門存儲數(shù)據(jù)的內(nèi)存空間 從而定義了一個數(shù)據(jù)段 比如我們用123B0H 123B9H這段空間來存放數(shù)據(jù) 段地址 123BH長度 10字節(jié) 3 5數(shù)據(jù)段 如何訪問數(shù)據(jù)段中的數(shù)據(jù)呢 將一段內(nèi)存當作數(shù)據(jù)段 是我們在編程時的一種安排 我們可以在具體操作的時候 用ds存放數(shù)據(jù)段的段地址 再根據(jù)需要 用相關指令訪問數(shù)據(jù)段中的具體單元 示例 3 5數(shù)據(jù)段 我們將123B0H 123BAH的內(nèi)存單元定義為數(shù)據(jù)段 我們現(xiàn)在要累加這個數(shù)據(jù)段中的前3個單元中的數(shù)據(jù) 代碼如下 3 5數(shù)據(jù)段 問題3 5寫幾條指令 累加數(shù)據(jù)段中的前3個字型數(shù)據(jù) 思考后看分析 問題3 5分析 注意 一個字型數(shù)據(jù)占兩個單元 所以偏移地址是0 2 4 3 1節(jié) 3 5節(jié)小結 1 字在內(nèi)存中存儲時 要用兩個地址連續(xù)的內(nèi)存單元來存放 字的低位字節(jié)存放在低地址單元中 高位字節(jié)存放再高地址單元中 2 用mov指令要訪問內(nèi)存單元 可以在mov指令中只給出單元的偏移地址 此時 段地址默認在DS寄存器中 3 address 表示一個偏移地址為address的內(nèi)存單元 3 1節(jié) 3 5節(jié)小結 續(xù) 4 在內(nèi)存和寄存器之間傳送字型數(shù)據(jù)時 高地址單元和高8位寄存器 低地址單元和低8位寄存器相對應 5 mov add sub是具有兩個操作對象的指令 jmp是具有一個操作對象的指令 6 可以根據(jù)自己的推測 在Debug中實驗指令的新格式 特別提示 特別提示 檢測點3 1 p52 沒有通過檢測點請不要向下學習 3 6棧 我們研究棧的角度 棧是一種具有特殊的訪問方式的存儲空間 它的特殊性就在于 最后進入這個空間的數(shù)據(jù) 最先出去 可以用一個盒子和3本書來描述棧的操作方式 3 6棧 棧有兩個基本的操作 入棧和出棧 入棧 將一個新的元素放到棧頂 出棧 從棧頂取出一個元素 棧頂?shù)脑乜偸亲詈笕霔?需要出棧時 又最先被從棧中取出 棧的操作規(guī)則 LIFO LastInFirstOut 后進先出 3 7CPU提供的棧機制 現(xiàn)今的CPU中都有棧的設計 8086CPU提供相關的指令來以棧的方式訪問內(nèi)存空間 這意味著 我們在基于8086CPU編程的時候 可以將一段內(nèi)存當作棧來使用 3 7CPU提供的棧機制 8086CPU提供入棧和出棧指令 最基本的 PUSH 入棧 POP 出棧 pushax 將寄存器ax中的數(shù)據(jù)送入棧中 popax 從棧頂取出數(shù)據(jù)送入ax 8086CPU的入棧和出棧操作都是以字為單位進行的 3 6棧 下面舉例說明 我們可以將10000H 1000FH這段內(nèi)存當作棧來使用 下面一段指令的執(zhí)行過程 movax 0123Hpushaxmovbx 2266Hpushbxmovcx 1122Hpushcxpopaxpopbxpopcx 3 6棧 指令序列的執(zhí)行過程演示注意 字型數(shù)據(jù)用兩個單元存放 高地址單元放高8位 低地址單元放低8位 是否有疑惑 兩個疑問 兩個疑問 1 CPU如何知道一段內(nèi)存空間被當作棧使用 2 執(zhí)行push和pop的時候 如何知道哪個單元是棧頂單元 分析結論 任意時刻 SS SP指向棧頂元素 對于兩個疑問的分析 回想 CPU如何指導當前要執(zhí)行的指令所在的位置 寄存器CS和IP中存放著當前指令的段地址和偏移地址 8086CPU中 有兩個寄存器 段寄存器SS存放棧頂?shù)亩蔚刂芳拇嫫鱏P存放棧頂?shù)钠频刂啡我鈺r刻 SS SP指向棧頂元素 push指令的執(zhí)行過程 pushax 1 SP SP 2 2 將ax中的內(nèi)容送入SS SP指向的內(nèi)存單元處 SS SP此時指向新棧頂 圖示 push指令的執(zhí)行過程 3 6棧 問題3 6 如果我們將10000H 1000FH這段空間當作棧 初始狀態(tài)棧是空的 此時 SS 1000H SP 思考后看分析 問題3 6分析 SP 0010H 問題3 6分析 續(xù) 我們將10000H 1000FH這段空間當作棧段 SS 1000H 棧空間大小為16字節(jié) 棧最底部的字單元地址為1000 000E 任意時刻 SS SP指向棧頂 當棧中只有一個元素的時候 SS 1000H SP 000EH 問題3 6分析 續(xù) 棧為空 就相當于棧中唯一的元素出棧 出棧后 SP SP 2 SP原來為000EH 加2后SP 10H 所以 當棧為空的時候 SS 1000H SP 10H 換個角度看 問題3 6分析 續(xù) 換個角度看 任意時刻 SS SP指向棧頂元素 當棧為空的時候 棧中沒有元素 也就不存在棧頂元素 所以SS SP只能指向棧的最底部單元下面的單元 該單元的偏移地址為棧最底部的字單元的偏移地址 2 棧最底部字單元的地址為1000 000E 所以??諘r SP 0010H pop指令的執(zhí)行過程 popax 1 將SS SP指向的內(nèi)存單元處的數(shù)據(jù)送入ax中 2 SP SP 2 SS SP指向當前棧頂下面的單元 以當前棧頂下面的單元為新的棧頂 圖示 pop指令的執(zhí)行過程 注意 pop指令的執(zhí)行過程 注意 出棧后 SS SP指向新的棧頂1000EH pop操作前的棧頂元素 1000CH處的2266H依然存在 但是 它已不在棧中 當再次執(zhí)行push等入棧指令后 SS SP移至1000CH 并在里面寫入新的數(shù)據(jù) 它將被覆蓋 3 8棧頂超界的問題 SS和SP只記錄了棧頂?shù)牡刂?依靠SS和SP可以保證在入棧和出棧時找到棧頂 可是 如何能夠保證在入棧 出棧時 棧頂不會超出??臻g 3 8棧頂超界的問題 當棧滿的時候再使用push指令入棧 ??盏臅r候再使用pop指令出棧 都將發(fā)生棧頂超界問題 棧頂超界是危險的 3 8棧頂超界的問題 棧頂超界是危險的 因為我們既然將一段空間安排為棧 那么在??臻g之外的空間里很可能存放了具有其他用途的數(shù)據(jù) 代碼等 這些數(shù)據(jù) 代碼可能是我們自己的程序中的 也可能是別的程序中的 畢竟一個計算機系統(tǒng)并不是只有我們自己的程序在運行 3 8棧頂超界的問題 但是由于我們在入棧出棧時的不小心 而將這些數(shù)據(jù) 代碼意外地改寫 將會引發(fā)一連串的錯誤 我們當然希望CPU可以幫我們解決這個問題 3 8棧頂超界的問題 比如說在CPU中有記錄棧頂上限和下限的寄存器 我們可以通過填寫這些寄存器來指定棧空間的范圍 然后 CPU在執(zhí)行push指令的時候靠檢測棧頂上限寄存器 在執(zhí)行pop指令的時候靠檢測棧頂下限寄存器保證不會超界 實際情況 8086CPU中并沒有這樣的寄存器 3 8棧頂超界的問題 8086CPU不保證對棧的操作不會超界 這就是說 8086CPU只知道棧頂在何處 由SS SP指示 而不知道讀者安排的??臻g有多大 這點就好像 CPU只知道當前要執(zhí)行的指令在何處 由CS SP指示 而不知道讀者要執(zhí)行的指令有多少 從這兩點我們可以看出 3 8棧頂超界的問題 8086CPU的工作機理 只考慮當前的情況 當前棧頂在何處 當前要執(zhí)行的指令是哪一條 結論 3 8棧頂超界的問題 結論 我們在編程的時候要自己操心棧頂超界的問題 要根據(jù)可能用到的最大棧空間 來安排棧的大小 防止入棧的數(shù)據(jù)太多而導致的超界 執(zhí)行出棧操作的時候也要注意 以防??盏臅r候繼續(xù)出棧而導致的超界 3 9push pop指令 push和pop指令是可以在寄存器和內(nèi)存之間傳送數(shù)據(jù)的 push和pop指令的格式 棧與內(nèi)存 ??臻g當然也是內(nèi)存空間的一部分 它只是一段可以以一種特殊的方式進行訪問的內(nèi)存空間 3 9push pop指令 push和pop指令的格式 1 push寄存器 將一個寄存器中的數(shù)據(jù)入棧pop寄存器 出棧 用一個寄存器接收出棧的數(shù)據(jù)例如 pushaxpopbx 3 9push pop指令 push和pop指令的格式 2 push段寄存器 將一個段寄存器中的數(shù)據(jù)入棧pop段寄存器 出棧 用一個段寄存器接收出棧的數(shù)據(jù)例如 pushdspopes 3 9push pop指令 push和pop指令的格式 3 push內(nèi)存單元 將一個內(nèi)存單元處的字入棧 棧操作都是以字為單位 pop內(nèi)存單元 出棧 用一個內(nèi)存字單元接收出棧的數(shù)據(jù)例如 push 0 pop 2 指令執(zhí)行時 CPU要知道內(nèi)存單元的地址 可以在push pop指令中給出內(nèi)存單元的偏移地址 段地址在指令執(zhí)行時 CPU從ds中取得 3 9push pop指令 問題3 7編程 將10000H 1000FH這段空間當作棧 初始狀態(tài)是空的 將AX BX DS中的數(shù)據(jù)入棧 思考后看分析 問題3 7分析 3 9push pop指令 問題3 8編程 1 將10000H 1000FH這段空間當作棧 初始狀態(tài)是空的 2 設置AX 001AH BX 001BH 3 將AX BX中的數(shù)據(jù)入棧 4 然后將AX BX清零 5 從棧中恢復AX BX原來的內(nèi)容 思考后看分析 問題3 8分析 結論 問題3 8分析 從上面的程序我們看到 用棧來暫存以后需要恢復的寄存器中的內(nèi)容時 出棧的順序要和入棧的順序相反 因為最后入棧的寄存器的內(nèi)容在棧頂 所以在恢復時 要最先出棧 3 9push pop指令 問題3 9編程 1 將10000H 1000FH這段空間當作棧 初始狀態(tài)是空的 2 設置AX 002AH BX 002BH 3 利用棧 交換AX和BX中的數(shù)據(jù) 思考后看分析 問題3 9分析 3 9push pop指令 問題3 10我們?nèi)绻?0000H處寫入字型數(shù)據(jù)2266H 可以用以下的代碼完成 movax 1000Hmovds axmov ax 2266Hmov 0 ax補全下面的代碼 3 9push pop指令 補全下面的代碼 完成同樣的功能 在10000H處寫入字型數(shù)據(jù)2266H movax 2266Hpushax要求 不能使用 mov內(nèi)存單元 寄存器 這類指令思考后看分析 問題3 10分析 我們看需補全代碼的最后兩條指令 將ax中的2266H壓入棧中 也就是說 最終應由pushax將2266H寫入10000H處 問題的關鍵就在于 如何使pushax訪問的內(nèi)存單元是10000H Push指令是入棧指令 注意執(zhí)行過程 完成程序 問題3 10分析 續(xù) 完成的程序 movax 1000Hmovss axmovsp 2movax 2266Hpushax結論 問題3 10分析 續(xù) 結論push pop實質(zhì)上就是一種內(nèi)存?zhèn)魉椭噶?可以在寄存器和內(nèi)存之間傳送數(shù)據(jù) 與mov指令不同的是 push和pop指令訪問的內(nèi)存單元的地址不是在指令中給出的 而是由SS SP指出的 同時 push和pop指令還要改變SP中的內(nèi)容 問題3 10分析 續(xù) 我們要十分清楚的是 push和pop指令同mov指令不同 CPU執(zhí)行mov指令只需一步操作 就是傳送 而執(zhí)行push pop指令卻需要兩步操作 執(zhí)行push時 先改變SP 后向SS SP處傳送 執(zhí)行pop時 先讀取SS SP處的數(shù)據(jù) 后改變SP 注意 push pop等棧操作指令 修改的只是SP 也就是說 棧頂?shù)淖兓秶畲鬄?0 FFFFH 提供 SS SP指示棧頂 改變SP后寫內(nèi)存的入棧指令 讀內(nèi)存后改變SP的出棧指令 這就是8086CPU提供的棧操作機制 棧的綜述 1 8086CPU提供了棧操作機制 方案如下 在SS SP中存放棧頂?shù)亩蔚刂泛推频刂?提供入棧和出棧指令 他們根據(jù)SS SP指示的地址 按照棧的方式訪問內(nèi)存單元 2 push指令的執(zhí)行步驟 1 SP SP 2 2 向SS SP指向的字單元中送入數(shù)據(jù) 3 pop指令的執(zhí)行步驟 1 從SS SP指向的字單元中讀取數(shù)據(jù) 2 SP SP 2 棧的綜述 續(xù) 4 任意時刻 SS SP指向棧頂元素 5 8086CPU只記錄棧頂 棧空間的大小我們要自己管理 6 用棧來暫存以后需要恢復的寄存器的內(nèi)容時 寄存器出棧的順序要和入棧的順序相反 7 push pop實質(zhì)上是一種內(nèi)存?zhèn)魉椭噶?注意它們的靈活應用 棧是一種非常重要的機制 一定要深入理解 靈活掌握 3 10棧段 前面講過 對于8086PC機 在編程時 我們可以根據(jù)需要 將一組內(nèi)存單元定義為一個段 我們可以將長度為N N 64K 的一組地址連續(xù) 起始地址為16的倍數(shù)的內(nèi)存單元 當作棧來用 從而定義了一個棧段 3 10棧段 比如我們將10010H 1001FH這段長度為16字節(jié)的內(nèi)存空間當作棧來用 以棧的方式進行訪問 這段空間就可以成為棧段 段地址為1000H 大小為16字節(jié) 3 10棧段 將一段內(nèi)存當作棧段 僅僅是我們在編程時的一種安排 CPU并不會由于這種安排 就在執(zhí)行push pop等棧操作指令時就自動地將我們定義的棧段當作??臻g來訪問 如何使的如push pop等棧操作指令訪問我們定義的棧段呢 將SS SP指向我們定義的棧段 3 10棧段 問題3 11如果我們將10000H 1FFFFH這段空間當作棧段 初始狀態(tài)是空的 此時 SS 1000H SP 思考后看分析 問題3 11分析 我們將10000H 1FFFFH這段空間當作棧段 SS 1000H ??臻g大小為64KB 棧最底部的字單元地址為1000 FFFE 任意時刻 SS SP指向棧頂 當棧中只有一個元素的時候 SS 1000H SP FFFEH 問題3 11分析 棧為空 就相當于棧中唯一的元素出棧 出棧后 SP SP 2 SP原來為FFFEH 加2后SP 0 所以 當棧為空的時候 SS 1000H SP 0 換個角度看 問題3 11分析 續(xù) 換個角度看任意時刻 SS SP指向棧頂元素 當棧為空的時候 棧中沒有元素 也就不存在棧頂元素 所以SS SP只能指向棧的最底部單元下面的單元 該單元的偏移地址為棧最底部的字單元的偏移地址 2 棧最底部字單元的地址為1000 FFFE 所以棧空時 SP 0000H 問題3 12 一個棧段最大可以設為多少 為什么 思考后看分析 問題3 12分析 一個棧段最大可以設為多少 分析 這個問題顯而易見 提出來只是為了提示我們將相關的知識融會起來 首先從棧操作指令所完成的功能的角度上來看 push pop等指令在執(zhí)行的時候只修改SP 問題3 12分析 所以棧頂?shù)淖兓秶? FFFFH 從??諘r候的SP 0 一直壓棧 直到棧滿時SP 0 如果再次壓棧 棧頂將環(huán)繞 覆蓋了原來棧中的內(nèi)容 所以一個棧段的容量最大為64KB 段的綜述 我們可以將一段內(nèi)存定義為一個段 用一個段地址指示段 用偏移地址訪問段內(nèi)的單元 這完全是我們自己的安排 我們可以用一個段存放數(shù)據(jù) 將它定義為 數(shù)據(jù)段 我們可以用一個段存放代碼 將它定義為 代碼段 我們可以用一個段當作棧 將它定義為 棧段 段的綜述 續(xù) 我們可以這樣安排 但若要讓CPU按照我們的安排來訪問這些段 就要 對于數(shù)據(jù)段 將它的段地址放在DS中 用mov add sub等訪問內(nèi)存單元的指令時 CPU就將我們定義的數(shù)據(jù)段中的內(nèi)容當作數(shù)據(jù)段來訪問 段的綜述 續(xù) 對于代碼段 將它的段地址放在CS中 將段中第一條指令的偏移地址放在IP中 這樣CPU就將執(zhí)行我們定義的代碼段中的指令 段的綜述 續(xù) 對于棧段 將它的段地址放在SS中 將棧頂單元的偏移地置放在SP中 這樣CPU在需要進行棧操作的時候 比如執(zhí)行push pop指令等 就將我們定義的棧段當作棧空間來用 段的綜述 續(xù) 可見 不管我們?nèi)绾伟才?CPU將內(nèi)存中的某段內(nèi)存當作代碼 是因為CS IP指向了那里 CPU將某段內(nèi)存當作棧 是因為SS IP指向了那里 段的綜述 續(xù) 我們一定要清楚 什么是我們的安排 以及如何讓CPU按我們的安排行事 要非常的清楚CPU的工作機理 才能在控制CPU來按照我們的安排運行的時候做到游刃有余 段的綜述 續(xù) 比如我們將10000H 1001FH安排為代碼段 并在里面存儲如下代碼 movax 1000Hmovss axmovsp 0020H 初始化棧頂movax csmovds ax 設置數(shù)據(jù)段段地址movax 0 addax 2 movbx 4 addbx 6 pushaxpushbxpopaxpopbx 段的綜述 續(xù) 設置CS 1000H IP 0 這段代碼將得到執(zhí)行 可以看到 在這段代碼中 我們又將10000H 1001FH安排為棧段和數(shù)據(jù)段 10000H 1001FH這段內(nèi)存 既是代碼段 又是棧段和數(shù)據(jù)段 段的綜述 續(xù) 一段內(nèi)存 可以既是代碼的存儲空間 又是數(shù)據(jù)的存儲空間 還可以是??臻g 也可以什么也不是 關鍵在于CPU中寄存器的設置 即 CS IP SS SP DS的指向 特別提示 檢測點3 2 p66 沒有通過檢測點請不要向下學習 小結 匯編語言 課件 王爽著 清華大學出版社 制作工具 MicrosoftPowerPoint2003 本課件由匯編網(wǎng) 制作提供 第4章第1個程序 4 1一個源程序從寫出到執(zhí)行的過程4 2源程序4 3編輯源程序4 4編譯4 5連接4 6以簡化的方式進行編譯和連接4 71 exe的執(zhí)行4 8可執(zhí)行文件中的程序裝入內(nèi)存并運行的原理4 9程序執(zhí)行過程的跟蹤 引言 現(xiàn)在我們將開始編寫完整的匯編語言程序 用編譯器將它們編譯成為可執(zhí)行文件 如 exe文件 在操作系統(tǒng)中運行 這一章 我們將編寫第一個這樣的程序 4 1一個源程序從寫出到執(zhí)行的過程 一個匯編語言程序從寫出到最終執(zhí)行的簡要過程 編寫 編譯 連接 執(zhí)行演示 編寫匯編源程序 使用文本編輯器 如Edit 記事本等 用匯編語言編寫匯編源程序 對源程序進行編譯連接 使用匯編語言編譯程序?qū)υ闯绦蛭募械脑闯绦蜻M行編譯 產(chǎn)生目標文件 再用連接程序?qū)δ繕宋募M行連接 生成可在操作系統(tǒng)中直接運行的可執(zhí)行文件 可執(zhí)行文件 可執(zhí)行文件中包含兩部分內(nèi)容 程序 從原程序中的匯編指令翻譯過來的機器碼 和數(shù)據(jù) 源程序中定義的數(shù)據(jù) 相關的描述信息 比如 程序有多大 要占多少內(nèi)存空間等 執(zhí)行可執(zhí)行文件中的程序 在操作系統(tǒng)中 執(zhí)行可執(zhí)行文件中的程序 操作系統(tǒng)依照可執(zhí)行文件中的描述信息 將可執(zhí)行文件中的機器碼和數(shù)據(jù)加載入內(nèi)存 并進行相關的初始化 比如 設置CS IP指向第一條要執(zhí)行的指令 然后由CPU執(zhí)行程序 4 2源程序 匯編指令偽指令XXXsegmentXXXendsendassume 4 2源程序 匯編指令有對應的機器碼的指令 可以被編譯為機器指令 最終為CPU所執(zhí)行 4 2源程序 偽指令沒有對應的機器碼的指令 最終不被CPU所執(zhí)行 誰來執(zhí)行偽指令呢 偽指令是由編譯器來執(zhí)行的指令 編譯器根據(jù)偽指令來進行相關的編譯工作 定義一個段 segment和ends是一對成對使用的偽指令 這是在寫可被編譯器編譯的匯編程序時 必須要用到的一對偽指令 segment和ends的功能是定義一個段 segment說明一個段開始 ends說明一個段結束 一個段必須有一個名稱來標識 使用格式為 段名segment段名ends 定義一個段 一個匯編程序是由多個段組成的 這些段被用來存放代碼 數(shù)據(jù)或當作??臻g來使用 一個有意義的匯編程序中至少要有一個段 這個段用來存放代碼 程序結束標記 End是一個匯編程序的結束標記 編譯器在編譯匯編程序的過程中 如果碰到了偽指令end 就結束對源程序的編譯 如果程序?qū)懲炅?要在結尾處加上偽指令end 否則 編譯器在編譯程序時 無法知道程序在何處結束 注意 不要搞混了end和ends 寄存器與段的關聯(lián)假設 assume 含義為 假設 它假設某一段寄存器和程序中的某一個用segment ends定義的段相關聯(lián) 通過assume說明這種關聯(lián) 在需要的情況下 編譯程序可以將段寄存器和某一個具體的段相聯(lián)系 4 2源程序 源程序中的 程序 匯編源程序 偽指令 編譯器處理 匯編指令 編譯為機器碼 程序 源程序中最終由計算機執(zhí)行 處理的指令或數(shù)據(jù) 注意 注意 我們可以將源程序文件中的所有內(nèi)容稱為源程序 將源程序中最終由計算機執(zhí)行處理的指令或數(shù)據(jù) 成為程序 程序最先以匯編指令的形式存在源程序中 經(jīng)編譯 連接后轉變?yōu)闄C器碼 存儲在可執(zhí)行文件中 圖示 程序經(jīng)編譯連接后變?yōu)闄C器碼 4 2源程序 標號一個標號指代了一個地址 codesg 放在segment的前面 作為一個段的名稱 這個段的名稱最終將被編譯 連接程- 配套講稿:
如PPT文件的首頁顯示word圖標,表示該PPT已包含配套word講稿。雙擊word圖標可打開word文檔。
- 特殊限制:
部分文檔作品中含有的國旗、國徽等圖片,僅作為作品整體效果示例展示,禁止商用。設計者僅對作品中獨創(chuàng)性部分享有著作權。
- 關 鍵 詞:
- 匯編語言 第二 全部 課件
裝配圖網(wǎng)所有資源均是用戶自行上傳分享,僅供網(wǎng)友學習交流,未經(jīng)上傳用戶書面授權,請勿作他用。
鏈接地址:http://kudomayuko.com/p-5956012.html