組合語言和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)
組合語言和cpu以及記憶體,埠等硬體知識是連在一起的.這也是為什麼組合語言沒有通用性的原因.下面簡單講講基本知識 針對intel x86及其相容機 x86組合語言的指令,其操作物件是cpu上的暫存器,系統記憶體,或者立即數.有些指令表面上沒有運算元,或者看上去缺少運算元,其實該指令有內定的操作物件,...
組合語言 AT T組合語言
這兩天的pwn題環境都是在linux中,採用的組合語言是 at t 格式。之前學習的是intel格式的8086彙編,今天學習了下at t組合語言。基於x86 架構的處理器所使用的彙編指令一般有兩種格式 操作intel格式at t格式 暫存器命名 push eax pushl eax 常數 立即運算元...
組合語言 a 基礎知識
本專題是學習王爽的 組合語言 第三版 的學習筆記。這本書按照作者的意思是要教會讀者怎樣去循序漸進地學習組合語言。首先,什麼是組合語言呢?組合語言是人和計算機溝通的最直接方式,它描述了機器最終所要執行的指令序列。作為一門底層的語言,其可以直接與計算機進行互動。注意此書中如果沒有能夠完成檢測點的內容,則...