組合語言(Assembly Language)是介於機器語言與高階語言之間的程式設計語言。主要針對處理器的架構設計,因此不同的處理器可能會有不同的指令集,這使得組合語言具有高度的硬體相關性。
低階語言:組合語言使用助憶符號來表示機器指令,這些符號與處理器的指令集直接對應,讓程式設計者能夠控制每一個指令的執行。
高效能:由於組合語言直接操作硬體資源(如寄存器、記憶體),其效能比高階語言更高,特別是在嵌入式系統、驅動程式或對效能有極高要求的場景中,組合語言的應用十分廣泛。
精確控制:程式設計者能夠完全掌控程式的執行流程、記憶體配置和處理器資源的使用,這使得組合語言在進行低階系統開發時具有極大的靈活性。
難度高:由於組合語言相較於高階語言更接近機器指令,程式設計者需要更高的專業知識。debug 困難且容易出現與硬體相關的問題。
暫存器(Register)是處理器內部的一種高速存儲單元,用於暫時儲存數據或指令,存取速度極快,遠高於主記憶體(RAM)。在組合語言的程式設計中,暫存器是至關重要的資源,因為它們是 CPU 進行各種運算的核心部分。處理器在執行指令時,會將數據載入暫存器中進行運算,這比直接操作記憶體更有效率。
通用暫存器(General-Purpose Registers, GPRs):這類暫存器可用於存放任何類型的數據,處理器在進行算術、邏輯或數據搬移操作時,都會使用到這些暫存器。例如,x86架構中的 AX、BX、CX 和 DX 是常見的通用暫存器。
特殊用途暫存器:
指令指標暫存器(Instruction Pointer, IP 或 PC):儲存當前正在執行的指令地址,處理器根據指令指標的值來決定下一條指令的位置。它在每次執行完一條指令後自動更新,用以指向下一條即將執行的指令。
堆疊指標暫存器(Stack Pointer, SP):用於指向堆疊的頂部。堆疊是一種特殊的數據結構,暫存器 SP 用於管理函數調用和返回地址。在進行函數調用或中斷處理時,堆疊指標用來儲存上下文資訊,確保正確性。
狀態暫存器/標誌暫存器(Status/Flag Register):此暫存器保存操作的結果標誌(flags),例如運算是否發生進位、是否為零等。這些標誌用於控制後續的程式流程。Zero Flag、Carry Flag、Overflow Flag 等。
將資料從記憶體載入到暫存器,或者從一個暫存器移到另一個暫存器。在 x86 組合語言中:
MOV AX, [1000h] ; 將記憶體地址 1000h 的數據搬移到 AX 暫存器
MOV BX, AX ; 將 AX 中的數據搬移到 BX
暫存器中的數據進行算術運算。例如:
ADD AX, BX ; 將 AX 和 BX 中的數值相加,結果保存在 AX 中
今天的練習都是有關組合語言的題目
Lab_1 - Bit-O-Asm-1
先來看看題目給的組合語言裡面都寫了些什麼。題幹寫說 flag 會儲存在 eax
裡面,那 <+15>
正好在做把 0x30
放進 eax
暫存器的動作。
<+0>: endbr64
<+4>: push rbp
<+5>: mov rbp,rsp
<+8>: mov DWORD PTR [rbp-0x4],edi
<+11>: mov QWORD PTR [rbp-0x10],rsi
<+15>: mov eax,0x30
<+20>: pop rbp
<+21>: ret
把 0x30
拿去線上的進制轉換工具,將 16 進位 轉換成 10 進位,30 -> 48,用 picoCTF{} 包起來就是我們的 flag 惹。
Lab_2 - Bit-O-Asm-2
題目寫說 flag 會儲存在 eax
裡面,那這題多了一次轉換,先把 0x9fe1a
存入 rbp-0x4
的位置,再將 rbp-0x4
的值加載到 eax
暫存器中。因此 eax
的值也就是 0x9fe1a
。
<+0>: endbr64
<+4>: push rbp
<+5>: mov rbp,rsp
<+8>: mov DWORD PTR [rbp-0x14],edi
<+11>: mov QWORD PTR [rbp-0x20],rsi
<+15>: mov DWORD PTR [rbp-0x4],0x9fe1a
<+22>: mov eax,DWORD PTR [rbp-0x4]
<+25>: pop rbp
<+26>: ret
一樣把 0x9fe1a
拿去線上的進制轉換工具,將 16 進位 轉換成 10 進位,9fe1a -> 654874,用 picoCTF{} 包起來就是我們的 flag 惹。
今天的練習就到這邊,以下是參考資料,請搭配服用:
內文如有錯誤,還請不吝指教~