C++中指針使用詳解(3)數組、指針和函數參數傳遞的底層 ABI實現

要深入理解 數組、指針和函數參數傳遞 的底層 ABI(Application Binary Interface)實現,需要從以下幾個維度出發進行學習:


一、什么是 ABI?

ABI 是編譯器和操作系統之間的協定,規定了:

  • 函數如何調用(參數傳遞、返回值)
  • 棧幀布局(局部變量、返回地址、保存寄存器)
  • 調用約定(Calling Convention)
  • 數據的對齊方式(alignment)
  • 如何在內存中布局結構體、數組、類對象等

例如:x86_64 系統通常使用 System V AMD64 ABI


二、函數參數傳遞 ABI 行為:值 / 地址 / 數組

1. 普通變量(按值傳遞)

void foo(int a) {// 棧幀中的 a 是實參副本
}
  • 編譯器會將 a 作為 整數寄存器(如 rdi)傳入
  • 或在棧中開空間拷貝參數(當寄存器用完或大于特定大小)

2. 指針(傳地址)

void foo(int* p) {*p = 10;
}
  • 指針 p 是 8 字節地址,通常放在寄存器(如 rdi
  • *p 會間接訪問內存(間接尋址)

3. 數組參數(退化為指針)

void foo(int arr[]) {arr[0] = 10;
}
  • int arr[] 會被 退化為 int* arr
  • ABI 上是 按指針傳遞

三、C++ 底層函數調用過程(以 x86_64 System V 為例)

調用 foo(int a, int* p) 時的流程(簡化):

main():a = 42;int* p = &a;call foo(a, p)

底層匯編(偽代碼):

mov edi, 42          ; 第一個參數 a → edi
mov rsi, &a          ; 第二個參數 p → rsi
call foo

四、函數棧幀結構(以 GCC / x86_64 為例)

一個函數的棧幀通常如下:

 ┌───────────────┐ ← 高地址│ 返回地址      │ ← 調用者壓入│ old %rbp      │ ← 保存上層基址│ 參數備份/局部變量 ││ 臨時寄存器保存 │└───────────────┘ ← %rsp 棧頂

調用過程:

  • call foo → 跳轉并壓入返回地址
  • push %rbp → 建立新的基址指針(%rbp)
  • sub rsp, n → 為局部變量分配空間

五、數組傳值傳引用的差異 ABI 視角下分析

1. 按值傳遞數組(不推薦)

void foo(int arr[5]) { ... } // 實際變為 int* arr
  • 編譯器不會復制整個數組
  • 傳的是指針地址
  • 在函數內對 arr[i] 的修改會影響外部

2. 真正的數組按值傳遞(必須用 std::array 或結構體包裝)

struct ArrWrap {int arr[5];
};void foo(ArrWrap a);
  • 編譯器會 完整拷貝結構體 到寄存器或棧
  • 不會影響原數組內容

六、C++ 對象參數 ABI 行為(指針/引用/拷貝)

參數類型ABI 表現
T可能按值復制進棧或寄存器
T&傳指針,指向原對象
T*明確傳地址
const T&仍然傳地址,只是禁止修改

七、數組和指針的底層行為對比

void foo(int* p);    // 編譯器看作地址傳遞
void bar(int arr[10]); // 實質上也是 int* arr

舉例說明區別:

int arr[10];
foo(arr); // arr 退化為 &arr[0]
  • sizeof(arr) 是 40
  • sizeof(p) 是 8(在 64 位系統)
void size_test(int* p, int arr[10]) {cout << sizeof(p) << endl;   // 8cout << sizeof(arr) << endl; // 8(退化后)
}

八、調試驗證:GCC 下使用 objdumpgdb

編譯為匯編查看 ABI 細節:

g++ -O0 -S main.cpp -o main.s

或者用 gdb 單步跟蹤:

gdb ./a.out
(gdb) break foo
(gdb) run
(gdb) info registers

九、結構體中的數組傳遞 ABI 規則

struct Data {int x;int arr[4];
};void process(Data d); // 會按值拷貝整個結構體(如果不大)

如果結構體很大,則:

  • 編譯器會在 caller 中分配臨時內存
  • 傳遞 指向該內存的隱藏指針

十、小結圖示(建議結合圖)

函數參數 ABI 層調用過程:main:┌─────────────┐│ 棧變量 a    │ ← &a└─────────────┘│▼
foo(a, &a):┌──────────────┐│ 寄存器傳參   │ ← rdi = a, rsi = &a│ 棧幀建立     ││ 局部變量空間 │└──────────────┘

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

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

相關文章

【RustDesk 】中繼1:壓力測試 Python 版 RustDesk 中繼服務器

測試 Python 版 RustDesk 中繼服務器 測試我們實現的中繼服務器有幾種方法,從簡單到復雜依次如下: 1. 基本連接測試客戶端 創建一個簡單的測試客戶端來驗證中繼服務器的基本功能: 2. 用兩個測試客戶端測試中繼功能 要測試完整的中繼功能,你需要運行兩個客戶端實例來模擬…

Spring Boot集成Spring Cloud 2024(不使用Feign)

本文介紹Spring Boot集成Spring Cloud 2024&#xff0c;且不使用Feign&#xff0c;而是采用Spring 6自帶的HttpExchange方式進行服務調用的詳細步驟&#xff1a; 環境準備 Spring Boot版本&#xff1a;推薦使用Spring Boot 3.4.1及以上版本&#xff0c;以更好地與Spring Clou…

vue中$set原理

Vue 中的 $set 方法&#xff08;Vue.set&#xff09;主要用于 向響應式對象中添加一個新的屬性&#xff0c;并確保這個新屬性是響應式的&#xff0c;能夠觸發視圖更新。 &#x1f4cc; 背景問題&#xff1a;為什么需要 $set&#xff1f; 在 Vue 2 中&#xff0c;直接給對象新增…

Superset二次開發之深度解讀系列:1.概述

Apache Superset 是一款現代化的企業級商業智能 Web 應用程序&#xff0c;專為數據探索和可視化而設計。本概述介紹了 Superset 的架構、核心組件和主要功能&#xff0c;以幫助開發人員了解該系統的工作原理。 What is Apache Superset? Apache Superset 是一個開源數據探索…

Linux系統之elfedit詳解

elfedit 是一個用于修改 ELF&#xff08;可執行與可鏈接格式&#xff09;文件頭的工具。它允許用戶根據指定的條件&#xff08;如機器類型、文件類型、操作系統/ABI&#xff09;匹配并更新 ELF 文件的頭部信息。支持 32 位和 64 位 ELF 文件&#xff0c;以及包含 ELF 文件的歸檔…

前端HTML基礎知識

1.HTML介紹 HTML(HyperText Markup Language&#xff0c;超文本標記語言)是構成網頁的基本元素&#xff0c;是一種用于創建網頁的標準化標記語言。HTML不是一種編程語言&#xff0c;而是一種標記語言&#xff0c;通過標簽來描述網頁的結構和內容。 超文本&#xff1a;超文本是…

【IP101】圖像濾波技術詳解:從均值濾波到高斯濾波的完整指南

&#x1f31f; 圖像濾波魔法指南 &#x1f3a8; 在圖像處理的世界里&#xff0c;濾波就像是給圖片"美顏"的魔法工具。讓我們一起來探索這些神奇的濾波術吧&#xff01; &#x1f4d1; 目錄 1. 均值濾波&#xff1a;圖像的"磨皮"大法2. 中值濾波&#xff1…

LINE FRIENDS 正式與 Walrus 合作,全新 AI 驅動的游戲即將上線

風靡全球的 LINE FRIENDS 角色即將以“minini”迷你造型登陸 Walrus&#xff0c;雖然尺寸更小&#xff0c;但承諾帶來“大”動作。IPX&#xff08;LINE FRIENDS 背后的公司&#xff09;打造了《minini universe: ROOM》游戲&#xff0c;這是一款基于其 minini 系列角色的多鏈游…

2025年信息素養大賽C++算法創意實踐挑戰賽初賽樣題及答案解析(小學組)

一、選擇題 1、下列代碼&#xff0c;能夠輸出 hello world 的是_____ A. cout (hello world) B. cout << hello world C. cout:hello world D. cout << "hello world"; 答案&#xff1a;D 解析&#xff1a;cout輸出的文本內容要用雙引號引起來 2、…

[c語言日寄]檢查環形鏈表

【作者主頁】siy2333 【專欄介紹】?c語言日寄?&#xff1a;這是一個專注于C語言刷題的專欄&#xff0c;精選題目&#xff0c;搭配詳細題解、拓展算法。從基礎語法到復雜算法&#xff0c;題目涉及的知識點全面覆蓋&#xff0c;助力你系統提升。無論你是初學者&#xff0c;還是…

黃雀在后:外賣大戰新變局,淘寶+餓了么開啟電商大零售時代

當所有人以為美團和京東的“口水戰”硝煙漸散&#xff0c;外賣大戰告一段落時&#xff0c;“螳螂捕蟬&#xff0c;黃雀在后”&#xff0c;淘寶閃購聯合餓了么“閃現”外賣戰場&#xff0c;外賣烽火再度燃起。 4 月30日&#xff0c;淘寶天貓旗下即時零售業務“小時達”正式升級…

如何在uni-app中自定義輸入框placeholder的樣式

在開發uni-app應用時&#xff0c;我們經常需要自定義輸入框&#xff08;<input>&#xff09;的樣式以匹配應用的整體設計。默認情況下&#xff0c;uni-app的輸入框提供了一些基本的樣式選項&#xff0c;但有時候我們需要更細致地控制輸入框的每個部分&#xff0c;例如pla…

使用Node編寫輕量級后端快速入門

使用Node編寫輕量級后端快速入門 node 要作為輕量級后端需要下載一些對應模塊可以參考下面命令。你可以借助 npm&#xff08;Node Package Manager&#xff09;來下載它們。 模塊下載 express&#xff1a;這是一個廣受歡迎的 Node.js Web 應用框架&#xff0c;能用于構建 Web…

從Markdown到專業文檔:如何用Python打造高效格式轉換工具

在技術寫作、學術研究和企業報告領域,Markdown因其簡潔高效的特性廣受開發者喜愛。但當需要輸出正式文檔時,Word和PDF格式仍是行業標準。傳統解決方案往往存在樣式丟失、代碼排版混亂、批量處理困難等痛點。本文將揭秘如何用Python構建一個支持多主題、保留代碼高亮、自動生成…

【docker學習筆記】如何刪除鏡像啟動默認命令

一些鏡像會在它打鏡像時&#xff0c;加入一些默認的啟動命令&#xff0c;可以通過docker inspect \<image id\>來查看Entrypoint。如下圖&#xff0c;docker run啟動時&#xff0c;會默認執行 "python3 -m vllm.entrypoints.openai.api_server" 如果不想執行&…

任意無人機手柄鏈接Unity-100元的鳳凰SM600手柄接入Unity Input System?

網上教程真少&#xff01;奮發圖強自力更生&#xff01;2025.5.1 目前有用的鏈接&#xff1a; unity如何添加自定義HID設備&#xff0c;自己開發的手柄如何支持unity。 - 嗶哩嗶哩 HID Support | Input System | 1.0.2 官方教程 https://zhuanlan.zhihu.com/p/503209742 分…

2024睿抗CAIP-編程技能賽-本科組(省賽)題解

藍橋杯拿了個省三&#xff0c;天梯沒進1隊&#xff0c;睿抗是我最后的機會 RC-u4 章魚圖的判斷 題目描述 對于無向圖 G ( V , E ) G(V,E) G(V,E)&#xff0c;我們定義章魚圖為&#xff1a; 有且僅有一個簡單環&#xff08;即沒有重復頂點的環&#xff09;&#xff0c;且所…

Java 泛型參數問題:‘ResponseData.this‘ cannot be referenced from a static contex

問題與處理策略 問題描述 Data AllArgsConstructor NoArgsConstructor public class ResponseData<T> {private Integer code;private String msg;private T data;public static final int CODE_SUCCESS 2001;public static final int CODE_FAIL 3001;public static …

用TCP實現服務器與客戶端的交互

目錄 一、TCP的特點 二、API介紹 1.ServerSocket 2.Socket 三、實現服務器 四、實現客戶端 五、測試解決bug 1.客戶端發送了數據之后&#xff0c;并沒有響應 2.clientSocket沒有執行close()操作 3.嘗試使用多個客戶端同時連接服務器 六、優化 1.短時間有大量客戶端訪…

鳥籠效應——AI與思維模型【84】

一、定義 鳥籠效應思維模型指的是人們在偶然獲得一件原本不需要的物品后,會為了這件物品的配套或使用需求,進而繼續添加更多與之相關但自己原本可能并不需要的東西,仿佛被這個“鳥籠”牽著走,最終陷入一種慣性消費或行為模式的現象。簡單來說,就是人們在心理上會有一種自…