從匯編的角度揭開C++ this指針的神秘面紗(上)

C++中的this指針一直比較神秘。任何類的對象,都有一個this指針,無處不在。那么this指針的本質究竟是什么?this指針什么時候會被用到?今天通過幾段簡單的代碼,來揭秘一下。

要先揭秘this指針,先來說一下函數調用時參數的傳遞過程。考慮以下代碼:

int sum(int i, int j, int k)
{return i + j + k;
}int main()
{int a, b, c;a = 1;b = 2;c = 3; sum(a,b,c);return 0;
}

這是一段非常簡單的函數調用代碼。我們生成其匯編代碼(x86-64),如下所示:

sum(int, int, int):pushq   %rbpmovq    %rsp, %rbpmovl    %edi, -4(%rbp)movl    %esi, -8(%rbp)movl    %edx, -12(%rbp)movl    -4(%rbp), %edxmovl    -8(%rbp), %eaxaddl    %eax, %edxmovl    -12(%rbp), %eaxaddl    %edx, %eaxpopq    %rbpret
main:pushq   %rbpmovq    %rsp, %rbpsubq    $16, %rspmovl    $1, -4(%rbp)movl    $2, -8(%rbp)movl    $3, -12(%rbp)movl    -12(%rbp), %edxmovl    -8(%rbp), %ecxmovl    -4(%rbp), %eaxmovl    %ecx, %esimovl    %eax, %edicall    sum(int, int, int)movl    $0, %eaxleaveret

我們重點來關注一下函數參數的傳遞過程。通過分析main函數的匯編函數, 我用類似于C語言的偽代碼解釋了一下每一行的意思,輔助理解,如下所示。

main        pushq   %rbpmovq    %rsp, %rbp      //rbp = rspsubq    $16, %rsp       //rsp -= 16movl    $1, -4(%rbp)    //*(rbp-4) = 1movl    $2, -8(%rbp)    //*(rbp-8) = 2 movl    $3, -12(%rbp)   //*(rbp-12) = 3movl    -12(%rbp), %edx //edx =*(rbp-12)movl    -8(%rbp), %ecx   //ecx =*(rbp-8) movl    -4(%rbp), %eax   //eax = *(rbp-4)movl    %ecx, %esi    //esi = ecx movl    %eax, %edi   //edi = eaxcall    sum(int, int, int)movl    $0, %eaxleaveret

在執行這條指令(call sum(int, int, int))前,main函數的棧空間分布如下:

即main函數會存儲三個變量: a, b, c. 同時會將其值分別賦值給edi, esi、edx寄存器。那么我們很好奇,將a, b, c三個變量的值賦值給edi, esi、edx寄存器會有什么用呢?我們先來看一下sum函數,我用類似于C語言的偽代碼解釋了一下每一行的意思,輔助理解,如下所示。

sum(int, int, int):pushq   %rbpmovq    %rsp, %rbp         //rbp = rspmovl    %edi, -4(%rbp)     //*(rbp-4) = edimovl    %esi, -8(%rbp)     //*(rbp-8) = esimovl    %edx, -12(%rbp)    //*(rbp-12) = edxmovl    -4(%rbp), %edx     //edx = *(rbp-4)movl    -8(%rbp), %eax     //eax = *(rbp-8)addl    %eax, %edx         //edx += eax  movl    -12(%rbp), %eax    //eax = *(rbp-12) addl    %edx, %eax         //eax += edx popq    %rbpret

sum函數的棧空間分布如下:

?

我們重點關注一下這幾條指令:

?movl ? ?%edi, -4(%rbp) ? ? //*(rbp-4) = edi
?movl ? ?%esi, -8(%rbp) ? ? //*(rbp-8) = esi
?movl ? ?%edx, -12(%rbp) ?//*(rbp-12) = edx

可以看到,在sum函數的棧空間中,其會分配三個存儲單元,rbp-4, rbp-8, rbp-12存儲1,2,3。而1,2,3這三個值分別又是從edi,? esi、edx三個寄存器中拷貝過來的。而這三個寄存器的值又是來自main函數中a, b, c三個變量的賦值。也就是說,這里edi,? esi、edx三個寄存器,在函數調用時,完成了參數的傳遞。那么這種參數傳遞的現像是不是有什么約定呢??答案是有的!

在Linux/macOS 等 Unix-like系統中,函數的調用約定標準為System V AMD64 ABI,其參數傳遞機制:

參數位置整數/指針寄存器浮點寄存器
第 1 個RDIXMM0
第 2 個RSIXMM1
第 3 個RDXXMM2
第 4 個RCXXMM3
第 5 個R8XMM4
第 6 個R9XMM5
第 7+ 個棧(右→左)XMM6-7

從這個約定中得知,在傳遞整數時,第一個參數用的是RDI寄存器,第二個參數用的是RSI寄存器,第三個參數用的是RDX寄存器。上面函數調用的例子中正好符合此調用約定(例子中用的是edi,? esi、edx三個寄存器傳遞第1,第2,第3個參數,而edi,? esi、edx正好是RDI、RSI、RDX三個寄存器的低32位)。

<this指針揭秘繼續...>

?

?

?

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

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

相關文章

18 - GCNet

論文《GCNet: Non-local Networks Meet Squeeze-Excitation Networks and Beyond》 1、作用 GCNet通過聚合每個查詢位置的全局上下文信息來捕獲長距離依賴關系&#xff0c;從而改善了圖像/視頻分類、對象檢測和分割等一系列識別任務的性能。非局部網絡&#xff08;NLNet&…

人工智能學習17-Pandas-查看數據

人工智能學習概述—快手視頻 人工智能學習17-Pandas-查看數據—快手視頻

RV1126+OPENCV在視頻中添加LOGO圖像

一.RV1126OPENCV在視頻中添加LOGO圖像大體流程圖 主要是利用RV1126的視頻流結合OPENCV的API在視頻流里面添加LOGO圖像&#xff0c;換言之就是在RV1126的視頻流里面疊加圖片。大體流程我們來看上圖&#xff0c;要完成這個功能我們需要創建兩個線程(實際上還有初始化過程&#xf…

汽車制造通信革新:網關模塊讓EtherCAT成功對接CCLINK

?在現代工業自動化生產領域&#xff0c;不同品牌和類型的設備往往采用不同的通信協議&#xff0c;這給設備之間的互聯互通帶來了挑戰。某汽車制造企業的生產線上&#xff0c;采用了三菱FX5U PLC作為主站進行整體生產流程的控制和調度&#xff0c;同時配備了庫卡機器人作為從站…

vue父類跳轉到子類帶參數,跳轉完成后去掉參數

當通過路由導航的時候&#xff0c;由于父類頁面帶參數到子類&#xff0c;導致路徑上面有參數 這樣不僅不美觀&#xff0c;而且在點擊導航菜單按鈕時還會有各種問題&#xff0c;這時我們只需要將路由后面的參數去掉就好了&#xff0c;在子頁面mounted()函數里面獲取到父類的參數…

純 CSS 實現的的3種掃光效果

介紹一個比較常見的動畫效果。 在日常開發中&#xff0c;為了強調凸顯某些文本或者元素&#xff0c;會加一些掃光動效&#xff0c;起到吸引眼球的效果&#xff0c;比如文本的 或者是一個卡片容器&#xff0c;里面可能是圖片或者文本或者任意元素 除此之外&#xff0c;還有那…

如何在FastAPI中構建一個既安全又靈活的多層級權限系統?

title: 如何在FastAPI中構建一個既安全又靈活的多層級權限系統? date: 2025/06/14 12:43:05 updated: 2025/06/14 12:43:05 author: cmdragon excerpt: FastAPI通過依賴注入系統和OAuth2、JWT等安全方案,支持構建多層級權限系統。系統設計包括基于角色的訪問控制、細粒度權…

大模型_Ubuntu24.04安裝RagFlow_使用hyper-v虛擬機_超級詳細--人工智能工作筆記0251

因為之前使用dify搭建了一個知識庫&#xff0c;但是dify的效果&#xff0c;尤其是在文檔解析方面是非常不友好的&#xff0c;雖然測試了&#xff0c;納米的效果非常好&#xff0c;但是納米只能容納2000個文件&#xff0c;如果 你的知識庫中有代碼&#xff0c;sql文件等等&…

LeetCode - LCR 173. 點名

題目 LCR 173. 點名 - 力扣&#xff08;LeetCode&#xff09; 思路 首先對數組進行排序&#xff0c;使學號按順序排列 在排序后的數組中&#xff0c;如果沒有缺失的學號&#xff0c;那么每個元素應該等于其索引值 使用二分查找找到第一個不等于其索引的元素位置&#xff1…

VSCode如何優雅的debug python文件,包括外部命令uv run main.py等等

debug程序的方式有很多種。每一種方式都各有缺點:有的方式雖然優雅,但是局限性很大;有的方式麻煩,但是局限性小。 常規方式: 優點:然后可以觀察所有線程。一勞永逸。缺點:就是寫參數很麻煩,但是你可以讓chatgpt等大模型幫你寫。最最最優雅的方式: 優點:就是需要在代碼…

[調試技巧]VS Code如何在代理模式下使用 MCP 工具?

在開發環境調試MCP&#xff0c;通過agent模式與大模型對話&#xff0c;并不能保證每次均正確調用tool。在閱讀官方文檔之后&#xff0c;得知以下小技巧。 添加 MCP 服務器后&#xff0c;您可以在代理模式下使用它提供的工具。要在代理模式下使用 MCP 工具 打開聊天視圖 (CtrlAl…

京東零售基于Flink的推薦系統智能數據體系 |Flink Forward Asia 峰會實錄分享

京東推薦系統的數據體系極其復雜&#xff0c;從召回、模型到策略和效果評估&#xff0c;每個環節都需要強大的海量數據處理能力支撐。然而&#xff0c;在實際運行中&#xff0c;整個數據鏈路面臨著諸多挑戰&#xff1a;如實時與離線數據的埋點口徑不一致、數倉模型存在偏差、計…

[學習] 牛頓迭代法:從數學原理到實戰

牛頓迭代法&#xff1a;從數學原理到實戰 ——高效求解方程根的數值方法 文章目錄 牛頓迭代法&#xff1a;從數學原理到實戰一、引言&#xff1a;為什么需要牛頓迭代法&#xff1f;二、數學原理&#xff1a;幾何直觀與公式推導1. **核心思想**2. **幾何解釋**3. **收斂性分析*…

使用 Git 將本地倉庫上傳到 GitHub 倉庫的完整指南

使用 Git 將本地倉庫上傳到 GitHub 倉庫的完整指南 一、引言 在現代軟件開發中&#xff0c;版本控制工具 Git 已成為不可或缺的一部分。GitHub 作為全球最大的代碼托管平臺&#xff0c;為開發者提供了代碼協作、項目管理和開源貢獻的便捷方式。本文將詳細介紹如何通過 Git 將本…

數據結構 - 棧與隊列

棧&#xff1a;限定僅在表尾進行插入或刪除操作的線性表。 表尾端有特殊含義&#xff0c;稱為棧頂&#xff08;top&#xff09;。 相應的&#xff0c;表頭端稱為棧底&#xff08;buttom&#xff09;。不含元素的空表成為空棧。 棧又稱為后進先出的線性表&#xff08;Last In…

jojojojojo

《JOJO的奇妙冒險》是由日本漫畫家荒木飛呂彥所著漫畫。漫畫于1987年至2004年在集英社的少年漫畫雜志少年JUMP上連載&#xff08;1987年12號刊-2004年47號刊&#xff09;&#xff0c;2005年后在集英社青年漫畫雜志Ultra Jumphttps://baike.baidu.com/item/Ultra%20Jump/2222322…

統計學核心概念與現實應用精解(偏機器學習)

統計學聽起來似乎很復雜&#xff0c;但其實它的核心就是兩個概念&#xff1a;概率分布和期望。這兩個概念就像是我們日常生活中的決策助手。 概率分布描述了隨機事件各種可能結果出現的可能性大小。比如&#xff0c;擲骰子時每個點數出現的概率&#xff0c;這就是一個典型的概…

go-carbon v2.6.8 發布,輕量級、語義化、對開發者友好的 golang 時間處理庫

carbon 是一個輕量級、語義化、對開發者友好的 Golang 時間處理庫&#xff0c;提供了對時間穿越、時間差值、時間極值、時間判斷、星座、星座、農歷、儒略日 / 簡化儒略日、波斯歷 / 伊朗歷的支持。 carbon 目前已捐贈給 dromara 開源組織&#xff0c;已被 awesome-go 收錄&am…

228永磁同步電機無速度算法--基于雙重鎖相環的滑模觀測器

一、原理介紹 在傳統的正交鎖相環的基礎上&#xff0c;利用前述濾波器、ZOH、代數環等非理想因素對電流信號進行延遲重構&#xff0c;進而得到一個與實際電流信號存在相位偏差的重構信號&#xff0c;且該相位偏差等同于初步估計位置信號與實際位置信號之間的相位偏差。將該重構…

零基礎入門 線性代數

線性代數是一種代數結構&#xff0c;通俗來講&#xff0c;向量空間是這個結構的基石&#xff0c;我們要在向量空間中研究向量與向量的關系 一 對象&#xff1a;向量 各位都有對象嘛&#xff1f;如果沒有對象&#xff0c;想不想知道你們的天命之人是誰捏&#xff1f;如果有對象…