匯編語言知多少(一): 概論

編程語言的發(fā)展

  • 機器語言: 由 0 和 1 組成.
  • 匯編語言(Assembly Language): 用符號代替了 0 和 1, 比機器語言更加便于閱讀和記憶.
  • 高級語言: C\C++\Java\Swift等, 更加接近于人類自然語言.

    來源維基百科-匯編語言

操作:
將寄存器 BX 的內容送到寄存器 AX.

機器語言: 1000100111011000
匯編語言: mov ax, bx
高級語言: ax = bx
  • 匯編語言與機器語言一一對應领突,每一條機器指令都有與之對應的匯編指令
  • 匯編語言可以通過編譯得到機器語言案怯,機器語言可以通過反匯編得到匯編語言
  • 高級語言可以通過編譯得到匯編語言\機器語言,但匯編語言\機器語言幾乎不可能還原成高級語言

匯編語言的特點

  • 可以直接訪問, 控制各種硬件設備, 比如存儲器, CPU等, 能最大限度發(fā)揮硬件的功能.
  • 匯編指令是機器指令的助記符, 和機器指令一一對應, 每一種CPU都有自己的機器指令集 \ 匯編指令集, 所以匯編語言不具備可移植性.
  • 不區(qū)分大小寫, mov 和 MOV 是一樣的.

采用高級語言C++和匯編語言編寫同一個功能, 將 a + b 的結果賦值給 c, 然后打印 c 的結果.

語言 源文件大小 目標文件大小 可執(zhí)行文件大小
匯編語言 近400字節(jié) 近200字節(jié) 近600字節(jié)
C++ 近150字節(jié) 近550字節(jié) 近9000字節(jié)

由于C++會鏈接很多底層庫, 所以可執(zhí)行文件會大這么多.

匯編語言的分類

要弄清楚這個, 我們先講一下微處理器.

微處理器(Microprocessor)是可編程特殊集成電路, 其所有組件小型化至一塊或數(shù)塊集成電路內, 可在其一端或多端接受編碼指令局蚀,執(zhí)行此指令并輸出描述其狀態(tài)的信號. 又稱半導體中央處理器琅绅,是微型計算機的一個主要部件.

  • 在具有微程序控制的指令集的微型計算機中, 微處理器不僅具有算術邏輯單元和控制邏輯單元, 還有控制存儲單元.
    • 用于處理通用資料鹅巍,叫作 CPU (Central Processing Unit), 中央處理器.
    • 用于圖像資料處理, 叫作 GPU (Graphics Processing Unit), 圖形處理器.
    • 用于音訊資料處理, 叫作 APU (Audio Processing Unit), 音訊處理器.
    • 其他
  • 微處理器工作原理
    • 通過設計好的指令集, 來輸入對應的指令, 控制處理器實現(xiàn)相應的功能.
    • 所以指令集決定了處理器的架構, 由于不同的公司設計不一樣的指令集, 導致對應的硬件電路都可能不一樣.
    • 匯編語言是用助記符來描述指令集. 便于人類編碼.
時間 事件
1971年 Intel公司發(fā)布世界第一款4位微處理器 4004
1972年 Intel公司發(fā)布世界第一款8位微處理器 8008
1978年 Intel公司發(fā)布16位微處理器 8086(是x86系列第一款)
1982年 AT&T貝爾實驗室設計的世界第一款32位微處理器BELLMAC-32A投產(chǎn)
1990年 用RISC技術(精簡指令集)設計全球第一款64位微處理器 R4000

那么匯編語言怎么分類呢?

  • 按照指令集架構分類:

    • 8086匯編(16bit), x86系列第一款. 我們學習的就是這一種,
    • x86匯編(32bit), 這種架構常被稱為i386, x86, 它是 Intel 設計的
    • x86匯編(64bit), 這種架構常被稱為 AMD64, Intel64, x86-64, x64, 它是 AMD 設計的, 是x86架構的64位擴展, 后來公開, 也被Intel所采用, 故現(xiàn)在也稱為 Intel64.
    • ARM匯編, ARM處理器由于高性能, 低耗電, 常用于嵌入式, 移動設備.
    • 其他
  • 按照匯編格式分類: 這幾種基本上是符號系統(tǒng)的區(qū)別

    • Intel 格式
    • AT&T 格式
    • ARM 格式
    • 其他

指的一提的是

  • x86 匯編指令的風格是 Intel 匯編, 被 Microsoft Windows, Visual C++ 采用.
  • x64 匯編指令的風格是 AT&T 匯編, 被 GNU, Gas 采用(Gas 也可使用Intel匯編).
  • ARM 匯編指令的風格是 ARM 匯編.被 Apple 采用. 應用于 iPhone 真機.
Intel 處理器
ARM 處理器

匯編語言的用途

  • 編寫驅動程序, 操作系統(tǒng)(比如Linux內核的某些關鍵部分).
  • 對性能要求極高的程序或者代碼片段,可與高級語言混合使用(內聯(lián)匯編).
  • 軟件安全
    • 病毒分析與防治.
    • 逆向\加殼\脫殼\破解\外掛\免殺\加密解密\漏洞\黑客.
  • 是理解整個計算機系統(tǒng)的最佳起點和最有效途徑, 為編寫高效代碼打下基礎.

了解 CPU 等硬件結構.

軟件\程序執(zhí)行的過程

image.png

每一個CPU芯片都有許多管腳, 這些管腳和總線(Bus)相連, CPU 通過總線跟外部器件交互.

8086芯片
  • 地址總線(Address Bus): 它的寬度決定了 CPU 的尋址能力
  • 數(shù)據(jù)總線(Data Bus): 它的寬度決定了 CPU 的單次數(shù)據(jù)傳送量, 也就是數(shù)據(jù)傳輸速度.
  • 控制總線(Control Bus): 它的寬度決定了 CPU 對其他器件的控制能力, 能有多少控制.
  • CPU 通過控制總線傳輸讀命令, 通過地址總線指定是內存中的3號單元, 通過數(shù)據(jù)總線傳輸數(shù)據(jù) 0000 1000 (08)
  • 這里面的 0, 1 是指的是線路中的 高電平, 低電平. 線路越寬, 能傳輸?shù)臄?shù)據(jù)越多

數(shù)據(jù)總線

8088的數(shù)據(jù)總線寬度是 8 根, 8086 的數(shù)據(jù)總線寬度是 16根, 那么分別向內存中寫入 89D8H.

練習:

  • 1 個 CPU 的尋址能力是 8 KB, 那么他的地址總線的寬度數(shù): 13, 因為 8KB = 2^{13}
  • 8086, 8088, 80286, 80386 的地址總線寬度為16根, 20根, 24根, 32根, 那么他們的尋址能力分別是 64KB, 1MB, 16MB, 4GB, 因為
    • 2^{10} = 1KB, 2^{16} = 64 KB
    • 2^{20} = 1024KB = 1 MB,
    • 2^{24} = 16 * 1024KB = 16 MB,
    • 2^{32} = 2^{12} * 1MB = 4 * 1024 * 1MB = 4GB
  • 8086, 8088, 8086, 80286, 80386 的數(shù)據(jù)總線寬度為8根, 8根, 16根, 16根, 32根, 那么他們一次可以傳送的數(shù)據(jù)是: 1B, 1B, 2B, 2B, 4B,
    • 因為傳輸 1Byte 的數(shù)據(jù)實際是8bit .
  • 從內存中讀取 1024 字節(jié)的數(shù)據(jù), 8086至少讀 512 次,
    • 因為 1024B = 2^{10} B, 8086 的傳輸速度是 2B / 次, 所以需要 512 次.

這里再啰嗦一遍, 1 字節(jié) = 8 位, 1 Byte = 8 bit, 我們常說的 64 位操作系統(tǒng), 指的是CPU 每次能處理 64 bit 的數(shù)據(jù).

內存

各類存儲器的邏輯連接與物理連接對應圖.


image.png

所有的內存單元都有唯一的地址, 叫作物理地址, 內存地址空間的大小受 CPU 地址總線寬度的限制.

8086的地址地址總線寬度為20, 可以定位 2^{20} 個不同的內存單元, ( 內存地址范圍為0x00000 ~ 0xFFFFF), 所以8086的內存空間大小為 1 MB.
注: 2^{20} = 1048576 , 0xFFFFF => 1048575

  • 0x00000 ~ 0x9FFFF: 主存儲器, 可讀可寫.
  • 0xA0000 ~ 0xBFFFF: 向顯存中寫入數(shù)據(jù), 這些數(shù)據(jù)會被顯卡輸出到顯示器, 可讀可寫.
  • 0xC0000 ~ 0xFFFFF: 存儲各種硬件\系統(tǒng)信息, 只讀.


    image.png

8086的尋址方式

  • CPU訪問內存單元時, 要給出內存單元地址.
  • 8086有 20位 的地址總線, 可以傳送 20 位的地址, 1M 的尋址能力.
  • 但它又是 16位 結構的CPU, 它內部能夠一次性處理, 傳輸, 暫時存儲的地址為 16位. 如果將地址從內部簡單發(fā)出, 那么它只能送出 16位 的地址, 表現(xiàn)出來的尋址能力只有 64KB
  • 所以8086采用了一種在內部使用 2個16位 地址合成的方式來生成 1個20位 的物理地址.

地址加法器采用 物理地址 = 段地址 x 16 + 偏移地址 的方式合成物理地址.
比如 8086CPU 要訪問地址為 123C8H 的內存單元

我們又能發(fā)現(xiàn), 8086CPU的要訪問的同一個 物理地址 可以由不同的 段地址偏移地址 組成.

內存的分段管理

  • 8086采用 起始地址(段地址x16) + 偏移地址 = 物理地址 的方式來給出物理地址.
  • 為了開發(fā)方便, 我們采用分段的方式來管理內存.
    • 比如地址 10000H ~ 100FFH 組成一段, 那么起始地址為 10000H, 段地址為 1000H, 大小為 100H.

如果給定一個段地址, 僅通過變化偏移地址來進行尋址, 最多可定位多少個內存單元?
偏移地址為 16 位, 變化范圍為 0 ~ FFFFH, 僅用偏移地址來尋址, 最多可尋64KB個內存單元(2^{16} = 64KB) , 若給定段地址為 1000H, 用偏移地址尋址, CPU的尋址范圍為 10000H ~ 1FFFFH.

在 8086PC機中, 存儲單元的地址用段地址和偏移地址來描述, 
比如數(shù)據(jù)在 21F60H 內存單元中, 對于 8086PC機來說, 數(shù)據(jù)存在內存2000: 1F60單元中, 
或者數(shù)據(jù)存在 2000H段 中的 1F60H 單元中.

CPU的典型構成

不同的 CPU, 寄存器的個數(shù), 結構是不同的, 8086 有 14 個寄存器, 都是16位 寄存器, 每個可以存放 2個 字節(jié).


寄存器是有限存貯容量的高速存貯部件图焰,它們可用來暫存指令楞泼、數(shù)據(jù)和地址.

通用寄存器

  • AX, BX, CX, DX這四個寄存器通常用來存放一般的數(shù)據(jù), 也被稱為是 通用寄存器, 通常, CPU會先將內存中的數(shù)據(jù)存儲到通用寄存器中, 然后再對通用寄存器中的數(shù)據(jù)進行運算.
  • 假設內存中有一塊內存空間的值是 3, 現(xiàn)在想把它的值加 1 , 并將結果存儲在新的內存空間中.
    • mov ax, srcMemory: CPU 先將原來內存空間的值存在寄存器中
    • add ax, 1 : 讓寄存器ax與 1 相加.
    • mov desMemory, ax : 將值賦給新的內存空間.
  • AX, BX, CX, DX這四個通用寄存器是16位的, 里面AH, AL 分別代表高位寄存器, 和低位寄存器, 其他同理.

在匯編的數(shù)據(jù)存儲中

  • 字節(jié): byte, 1 個字節(jié)由8 bit組成
  • 字: word, 1個字由2個字節(jié)組成

上面展示的數(shù)據(jù) 20000 (4E20H), 字: 010011100 0100000B, 左邊是 高八位, 右邊是低八位.

段寄存器
8086 存在4個段寄存器, 當 CPU 需要訪問內存時, 由這4個提供段寄存器提供內存單元的 段地址.

  • CS (Code Segmnet): 代碼段寄存器
  • DS (Data Segmnet): 數(shù)據(jù)段寄存器
  • SS (Stack Segmnet): 堆棧段寄存器
  • ES (Extra Segmnet): 附加段寄存器
  1. 8086CPU 當前狀態(tài): CS 中的內容為 2000H, IP 中的內容是 0000H, CS 為代碼段寄存器, IP (Instruction Pointer Segment)為指令指針寄存器, 他們指示了 CPU 當前要讀取指令的地址.
  2. 內存 20000H ~ 20009H 單元存放著可執(zhí)行的機器碼.
  • 地址: 20000H ~ 20002H, 內容: B8 23 01, 長度 3 Byte, 匯編指令: mov ax, 0123H
  • 地址: 20003H ~ 20005H, 內容: BB 03 00, 長度 3 Byte, 匯編指令: mov bx, 0003H
  • 地址: 20006H ~ 20007H, 內容: 89 D8, 長度 2 Byte, 匯編指令: mov ax, bx
  • 地址: 20008H ~ 20009H, 內容: 01 D8, 長度 2 Byte, 匯編指令: mov ax, bx

下面將詳細就介紹 CPU 如何處理匯編指令.

  1. CS, IP 中的內容送到 地址加法器 中, 物理地址 = 段地址 x 16 + 偏移地址, 輸出 20000H
  2. 地址加法器 將物理地址送入到 輸入輸出控制電路.
  3. 輸入輸出控制電路 將物理地址 20000H 輸入到 地址總線 開始尋址.
  4. 從內存 20000H 單元開始存放的機器指令 B8 23 01 通過 數(shù)據(jù)總線 被送入到 CPU.
  5. 輸入輸出控制電路 將機器指令 B8 23 01 送入 指令緩沖器.
    • 此時 IP 中的值自動增加, 以便CPU 可以讀取下一條指令
    • 因為當前讀入的指令 B8 23 01 長度為 3 個字節(jié), 所以 IP 中的值加 3, 此時CS: IP執(zhí)行內存單元 2000: 0003
  6. 執(zhí)行控制器 執(zhí)行指令 B8 23 01, 即 mov ax, 0123H, 此時 AX 中的內容為 0123H.
  7. CPU 從內存 20003H 處讀取指令 BB 03 00, 送入 指令緩沖器, 此時 IP 再次加 3.
  8. 執(zhí)行指令 BB 03 00 即 mov bx, 0003H.
  9. CPU 從內存 20006H 處讀取指令 89 D8, 輸入指令緩沖器. 此時 IP 值加 2.
  10. 執(zhí)行指令 89 D8, 即 mov ax, bx, AX 中的內容變?yōu)?0003H.
  11. CPu 從內存 20008H 讀取指令 01 D8 入指令緩沖器. IP 的值加 2 .
  12. 執(zhí)行指令 01 D8, 即 add ax, bx, AX 中的內容變?yōu)?0006H.

上面這個過程可以簡述為

  1. 從 CS: IP 指向的內存單元讀取指令, 讀取的指令進入指令緩沖器.
  2. IP = IP + 所讀取指令的長度, 從而指向下一個指令的.
  3. 執(zhí)行指令, 重復步驟1, 重復這個過程.

指令和數(shù)據(jù)

看完上面這個過程, 我們會發(fā)現(xiàn) 指令和 數(shù)據(jù)都是二進制信息,
比如 內存中二進制信息 10001001 11011000, 既可當做數(shù)據(jù) 89D8H , 也可當做指令 mov ax, bx

那么 CPU 怎么區(qū)分兩者呢

  • CPU 將 CS: IP 指向的內存單元的全部內容看做指令. 指令里面可能包含數(shù)據(jù).
  • 如果內存中的某段內容曾被CPU執(zhí)行過,那么它所在的內存單元必然被CS:IP指向過

處理器架構超陆、指令集和匯編語言浦马,三者有何關系
維基百科-匯編語言
維基百科-X86
維基百科-ARM架構
維基百科-微處理器
維基百科-寄存器

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末晶默,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子趴梢,更是在濱河造成了極大的恐慌,老刑警劉巖憔狞,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件彰阴,死亡現(xiàn)場離奇詭異尿这,居然都是意外死亡,警方通過查閱死者的電腦和手機妻味,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進店門责球,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拓劝,“玉大人,你說我怎么就攤上這事栖博∠岫矗” “怎么了?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵丧叽,是天一觀的道長踊淳。 經(jīng)常有香客問我陕靠,道長,這世上最難降的妖魔是什么垄开? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任税肪,我火速辦了婚禮虚吟,結果婚禮上串慰,老公的妹妹穿的比我還像新娘唱蒸。我一直安慰自己,他們只是感情好庆捺,可當我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布屁魏。 她就那樣靜靜地躺著,像睡著了一般你画。 火紅的嫁衣襯著肌膚如雪桃漾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天适滓,我揣著相機與錄音凭迹,去河邊找鬼苦囱。 笑死,一個胖子當著我的面吹牛朽砰,可吹牛的內容都是我干的喉刘。 我是一名探鬼主播,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼造锅,長吁一口氣:“原來是場噩夢啊……” “哼廉邑!你這毒婦竟也來了倒谷?” 一聲冷哼從身側響起渤愁,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤深夯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后雹拄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掌呜,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡质蕉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了殊霞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汰蓉。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡顾孽,死狀恐怖比规,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情测秸,我是刑警寧澤灾常,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站沈撞,受9級特大地震影響雕什,放射性物質發(fā)生泄漏显晶。R本人自食惡果不足惜磷雇,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一躏救、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧睁本,春花似錦忠怖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贺纲。三九已至,卻和暖如春猴誊,著一層夾襖步出監(jiān)牢的瞬間懈叹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工胧洒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留墨状,地道東北人。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓汛兜,卻偏偏與公主長得像通今,于是被迫代替她去往敵國和親肛根。 傳聞我的和親對象是個殘疾皇子派哲,可洞房花燭夜當晚...
    茶點故事閱讀 43,554評論 2 349

推薦閱讀更多精彩內容

  • 8086匯編 本筆記是筆者觀看小甲魚老師(魚C論壇)《零基礎入門學習匯編語言》系列視頻的筆記僻澎,在此感謝他和像他一樣...
    Gibbs基閱讀 37,139評論 8 114
  • 編程語言的發(fā)展 機器語言由0和1組成 匯編語言(Assembly Language)用符號代替了0和1怎棱,比機器語言...
    阿凡提說AI閱讀 3,994評論 0 15
  • 越底層越單純!真正的程序員都需要了解的一門非常重要的語言,匯編! 機器語言 我們所寫的語言最終安裝在機器上的是什么...
    瑞陽gg閱讀 586評論 0 0
  • 匯編總結 匯編的發(fā)展史 機械語言 由0和1組成的機器指令(如:0101 0001 1101 0110) 匯編語言(...
    iChuck閱讀 1,302評論 1 8
  • 王爽匯編全書知識點大綱 第一章 基礎知識 機器語言 匯編語言的產(chǎn)生 匯編語言的組成 存儲器 cpu對存儲器的讀寫 ...
    2c3ba901516f閱讀 2,408評論 0 1