本書源于作者的經(jīng)典書籍The Art of Assembly Language,從32位匯編語言升級為64位匯編語言,基于MASM講解x86-64CPU上匯編語言的編程藝術(shù)。本書從計(jì)算機(jī)的組成結(jié)構(gòu)開始介紹,包括計(jì)算機(jī)數(shù)據(jù)表示和運(yùn)算,以及內(nèi)存的訪問和組織等。之后詳細(xì)講解匯編語言程序設(shè)計(jì),涉及過程和算術(shù)運(yùn)算的相關(guān)知識,再通過低級控制結(jié)構(gòu)過渡到高級主題,如表查找和位操作。此外,還探索了x87浮點(diǎn)單元、SIMD指令,以及MASM的宏工具。
本書源于作者的經(jīng)典書籍The Art of Assembly Language,從32位匯編語言升級為64位匯編語言,基于Microsoft宏匯編程序(MASM)講解x86-64 CPU上匯編語言的編程藝術(shù),涵蓋原理、方法和技巧,是系統(tǒng)學(xué)習(xí)和掌握匯編語言編程的有益參考。本書從計(jì)算機(jī)的組成結(jié)構(gòu)開始介紹,包括計(jì)算機(jī)數(shù)據(jù)表示和運(yùn)算,以及內(nèi)存的訪問和組織等。之后詳細(xì)講解匯編語言程序設(shè)計(jì),涉及過程和算術(shù)運(yùn)算的相關(guān)知識,再通過低級控制結(jié)構(gòu)過渡到高級主題,如表查找和位操作。此外,還探索了x87浮點(diǎn)單元、SIMD指令,以及MASM的宏工具。
前 言
The Art of 64-Bit Assembly: x86-64 Machine Organization and Programming
本書是作者30年工作的結(jié)晶。本書最早的版本是作者在加州理工大學(xué)波莫納分校和加州大學(xué)河濱分校提供給學(xué)生的課堂筆記,標(biāo)題是“如何使用8088匯編語言為IBM PC編程”。學(xué)生們和作者的一個好朋友瑪麗·菲利普斯(Mary Philips)提出了很多寶貴的意見。比爾·波洛克(Bill Pollock)最先在互聯(lián)網(wǎng)上發(fā)現(xiàn)了課堂筆記的早期版本,并在卡羅爾·朱拉多(Karol Jurado)的幫助下,使The Art of Assembly Language第1版于2003年正式出版。
后來,基于數(shù)以千計(jì)讀者的意見和反饋,以及在No Starch出版社的比爾·波洛克(Bill Pollock)、艾莉森·彼得森(Alison Peterson)、安塞爾·斯塔頓(Ansel Staton)、萊利·霍夫曼(Riley Hoffman)、梅根·鄧查克(Megan Dunchak)、琳達(dá)·雷克滕瓦爾德(Linda Recktenwald)、蘇珊·格利納特·史蒂文斯(Susan Glinert Stevens)、南!へ悹枺∟ancy Bell)和技術(shù)審稿人內(nèi)森·貝克(Nathan Baker)的支持下,The Art of Assembly Language的第2版于2010年出版。
轉(zhuǎn)眼十年過去了,The Art of Assembly Language(作者將其簡稱為AoA)漸漸失去了流行度,因?yàn)樵摃U述的內(nèi)容與英特爾x86的35年前的32位設(shè)計(jì)緊密關(guān)聯(lián)。今天,打算學(xué)習(xí)80x86匯編語言的人可能想學(xué)習(xí)在較新的x86-64 CPU上的64位匯編語言。因此,鑒于32位的AoA基于HLA,在2020年年初,作者即開始使用MASM,逐步將陳舊的32位AoA轉(zhuǎn)換為64位的。
剛開始著手這個將AoA從32位轉(zhuǎn)為64位的項(xiàng)目時(shí),作者曾天真地認(rèn)為只需要把少量HLA程序翻譯成MASM,調(diào)整一些文本,花費(fèi)少量的精力即可。結(jié)果證明作者的想法大錯特錯。No Starch出版社的工作人員希望在可讀性和易理解性方面取得突破,托尼·特里貝利(Tony Tribelli)在對這本書中的每一行文本和代碼進(jìn)行技術(shù)審查時(shí)所做的工作令人難以置信。因此,這個從32位到64位轉(zhuǎn)換項(xiàng)目的工作相當(dāng)于從頭開始撰寫一本新書。不過至少所有的努力都是值得的,相信讀者能從我們辛勤編撰的成果中有所領(lǐng)悟。
關(guān)于本書中所提供的源代碼
本書中包含了大量的x86-64匯編語言(以及C/C 語言)源代碼。通常情況下,源代碼有三種形式,即代碼片段(code snippet)、單一匯編語言過程或函數(shù)(single assembly language procedure or function)以及完整程序(full-blown program)。
代碼片段是程序的片段。代碼片段不是獨(dú)立的程序,并且不能使用MASM進(jìn)行編譯或匯編(如果是C/C 源代碼,則不能使用C/C 編譯器編譯這些代碼片段)。本書中之所以使用代碼片段,是為了說明一個觀點(diǎn)或提供一個編程技術(shù)的小例子。本書中代碼片段的典型示例如下:
someConst = 5
.
.
.
mov eax, someConst
垂直省略號表示可能出現(xiàn)在其位置的任意代碼(需要注意的是,并非所有代碼片段都使用垂直省略號)。
匯編語言過程或函數(shù)也不是獨(dú)立的程序。雖然讀者可以對本書中出現(xiàn)的許多匯編語言過程加以匯編(只需將本書中的代碼直接復(fù)制到編輯器中,然后在生成的文本文件上運(yùn)行MASM),但這些過程并不會自行執(zhí)行。代碼片段和匯編語言過程的主要區(qū)別在于:匯編語言過程包含在本書可下載的源文件中(下載網(wǎng)址為https://artofasm.randallhyde.com/)。
在本書中,可以編譯和執(zhí)行的完整程序被標(biāo)記為程序清單(listing),它有“程序清單C-N”形式的編號或標(biāo)識符,其中C是章編號,N是順序遞增的程序清單編號,每章中編號N從1開始。以下是本書中出現(xiàn)的程序清單示例。
程序清單1-3 MASM程序(listing1-3.asm文件),被程序清單1-2中的C 程序調(diào)用
; 程序清單1-3
; 一個簡單的MASM模塊,包含一個空函數(shù),被程序清單1-2中的C 代碼調(diào)用。
.CODE
; (有關(guān)option偽指令的說明,請參見后續(xù)正文。)
option casemap:none
; 以下是“asmFunc”函數(shù)的定義。
public asmFunc
asmFunc PROC
; 空函數(shù),直接返回到C 代碼。
ret ; 返回到調(diào)用方
asmFunc ENDP
END
與匯編語言過程一樣,在作者的網(wǎng)站(https://artofasm.randallhyde.com/)上也可以找到本書所有的程序清單。該網(wǎng)站包含了本書所有源代碼文件以及相關(guān)資源信息(例如勘誤表、電子版和其他有用信息)的頁面。為了便于閱讀,有幾個章節(jié)將程序清單編號附加到過程和宏上,這些過程和宏不是完整的程序。有些程序清單只用來演示MASM的語法錯誤,因此無法運(yùn)行。源代碼發(fā)行包中仍然包含這些程序清單的源代碼,代碼名稱為對應(yīng)的程序清
單名。
通常情況下,本書使用build命令和示例輸出跟蹤可執(zhí)行的程序清單。以下是一個典型示例(用戶輸入內(nèi)容以黑體字的形式給出):
C:\>build listing4-7
C:\>echo off
Assembling: listing4-7.asm
c.cpp
C:\>listing4-7
Calling Listing 4-7:
aString: maxLen:20, len:20, string data:'Initi
蘭德爾·海德
(Randall Hyde)
嵌入式軟件工程師,曾在醫(yī)療、核能、消費(fèi)電子和娛樂行業(yè)工作。他在大學(xué)教授匯編語言編程超過10年,多年來為嵌入式和商業(yè)應(yīng)用程序編寫了數(shù)十萬行匯編代碼。著有The Art of Assembly Language和Write Great Code系列書籍,均由No Starch出版社出版。
目 錄
The Art of 64-Bit Assembly: x86-64 Machine Organization and Programming
譯者序
推薦序
前言
致謝
第一部分 計(jì)算機(jī)的組成結(jié)構(gòu)
第1章 匯編語言的第一個程序 2
1.1 先決條件 2
1.2 在計(jì)算機(jī)上安裝MASM 3
1.3 在計(jì)算機(jī)上安裝文本編輯器 3
1.4 MASM程序的結(jié)構(gòu)剖析 3
1.5 運(yùn)行第一個MASM程序 4
1.6 運(yùn)行第一個MASM和C 的混合
程序 4
1.7 英特爾x86-64 CPU系列簡介 6
1.8 內(nèi)存子系統(tǒng) 9
1.9 在MASM中聲明內(nèi)存變量 10
1.9.1 將內(nèi)存地址與變量關(guān)聯(lián) 11
1.9.2 將數(shù)據(jù)類型與變量關(guān)聯(lián) 12
1.10 在MASM中聲明(命名)常量 12
1.11 基本的機(jī)器指令 13
1.11.1 mov指令 13
1.11.2 指令操作數(shù)的類型檢查 14
1.11.3 add和sub指令 15
1.11.4 lea指令 15
1.11.5 call和ret指令以及MASM
過程 16
1.12 調(diào)用C/C 過程 17
1.13 “Hello, world!”程序 18
1.14 在匯編語言中返回函數(shù)結(jié)果 19
1.15 自動化構(gòu)建過程 24
1.16 微軟ABI注釋 25
1.16.1 變量大小 25
1.16.2 寄存器的用途 28
1.16.3 棧對齊 28
1.17 拓展閱讀資料 28
1.18 自測題 29
第2章 計(jì)算機(jī)數(shù)據(jù)表示和運(yùn)算 31
2.1 數(shù)制系統(tǒng) 31
2.1.1 十進(jìn)制數(shù)制系統(tǒng)的回顧 31
2.1.2 二進(jìn)制數(shù)制系統(tǒng) 32
2.1.3 二進(jìn)制約定 32
2.2 十六進(jìn)制數(shù)制系統(tǒng) 33
2.3 關(guān)于數(shù)字與表示的注釋 34
2.4 數(shù)據(jù)組織 36
2.4.1 位 36
2.4.2 半字節(jié) 36
2.4.3 字節(jié) 37
2.4.4 字 38
2.4.5 雙字 39
2.4.6 四字和八字 39
2.5 位的邏輯運(yùn)算 39
2.5.1 邏輯與運(yùn)算 40
2.5.2 邏輯或運(yùn)算 40
2.5.3 邏輯異或運(yùn)算 40
2.5.4 邏輯非運(yùn)算 41
2.6 二進(jìn)制數(shù)和位串的邏輯運(yùn)算 41
2.7 有符號數(shù)和無符號數(shù) 45
2.8 符號擴(kuò)展和零擴(kuò)展 49
2.9 符號縮減和飽和法 49
2.10 簡要回顧:控制轉(zhuǎn)移指令概述 50
2.10.1 jmp指令 50
2.10.2 條件跳轉(zhuǎn)指令 51
2.10.3 cmp指令和相應(yīng)的條件
跳轉(zhuǎn) 52
2.10.4 條件跳轉(zhuǎn)的同義詞 53
2.11 移位和循環(huán)移位 54
2.12 位字段和打包數(shù)據(jù) 57
2.13 IEEE浮點(diǎn)數(shù)格式 63
2.13.1 單精度格式 64
2.13.2 雙精度格式 65
2.13.3 擴(kuò)展精度格式 65
2.13.4 規(guī)范化浮點(diǎn)值 65
2.13.5 非數(shù)值數(shù)據(jù) 66
2.13.6 MASM對浮點(diǎn)值的支持 66
2.14 BCD表示法 67
2.15 字符 67
2.15.1 ASCII字符編碼 68
2.15.2 MASM對ASCII字符的
支持 69
2.16 Unicode字符集 70
2.16.1 Unicode碼位 70
2.16.2 Unicode碼平面 70
2.16.3 Unicode編碼 71
2.17 MASM對Unicode的支持 72
2.18 拓展閱讀資料 72
2.19 自測題 72
第3章 內(nèi)存的訪問和組織 76
3.1 運(yùn)行時(shí)的內(nèi)存組織 76
3.1.1 “.code”段 77
3.1.2 “.data”段 77
3.1.3 “.const”段 78
3.1.4 “.data?”段 79
3.1.5 程序中聲明段的組織方式 79
3.1.6 內(nèi)存訪問和4KB內(nèi)存管理
單元頁 80
3.2 MASM如何為變量分配內(nèi)存 81
3.3 標(biāo)簽聲明 82
3.4 小端模式和大端模式的數(shù)據(jù)組織
方式 82
3.5 內(nèi)存訪問 84
3.6 MASM對數(shù)據(jù)對齊的支持 85
3.7 x86-64的尋址模式 87
3.7.1 x86-64的寄存器尋址模式 88
3.7.2 x86-64的64位內(nèi)存尋址模式 88
3.7.3 不支持大地址的應(yīng)用程序 91
3.8 地址表達(dá)式 94
3.9 棧段以及push和pop指令 97
3.9.1 基本的push指令 97
3.9.2 基本的pop指令 98
3.9.3 使用push和pop指令保存
寄存器的狀態(tài) 99
3.10 ! 99
3.11 其他push和pop指令 102
3.12 不通過彈出棧從棧中移除數(shù)據(jù) 102
3.13 不通過彈出棧訪問壓入棧的
數(shù)據(jù) 103
3.14 微軟ABI注釋 104
3.15 拓展閱讀資料 104
3.16 自測題 104
第4章 常量、變量和數(shù)據(jù)類型 106
4.1 imul指令 106
4.2 inc和dec指令 107
4.3 MASM常量聲明 107
4.3.1 常量表達(dá)式 109
4.3.2 this和$運(yùn)算符 111
4.3.3 常量表達(dá)式求值 112
4.4 MASM typedef語句 112
4.5 類型強(qiáng)制 113
4.6 指針數(shù)據(jù)類型 116
4.6.1 在匯編語言中使用指針 117
4.6.2 在M