Linux x64匯編語言編程 X64 Assembly Language Step-By-Step: Programming with Linux, 4/e
[美] 傑夫·鄧特曼(Jeff Duntemann)著 賈玉彬 王文傑 譯
- 出版商: 清華大學
- 出版日期: 2025-06-01
- 售價: $948
- 語言: 簡體中文
- ISBN: 7302686416
- ISBN-13: 9787302686415
-
相關分類:
Linux
- 此書翻譯自: X64 Assembly Language Step-By-Step: Programming with Linux, 4/e (Hardcover)
尚未上市,歡迎預購
買這商品的人也買了...
相關主題
商品描述
"《Linux x64匯編語言編程》介紹二進制、十六進制、計算、編程和x64架構的基礎知識,分析Linux軟件開發過程,講解NASM匯編器、x64指令集、內存尋址、過程、宏及Linux的C庫函數接口,披露軟件設計、編碼、測試和調試的實用技巧。本書示例代碼豐富,文筆幽默,將深奧的知識講得簡單易懂,引導你循序漸進地學會匯編編程。 《Linux x64匯編語言編程》是**的Intel/AMD x64教程,是學習x64匯編語言的黃金標準,非常適合自學。"
目錄大綱
目錄
第1章 一切都在計劃之中——真正理解電腦的工作原理 1
1.1 完美的周六計劃 1
1.1.1 步驟和測試 2
1.1.2 決定總是具有二元性 3
1.1.3 電腦像我們一樣思考 4
1.2 如果這是真的 4
1.3 將匯編語言編程比作方塊舞 4
1.4 將匯編語言編程比作棋盤游戲 5
1.4.1 代碼和數據 6
1.4.2 地址 7
1.4.3 總結 7
第2章 外星人基地——理解二進制和十六進制 9
2.1 新數學怪獸的回歸 9
2.1.1 使用火星文計數 10
2.1.2 剖析火星數字 12
2.1.3 數基的本質 13
2.2 八進制:鬼精靈如何偷走8和9 13
2.3 十六進制:解決數字短缺問題 17
2.4 從十六進制到十進制以及從十進制到十六進制 20
2.4.1 從十六進制到十進制 21
2.4.2 從十進制到十六進制 22
2.5 練習!練習!練習! 23
2.6 十六進制算術 24
2.6.1 列和進制 26
2.6.2 減法和借位 27
2.6.3 跨多列借位 28
2.6.4 重點是什麽? 29
2.7 二進制 29
2.7.1 二進制值 31
2.7.2 為什麽是二進制 33
2.8 十六進製作為二進制的簡寫 33
2.9 準備計算 35
第3章 揭開面紗——瞭解電腦的真實面貌 36
3.1 RAX寄存器,我們幾乎不瞭解 36
3.2 開關、晶體管和內存 38
3.2.1 如果敵方陸路來襲,則點亮一盞燈 38
3.2.2 晶體管開關 39
3.2.3 令人難以置信的比特縮小現象 41
3.2.4 隨機訪問 42
3.2.5 內存訪問時間 44
3.2.6 字節、字、雙字和四字 44
3.2.7 排成一排的精美芯片 45
3.3 CPU和裝配線 48
3.3.1 與內存對話 48
3.3.2 搭乘數據總線 49
3.3.3 寄存器 50
3.3.4 裝配線 51
3.4 遵循計劃的盒子 51
3.4.1 獲取並執行 52
3.4.2 CPU的內部結構 53
3.4.3 改變路線 55
3.5 什麽與如何:架構和微架構 56
3.5.1 不斷演變的架構 56
3.5.2 地下室的秘密機器 57
3.6 工廠經理 58
3.6.1 操作系統:轉角辦公室 59
3.6.2 BIOS:軟件不“軟” 59
3.6.3 多任務魔法 60
3.6.4 提升至內核 61
3.6.5 內核爆炸 62
3.6.6 計劃 63
第4章 尋址、尋址、尋址——寄存器、內存尋址及瞭解數據的位置 64
4.1 內存模型的樂趣 64
4.1.1 16位能“買到”64KB 65
4.1.2 兆字節(MB)的本質 68
4.1.3 向後兼容和虛擬86模式 69
4.1.4 16位的視野限制 70
4.2 分段的本質 71
4.2.1 一條地平線,而不是一個具體位置 74
4.2.2 使用16位寄存器生成20位地址 74
4.3 分段寄存器 76
4.3.1 分段寄存器和x64 77
4.3.2 通用寄存器 77
4.3.3 寄存器的高位和低位 79
4.3.4 指令指針 81
4.3.5 標志寄存器 82
4.3.6 數學協處理器及其寄存器 82
4.4 四種主要的匯編編程模型 83
4.4.1 實模式平面模型 83
4.4.2 實模式分段模型 85
4.4.3 32位保護模式平面模型 87
4.4.4 64位長模式編程模型 89
第5章 匯編的正確方式——匯編語言程序的開發過程 91
5.1 編程的96種方法 91
5.2 文件及其內容 92
5.2.1 二進制文件與文本文件 92
5.2.2 使用GHex十六進制編輯器查看二進制文件內部 94
5.2.3 解釋原始數據 97
5.2.4 字節順序 98
5.3 輸入文本,輸出代碼 102
5.3.1 匯編語言 102
5.3.2 註釋 104
5.3.3 當心“只寫源代碼”! 105
5.3.4 目標代碼、鏈接器和庫 106
5.3.5 可重定位性 108
5.4 匯編語言的開發過程 108
5.4.1 工作目錄的規則 110
5.4.2 編輯源代碼文件 110
5.4.3 匯編源代碼文件 111
5.4.4 匯編器錯誤 111
5.4.5 回到編輯器 113
5.4.6 編譯器警告 113
5.5 鏈接目標代碼文件 114
5.5.1 鏈接器錯誤 115
5.5.2 測試EXE文件 115
5.5.3 錯誤與缺陷 116
5.5.4 調試器和調試 117
5.6 走進匯編語言的世界 117
5.6.1 安裝軟件 118
5.6.2 步驟1:在編輯器中編輯程序 120
5.6.3 步驟2:使用NASM匯編程序 121
5.6.4 步驟3:使用ld鏈接程序 123
5.6.5 步驟4:測試可執行文件 124
5.6.6 步驟5:在調試器中觀察它的運行 124
第6章 一個可使用工具的立足之地——Linux和塑造你的工作方式的工具 126
6.1 集成開發環境(IDE) 126
6.2 SASM簡介 128
6.2.1 配置SASM 129
6.2.2 SASM的字體 130
6.2.3 使用編譯器鏈接 130
6.2.4 SASM速覽 132
6.2.5 SASM的編輯器 134
6.2.6 SASM對你的代碼有何要求 134
6.3 Linux和終端 135
6.3.1 Linux控制台 136
6.3.2 Konsole中的字符編碼 136
6.3.3 三個標準UNIX文件 138
6.3.4 I/O重定向 139
6.3.5 簡單文本過濾器 141
6.3.6 使用SASM內部的標準輸入和標準輸出 142
6.3.7 使用轉義序列進行終端控制 142
6.3.8 為什麽不使用GUI應用程序 143
6.4 使用Linux Make 145
6.4.1 依賴 145
6.4.2 當文件是最新的 147
6.4.3 依賴鏈 148
6.4.4 調用Make 149
6.4.5 為Make創建自定義按鍵綁定 150
6.4.6 使用touch強制構建 151
6.5 使用SASM進行調試 152
第7章 遵循你的指令——近距離觀察機器指令 154
7.1 構建自己的沙箱 154
7.2 指令及其操作數 157
7.3 源操作數和目標操作數 157
7.3.1 即時數據 158
7.3.2 寄存器數據 160
7.3.3 內存數據和有效地址 162
7.3.4 混淆數據及其地址 162
7.3.5 內存數據的大小 163
7.3.6 糟糕的舊時光 164
7.4 團結在“標志”周圍 164
7.4.1 標志禮儀 167
7.4.2 在SASM中觀察標志 167
7.4.3 使用INC和DEC進行加1和減1操作 167
7.4.4 標志如何改變程序的執行 169
7.4.5 如何檢查SASM中的變量 170
7.5 有符號值和無符號值 172
7.5.1 二進制補碼和NEG 172
7.5.2 符號擴展和MOVSX 174
7.6 隱式操作數和MUL 176
7.6.1 MUL和進制標志 177
7.6.2 使用DIV進行無符號除法 178
7.6.3 MUL和DIV速度很慢 179
7.7 閱讀和使用匯編語言參考 180
7.7.1 復雜記憶的備忘錄 180
7.7.2 初學者的匯編語言參考 181
7.7.3 標志 181
7.8 NEG取反(二進制補碼,即乘以-1) 182
7.8.1 受影響的標志 182
7.8.2 有效形式 182
7.8.3 示例 182
7.8.4 備註 182
7.8.5 有效形式 183
7.8.6 操作數符號 183
7.8.7 示例 184
7.8.8 備註 184
7.8.9 這里沒有提到的內容…… 185
第8章 我們崇高的目標——創建有效的程序 186
8.1 匯編語言程序的骨架 186
8.1.1 初始註釋塊 188
8.1.2 .data部分 188
8.1.3 .bss部分 189
8.1.4 .text部分 189
8.1.5 標簽 190
8.1.6 初始化數據的變量 191
8.1.7 字符串變量 191
8.1.8 使用EQU和$推導字符串長度 193
8.2 通過棧後進先出 194
8.2.1 每小時500個盤子 195
8.2.2 倒置堆疊 196
8.2.3 壓入指令 197
8.2.4 POP指令登場 198
8.2.5 PUSHA和POPA已停用 199
8.2.6 壓入和彈出的詳細信息 200
8.2.7 短期存儲 201
8.3 通過SYSCALL使用Linux內核服務 202
8.3.1 通過SYSCALL指令使用x64內核服務 202
8.3.2 ABI與API的區別 203
8.3.3 ABI的寄存器參數方案 203
8.3.4 通過SYSCALL退出程序 204
8.3.5 被SYSCALL破壞的寄存器 205
8.4 設計一個不平凡的程序 205
8.4.1 定義問題 206
8.4.2 從偽代碼開始 207
8.4.3 持續改進 207
8.4.4 那些不可避免的驚訝時刻 211
8.4.5 掃描緩沖區 212
8.4.6 差一錯誤 214
8.4.7 從偽代碼到匯編代碼 215
8.4.8 SASM輸出窗口的陷阱 218
8.4.9 進一步學習 218
第9章 位、標志、分支和表——逐步駛入匯編編程的主航道 219
9.1 位就是位(字節也是位) 219
9.1.1 位編號 220
9.1.2 最合乎邏輯的做法 220
9.1.3 AND指令 221
9.1.4 掩碼位 221
9.1.5 OR指令 223
9.1.6 XOR(異或)指令 223
9.1.7 NOT指令 224
9.1.8 分段寄存器沒有邏輯 225
9.2 移位 225
9.2.1 通過什麽移位 226
9.2.2 移位的工作原理 226
9.2.3 將位放入進制標志 227
9.2.4 旋轉指令 227
9.2.5 通過進制標志旋轉位 228
9.2.6 將已知值設置到進制標志中 228
9.3 位操作實戰 229
9.3.1 將一字節拆分成兩個“半字節” 232
9.3.2 將高半字節移入低半字節 232
9.3.3 使用查找表 233
9.3.4 通過移位和加法進行乘法 234
9.4 標志、測試和分支 237
9.4.1 無條件跳轉 237
9.4.2 有條件跳轉 238
9.4.3 在缺少條件的情況下跳轉 239
9.4.4 標志 240
9.4.5 使用CMP進行比較 240
9.4.6 跳轉指令的“叢林” 241
9.4.7 “大於”與“高於” 241
9.4.8 使用TEST查找1位 243
9.4.9 使用BT尋找0位 244
9.5 x64長模式內存尋址詳解 244
9.5.1 有效地址計算 246
9.5.2 位移 247
9.5.3 x64位移大小問題 247
9.5.4 基址尋址 248
9.5.5 基址 + 位移尋址 248
9.5.6 基址 + 索引尋址 248
9.5.7 索引×比例+位移尋址 249
9.5.8 其他尋址方案 251
9.5.9 LEA:絕密數學機器 253
9.6 字符表轉換 254
9.6.1 轉換表 254
9.6.2 使用MOV或XLAT進行轉換 256
9.7 用表代替計算 261
第10章 分而治之——使用過程和宏來應對程序復雜性 262
10.1 層層嵌套 263
10.2 調用和返回 272
10.2.1 調用中的調用 274
10.2.2 意外遞歸的危險 275
10.2.3 需要警惕的標志相關錯誤 276
10.2.4 過程及其所需的數據 278
10.2.5 保存調用者的寄存器 278
10.2.6 在Linux系統調用中保存寄存器 280
10.2.7 PUSHAD和POPAD已廢棄 281
10.2.8 本地數據 283
10.2.9 在過程定義中放置常量數據 283
10.2.10 更多表技巧 285
10.3 本地標簽和跳轉的長度 287
10.3.1 強制本地標簽訪問 290
10.3.2 短、近和遠跳轉 290
10.4 構建外部過程庫 291
10.4.1 當工具達到極限時 292
10.4.2 在SASM中使用包含文件 292
10.4.3 SASM包含文件的存儲位置 299
10.4.4 創建包含文件庫的最佳方法 300
10.4.5 獨立匯編和模塊 301
10.4.6 全局和外部聲明 301
10.4.7 全局變量和外部變量的機制 303
10.4.8 將庫鏈接到程序中 313
10.4.9 太多過程和庫會造成危險 313
10.5 製作過程的藝術 314
10.5.1 可維護性和重用性 314
10.5.2 決定什麽應該是一個過程 315
10.5.3 使用註釋標題 316
10.6 Linux控制臺中的簡單光標控制 317
10.7 創建和使用宏 325
10.7.1 宏定義的機制 326
10.7.2 定義帶參數的宏 332
10.7.3 調用宏的機制 333
10.7.4 宏內的本地標簽 334
10.7.5 宏庫作為包含文件 335
10.7.6 宏與過程:優點和缺點 335
第11章 字符串及其他——那些令人驚嘆的字符串指令 337
11.1 匯編語言字符串的概念 338
11.1.1 徹底改變你的“字符串感” 338
11.1.2 源字符串和目標字符串 339
11.1.3 文本顯示虛擬屏幕 339
11.2 REP STOSB:軟件機關槍 347
11.2.1 機關槍式操作虛擬顯示 348
11.2.2 執行STOSB指令 348
11.2.3 STOSB和方向標志DF 349
11.2.4 定義顯示緩沖區中的行 350
11.2.5 將緩沖區發送到Linux控制台 351
11.3 半自動武器:沒有REP的STOSB 351
11.3.1 誰減少了RCX? 352
11.3.2 LOOP指令 352
11.3.3 在屏幕上顯示標尺 353
11.3.4 MUL不是IMUL 354
11.3.5 Ruler的教訓 355
11.3.6 STOS的四種大小 355
11.3.7 再見,BCD算術 356
11.4 MOVSB:快速塊復制 356
11.4.1 DF和重疊阻擋移動 357
11.4.2 單步REP字符串指令 360
11.5 將數據存儲到不連續的字符串中 361
11.5.1 顯示一個ASCII表 361
11.5.2 嵌套指令循環 366
11.5.3 當RCX變為0時跳轉 367
11.5.4 關閉內循環 367
11.5.5 關閉外循環 368
11.5.6 回顧showchar 369
11.6 命令行參數、字符串搜索和Linux棧 369
11.6.1 顯示SASM的命令行參數 370
11.6.2 使用SCASB進行字符串搜索 373
11.6.3 REPNE與REPE 374
11.6.4 無法將命令行參數傳遞給SASM中的程序 375
11.7 棧及其結構和使用方法 375
11.7.1 直接訪問棧 377
11.7.2 程序序言和結語 380
11.7.3 棧上的尋址數據 381
11.7.4 不要彈出 382
第12章 轉向C——調用C語言編寫的外部函數 383
12.1 GNU 384
12.1.1 瑞士軍刀編譯器 385
12.1.2 以GNU方式構建代碼 385
12.1.3 SASM使用GCC 387
12.1.4 如何在匯編工作中使用gcc 387
12.1.5 為什麽不使用gas 388
12.2 鏈接標準C庫 389
12.2.1 C調用約定 390
12.2.2 調用者、被調用者和破壞者 390
12.2.3 設置棧幀 392
12.2.4 在結語中銷毀棧幀 393
12.2.5 棧對齊 393
12.2.6 通過puts()輸出字符 395
12.3 使用printf()格式化文本輸出 397
12.3.1 將參數傳遞給printf() 398
12.3.2 printf()需要在RAX中加上前置0 399
12.3.3 你需要使用-no-pie選項 400
12.4 使用fgets()和scanf()輸入數據 400
12.5 成為Linux時間領主 406
12.5.1 C庫的時間機器 406
12.5.2 從系統時鐘獲取time_t值 407
12.5.3 將time_t值轉換為格式化字符串 408
12.5.4 生成單獨的本地時間值 409
12.5.5 使用MOVSD復制glibc的tm結構 409
12.6 理解AT&T指令助記符 413
12.6.1 AT&T助記符約定 413
12.6.2 AT&T內存引用語法 415
12.7 生成隨機數 416
12.7.1 使用srand()為生成器設定種子 416
12.7.2 生成偽隨機數 417
12.7.3 相比之下有些比特更隨機 423
12.7.4 調用寄存器中的地址 425
12.7.5 使用puts()將一個裸換行符發送到控制台 426
12.7.6 如何向libc函數傳遞六個以上的參數 426
12.8 C語言如何處理命令行參數 427
12.9 簡單文件 I/O 430
12.9.1 使用sscanf()將字符串轉換為數字 431
12.9.2 創建和打開文件 432
12.9.3 使用fgets()從文件讀取文本 434
12.9.4 使用fprintf()將文本寫入文件 436
12.9.5 將過程收集到庫中的註意事項 437
12.10 永遠學習,永遠不要停下來 444
12.10.1 何去何從 445
12.10.2 走出原點 446
(以下內容可掃描封底二維碼下載)
附錄A Insight調試器的回歸 447
附錄B 部分x64指令參考 454
附錄C 字符集圖表 509