彙編的基礎知識 1

2021-04-13 07:28:51 字數 2694 閱讀 9932

組合語言和cpu以及記憶體,埠等硬體知識是連在一起的. 這也是為什麼組合語言沒有通用性的原因. 下面簡單講講基本知識(針對intel x86及其相容機)

*************************===

x86組合語言的指令,其操作物件是cpu上的暫存器,系統記憶體,或者立即數. 有些指令表面上沒有運算元, 或者看上去缺少運算元, 其實該指令有內定的操作物件, 比如push指令, 一定是對ss:esp指定的記憶體操作, 而cdq的操作物件一定是eax / edx.

在組合語言中,暫存器用名字來訪問. cpu 暫存器有好幾類, 分別有不同的用處:

1. 通用暫存器:

eax,ebx,ecx,edx,esi,edi,ebp,esp(這個雖然通用,但很少被用做除了堆疊指標外的用途)

這些32位可以被用作多種用途,但每乙個都有"專長". eax 是"累加器"(accumulator), 它是很多加法乘法指令的預設暫存器. ebx 是"基位址"(base)暫存器, 在記憶體定址時存放基位址. ecx 是計數器(counter), 是重複(rep)字首指令和loop指令的內定計數器. edx是...(忘了..哈哈)但它總是被用來放整數除法產生的餘數. 這4個暫存器的低16位可以被單獨訪問,分別用ax,bx,cx和dx. ax又可以單獨訪問低8位(al)和高8位(ah), bx,cx,dx也類似. 函式的返回值經常被放在eax中.

esi/edi分別叫做"源/目標索引暫存器"(source/destination index),因為在很多字串操作指令中, ds:esi指向源串,而es:edi指向目標串.

ebp是"基址指標"(base pointer), 它最經常被用作高階語言函式呼叫的"框架指標"(frame pointer). 在破解的時候,經常可以看見乙個標準的函式起始**:

push ebp ;儲存當前ebp

mov ebp,esp ;ebp設為當前堆疊指標

sub esp, *** ;預留***位元組給函式臨時變數.

...

這樣一來,ebp 構成了該函式的乙個框架, 在ebp上方分別是原來的ebp, 返回位址和引數. ebp下方則是臨時變數. 函式返回時作 mov esp,ebp/pop ebp/ret 即可.

esp 專門用作堆疊指標.

2. 段暫存器:

cs(code segment,**段) 指定當前執行的**段. eip (instruction pointer, 指令指標)則指向該段中乙個具體的指令. cs:eip指向哪個指令, cpu 就執行它. 一般只能用jmp, ret, jnz, call 等指令來改變程式流程,而不能直接對它們賦值.

ds(data segment, 資料段) 指定乙個資料段. 注意:在當前的計算機系統中, **和資料沒有本質差別, 都是一串二進位制數, 區別只在於你如何用它. 例如, cs 制定的段總是被用作**, 一般不能通過cs指定的位址去修改該段. 然而,你可以為同乙個段申請乙個資料段描述符"別名"而通過ds來訪問/修改. 自修改**的程式常如此做.

es,fs,gs 是輔助的段暫存器, 指定附加的資料段.

ss(stack segment)指定當前堆疊段. esp 則指出該段中當前的堆疊頂. 所有push/pop 系列指令都只對ss:esp指出的位址進行操作.

3. 標誌暫存器(eflags):

該暫存器有32位,組合了各個系統標誌. eflags一般不作為整體訪問, 而只對單一的標誌位感興趣. 常用的標誌有:

進製標誌c(carry), 在加法產生進製或減法有借位時置1, 否則為0.

零標誌z(zero), 若運算結果為0則置1, 否則為0

符號位s(sign), 若運算結果的最高位置1, 則該位也置1.

溢位標誌o(overflow), 若(帶符號)運算結果超出可表示範圍, 則置1.

jxx 系列指令就是根據這些標誌來決定是否要跳轉, 從而實現條件分枝. 要注意,很多jxx 指令是等價的, 對應相同的機器碼. 例如, je 和jz 是一樣的,都是當z=1是跳轉. 只有jmp 是無條件跳轉. jxx 指令分為兩組, 分別用於無符號操作和帶符號操作. jxx 後面的"xx" 有如下字母:

無符號操作: 帶符號操作:

a = "above", 表示"高於" g = "greater", 表示"大於"

b = "below", 表示"低於" l = "less", 表示"小於"

c = "carry", 表示"進製"或"借位" o = "overflow", 表示"溢位"

s = "sign", 表示"負"

通用符號:

e = "equal" 表示"等於", 等價於z (zero)

n = "not" 表示"非", 即標誌沒有置位. 如jnz "如果z沒有置位則跳轉"

z = "zero", 與e同.

如果仔細想一想,就會發現 ja = jnbe, jae = jnb, jbe = jna, jg = jnle, jge= jnl, jl= jnge, ....

4. 埠

埠是直接和外部裝置通訊的地方。外設接入系統後,系統就會把外設的資料介面對映到特定的埠位址空間,這樣,從該埠讀入資料就是從外設讀入資料,而向 外設寫入資料就是向埠寫入資料。當然這一切都必須遵循外設的工作方式。埠的位址空間與記憶體位址空間無關,系統總共提供對64k個8位埠的訪問,編號 0-65535. 相鄰的8位埠可以組成成乙個16位埠,相鄰的16位埠可以組成乙個32位埠。埠輸入輸出由指令in,out,ins和outs實現,具體可參考 組合語言書籍。 

彙編學習1 基礎知識

機器語言 01構成,計算機能識別。0101000 push ax 組合語言的主體是彙編指令。彙編指令和機器指令的差別在於指令的表示方法上,彙編指令是機器指令便於記憶的書寫格式,是機器指令的助記符,與機器指令一一對應。每一種cpu都有自己的彙編指令集。機器指令 1000 1001 1101 1000 ...

彙編基礎知識

最近感覺自己學的到了乙個瓶頸,學的不知道有多少是記住的,總是感覺自己要學的東西有那麼多,時間又太少。專業課也越來越多,花在程式設計上的時間就少了,但是這畢竟是我的興趣愛好,所以我不想放棄。昨晚突然有個想法,以後寫部落格的頻率加快,儘管這樣部落格的質量也就下降了很多,但是我還是覺得部落格就是來記錄我成...

彙編 基礎知識

一 進製數的表示 十進位制後加d,二進位制後加b,八進位制加o,十六進製制加h 二 十進位制數轉換為二進位制數或十六進製制數 使用除2取餘法或使用除16取餘法,結果向上讀,如4,得餘數0 0 1,則相應二進位制為100,十六進製制數類似 三 二進位制數或十六進製制數轉換為十進位制數 使用權的展開式 ...