《x86匯編語言:從實模式到保護模式》第二版修改方向1,在書的前面添加基礎(chǔ)性的內(nèi)容,用來說明匯編語言的由來和必要性,說明匯編語言編程的特點,以期平滑自然地進(jìn)入?yún)R編語言主題。2,原書中對指令系統(tǒng)及x86指令格式的描述過于簡略,此版增補這部分內(nèi)容;3,讀者普遍反映第14章太難太緊湊,此版將相關(guān)內(nèi)容拆分,降低學(xué)習(xí)的難度;4,整個保護模式部分以現(xiàn)在的觀點來看,內(nèi)容組織不夠合理,予以重新組織,配書代碼重新編寫和組織;5,原書中有模糊的錯誤的表述,此版予以更正。
李忠,主要出版著作《穿越計算機的迷霧》《x86匯編語言:從實模式到保護模式》《穿越計算機的迷霧(第2版)》《C語言非常道》等。
目 錄
第1部分 預(yù)備知識
第1章 十六進(jìn)制計數(shù)法 002
1.1 二進(jìn)制計數(shù)法回顧 002
1.1.1 關(guān)于二進(jìn)制計數(shù)法 002
1.1.2 二進(jìn)制到十進(jìn)制的轉(zhuǎn)換 003
1.1.3 十進(jìn)制到二進(jìn)制的轉(zhuǎn)換 003
1.2 十六進(jìn)制計數(shù)法 004
1.2.1 十六進(jìn)制計數(shù)法的原理 004
1.2.2 十六進(jìn)制到十進(jìn)制的轉(zhuǎn)換 005
1.2.3 十進(jìn)制到十六進(jìn)制的轉(zhuǎn)換 005
1.2.4 為什么需要十六進(jìn)制 006
1.3 使用Windows計算器方便你的學(xué)習(xí)過程 007
本章習(xí)題 008
第2章 計算機和匯編語言 009
2.1 用電表示數(shù)字 009
2.2 二進(jìn)制加法機 010
2.3 具有記憶功能的器件——寄存器 011
2.4 帶寄存器的加法機 013
2.5 能做四則運算的機器 014
2.6 機器指令 015
2.7 內(nèi)存 017
2.8 自動計算 021
2.9 處理器 023
2.10 匯編語言的誕生 025
本章習(xí)題 027
第3章 分段機制和邏輯地址 028
3.1 寄存器和字長 028
3.2 內(nèi)存訪問和字節(jié)序 029
3.3 古老的INTEL 8086處理器 030
3.3.1 8086的通用寄存器 030
3.3.2 程序的重定位難題 031
3.3.3 邏輯地址 034
3.3.4 8086的內(nèi)存分段機制 036
本章習(xí)題 040
第4章 匯編語言和匯編軟件 041
4.1 匯編語言程序 041
4.2 NASM編譯器 043
4.2.1 NASM的下載和安裝 043
4.2.2 代碼的書寫和編譯過程 044
4.2.3 用HexView觀察編譯后的機器代碼 047
4.3 配書文件包的下載和使用 048
本章習(xí)題 049
第2部分 實模式
第5章 虛擬機的安裝和使用 051
5.1 計算機的啟動過程 051
5.1.1 如何將編譯好的程序提交給處理器 051
5.1.2 計算機的加電和復(fù)位 052
5.1.3 基本輸入輸出系統(tǒng) 052
5.1.4 硬盤及其工作原理 054
5.1.5 一切從主引導(dǎo)扇區(qū)開始 055
5.2 創(chuàng)建和使用虛擬機 056
5.2.1 別害怕,虛擬機是軟件 056
5.2.2 下載和安裝Oracle VM VirtualBox 057
5.2.3 虛擬硬盤簡介 058
5.2.4 練習(xí)使用FixVhdWr工具向虛擬硬盤寫數(shù)據(jù) 059
第6章 編寫主引導(dǎo)扇區(qū)代碼 063
6.1 本章代碼清單 063
6.2 歡迎來到主引導(dǎo)扇區(qū) 063
6.3 注釋 064
6.4 在屏幕上顯示文字 064
6.4.1 顯卡和顯存 064
5.4.2 初始化段寄存器 067
6.4.3 顯存的訪問和ASCII代碼 067
6.4.4 顯示字符 070
6.4.5 mov指令的格式 071
6.5 顯示標(biāo)號的匯編地址 072
6.5.1 標(biāo)號 072
6.5.2 如何顯示十進(jìn)制數(shù)字 076
6.5.3 在程序中聲明并初始化數(shù)據(jù) 077
6.5.4 分解數(shù)的各個數(shù)位 078
6.5.5 顯示分解出來的各個數(shù)位 082
6.6 使程序進(jìn)入無限循環(huán)狀態(tài) 083
6.7 完成并編譯主引導(dǎo)扇區(qū)代碼 085
6.7.1 主引導(dǎo)扇區(qū)有效標(biāo)志 085
6.7.2 代碼的保存和編譯 086
6.8 加載和運行主引導(dǎo)扇區(qū)代碼 086
6.8.1 把編譯后的指令寫入主引導(dǎo)扇區(qū) 086
6.8.2 啟動虛擬機觀察運行結(jié)果 087
6.9 程序的調(diào)試技術(shù) 087
6.9.1 開源的Bochs虛擬機軟件 087
6.9.2 Bochs下的程序調(diào)試入門 088
本章習(xí)題 094
第7章 相同的功能,不同的代碼 095
7.1 代碼清單7-1 095
7.2 跳過非指令的數(shù)據(jù)區(qū) 095
7.3 在數(shù)據(jù)聲明中使用字面值 096
7.4 段地址的初始化 096
7.5 段之間的批量數(shù)據(jù)傳送 097
7.6 使用循環(huán)分解數(shù)位 099
7.7 計算機中的負(fù)數(shù) 101
7.7.1 無符號數(shù)和有符號數(shù) 101
7.7.2 處理器視角中的數(shù)據(jù)類型 104
7.8 數(shù)位的顯示 107
7.9 其他標(biāo)志位和條件轉(zhuǎn)移指令 108
7.9.1 奇偶標(biāo)志位PF 108
7.9.2 進(jìn)位標(biāo)志CF 109
7.9.3 溢出標(biāo)志OF 109
7.9.4 現(xiàn)有指令對標(biāo)志位的影響 110
7.9.5 條件轉(zhuǎn)移指令 111
7.10 NASM編譯器的$和$$標(biāo)記 113
7.11 觀察運行結(jié)果 114
7.12 本章程序的調(diào)試 114
7.12.1 調(diào)試命令“n”的使用 114
7.12.2 調(diào)試命令“u”的使用 115
7.12.3 用調(diào)試命令“info”查看標(biāo)志位 117
本章習(xí)題 118
?
第8章 比高斯更快的計算 119
8.1 從1加到100的故事 119
8.2 代碼清單8-1 119
8.3 顯示字符串 119
8.4 計算1到100的累加和 120
8.5 累加和各個數(shù)位的分解與顯示 121
8.5.1 棧和棧段的初始化 121
8.5.2 分解各個數(shù)位并壓棧 121
8.5.3 出棧并顯示各個數(shù)位 124
8.5.4 進(jìn)一步認(rèn)識棧 125
8.6 程序的編譯和運行 127
8.6.1 觀察程序的運行結(jié)果 127
8.6.2 在調(diào)試過程中查看棧中內(nèi)容 127
8.7 8086處理器的尋址方式 128
8.7.1 寄存器尋址 129
8.7.2 立即尋址 129
8.7.3 內(nèi)存尋址 129
本章習(xí)題 134
第9章 硬盤和顯卡的訪問與控制 135
9.1 本章代碼清單 136
9.2 用戶程序的結(jié)構(gòu) 136
9.2.1 分段、段的匯編地址和段內(nèi)匯編地址 136
9.2.2 用戶程序頭部 140
9.3 加載程序(器)的工作流程 142
9.3.1 初始化和決定加載位置 142
9.3.2 準(zhǔn)備加載用戶程序 143
9.3.3 外圍設(shè)備及其接口 145
9.3.4 I/O端口和端口訪問 146
9.3.5 通過硬盤控制器端口讀扇區(qū)數(shù)據(jù) 148
9.3.6 過程調(diào)用 151
9.3.7 加載用戶程序 156
9.3.8 用戶程序重定位 157
9.3.9 將控制權(quán)交給用戶程序 161
9.3.10 8086處理器的無條件轉(zhuǎn)移指令 161
9.4 用戶程序的工作流程 164
9.4.1 初始化段寄存器和棧切換 164
9.4.2 調(diào)用字符串顯示例程 165
9.4.3 過程的嵌套 165
9.4.4 屏幕光標(biāo)控制 166
9.4.5 取當(dāng)前光標(biāo)位置 167
9.4.6 處理回車和換行字符 168
9.4.7 顯示可打印字符 169
9.4.8 滾動屏幕內(nèi)容 169
9.4.9 重置光標(biāo) 170
9.4.10 切換到另一個代碼段中執(zhí)行 170
9.4.11 訪問另一個數(shù)據(jù)段 171
9.5 編譯和運行程序并觀察結(jié)果 171
本章習(xí)題 172
第3部分 保護模式
第10章 中斷和動態(tài)時鐘顯示 174
10.1 外部硬件中斷 175
10.1.1 非屏蔽中斷 176
10.1.2 可屏蔽中斷 176
10.1.3 實模式下的中斷向量表 178
10.1.4 實時時鐘、CMOS RAM和BCD編碼 179
10.1.5 實時時鐘RTC的中斷信號 181
10.1.6 代碼清單10-1 185
10.1.7 初始化8259、RTC和中斷向量表 185
10.1.8 使處理器進(jìn)入低功耗狀態(tài) 187
10.1.9 實時時鐘中斷的處理過程 187
10.1.10 代碼清單10-1的編譯和運行 190
10.2 內(nèi)部中斷 191
10.3 軟中斷 191
10.3.1 BIOS中斷 192
10.3.2 代碼清單10-2 193
10.3.3 從鍵盤讀字符并顯示 193
10.3.4 代碼清單10-2的編譯和運行 194
本章習(xí)題 194
第11章 32位x86處理器編程架構(gòu) 195
11.1 IA-32架構(gòu)的基本執(zhí)行環(huán)境 195
11.1.1 寄存器的擴展 195
11.1.2 基本的工作模式 198
11.1.3 線性地址和分頁 199
11.2 現(xiàn)代處理器的結(jié)構(gòu)和特點 200
11.2.1 流水線 200
11.2.2 高速緩存 201
11.2.3 亂序執(zhí)行 201
11.2.4 寄存器重命名 202
11.2.5 分支目標(biāo)預(yù)測 203
11.3 32位處理器的尋址方式 204
第12章 進(jìn)入保護模式 206
12.1 代碼清單12-1 207
12.2 全局描述符表 207
12.3 存儲器的段描述符 208
12.4 安裝存儲器的段描述符并加載GDTR 213
12.5 關(guān)于第21條地址線A20的問題 215
12.6 保護模式下的內(nèi)存訪問 216
12.7 程序的運行和調(diào)試 221
12.7.1 運行程序并觀察結(jié)果 221
12.7.2 處理器剛加電時的段寄存器狀態(tài) 222
12.7.3 設(shè)置PE位后的段寄存器狀態(tài) 224
12.7.4 加載段寄存器DS之后的狀態(tài) 225
12.7.5 查看全局描述符表GDT 225
12.7.6 查看控制寄存器的內(nèi)容 226
本章習(xí)題 226
第13章 操作數(shù)和有效地址的尺寸 227
13.1 代碼清單13-1 227
13.2 INTEL 80286處理器的16位保護模式 227
13.3 指令的操作尺寸 228
13.3.1 16位操作尺寸 228
13.3.2 32位操作尺寸 229
13.3.3 默認(rèn)操作尺寸 229
13.3.4 操作尺寸反轉(zhuǎn)前綴 232
13.3.5 編譯時的操作尺寸 234
13.4 清空流水線并串行化處理器 235
13.5 有效地址尺寸和內(nèi)存訪問 237
13.6 一般指令在32位操作尺寸下的擴展 239
本章習(xí)題 241
第14章 存儲器的保護 243
14.1 代碼清單14-1 243
14.2 進(jìn)入32位保護模式 243
14.2.1 話說mov ds,ax和mov ds,eax 243
14.2.2 創(chuàng)建GDT并安裝段描述符 244
14.3 修改段寄存器時的保護 247
14.4 地址變換時的保護 249
14.4.1 代碼段執(zhí)行時的保護 249
14.4.2 數(shù)據(jù)訪問時的保護 250
14.4.3 棧操作時的保護 251
14.5 使用別名訪問代碼段對字符排序 253
14.6 程序的編譯和運行 256
本章習(xí)題 256
第15章 程序的動態(tài)加載和執(zhí)行 257
15.1 本章代碼清單 258
15.2 內(nèi)核的結(jié)構(gòu)、功能和加載 258
15.2.1 內(nèi)核的結(jié)構(gòu) 258
15.2.2 內(nèi)核的加載 259
15.2.3 安裝內(nèi)核的段描述符 261
15.3 在內(nèi)核中執(zhí)行 265
15.4 用戶程序的加載和重定位 267
15.4.1 用戶程序的結(jié)構(gòu) 267
15.4.2 計算用戶程序占用的扇區(qū)數(shù) 268
15.4.3 簡單的動態(tài)內(nèi)存分配 270
15.4.4 段的重定位和描述符的創(chuàng)建 271
15.4.5 重定位用戶程序內(nèi)的符號地址 274
15.5 執(zhí)行用戶程序 278
15.6 代碼的編譯、運行和調(diào)試 279
本章習(xí)題 281
第16章 任務(wù)和特權(quán)級保護 282
16.1 任務(wù)的隔離和特權(quán)級保護 283
16.1.1 任務(wù)、任務(wù)的LDT和TSS 283
16.1.2 全局空間和局部空間 284
16.1.3 特權(quán)級保護概述 287
16.2 代碼清單16-1 295
16.3 內(nèi)核程序的初始化 295
16.3.1 調(diào)用門 296
16.3.2 調(diào)用門的安裝和測試 299
16.4 加載用戶程序并創(chuàng)建任務(wù) 301
16.4.1 任務(wù)控制塊和TCB鏈 301
16.4.2 使用棧傳遞過程參數(shù) 304
16.4.3 加載用戶程序 306
16.4.4 創(chuàng)建局部描述符表 306
16.4.5 重定位U-SALT表 308
16.4.6 創(chuàng)建0、1和2特權(quán)級的棧 309
16.4.7 安裝LDT描述符到GDT中 309
16.4.8 任務(wù)狀態(tài)段TSS的格式 310
16.4.9 創(chuàng)建任務(wù)狀態(tài)段TSS 314
16.4.10 安裝TSS描述符到GDT中 315
16.4.11 帶參數(shù)的過程返回指令 315
16.5 用戶程序的執(zhí)行 316
16.5.1 通過調(diào)用門轉(zhuǎn)移控制的完整過程 316
16.5.2 進(jìn)入3特權(quán)級的用戶程序的執(zhí)行 320
16.5.3 檢查調(diào)用者的請求特權(quán)級RPL 323
16.5.4 在Bochs中調(diào)試程序的新方法 324
本章習(xí)題 325
第17章 協(xié)同式任務(wù)切換 326
17.1 本章代碼清單 326
17.2 任務(wù)切換前的設(shè)置 326
17.3 任務(wù)切換的方法 329
17.4 用jmp指令發(fā)起任務(wù)切換的實例 333
17.5 處理器在實施任務(wù)切換時的操作 340
17.6 程序的編譯和運行 342
本章習(xí)題 342
第18章 中斷和異常的處理與搶占式多任務(wù) 343
18.1 中斷和異常 343
18.1.1 中斷和異常概述 343
18.1.2 中斷描述符表、中斷門和陷阱門 346
18.2 本章代碼清單 348
18.3 內(nèi)核的加載和初始化 348
18.3.1 創(chuàng)建中斷描述符表 348
18.3.2 8259A芯片的初始化 352
18.3.3 中斷和異常處理程序的保護 354
18.3.4 中斷任務(wù) 355
18.3.5 錯誤代碼 357
18.3.6 用定時中斷實施任務(wù)切換 358
18.4 內(nèi)核任務(wù)的創(chuàng)建 360
18.5 用戶任務(wù)的創(chuàng)建和執(zhí)行 360
18.6 程序的編譯和執(zhí)行 362
本章習(xí)題 362
?
第19章 分頁機制和動態(tài)頁面分配 363
19.1 分頁機制概述 364
19.1.1 簡單的分頁模型 364
19.1.2 頁目錄、頁表和頁 373
19.1.3 地址變換的具體過程 375
19.2 本章代碼清單 376
19.3 使內(nèi)核在分頁機制下工作 377
19.3.1 創(chuàng)建內(nèi)核的頁目錄表和頁表 377
19.3.2 任務(wù)全局空間和局部空間的頁面映射 382
19.4 創(chuàng)建內(nèi)核任務(wù) 389
19.4.1 內(nèi)核的虛擬內(nèi)存分配 389
19.4.2 頁面位映射串和空閑頁的查找 394
19.4.3 內(nèi)核任務(wù)的確立 398
19.5 用戶任務(wù)的創(chuàng)建和切換 399
19.5.1 用戶任務(wù)的虛擬內(nèi)存分配策略 399
19.5.2 用戶任務(wù)的虛擬地址空間分配 402
19.5.3 創(chuàng)建用戶任務(wù)的LDT 403
19.5.4 用戶程序的加載 405
19.5.5 重定位U-SALT并復(fù)制頁目錄表 405
19.5.6 切換到用戶任務(wù)執(zhí)行 408
19.6 程序的編譯、執(zhí)行和調(diào)試 409
19.6.1 本章程序的編譯和運行方法 409
19.6.2 查看CR3寄存器的內(nèi)容 409
19.6.3 查看線性地址對應(yīng)的物理頁信息 410
19.6.4 查看當(dāng)前任務(wù)的頁表信息 411
19.6.5 使用線性(虛擬)地址調(diào)試程序 411
本章習(xí)題 412
第20章 平坦內(nèi)存模型和軟件任務(wù)切換 413
20.1 多段模型和平坦模型 413
20.1.1 多段模型和段頁式內(nèi)存管理 413
20.1.2 平坦模型 415
20.2 本章代碼清單 416
20.3 初始化系統(tǒng)并加載內(nèi)核 416
20.3.1 定義平坦模型下的段描述符 417
20.3.2 平坦模型下的內(nèi)核程序 418
20.3.3 加載內(nèi)核程序 419
20.4 內(nèi)核的初始化 421
20.4.1 進(jìn)入內(nèi)核并初始化中斷系統(tǒng) 421
20.4.2 軟中斷和系統(tǒng)調(diào)用 422
20.4.3 系統(tǒng)調(diào)用的安裝及其工作原理 423
20.4.4 任務(wù)狀態(tài)段TSS的新用法 424
20.5 用戶任務(wù)的創(chuàng)建 427
20.5.1 平坦模型下的用戶程序結(jié)構(gòu) 428
20.5.2 用戶任務(wù)的創(chuàng)建過程 428
20.6 軟件任務(wù)切換 429
20.6.1 保存當(dāng)前任務(wù)的狀態(tài) 430
20.6.2 恢復(fù)并執(zhí)行新任務(wù) 430
20.7 內(nèi)核任務(wù)的執(zhí)行 431
20.8 用戶任務(wù)的執(zhí)行 432
本章習(xí)題 433