【匯編逆向系列】七、函數調用包含多個參數之浮點型- XMM0-3寄存器

目錄

1. 匯編代碼

1.1 debug編譯

1.2 release編譯

2. 匯編分析

2.1 浮點參數傳遞規則

2.2 棧幀rsp的變化時序

2.3 參數的訪問邏輯

2.4 返回值XMM0寄存器

3. 匯編轉化

3.1 Debug編譯

3.2 Release 編譯

3.3 C語言轉化


1. 匯編代碼

上一節介紹了整型的函數傳參,那么浮點型有什么不同,將在這一節介紹,包含float和double的浮點型都是類似的傳參方式。這一節將不再區分少數參數和多個參數,直接使用多個參數浮點型的匯編代碼例子。

1.1 debug編譯

many_double_params:0000000000000A20: F2 0F 11 5C 24 20  movsd       mmword ptr [rsp+20h],xmm30000000000000A26: F2 0F 11 54 24 18  movsd       mmword ptr [rsp+18h],xmm20000000000000A2C: F2 0F 11 4C 24 10  movsd       mmword ptr [rsp+10h],xmm10000000000000A32: F2 0F 11 44 24 08  movsd       mmword ptr [rsp+8],xmm00000000000000A38: 57                 push        rdi0000000000000A39: 48 83 EC 10        sub         rsp,10h0000000000000A3D: 48 8B FC           mov         rdi,rsp0000000000000A40: B9 04 00 00 00     mov         ecx,40000000000000A45: B8 CC CC CC CC     mov         eax,0CCCCCCCCh0000000000000A4A: F3 AB              rep stos    dword ptr [rdi]0000000000000A4C: F2 0F 10 44 24 20  movsd       xmm0,mmword ptr [rsp+20h]0000000000000A52: F2 0F 58 44 24 28  addsd       xmm0,mmword ptr [rsp+28h]0000000000000A58: F2 0F 58 44 24 30  addsd       xmm0,mmword ptr [rsp+30h]0000000000000A5E: F2 0F 58 44 24 38  addsd       xmm0,mmword ptr [rsp+38h]0000000000000A64: F2 0F 58 44 24 40  addsd       xmm0,mmword ptr [rsp+40h]0000000000000A6A: F2 0F 58 44 24 48  addsd       xmm0,mmword ptr [rsp+48h]0000000000000A70: F2 0F 5E 05 00 00  divsd       xmm0,mmword ptr [__real@4018000000000000]00 000000000000000A78: 48 83 C4 10        add         rsp,10h0000000000000A7C: 5F                 pop         rdi0000000000000A7D: C3                 ret0000000000000A7E: CC                 int         30000000000000A7F: CC                 int         30000000000000A80: CC                 int         3

1.2 release編譯


many_double_params:0000000000000000: F2 0F 58 C1        addsd       xmm0,xmm10000000000000004: F2 0F 58 C2        addsd       xmm0,xmm20000000000000008: F2 0F 58 C3        addsd       xmm0,xmm3000000000000000C: F2 0F 58 44 24 28  addsd       xmm0,mmword ptr [rsp+28h]0000000000000012: F2 0F 58 44 24 30  addsd       xmm0,mmword ptr [rsp+30h]0000000000000018: F2 0F 5E 05 00 00  divsd       xmm0,mmword ptr [__real@4018000000000000]00 000000000000000020: C3                 ret

2. 匯編分析

2.1 浮點參數傳遞規則

在 Windows x64 調用約定中:

  • 前 4 個浮點參數??通過?XMM0-XMM3?寄存器傳遞
  • 第 5 個及以上參數??通過棧傳遞(從右向左壓棧)
  • 調用者需預留 ??32 字節影子空間??(Shadow Space),用于被調函數保存寄存器參數

2.2 棧幀rsp的變化時序

在棧幀變化上浮點型與整型保持著完全一致的邏輯

; 1. 保存前4個浮點參數到影子空間
movsd [rsp+20h], xmm3   ; 參數4 → [影子空間+0x20]
movsd [rsp+18h], xmm2   ; 參數3 → [影子空間+0x18]
movsd [rsp+10h], xmm1   ; 參數2 → [影子空間+0x10]
movsd [rsp+8],   xmm0   ; 參數1 → [影子空間+0x08]; 2. 保存非易失寄存器
push rdi                 ; RSP -= 8; 3. 分配局部變量空間
sub rsp, 10h             ; RSP -= 16 (0x10); 4. 初始化局部空間(調試版行為)
mov rdi, rsp
mov ecx, 4
mov eax, 0CCCCCCCCh      ; 填充未初始化數據標記
rep stosd                ; 用 0xCC 填充 16 字節

?在call指令調用函數時,棧幀rsp-=8, 所以影子空間的位置都要+0x08, 由[rsp]-[rsp+0x20]變化為[rsp+8]-[rsp+0x28]所以movsd [rsp+8], xmm0 ; 參數1 → [影子空間+0x08],第一個參數是放在[rsp+8]。

在push rdi 后, 再次 rsp-=8, 此時所有參數位置要再次+ 0x08

在sub rsp 10h之后,再次 rsp -= 0x10, 所以所有參數位置再次+ 0x10h

這里也充分說明了局部變量的地址是向下增長的

2.3 參數的訪問邏輯

; 加載并累加參數(偏移基于當前 RSP)
movsd xmm0, [rsp+20h]   ; 加載參數1 (當前 RSP+0x20 = 原始影子空間+0x08)
addsd xmm0, [rsp+28h]   ; + 參數2 (原始影子空間+0x10)
addsd xmm0, [rsp+30h]   ; + 參數3 (原始影子空間+0x18)
addsd xmm0, [rsp+38h]   ; + 參數4 (原始影子空間+0x20)
addsd xmm0, [rsp+40h]   ; + 參數5 (調用者壓棧的第1個額外參數)
addsd xmm0, [rsp+48h]   ; + 參數6 (調用者壓棧的第2個額外參數)

由于棧是向下增長的,從參數六開始壓棧,參數1 的地址其實是最低的

2.4 返回值XMM0寄存器

在x64架構下,浮點計算的返回值統一使用 ??XMM0 寄存器??作為傳遞載體。這一規則適用于單精度(float)和雙精度(double)浮點數,且是跨操作系統(如 Windows 和 Linux)的標準約定

浮點類型??(包括?floatdouble):結果存儲在?XMM0?的低位部分:

  • ??單精度??(32位):使用?XMM0?的低32位
  • 雙精度??(64位):使用?XMM0?的低64位

3. 匯編轉化

3.1 Debug編譯

movsd [rsp+20h], xmm3   ; 保存第4個參數(xmm3 → [影子空間+0x20])[1](@ref)
movsd [rsp+18h], xmm2   ; 保存第3個參數(xmm2 → [影子空間+0x18])
movsd [rsp+10h], xmm1   ; 保存第2個參數(xmm1 → [影子空間+0x10])
movsd [rsp+8], xmm0     ; 保存第1個參數(xmm0 → [影子空間+0x08])
push rdi                ; 保存非易失寄存器 RDI(RSP -= 8)
sub rsp, 10h            ; 分配 16 字節局部空間(RSP -= 16)
mov rdi, rsp
mov ecx, 4             ; 循環4次(4×4字節=16字節)
mov eax, 0CCCCCCCCh    ; 未初始化內存標記(調試用)
rep stosd              ; 用 0xCC 填充局部空間
movsd xmm0, [rsp+20h]   ; 加載第1個參數(原始 xmm0)
addsd xmm0, [rsp+28h]   ; + 第2個參數(原始 xmm1)
addsd xmm0, [rsp+30h]   ; + 第3個參數(原始 xmm2)
addsd xmm0, [rsp+38h]   ; + 第4個參數(原始 xmm3)
addsd xmm0, [rsp+40h]   ; + 第5個參數(棧傳遞)
addsd xmm0, [rsp+48h]   ; + 第6個參數(棧傳遞)
divsd xmm0, [__real@4018000000000000]  ; xmm0 /= 6.0
add rsp, 10h            ; 釋放局部空間(RSP += 16)
pop rdi                 ; 恢復 RDI(RSP += 8)
ret                     ; 返回結果(xmm0 作為返回值)

3.2 Release 編譯

; 函數入口點,參數通過寄存器和棧傳遞
0000000000000000: 8D 04 11           lea         eax, [rcx+rdx]   ; EAX = 參數1(RCX) + 參數2(RDX)
0000000000000003: 41 03 C0           add         eax, r8d          ; EAX += 參數3(R8D)
0000000000000006: 41 03 C1           add         eax, r9d          ; EAX += 參數4(R9D)
0000000000000009: 03 44 24 28        add         eax, dword ptr [rsp+28h] ; EAX += 參數5(棧偏移0x28)
000000000000000D: 03 44 24 30        add         eax, dword ptr [rsp+30h] ; EAX += 參數6(棧偏移0x30)
0000000000000011: 03 44 24 38        add         eax, dword ptr [rsp+38h] ; EAX += 參數7(棧偏移0x38)
0000000000000015: 03 44 24 40        add         eax, dword ptr [rsp+40h] ; EAX += 參數8(棧偏移0x40)
0000000000000019: 03 44 24 48        add         eax, dword ptr [rsp+48h] ; EAX += 參數9(棧偏移0x48)
000000000000001D: 03 44 24 50        add         eax, dword ptr [rsp+50h] ; EAX += 參數10(棧偏移0x50)
0000000000000021: C3                 ret                          ; 返回結果(EAX為返回值)

3.3 C語言轉化

#include <stdint.h>// 函數原型(6個 double 參數)
double many_double_params(double p1, double p2, double p3, double p4,double p5, double p6
) {// 累加所有參數double sum = p1 + p2 + p3 + p4 + p5 + p6;// 除以 6.0 后返回return sum / 6.0;
}

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

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

相關文章

華為云Flexus+DeepSeek征文 | 從零到一:用Flexus云服務打造低延遲聯網搜索Agent

作者簡介 我是摘星&#xff0c;一名專注于云計算和AI技術的開發者。本次通過華為云MaaS平臺體驗DeepSeek系列模型&#xff0c;將實際使用經驗分享給大家&#xff0c;希望能幫助開發者快速掌握華為云AI服務的核心能力。 目錄 作者簡介 前言 1. 項目背景與技術選型 1.1 項目…

【多智能體】受木偶戲啟發實現多智能體協作編排

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一個正在變禿、變強的文藝傾年。 &#x1f514;本專欄《人工智能》旨在記錄最新的科研前沿&#xff0c;包括大模型、具身智能、智能體等相關領域&#xff0c;期待與你一同探索、學習、進步&#xff0c;一起卷起來叭&#xff…

Java八股文——Spring篇

文章目錄 Java八股文專欄其它文章Java八股文——Spring篇SpringSpring的IoC和AOPSpring IoC實現機制Spring AOP實現機制 動態代理JDK ProxyCGLIBByteBuddy Spring框架中的單例Bean是線程安全的嗎&#xff1f;什么是AOP&#xff0c;你們項目中有沒有使用到AOPSpring中的事務是如…

NineData數據庫DevOps功能全面支持百度智能云向量數據庫 VectorDB,助力企業 AI 應用高效落地

NineData 的數據庫 DevOps 解決方案已完成對百度智能云向量數據庫 VectorDB 的全鏈路適配&#xff0c;成為國內首批提供 VectorDB 原生操作能力的服務商。此次合作聚焦 AI 開發核心場景&#xff0c;通過標準化 SQL 工作臺與細粒度權限管控兩大能力&#xff0c;助力企業安全高效…

開源技術驅動下的上市公司財務主數據管理實踐

開源技術驅動下的上市公司財務主數據管理實踐 —— 以人造板制造業為例 引言&#xff1a;財務主數據的戰略價值與行業挑戰 在資本市場監管日益嚴格與企業數字化轉型的雙重驅動下&#xff0c;財務主數據已成為上市公司財務治理的核心基礎設施。對于人造板制造業而言&#xff0…

借助它,普轉也能獲得空轉信息?

在生命科學研究領域&#xff0c;轉錄組技術是探索基因表達奧秘的有力工具&#xff0c;在疾病機制探索、生物發育進程解析等諸多方面取得了顯著進展。然而&#xff0c;隨著研究的深入&#xff0c;研究人員發現普通轉錄組只能提供整體樣本中的基因表達水平信息&#xff0c;卻無法…

synchronized 學習

學習源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.應用場景 不超賣&#xff0c;也要考慮性能問題&#xff08;場景&#xff09; 2.常見面試問題&#xff1a; sync出…

Java事務回滾詳解

一、什么是事務回滾&#xff1f; 事務回滾指的是&#xff1a;當執行過程中發生異常時&#xff0c;之前對數據庫所做的更改全部撤銷&#xff0c;數據庫狀態恢復到事務開始前的狀態。這是數據庫“原子性”原則的體現。 二、Spring 中的 Transactional 默認行為 在 Spring 中&am…

云災備數據復制技術研究

云災備數據復制技術&#xff1a;數字時代的“安全氣囊” 在當今信息化時代&#xff0c;數據就像城市的“生命線”&#xff0c;一旦中斷&#xff0c;后果不堪設想。想象一下&#xff0c;如果政務系統突然崩潰&#xff0c;成千上萬的市民服務將陷入癱瘓。這就是云災備技術的重要…

如何處理Shopify主題的顯示問題:實用排查與修復指南

在Shopify店鋪運營過程中&#xff0c;主題顯示問題是影響用戶體驗與品牌形象的常見痛點。可能是字體錯位、圖片無法加載、移動端顯示混亂、功能失效等&#xff0c;這些都可能造成客戶流失和轉化下降。 本文將從問題識別、原因分析、修復方法到開發者建議全方位解讀如何高效解決…

前端監控方案詳解

一、前端監控方案是什么&#xff1f; 前端監控方案是一套系統化的工具和流程&#xff0c;用于收集、分析和報告網站或Web應用在前端運行時的各種性能指標、錯誤日志、用戶行為等數據。它通常包括以下幾個核心模塊&#xff1a; 性能監控&#xff1a;頁面加載時間、資源加載時間…

Camera相機人臉識別系列專題分析之十二:人臉特征檢測FFD算法之libvega_face.so數據結構詳解

【關注我&#xff0c;后續持續新增專題博文&#xff0c;謝謝&#xff01;&#xff01;&#xff01;】 上一篇我們講了&#xff1a; Camera相機人臉識別系列專題分析之十一&#xff1a;人臉特征檢測FFD算法之低功耗libvega_face.so人臉屬性(年齡&#xff0c;性別&#xff0c;膚…

如何配置HarmonyOS 5與React Native的開發環境?

配置 HarmonyOS 5 與 React Native 的開發環境需遵循以下步驟 一、基礎工具安裝 ?DevEco Studio 5.0? 從 HarmonyOS 開發者官網 下載安裝勾選組件&#xff1a; HarmonyOS SDK (API 12)ArkTS 編譯器JS/ArkTS 調試工具HarmonyOS 本地模擬器 ?Node.js 18.17 # 安裝后驗證版…

kotlin kmp 副作用函數 effect

在 Kotlin Multiplatform (KMP) Compose 中&#xff0c;“effect functions”&#xff08;或“effect handlers”&#xff09;是專門的可組合函數&#xff0c;用于在 UI 中管理副作用。 在 Compose 中&#xff0c;可組合函數應該是“純”的和聲明式的。這意味著它們應該理想地…

3.3.1_1 檢錯編碼(奇偶校驗碼)

從這節課開始&#xff0c;我們會探討數據鏈路層的差錯控制功能&#xff0c;差錯控制功能的主要目標是要發現并且解決一個幀內部的位錯誤&#xff0c;我們需要使用特殊的編碼技術去發現幀內部的位錯誤&#xff0c;當我們發現位錯誤之后&#xff0c;通常來說有兩種解決方案。第一…

【Pandas】pandas DataFrame isna

Pandas2.2 DataFrame Missing data handling 方法描述DataFrame.fillna([value, method, axis, …])用于填充 DataFrame 中的缺失值&#xff08;NaN&#xff09;DataFrame.backfill(*[, axis, inplace, …])用于**使用后向填充&#xff08;即“下一個有效觀測值”&#xff09…

MQTT協議:物聯網時代的通信基石

MQTT協議&#xff1a;物聯網時代的通信基石 在當今快速發展的物聯網&#xff08;IoT&#xff09;時代&#xff0c;設備之間的通信變得尤為重要。MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;協議作為一種輕量級的消息傳輸協議&#xff0c;正逐漸成為物聯…

Excel 表格內批量添加前綴與后綴的實用方法

我們經常需要為 Excel 表格中的內容統一添加前綴或后綴&#xff0c;例如給編號加“NO.”、給姓名加“會員_”等。手動操作效率低&#xff0c;本文將介紹幾種實用的方法&#xff0c;幫助你快速完成批量添加前綴和后綴的操作。 使用“&”運算符添加前綴或后綴&#xff08;推…

uniapp 實現騰訊云IM群文件上傳下載功能

UniApp 集成騰訊云IM實現群文件上傳下載功能全攻略 一、功能背景與技術選型 在團隊協作場景中&#xff0c;群文件共享是核心需求之一。本文將介紹如何基于騰訊云IMCOS&#xff0c;在uniapp中實現&#xff1a; 群內文件上傳/下載文件元數據管理下載進度追蹤跨平臺文件預覽 二…

GO協程(Goroutine)問題總結

在使用Go語言來編寫代碼時&#xff0c;遇到的一些問題總結一下 [參考文檔]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函數默認的Goroutine 場景再現&#xff1a; 今天在看到這個教程的時候&#xff0c;在自己的電…