函數調用過程中的棧幀變化

int add(int a, int b) {int c = a + b;return c;
}int main() {int result = add(1, 2);return 0;
}

生成匯編代碼:g++ -S Cplus.cpp -o Cplus.s

.file	"Cplus.cpp".text.globl	_Z3addii.def	_Z3addii;	.scl	2;	.type	32;	.endef.seh_proc	_Z3addii
_Z3addii:pushq	%rbp.seh_pushreg	%rbpmovq	%rsp, %rbp.seh_setframe	%rbp, 0subq	$16, %rsp.seh_stackalloc	16.seh_endprologuemovl	%ecx, 16(%rbp)movl	%edx, 24(%rbp)movl	16(%rbp), %edxmovl	24(%rbp), %eaxaddl	%edx, %eaxmovl	%eax, -4(%rbp)movl	-4(%rbp), %eaxaddq	$16, %rsppopq	%rbpret.seh_endproc.def	__main;	.scl	2;	.type	32;	.endef.globl	main.def	main;	.scl	2;	.type	32;	.endef.seh_proc	main
main:pushq	%rbp	# 將寄存器的值壓入棧中.seh_pushreg	%rbp # 上一個棧幀的基址movq	%rsp, %rbp # 當前棧幀的基址.seh_setframe	%rbp, 0subq	$48, %rsp # 預留空間.seh_stackalloc	48.seh_endprologuecall	__mainmovl	$2, %edxmovl	$1, %ecxcall	_Z3addii # 調用函數movl	%eax, -4(%rbp)movl	$0, %eaxaddq	$48, %rsppopq	%rbpret.seh_endproc.ident	"GCC: (x86_64-win32-sjlj-rev0, Built by MinGW-W64 project) 8.1.0"
  • 函數調用過程:
    初始狀態: rbp = rsp = 0x1000
地址棧中的內容執行的操作指令
0x0ff8上一個函數的棧幀基址(rbp=0x1000)rsp-=8 0x0ff8->rsppushq %rbp
rbp=rsp=0x0ff8,表示當前函數棧幀的基址movq %rsp, %rbp
0x0ff0eax值(0x0ff8,0x0ff4)
0x0fe8
0x0fe0
0x0fd8
0x0fd0
0x0fc8rsp-=48 0x0fc8->rspsubq $48, %rsp
0x0fc0返回地址rsp-=8 0x0fc0->rspcall __main
0x0fb8返回地址rsp-=8 0x0fb8->rspcall _Z3addii
0x0fb0main函數的棧幀基址(rbp=0x0ff8)rsp-=8 0x0fb0->rsppushq %rbp
0x0fa8eax值 (0x0fb0,0x0fa4)rbp=rsp=0x0fb0,表示當前函數棧幀的基址movq %rsp, %rbp
0x0fa0rsp-=16 0x0fa0->rspsubq $16, %rsp
0x0f98

注意:

  1. 參數傳遞規則??
    ??前 4 個整數參數??:通過寄存器傳遞(順序:rcx, rdx, r8, r9)。
    ??多余參數??:通過棧傳遞(從右向左壓棧)。
    這是反匯編或編譯器生成的代碼,可能是調試版本或未優化的結果。實際參數應直接從寄存器讀取:
  2. movl %ecx, 16(%rbp)的問題
    雖然 subq $48, %rsp 預留了 48 字節棧空間,但:
    實際只用了 4 字節(保存返回值);
    剩下的是 對齊 + 編譯器保守行為 + SEH支持 的結果;
    并不是異常,是很正常且常見的行為。
  • 函數返回過程:
movl	%ecx, 16(%rbp)
movl	%edx, 24(%rbp)
movl	16(%rbp), %edx
movl	24(%rbp), %eax
addl	%edx, %eax
movl	%eax, -4(%rbp)
movl	-4(%rbp), %eaxaddq	$16, %rsp   # 釋放空間
popq	%rbp        # rbp = *(rsp), rsp+=8
ret                 # 讀取rsp獲得返回地址,rsp+=8
  • 返回到主函數后:
movl	%eax, -4(%rbp)  # 
movl	$0, %eax        # 寄存器置于0
addq	$48, %rsp       # 釋放空間
popq	%rbp            # rbp = *(rsp), rsp+=8
ret                     # 讀取rsp獲得返回地址,rsp+=8,最終rsp=0x1000(初始值)

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

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

相關文章

【Java面試筆記:實戰】41、Java面試核心考點!AQS原理及應用生態全解析

引言:AQS在Java并發體系中的核心地位 AQS(AbstractQueuedSynchronizer)作為Java并發包的底層基石,是理解ReentrantLock、Semaphore等同步工具的關鍵。 在Java架構師面試中,AQS的原理與應用是高頻考點,掌握其核心機制對理解JUC包和構建高并發系統至關重要。 本文將從原…

碩士課題常用命令

ros常用命令: 1.環境變量刷新 source devel/setup.bash2.ROS_INFO的信息在終端顯示為亂碼或者問號,則在main函數中加入: setlocale(LC_ALL, "");3.刷新bashrc文件 source ~/.bashrcPX4 roslaunch px4 mavros_posix_sitl.launc…

2.6 激光雷達消息格式

新建終端,執行命令 roslaunch wpr_simulation wpb_simple.launch 在新建終端,執行命令 roslaunch wpr_simulation wpb_rviz.launch 顯示/Scan話題消息,后面的參數是noarr無數組,防止刷屏 rostopic echo /scan --noarr 參考官…

常見的網絡協議有哪些

1.應用層 1.1 HTTP/HTTPS 前端與服務器通信的基礎協議,用于傳輸 HTML、CSS、JS、圖片等資源。 1.2WebSocket(如社交聊天、股票實時報價、視頻會議、在線教育等) WebSocket協議建立在TCP協議之上,實現了瀏覽器與服務器之間的實時…

Prometheus + Grafana 監控 RabbitMQ 實踐指南

文章目錄 Prometheus Grafana 監控 RabbitMQ 實踐教程一、前言二、環境搭建2.1 環境準備2.2 安裝 Prometheus2.3 安裝 Grafana 三、集成 RabbitMQ Exporter3.1 下載 RabbitMQ Exporter3.2 解壓文件3.3 配置環境變量3.4 啟動 RabbitMQ Exporter3.6 驗證 Exporter 狀態 四、Prom…

Babylon.js場景加載器(Scene Loader)使用指南

在3D開發中,Babylon.js的場景加載器(Scene Loader)是加載各種3D模型格式的核心工具。本文將詳細介紹如何高效使用Scene Loader加載多種格式的3D模型文件。 一、基本概念與支持格式 要加載特定類型的文件,Babylon.js需要先注冊對應的文件類型插件。目前…

編程學習網站大全(C++/OpenCV/QT方向)—— 資源導航與深度評測

工欲善其事,必先利其器 本文系統整理了C、OpenCV、QT三大方向的優質學習網站,結合技術特點與平臺優勢,助你精準選擇學習資源,少走彎路! 一、C 學習網站精選 📚 1. cppreference.com 權威性最高&#xff1a…

逆向入門(5)程序逆向篇-AD_CM#2

打開程序 常規注冊界面,打開OD,隨便找找就看到關鍵字了 沒有殼邏輯也挺簡單的 獲取輸入框,用5比較輸入內容的長度,小于則跳轉提示密碼長度不夠 否則就進入下一個流程,去獲取序列號,其實可以直接將jnz換…

OD 算法題 B卷【路燈照明II】

文章目錄 路燈照明II 路燈照明II 在一條筆直的公路上安裝了N個路燈,從位置0開始安裝,間距固定為100米;每個路燈都有自己的照明半徑,計算第一個路燈和最后一個路燈之間,無法照明的區間長度和; 輸入描述: 第…

JUC核心解析系列(四)——同步工具類 (Synchronizers)深度解析

在多線程開發中,死鎖、資源競爭、線程協調等問題如同暗礁,稍有不慎就會導致程序崩潰。而JUC同步工具類正是解決這些問題的瑞士軍刀! 一、同步工具類核心價值:線程協作的藝術 在高并發系統中,線程協作是保證數據一致性…

板凳-------Mysql cookbook學習 (十--6)

第7章:排序查詢結果 7.0 引言 mysql> use cookbook Database changed mysql> select * from driver_log; ---------------------------------- | rec_id | name | trav_date | miles | ---------------------------------- | 1 | Ben | 2014-07-30 …

從入門到精通:C# 中 AutoMapper 的深度解析與實戰應用

在 C# 開發領域,尤其是企業級應用開發過程中,不同層次和模塊之間的數據傳遞與對象轉換是常見需求。例如,從數據庫讀取的實體類,在傳遞到前端時,往往需要轉換為更簡潔、安全的數據傳輸對象(DTO) …

【熱更新知識】學習一 Lua語法學習

1、注釋 1.1 單行注釋 --注釋內容 --單行注釋 print打印函數 1.2 多行注釋,三種方式 --[[注釋內容]] --[[注釋內容]]-- --[[注釋內容--]] --[[ 多行 注釋 ]]--[[ 第二種多行注釋 1 2 ]]----[[ 第三種 多行 注釋 --]] 2、簡單變量 2.1 聲明變量&#xff0c…

React 第三方狀態管理庫的比較與選擇

在現代前端開發中,狀態管理是一個重要的環節。選擇合適的狀態管理庫可以極大地提高項目的可維護性和開發效率。本文將對幾種流行的狀態管理庫進行比較,包括Valtio、XState、MobX、Recoil和Zustand,幫助開發者在實際項目中做出明智的選擇。 1. Valtio 1.1. 設計理念 Valti…

《Kafka 在實時消息系統中的高可用架構設計》

Kafka 在實時消息系統中的高可用架構設計 引言 在當今互聯網社交應用中,實時消息系統已成為核心基礎設施。以中性互聯網公司為例,其每天需要處理數十億條消息,涵蓋一對一聊天、群組互動、直播彈幕等多種場景。特別是在大型直播活動中&#…

SKUA-GOCAD入門教程-第八節 線的創建與編輯3

8.1.4根據面對象創建曲線 (1)從曲面生成曲線 從曲面邊界生成曲線您可以從選定的曲面邊界創建一條單段曲線。 1、選擇 Curve commands > New > Borders > One 打開從曲面的一條邊界創建曲線對話框。 圖1 在“Name名稱”框中,輸入要創建的曲線的名稱。

Unity編輯器-獲取Projectwindow中拖拽內容的路徑

參考 Unity Editor 實現給屬性面板上拖拽賦值資源路徑 API Event DragAndDrop 示例 Mono腳本 using UnityEngine; public class TestScene : MonoBehaviour {[SerializeField] string testName; }Editor腳本 重寫InspectorGUI,在該函數中通過Event的Type參數獲…

重要的城市(圖論 最短路)

分析 a ≠ b的從a到B的最短路,才有重要城市。 求出最短路,才能確定重要城市。 是多源最短路,n ≤ 200,可用Floyd。 若a到b,只有一條最短路,那么 a到b的路徑上的點(除了a、b)都是…

50種3D效果演示(OpenGL)

效果: 一、只需打開命令行(Windows 可用 cmd),輸入: pip install PyQt5 PyOpenGL numpy二、用命令行進入保存 .py 文件的目錄,運行: python openGL_3d_demo.py三、建立python文件命名openGL_3…

Java大模型開發入門 (6/15):對話的靈魂 - 深入理解LangChain4j中的模型、提示和解析器

前言 在上一篇文章中,我們見證了AiService注解的驚人威力。僅僅通過定義一個Java接口,我們就實現了一個功能完備的AI聊天服務。這感覺就像魔法一樣! 但作為專業的工程師,我們知道“任何足夠先進的技術,都與魔法無異”…