組合語言入門教程

2022-12-06 01:36:05 字數 5840 閱讀 7732

一、所有電腦語言寫出的程式執行時在記憶體中都以機器碼方式儲存,機器碼可以被比較準確的翻譯成組合語言,這是因為組合語言相容性最好,故幾乎所有跟蹤、除錯工具(包括win95/98下)都是以彙編示人的,如果閣下對crack頗感興趣……;二、彙編直接與硬體打交道,如果你想搞通程式在執行時在電腦中的來龍去脈,也就是搞清電腦每個組成部分究竟在幹什麼、究竟怎麼幹?乙個真正的硬體發燒友,不懂這些可不行。三、如今玩dos的多是「高手」,如能像吾一樣混入(我不是高手)「高手」內部,不僅可以從「高手」朋友那兒套些黑客級「機密」,還可以自詡「高手」盡情享受強烈的虛榮感--#$%& 「醒醒!

」對初學者而言,彙編的許多命令太複雜,往往學習很長時間也寫不出乙個漂漂亮亮的程式,以致妨礙了我們學習彙編的興趣,不少人就此放棄。所以我個人看法學彙編,不一定要寫程式,寫程式確實不是彙編的強項,大家不妨玩玩debug,有時crack出乙個小軟體比完成乙個程式更有成就感(就像學電腦先玩遊戲一樣)。某些高深的指令事實上只對有經驗的彙編程式設計師有用,對我們而言,太過高深了。

為了使學習組合語言有個好的開始,你必須要先排除那些華麗複雜的命令,將注意力集中在最重要的幾個指令上(cmp loop mov jnz……)。但是想在囉裡吧嗦的教科書中完成上述目標,談何容易,所以本人整理了這篇超濃縮(用winzip、winrar…依次壓迫,嘿嘿!)教程。

大言不慚的說,看通本文,你完全可以「不經意」間在前輩或是後生賣弄一下debug,很有成就感的,試試看!那麼――這個接下來呢?―― here we go!

(閱讀時看不懂不要緊,下文必有分解)

因為彙編是通過cpu和記憶體跟硬體對話的,所以我們不得不先了解一下cpu和記憶體:(關於數的進製問題在此不提)

cpu是可以執行電腦所有算術╱邏輯運算與基本 i/o 控制功能的一塊晶元。一種組合語言只能用於特定的cpu。也就是說,不同的cpu其組合語言的指令語法亦不相同。

個人電腦由2023年推出至今,其cpu發展過程為:8086→80286→80386→80486→pentium →……,還有amd、cyrix等旁支。後面相容前面cpu的功能,只不過多了些指令(如多能奔騰的mmx指令集)、增大了暫存器(如386的32位eax)、增多了暫存器(如486的fs)。

為確保匯程式設計序可以適用於各種機型,所以推薦使用8086組合語言,其相容性最佳。本文所提均為8086組合語言。暫存器(register)是cpu內部的元件,所以在暫存器之間的資料傳送非常快。

用途:1.可將暫存器內的資料執行算術及邏輯運算。

2.存於暫存器內的位址可用來指向記憶體的某個位置,即定址。3.

可以用來讀寫資料到電腦的周邊裝置。8086 有8個8位資料暫存器,這些8位暫存器可分別組成16位暫存器累加暫存器,常用於運算基址暫存器,常用於位址索引計數暫存器,常用於計數資料暫存器,常用於資料傳遞。為了運用所有的記憶體空間,8086設定了四個段暫存器,專門用來儲存段位址:

cs(code segment):**段暫存器;ds(data segment):資料段暫存器;ss(stack segment):

堆疊段暫存器;es(extra segment):附加段暫存器。當乙個程式要執行時,就要決定程式**、資料和堆疊各要用到記憶體的哪些位置,通過設定段暫存器 cs,ds,ss 來指向這些起始位置。

通常是將ds固定,而根據需要修改cs。所以,程式可以在可定址空間小於64k的情況下被寫成任意大小。 所以,程式和其資料組合起來的大小,限制在ds 所指的64k內,這就是com檔案不得大於64k的原因。

8086以記憶體做為戰場,用暫存器做為軍事基地,以加速工作。除了前面所提的暫存器外,還有一些特殊功能的暫存器:ip(intruction pointer):

指令指標暫存器,與cs配合使用,可跟蹤程式的執行過程;sp(stack pointer):堆疊指標,與ss配合使用,可指向目前的堆疊位置。bp(base pointer):

基址指標暫存器,可用作ss的乙個相對基址位置;si(source index):源變址暫存器可用來存放相對於ds段之源變址指標;di(destination index):目的變址暫存器,可用來存放相對於 es 段之目的變址指標。

還有乙個標誌暫存器fr(flag register),有九個有意義的標誌,將在下文用到時詳細說明。

記憶體是電腦運作中的關鍵部分,也是電腦在工作中儲存資訊的地方。記憶體組織有許多可存放數值的儲存位置,叫「位址」。8086位址匯流排有20位,所以cpu擁有達1m的定址空間,這也是dos的有效控制範圍,而8086能做的運算僅限於處理16位資料,即只有0到64k,所以,必須用分段定址才能控制整個記憶體位址。

完整的20位位址可分成兩部份:1.段基址(segment):

16位二進位制數後面加上四個二進位制0,即乙個16進製制0,變成20位二進位制數,可設定1m中任何乙個64k段,通常記做16位二進位制數;2.偏移量(offset):直接使用16位二進位制數,指向段基址中的任何乙個位址。

如:2222(段基址):3333(偏移量),其實際的20位位址值為:

25553。除了上述營養要充分吸收外,你還要知道什麼是dos、bios功能呼叫,簡單的說,功能呼叫類似於win95 api,相當於子程式。匯編寫程式已經夠要命了,如果不用ms、ibm的子程式,這日子真是沒法過了(關於功能呼叫詳見《電腦愛好者》98年11期)。

編寫組合語言有兩種主要的方法:1.使用masm或tasm等編譯器;2.

使用除錯程式其實並不能算是乙個編譯器,它的主要用途在於除錯,即修正匯程式設計序中的錯誤。不過,也可以用來寫短的匯程式設計序,尤其對初學者而言,debug 更是最佳的入門工具。因為debug操作容易:

只要鍵入debug回車,a回車即可進行彙編,過程簡單,而使用編譯器時,必須用到文字編輯器、編譯器本身、link以及exe2bin等程式,其中每乙個程式都必須用到一系列相當複雜的命令才能工作,而且用編譯器處理源程式,必須加入許多與指令語句無關的指示性語句,以供編譯器識別,使用 debug 可以避免一開始就碰到許多難以理解的程式行。debug 除了能夠匯程式設計序之外,還可用來檢查和修改記憶體位置、載入儲存和執行程式、以及檢查和修改暫存器,換句話說,debug是為了讓我們接觸硬體而設計的。(8086常用指令用法將在每個匯程式設計序中講解,限於篇幅,不可能將所有指令列出)。

debug的的a命令可以彙編出簡單的com檔案,所以debug編寫的程式一定要由位址 100h(com檔案要求)開始才合法。follow me,setp by setp(步步回車):

輸入 a100 ; 從ds:100開始彙編

2.輸入 mov dl,1 ; 將數值 01h 裝入 dl 暫存器

3.輸入 mov ah,2 ; 將數值 02h 裝入 dl 暫存器

4.輸入 int 21 ; 呼叫dos 21號中斷2號功能,用來逐個顯示裝入dl的字元

5.輸入 int 20 ; 呼叫dos 20號中斷,終止程式,將控制權交回給 debug

6.請按 enter 鍵

7.現在已將組合語言程式放入記憶體中了,輸入 g(執行)

8.出現結果:輸出乙個符號。

ㄖ ←輸出結果其實不是它,因word97無法顯示原結果,故找一贗品將就著。

program terminated normally

我們可以用u命令將十六進製制的機器碼反彙編(unassemble)成彙編指令。你將發現每一行右邊的彙編指令就是被彙編成相應的機器碼,而8086實際上就是以機器碼來執行程式。

1.輸入 u100,106

1fed:0100 b201 mov dl,01

1fed:0102 b402 mov ah,02

1fed:0104 cd21 int 21

1fed:0106 cd20 int 20

debug可以用r命令來檢視、改變暫存器內容。cs:ip暫存器,儲存了將執行指令位址。

1.輸入r

ax=0000 bx=0000 cx=0000 dx=0000 sp=ffee bp=0000 si=0000 di=0000

ds=1fed es=1fed ss=1fed cs=1fed ip=0100 nv up ei pl nz na po nc

1fed:0100 b201 mov dl,01

當程式由ds:100開始執行,那麼終止程式時,debug會自動將ip內容重新設定為100。當你要將此程式做成乙個獨立的可執行檔案,則可以用n命令對該程式命名。

但一定要為com檔案,否則無法以debug載入。

輸入n ;我們得告訴debug程式長度:程式從100開始到106,故占用7

;位元組。我們利用bx存放長度值高位部分,而以cx存放低位部分。

2.輸入rbx ;檢視 bx 暫存器的內容,本程式只有7個位元組,故本步可省略

3.輸入 rcx  ;檢視 cx 暫存器的內容

4.輸入 7  ;程式的位元組數

5.輸入 w ;用w命令將該程式寫入(write)磁碟中

修行至此,我們便可以真正接觸8086彙編指令了。 當我們寫組合語言程式的時候,通常不會直接將機器碼放入記憶體中,而是打入一串助記符號(mnemonic symbols),這些符號比十六進製制機器碼更容易記住,此之謂彙編指令。助記符號,告訴cpu應執行何種運算。

也就是說,助憶符號所構成的組合語言是為人設計的,而機器語言是對pc設計的。

現在,我們再來剖析乙個可以將所有ascii碼顯示出來的程式。

1. 輸入 debug

2. 輸入 a100

3.輸入 mov cx,0100 ;裝入迴圈次數

mov dl,00 ;裝入第乙個ascii碼,隨後每次迴圈裝入新碼

mov ah,02

int 21

inc dl ;inc:遞增指令,每次將資料暫存器 dl 內的數值加 1

loop 0105 ;loop:迴圈指令,每執行一次loop,cx值減1,並跳

;到迴圈的起始位址105,直到cx為0,迴圈停止

int 20

4.輸入 g即可顯示所有ascii碼

當我們想任意顯示字串,如:understand?,則可以使用dos21h號中斷9h號功能。輸入下行程式,存檔並執行看看:

1.輸入 a100

mov dx,109 ;ds:dx = 字串的起始位址

mov ah,9 ;dos的09h功能呼叫

int 21 ;字串輸出

int 20

db 'understand?$';定義字串

在組合語言中,有兩種不同的指令:1.正規指令:

如 mov 等,是屬於cpu的指令,用來告訴cpu在程式執行時應做些什麼,所以它會以運算碼(op-code)的方式存入記憶體中;2.偽指令:如db等,是屬於debug等編譯器的指令,用來告訴編譯器在編譯時應做些什麼。

db(define byte)指令用來告訴debug 將單引號內的所有ascii 碼放入記憶體中。使用 9h 功能的字串必須以$結尾。用d命令可用來檢視db偽指令將那些內容放入記憶體。

6.輸入 d100

1975:0100 ba 09 01 b4 09 cd 21 cd-20 75 6e 64 65 72 73 74underst

1975:0110 61 6e 64 24 8b 46 f8 89-45 04 8b 46 34 00 64 19 and$.f..e..

1975:0120 89 45 02 33 c0 5e 5f c9-c3 00 c8 04 00 00 57 56 .e.3wv

1975:0130 6b f8 0e 81 c7 fe 53 8b-df 8b c2 e8 32 fe 0b c0 k.....s.....2...

1975:0140 74 05 33 c0 99 eb 17 8b-45 0c e8 d4 97 8b f0 89 t.3.....e.......

1975:0150 56 fe 0b d0 74 ec 8b 45-08 03 c6 8b 56 fe 5e 5f v...t..e....v.^_

1975:0160 c9 c3 c8 02 00 00 6b d8-0e 81 c3 fe 53 89 5e fe ......k.....s.^.

1975:0170 8b c2 e8 fb fd 0b c0 75-09 8b 5e fe 8b 47 0c e8 .......u..^..g..

簡譜入門教程

簡譜入門學習 第一講音的概念 1 音的概念 第一節音的形成 首先讓我們來認識一下這看不見又摸不到的 音 倒底是什麼呢?音 是一種物理現象。它是由於物體受到振動,而產生 波 再由空氣傳到您的耳朵裡,通過大腦反饋,您聽到的就是 音 第二節音的分類 物體的大小 薄厚與振動的強弱不同,所產生音的高低也就不同...

CSS入門教程

一 css簡介 感性體驗css 什麼是css呢?你可能急迫的想知道答案。但是空泛的文字描述意義不大,讓我們先來一點感性體驗吧。看看這個沒有新增css的html檔案,是乙個普普通通的網頁。然而通過給這個檔案新增的css規則,我們可以得到十分美觀的網頁。這還不是全部,不改動html,只是通過新增不同的c...

鋼琴入門教程

鋼琴入門教程.txt我不奢望什麼,只希望你以後的女人乙個不如乙個。真懷念小時候啊,天熱的時候我也可以像男人一樣光膀子!鋼琴入門教程 第一課 一 學學坐姿星夜鋼琴教育網 首先,一開始要先學好正確的坐姿。坐的姿勢以自然,端正,有利於彈奏為原則,不要僵硬,緊張,或過於鬆懈。身體的重心要依靠臀部和腳尖支撐。...