首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

組合語言學習指南(三):流程控制、呼叫慣例與字串指令詳解

     編輯:組合語言

前言:面向機器碼與反組譯的指令深度剖析

組合器(MASM、TASM)提供高級特性,但真正的組合語言優勢在於精確控制硬體。本文聚焦機器指令層面,解析 JMP、CALL、INT、LDS/LES 及字串操作指令,為閱讀反組譯碼打下堅實基礎。

無條件跳轉:JMP 的三種形態

  • 短跳轉:目標位址與目前位址差距 ≤ 128 位元組
  • 近跳轉:同一代碼段內(CS 不變,僅修改 EIP)
  • 遠跳轉:跨代碼段(CS:EIP 皆變),32 位元保護模式下極少見

組合器自動依距離選擇編碼。支援直接/間接定址:


jmp 8E347D60          ; 直接段內跳轉
jmp ebx               ; 暫存器間接,僅段內
jmp dword ptr [ebx]   ; 記憶體間接段內跳轉
jmp fword ptr [00903DF0] ; 記憶體間接段間跳轉 (48 位完整位址)

DWORD PTR 取 32 位偏移,FWORD PTR 取 48 位完整位址(選擇子:偏移)。

條件跳轉:Jcc

僅支援段內直接定址,依旗標(ZF、CF、SF、OF 等)決定是否跳轉。

子程式呼叫:CALL 與 RET

CALL 跳轉前將下一指令位址壓入堆疊。段內呼叫壓 32 位偏移,段間呼叫壓 48 位完整位址。對應返回指令:

  • RETN:段內返回,彈出 32 位
  • RETF:段間返回,彈出 48 位

RETN n/RETF n 可攜帶立即數,返回後自動調整 ESP 清除參數(以字為單位,ESP += n*2)。

關鍵洞察:CALL/RET 設計為配對使用,但無硬性綁定。可手動 PUSH 位址後 RET 實現非常規流程轉移,常用於反除錯。

中斷指令:INT n 與 IRET

保護模式下 INT n 必被作業系統攔截。執行流程:

  1. 壓入 EFLAGS
  2. 壓入下一指令完整位址 (CS:EIP)
  3. 查中斷描述符表 (IDT) 轉入中斷服務程式 (ISR)

ISR 通常涉及特權級轉換、堆疊切換。IRET 執行逆向操作:彈出 CS:EIP、彈出 EFLAGS(可能已被 ISR 修改,如 CF 表示成功與否)。同樣,IRET 可獨立用於任務切換。

載入完整指標:LDS/LES/LFS/LGS/LSS

從記憶體讀取 48 位完整指標(偏移在前,選擇子在後),將選擇子載入段暫存器,偏移載入指定通用暫存器。例如 LDS ESI, [addr] 將 DS 載入選擇子,ESI 載入偏移,後續可用 DS:[ESI] 存取資料。

字串操作指令家族

硬體規定隱含運算元:

  • 來源:DS:[ESI]
  • 目的:ES:[EDI]
  • 暫存:AL/AX/EAX

使用前必須正確設定 ESI、EDI、段暫存器。每指令有三種寬度:B(位元組)、W(字)、D(雙字)。

執行後 ESI/EDI 自動增減(依方向旗標 DF),寬度分別為 1/2/4。

重複前綴 REP 與 LOOP 迴圈

硬體規定 ECX 為計數器。

  • REP MOVSD:ECX 次移動雙字,每次 ECX-- 直到為 0
  • LOOP label:ECX--,非零則跳轉

條件變體:REPZ/REPNZ、LOOPZ/LOOPNZ 額外檢查 ZF。


; 複製 200 個雙字
lds esi, src_ptr
les edi, dst_ptr
mov ecx, 200
rep movsd

; 處理 100 個字
lds esi, src_ptr
mov ecx, 100
loop1:
  lodsw
  ; 處理 AX
  loop loop1

總結

掌握流程控制指令的定址模式、呼叫/返回的堆疊行為、中斷機制與字串指令的隱含運算元,是讀懂反組譯碼、編寫高效組合程式的關鍵。這些指令直映射 CPU 微架構,理解其運作細節,方能駕輕就熟。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
指令功能旗標影響
CMPSB/W/D比較來源/目的字串ZF=1 若相等
SCASB/W/D掃描:AL/AX/EAX 與目的比較ZF
LODSB/W/D載入:來源 → AL/AX/EAX無
STOSB/W/D存放:AL/AX/EAX → 目的無
MOVSB/W/D移動:來源 → 目的無
INSB/W/D從埠 (DX) 讀入目的字串無
OUTSB/W/D來源字串輸出至埠 (DX)無