匯編中常用寄存器介紹

X86-32位寄存器

4個數據寄存器:EAX、EBX、ECX和EDX;
2個變址和指針寄存器:ESI和EDI;
2個指針寄存器:ESP和EBP;
1個指令指針寄存器:EIP;
6個段寄存器:ES、CS、SS、DS、FS和GS;
1個標志寄存器:EFlags。
在X86-64寄存器中,所有寄存器都是64位,相對32位的x86寄存器來說,標識符發生了變化,比如從原來的ebp變成了rbp。為了保持
兼容性,32位寄存器都可以繼續使用,比如ebp寄存器,不過指向了rbp的低32位。

X86-64的64位寄存器:

16個寄存器:raX、rbx、rcX、rdX、esi、edi、rbp、rsp、r8、r9、r10、r11、r12、r13、r14、r15.
6個傳參寄存器:rdi、rsi、rdx、rcX、rB、r9.

EAX (??擴展累加器寄存器??-Extended Accumulator Register)

核心作用包括:
??算術運算??:作為乘除法(MUL/DIV)的默認操作數,存儲運算結果。例如,32位乘法結果的高32位存于EDX,低32位存于EAX。
??I/O操作??:與輸入輸出指令(如IN/OUT)綁定,傳遞端口地址和數據。
??位寬靈活性??:支持8位(AL/AH)、16位(AX)、32位(EAX)訪問,便于處理不同尺寸數據。
存儲函數返回值??:當函數執行完畢返回時,返回值默認存放在 EAX 寄存器中(32位模式下)。

例如:C 語言函數 int add() { return 10; }編譯后,MOV EAX, 10會出現在返回前。

ECX(Extended Counter Register,擴展計數寄存器)??

1.??循環計數器??
??LOOP指令依賴??:ECX 存儲循環次數,每執行一次 LOOP指令,ECX 自動減 1,直到為 0 時跳出循環。

MOV ECX, 10      ; 設置循環10次
start:; 循環體代碼LOOP start   ; ECX -= 1,若 ECX ≠ 0 則跳回 start

2.字符串/數據塊操作?
搭配 REP(Repeat Prefix)指令前綴處理重復操作:

??REP MOVSB??:復制字節串(源地址 ESI→ 目標地址 EDI,次數=ECX)。
??REP STOSB??:將 AL的值填充到 EDI指向的內存(長度=ECX)。

MOV ESI, source_addr ; 源地址
MOV EDI, dest_addr   ; 目標地址
MOV ECX, 100         ; 復制 100 字節
REP MOVSB            ; 按字節循環復制

在 ??x86 架構??下調用實例方法時,??ECX 默認存儲當前對象的引用(this)??
在C++類的成員函數中都掩藏一個保存當前C++對象地址的this指針,成員函數中訪問所屬C++對象的成員變量時,都是通過ths指針
問對應C++對象的成員變量的。
在C++匯編代碼中,在調用C+成員函數時會使用ECX寄存器用來傳遞C++對象地址,即C++對象中的this指針。
下面是C#例子

public class MyClass {public void MyMethod() { }
}
// 編譯后調用過程(偽匯編):
MOV ECX, objAddress  // ECX = 對象地址
CALL MyClass.MyMethod

x64過渡??:
現代 .NET 程序多為 64 位,參數傳遞主要通過 ??RCX/RDX/R8/R9??,ECX 已較少出現。

??ESI(Source Index)?? 和 ??EDI(Destination Index)ESI??

??源地址指針?? ,指向需要讀取的內存數據起始地址(如字符串、數組、緩沖區),指令LODSB, MOVS, REP MOVSB。
EDI??

MOV ESI, source_addr  ; 源地址 → ESI
MOV EDI, dest_addr    ; 目標地址 → EDI
MOV ECX, 100          ; 復制 100 字節 → ECX
REP MOVSB             ; 按字節循環復制

??目標地址指針??,指向需要寫入的內存數據起始地址(如復制、填充操作的目標位置),指令STOSB, MOVS, REP STOSB

MOV EDI, buffer_addr  ; 待掃描內存 → EDI
MOV AL, 'A'           ; 目標字符 'A' → AL
MOV ECX, 50           ; 掃描 50 字節
REPNE SCASB           ; 掃描直到找到 'A' 或 ECX=0

這兩個是變址寄存器,ESl是源地址寄存器,ED1是目的地址寄存器,主要用于內存拷貝的串操作指令中,比如memcpy的匯編實現
中。它們也可以作為通用寄存器來使用。
在 C# 中的底層表現??:
??1.內存復制??(如 Buffer.BlockCopy())
若運行在 x86 環境,JIT 編譯器可能生成 REP MOVSD指令(效率遠超逐字節復制)。
2.字符串操作??(如 string.Concat())
內部可能用 EDI指向新字符串內存,ESI指向原字符串,批量復制數據。

3.??不安全代碼??(unsafe塊)
固定指針操作時,fixed語句可能觸發 ESI/EDI 的寄存器分配:

unsafe {fixed (byte* src = sourceArray, dest = targetArray) {// JIT 可能將 src → ESI, dest → EDIfor (int i = 0; i < count; i++) dest[i] = src[i]; // 可能被優化為 MOVSB 指令}
}

ESI/EDI 的核心價值??:
1.??高效內存操作??:硬件支持自動索引,大幅減少循環指令開銷。
2.??數據流處理??:在字符串、數組操作中顯著提升性能(尤其在舊 x86 架構中)。

??ESP(Stack Pointer)?? 和 ??EBP(Base Pointer)

這兩者是??管理函數調用棧的核心寄存器??,直接關聯函數的執行流程、參數傳遞、局部變量存儲等關鍵操作。
函數調用時,操作系統通過??棧(Stack)?? 管理臨時數據:

  1. ??調用函數時??:參數、返回地址壓入棧。
  2. ??函數執行時??:在棧上分配局部變量,保存寄存器狀態。
  3. ??函數返回時??:清理棧數據,恢復原始狀態。
    ESP 和 EBP 正是協調這一過程的核心寄存器。

ESP(Stack Pointer)的核心作用??

? 指向棧頂的實時位置??(32位模式中為32位地址),相當于棧的“讀寫指針”。
**壓棧(PUSH)**??:ESP??自動減 4??(因為棧從高地址向低地址增長),寫入數據。

PUSH EAX        ; 等效于: SUB ESP, 4 + MOV [ESP], EAX

彈棧(POP)??:ESP??自動加 4??,讀出數據。

POP EBX         ; 等效于: MOV EBX, [ESP] + ADD ESP, 4

動態響應操作??:

?操作??ESP 變化地址變化
PUSH regESP -= 4棧頂向低地址移動
POP regESP += 4棧頂向高地址回退
CALL funcESP -= 4存入返回地址
RETESP += 4清理返回地址

EBP(Base Pointer)的核心作用??

指向當前棧幀的基地址??(固定位置),是棧內存的“錨點”,用于??定位參數和局部變量??。
棧幀(Stack Frame)結構??:
在這里插入圖片描述函數調用棧分布

; 函數入口(Prologue)
PUSH EBP         ; 保存調用者的EBP
MOV EBP, ESP     ; 新棧幀起點 = 當前ESP
SUB ESP, 8       ; 分配8字節局部變量空間(ESP移動); 訪問參數和局部變量:
MOV EAX, [EBP + 8]   ; 獲取第一個參數
MOV [EBP - 4], EAX   ; 寫入第一個局部變量; 函數出口(Epilogue)
MOV ESP, EBP     ; 釋放局部變量(ESP回退)
POP EBP          ; 恢復調用者的EBP
RET              ; 返回到調用者

 ??ESP vs EBP 核心差異??
在 C# 中的體現??:
1.??棧幀自動管理??:

C# 函數中的??參數和局部變量??在編譯后由 CLR 自動通過 ESP/EBP(或 x64 中的 RSP/RBP)管理:

void Calculate(int x) {int a = x * 2;  // 局部變量 a 在棧上分配(EBP - N)Console.WriteLine(a);
}

2.??調試觀察??:

在 Visual Studio 中:
啟用 ??Debug → Windows → Registers?? 查看 ESP/EBP。
使用 ??Debug → Windows → Disassembly?? 觀察棧幀操作指令(如 MOV EBP, ESP)。
3.??不安全代碼中的直接操作??:
在 unsafe塊中可通過指針間接操作棧地址(但需謹慎!):

unsafe {int val = 10;int* p = &val;  // p 實際指向棧內存地址(EBP - 偏移)
}

EIP(Extended Instruction Pointer,擴展指令指針寄存器)

EIP寄存器是用來存放即將要執行的匯編指令地址的。這里講的匯編地址,是代碼段的地址,和我們平時說的變量占用的內存(數據
段地址)是兩個概念,要注意區分一下,不要混淆。
當CPU從EIP寄存器中將匯編指令地址載入到CPU中時,EIP寄存器中的地址會自動累加,累加的值正好就是被取走的那條匯編指令
的長度,這樣EP寄存器中的地址就是即將要執行的下一條匯編指令的地址了。
程序流程控制??:
存儲當前或下一條指令的內存地址(32位模式),CPU 按 EIP 指向的位置取指令執行
??自動遞增??:
每條指令執行后,EIP ??自動增加??字節長度(如 MOV EAX, 1占用 5 字節 → EIP+=5)
??跳轉機制:??
JMP、CALL、RET、中斷等指令會??主動修改 EIP??,改變程序流向
??只讀性:??
??普通指令無法直接修改 EIP??(如 MOV EIP, 0x1234是非法的),必須通過控制流指令間接修改

關鍵應用場景??

  1. ??函數調用與返回(核心流程)??
    1.調用函數時(CALL)??:
    當前 EIP(即返回地址)??被壓入棧??(ESP -= 4 → [ESP] = EIP)。
    EIP被修改為??目標函數的入口地址??,跳轉執行。
CALL 0x400000      ; 壓入返回地址 → 更新 EIP=0x400000

??函數返回時(RET)??:
從棧頂彈出返回地址到 EIP,恢復原流程:

RET               ; POP EIP → 恢復調用點下一條指令地址

2.??條件分支與跳轉??
??條件跳轉??(如 JE/ JNE): 根據標志位(ZF)判斷是否修改 EIP:

CMP EAX, 10       ; 比較 EAX 與 10
JE  label_equal   ; 若相等,則 EIP = label_equal 的地址

無條件跳轉??(JMP):強制修改 EIP 至目標地址:

JMP 0x5000  ; EIP = 0x5000
  1. ??中斷與異常處理??
    發生中斷/異常時:
    1.當前 EIP??自動壓棧保存??(進入內核態)。
    2.EIP被設置為??中斷處理程序的入口地址??(從 IDT 表中查詢)。
    3.處理完成后,通過 IRET指令恢復原 EIP繼續執行。

??在 C# 中的體現
??1.調試與反編譯??:
在 Visual Studio 調試器中:
寄存器窗口顯示 ??EIP/RIP??,指向當前執行的指令地址。
調用棧(Call Stack)本質是??連續壓入棧的 EIP 序列??。
反匯編窗口(Debug → Windows → Disassembly)顯示的指令地址即 EIP的實時指向。
2.??不安全代碼行為??
在 unsafe塊中,指針操作錯誤可能導致 EIP 被意外篡改(需開啟安全編譯選項防御):

unsafe {int* ptr = ...;void* target = ptr + 10;// 錯誤操作可能使函數返回地址被覆蓋
}

段寄存器(Segment Registers)

常用的段寄存器有CS、SS、DS、ES、FS和GS 。
?CS??:??Code Segment??,代碼段:定義當前執行的指令所在內存區域(EIP 從該段中取值)。
??DS??:??Data Segment??;數據段:默認的變量讀寫、內存操作區域。
??SS??:Stack Segment??;棧段:存放函數調用棧(ESP/EBP 在此段內工作)。
??ES??:??Extra Segment??;附加數據段:通常用于字符串操作中的??目標地址??(如 REP MOVSB中的 EDI)。
??FS??;??Extra Segment2??;額外段:??操作系統專用??(如 Windows 存??線程信息塊 TIB??,Linux 存??線程局部存儲 TLS??)。
??GS??:??Extra Segment 3??;額外段:用途與 FS 類似(64位系統中更常用)。

標志寄存器(FLAGS / EFLAGS / RFLAGS)

存儲 ??CPU 狀態和控制位??的核心寄存器,直接影響程序執行流程、邏輯判斷和系統行為。其每一位都表示特定的狀態或控制開關(如運算是否溢出、是否允許中斷)
在這里插入圖片描述
16位FLAGS??-16位基礎狀態標志(CF/PF/AF/ZF/SF/TF/IF/DF/OF)
32位??EFLAGS??-32位新增系統標志(如 IOPL、NT、ID)
64位??RFLAGS??-64位高32位保留未使用,僅低32位有效
在這里插入圖片描述MOV AL, 0xFF ; AL = 255 (無符號) 或 -1 (有符號) ADD AL, 0x01 ; 結果 = 0x00 (256 或 0)

    ??CF=1??(無符號加法溢出:255+1=256 > 255)??ZF=1??(結果為0)??SF=0??(最高位0)??OF=0??(有符號運算無溢出:-1+1=0,結果正確)

控制標志位

標志寄存器的關鍵作用??

  1. ??條件跳轉(Jcc指令依賴標志位)??
CMP EAX, 100     ; 比較 EAX-100,自動設置 ZF/CF/OF/SF
JZ  equal_label  ; 若 ZF=1(EAX=100)則跳轉
JG  above_label  ; 若 ZF=0 AND SF=OF(有符號 EAX>100)則跳轉
  1. 系統行為控制??
    ??關中斷保護關鍵代碼??:
CLI              ; 禁止中斷(IF=0)
MOV [CriticalData], EAX  ; 安全更新共享數據
STI              ; 恢復中斷(IF=1

高效字符串操作??:

CLD              ; DF=0(正向操作)
MOV ESI, src_addr
MOV EDI, dst_addr
REP MOVSB         ; 從 ESI→EDI 按字節復制(地址自動遞增)
  1. ??程序調試??

    調試器設置 ??TF=1??,每步觸發 ??INT 1?? 中斷 → 執行觀察/記錄。
    通過 ??Trap Flag?? 實現源碼級單步跟蹤。
    ??在 C# 中的觀察??
    ??1.條件分支編譯結果?

if (value > 100) { ... } 
// 編譯為:CMP + JG(依賴 ZF/SF/OF)

2.不安全代碼的溢出檢查?

checked { int x = int.MaxValue + 1; // 溢出觸發 OverflowException(CPU 檢測到 OF=1)
}

??3.調試中查看標志??
在 Visual Studio 調試器(反匯編窗口)的寄存器視圖中可查看 ??EFLAGS?? 各標志位。

參考文章:

分析C++軟件異常需要掌握的匯編知識匯總

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/92689.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/92689.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/92689.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SOMGAN:用自組織映射改善GAN的模式探索能力

論文信息 論文題目:Improving mode exploring capability ofgenerative adversarial nets by self-organizing map(利用自組織映射提高生成對抗網絡的模式探索能力) 期刊:Neurocomputing 摘要:生成對抗網絡(GANs)的出現將生成模型的研究推向了一個新的高潮。支持這一進步…

《匯編語言:基于X86處理器》第12章 復習題和練習

本篇記錄了《匯編語言&#xff1a;基于X86處理器》第12章 復習題和練習的筆記。12.6復習題和練習12.6.1 簡答題1.假設有二進制浮點數1101.01101&#xff0c;如何將其表示為十進制分數之和?答&#xff1a;1101.01101(1x)(1x)(0x)(1x)(0x)(1x)(1x)(1x)(1x) 13.406252.為什么十進…

ApacheCon Asia 2025 中國開源年度報告:Apache Doris 國內第一

上周剛落下帷幕的 ApacheCon Asia 2025 中&#xff0c;一個數據讓所有人都為之震撼&#xff1a;全球 Apache 基金會項目 OpenRank 排行榜中&#xff0c;Apache Doris 位居第二&#xff0c;在中國 Apache 項目中更是穩居第一。 這個排名意味著什么&#xff1f;在 Apache 基金會管…

Pytest中實現自動生成測試用例腳本代碼

&#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快在Python的測試框架中&#xff0c;我們通常會針對某個系統進行測試用例的維護&#xff0c;在對龐大系統進行用例維護時&#xff0c;往往會發現很多測試用例是差不多…

一周學會Matplotlib3 Python 數據可視化-標注 (Annotations)

鋒哥原創的Matplotlib3 Python數據可視化視頻教程&#xff1a; 2026版 Matplotlib3 Python 數據可視化 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 課程介紹 本課程講解利用python進行數據可視化 科研繪圖-Matplotlib&#xff0c;學習Matplotlib圖形參數基本設置&…

安全合規1--實驗:ARP欺騙、mac洪水攻擊、ICMP攻擊、TCP SYN Flood攻擊

一、實驗環境 (思科的云實驗平臺)攻擊機&#xff1a;Kali Linux&#xff08;IP&#xff1a;192.168.234.128&#xff0c;MAC&#xff1a;00:00:29:35:64:EC&#xff09;目標1&#xff1a;網關&#xff08;IP&#xff1a;192.168.234.2&#xff0c;MAC&#xff1a;00:50:56:ED:D…

Linux下GCC的C++實現Hive到Snowflake數據遷移

程序結構 ├── main.cpp ├── config.json ├── hive_export/ ├── parquet_data/ ├── sql_scripts/ └── logs/核心代碼實現 (main.cpp) #include <iostream> #include <fstream> #include <vector> #include <thread> #include <mut…

drippingblues靶機教程

一、信息搜集首先將其在VirtualBOX中安裝&#xff0c;并將kali與靶機都設置為橋接模式緊接著我們掃描IP&#xff0c;來發現靶機地址&#xff0c;經過搜集&#xff0c;發現IP是192.168.1.9&#xff0c;我們去訪問一下緊接著我們掃一下開放了哪些端口。發現開放了21、22以及80端口…

39.【.NET8 實戰--孢子記賬--從單體到微服務--轉向微服務】--擴展功能--調整發布腳本

這篇文章&#xff0c;我們要調整發布腳本。之所以要調整發布腳本&#xff0c;是因為現在我們的項目有三個環境&#xff1a;本地&#xff08;Local&#xff09;、開發&#xff08;Development&#xff09;、生產&#xff08;Production&#xff09;。Tip&#xff1a;我們的項目雖…

商品、股指及ETF期權五檔盤口Tick級與分鐘級歷史行情數據多維解析

在金融數據分析領域&#xff0c;本地CSV文件是存儲高頻與低頻數據的常用載體。本文以期權市場數據為例&#xff0c;探討如何基于CSV格式處理分鐘級行情、高頻Tick數據、日頻數據、逐筆委托記錄、五檔訂單簿及歷史行情數據&#xff0c;并提供專業的技術實現方案。以下將從數據預…

云端軟件工程智能代理:任務委托與自動化實踐全解

云端軟件工程智能代理&#xff1a;任務委托與自動化實踐全解 背景與未來趨勢 隨著軟件工程復雜度不斷提升&#xff0c;開發者對自動化工具的依賴也日益增強。我們正進入一個“人機協作”的新時代&#xff0c;開發者可以專注于核心創新&#xff0c;將重復性、繁瑣的任務委托給智…

making stb style lib(1): do color print in console

col.h: see origin repo // origin repo: https://github.com/resyfer/libcol #ifndef _COL_HOL_H_ #define _COL_HOL_H_#include <stdlib.h> #include <stdio.h> #include <stdbool.h> #include <string.h> #include <math.h> // 新增&#xf…

llm本地部署+web訪問+交互

要實現基于llm的web訪問和交互&#xff0c;需支持對llm的訪問和對網絡搜索的調用。 這里使用ollama llm兼容openai sdk訪問&#xff1b;使用proxyless-llm-websearch模擬網絡搜索。 1 ollama本地部署 假設ollama已經部署&#xff0c;具體過程參考 在mac m1基于ollama運行dee…

自動駕駛數據閉環

自動駕駛的數據閉環是支撐算法持續迭代的核心機制&#xff0c;其本質是通過“數據采集-處理-訓練-部署-反饋”的循環&#xff0c;不斷優化模型對復雜場景的適應性。由于自動駕駛數據量極大&#xff08;單車日均TB級&#xff09;、場景多樣&#xff08;從常規道路到極端邊緣場景…

二十、MySQL-DQL-條件查詢

DQL-條件查詢代碼&#xff1a; DQL-條件查詢 -- 1.查詢 姓名 為 楊逍 的員工 select * from tb_emp where name 楊逍; -- 2.查詢 id小于等于5 的員工信息 select * from tb_emp where id < 5; -- 3.查詢 沒有分配職位 的員工信息 select * from tb_emp where job is null; …

Mac下安裝Conda虛擬環境管理器

Conda 是一個開源的包、環境管理器&#xff0c;可以用于在同一個機器上創建不同的虛擬環境&#xff0c;安裝不同Python 版本的軟件包及其依賴&#xff0c;并能夠在不同的虛擬環境之間切換 Conda常通過安裝Anaconda/Miniconda來進行使用。一般使用Miniconda就夠了。Miniconda 是…

Android 中解決 Button 按鈕背景色設置無效的問題

1、問題描述 在布局文件中有兩個 Button 按鈕&#xff0c;為每個按鈕設置不同的背景色&#xff0c;但是顯示出來的效果都是紫色的&#xff0c;跟設置的顏色不同&#xff0c;布局文件如下所示&#xff1a;<Buttonandroid:id"id/button_cancel"android:layout_width…

云服務器--阿里云OSS(2)【Springboot使用阿里云OSS】

&#x1f4d2; 阿里云 OSS Spring Boot 異步任務&#xff08;直接存 OSS&#xff09; 1. 項目結構 src/main/java/com/example/demo├── controller│ └── UploadController.java // 接收上傳請求├── service│ ├── AsyncUploadService.java // 異步上傳…

get請求中文字符參數亂碼問題

第一種方法 服務器默認的傳參編碼格式是ISO8859-1,所以前端直接原樣字符串請求&#xff0c;到后端解析一下就得到正確字符 String fileName request.getParameter("fileName"); fileName new String(fileName.getBytes("ISO8859-1"),"UTF-8");…

C語言(10)——結構體、聯合體、枚舉

關于C語言零基礎學習知識&#xff0c;小編有話說&#xff0c;各位看官敬請入下面的專欄世界&#xff1a;打怪升級之路——C語言之路_ankleless的博客-CSDN博客 Hi&#xff01;冒險者&#x1f60e;&#xff0c;歡迎闖入 C 語言的奇幻異世界&#x1f30c;&#xff01; 我是 Ankle…