【汇编逆向系列】八、函数调用包含混合参数-8种参数传参,条件跳转指令,转型指令,movaps 16字节指令

发布于:2025-06-08 ⋅ 阅读:(22) ⋅ 点赞:(0)

1. 汇编代码

本案例是通过函数传参传递8种不同的类型的参数,来巩固上两节所学习的知识。整型的传参和浮点型的传参和rsp栈空间的使用,影子空间的申请。

1.1 debug编译

eight_mixed_params:
  00000000000008A0: 44 88 4C 24 20     mov         byte ptr [rsp+20h],r9b
  00000000000008A5: F2 0F 11 54 24 18  movsd       mmword ptr [rsp+18h],xmm2
  00000000000008AB: F3 0F 11 4C 24 10  movss       dword ptr [rsp+10h],xmm1
  00000000000008B1: 89 4C 24 08        mov         dword ptr [rsp+8],ecx
  00000000000008B5: 57                 push        rdi
  00000000000008B6: 48 83 EC 20        sub         rsp,20h
  00000000000008BA: 48 8B FC           mov         rdi,rsp
  00000000000008BD: B9 08 00 00 00     mov         ecx,8
  00000000000008C2: B8 CC CC CC CC     mov         eax,0CCCCCCCCh
  00000000000008C7: F3 AB              rep stos    dword ptr [rdi]
  00000000000008C9: 8B 4C 24 30        mov         ecx,dword ptr [rsp+30h]
  00000000000008CD: 0F B6 44 24 50     movzx       eax,byte ptr [rsp+50h]
  00000000000008D2: 85 C0              test        eax,eax
  00000000000008D4: 74 10              je          00000000000008E6
  00000000000008D6: F2 0F 10 05 00 00  movsd       xmm0,mmword ptr [__real@3ff0000000000000]
                    00 00
  00000000000008DE: F2 0F 11 44 24 18  movsd       mmword ptr [rsp+18h],xmm0
  00000000000008E4: EB 09              jmp         00000000000008EF
  00000000000008E6: 0F 57 C0           xorps       xmm0,xmm0
  00000000000008E9: F2 0F 11 44 24 18  movsd       mmword ptr [rsp+18h],xmm0
  00000000000008EF: F2 0F 2A 44 24 30  cvtsi2sd    xmm0,dword ptr [rsp+30h]
  00000000000008F5: F3 0F 5A 4C 24 38  cvtss2sd    xmm1,dword ptr [rsp+38h]
  00000000000008FB: F2 0F 58 C1        addsd       xmm0,xmm1
  00000000000008FF: F2 0F 58 44 24 40  addsd       xmm0,mmword ptr [rsp+40h]
  0000000000000905: 0F BE 44 24 48     movsx       eax,byte ptr [rsp+48h]
  000000000000090A: F2 0F 2A C8        cvtsi2sd    xmm1,eax
  000000000000090E: F2 0F 58 C1        addsd       xmm0,xmm1
  0000000000000912: F2 0F 58 44 24 18  addsd       xmm0,mmword ptr [rsp+18h]
  0000000000000918: 0F BF 44 24 58     movsx       eax,word ptr [rsp+58h]
  000000000000091D: F2 0F 2A C8        cvtsi2sd    xmm1,eax
  0000000000000921: F2 0F 58 C1        addsd       xmm0,xmm1
  0000000000000925: F2 0F 2A 4C 24 60  cvtsi2sd    xmm1,dword ptr [rsp+60h]
  000000000000092B: F2 0F 58 C1        addsd       xmm0,xmm1
  000000000000092F: 8B 44 24 68        mov         eax,dword ptr [rsp+68h]
  0000000000000933: F2 48 0F 2A C8     cvtsi2sd    xmm1,rax
  0000000000000938: F2 0F 58 C1        addsd       xmm0,xmm1
  000000000000093C: F2 0F 11 44 24 10  movsd       mmword ptr [rsp+10h],xmm0
  0000000000000942: F2 0F 10 44 24 10  movsd       xmm0,mmword ptr [rsp+10h]
  0000000000000948: F2 0F 5E 05 00 00  divsd       xmm0,mmword ptr [__real@4020000000000000]
                    00 00
  0000000000000950: 48 83 C4 20        add         rsp,20h
  0000000000000954: 5F                 pop         rdi
  0000000000000955: C3                 ret
  0000000000000956: CC                 int         3
  0000000000000957: CC                 int         3

1.2 release编译

eight_mixed_params:
  0000000000000000: 80 7C 24 28 00     cmp         byte ptr [rsp+28h],0
  0000000000000005: 74 0A              je          0000000000000011
  0000000000000007: F2 0F 10 25 00 00  movsd       xmm4,mmword ptr [__real@3ff0000000000000]
                    00 00
  000000000000000F: EB 03              jmp         0000000000000014
  0000000000000011: 0F 57 E4           xorps       xmm4,xmm4
  0000000000000014: 0F 57 DB           xorps       xmm3,xmm3
  0000000000000017: 41 0F BE C1        movsx       eax,r9b
  000000000000001B: F2 0F 2A D9        cvtsi2sd    xmm3,ecx
  000000000000001F: 0F 57 C0           xorps       xmm0,xmm0
  0000000000000022: F3 0F 5A C1        cvtss2sd    xmm0,xmm1
  0000000000000026: 0F 57 C9           xorps       xmm1,xmm1
  0000000000000029: F2 0F 58 D8        addsd       xmm3,xmm0
  000000000000002D: 0F 57 C0           xorps       xmm0,xmm0
  0000000000000030: F2 0F 2A C0        cvtsi2sd    xmm0,eax
  0000000000000034: 0F BF 44 24 30     movsx       eax,word ptr [rsp+30h]
  0000000000000039: F2 0F 58 DA        addsd       xmm3,xmm2
  000000000000003D: 0F 57 D2           xorps       xmm2,xmm2
  0000000000000040: F2 0F 2A 54 24 38  cvtsi2sd    xmm2,dword ptr [rsp+38h]
  0000000000000046: F2 0F 58 D8        addsd       xmm3,xmm0
  000000000000004A: F2 0F 2A C8        cvtsi2sd    xmm1,eax
  000000000000004E: 8B 44 24 40        mov         eax,dword ptr [rsp+40h]
  0000000000000052: F2 0F 58 DC        addsd       xmm3,xmm4
  0000000000000056: F2 0F 58 D9        addsd       xmm3,xmm1
  000000000000005A: 0F 57 C9           xorps       xmm1,xmm1
  000000000000005D: F2 48 0F 2A C8     cvtsi2sd    xmm1,rax
  0000000000000062: F2 0F 58 DA        addsd       xmm3,xmm2
  0000000000000066: F2 0F 58 D9        addsd       xmm3,xmm1
  000000000000006A: F2 0F 59 1D 00 00  mulsd       xmm3,mmword ptr [__real@3fc0000000000000]
                    00 00
  0000000000000072: 0F 28 C3           movaps      xmm0,xmm3
  0000000000000075: C3                 ret

2. 汇编分析

2.1 调用者压栈

调用这个函数的调用者需要先将函数压栈到rsp栈帧寄存器,通过

  00000000000008A0: 44 88 4C 24 20     mov         byte ptr [rsp+20h],r9b
  00000000000008A5: F2 0F 11 54 24 18  movsd       mmword ptr [rsp+18h],xmm2
  00000000000008AB: F3 0F 11 4C 24 10  movss       dword ptr [rsp+10h],xmm1
  00000000000008B1: 89 4C 24 08        mov         dword ptr [rsp+8],ecx

 代码可知,r9b 为第四个参数是整型,byte是1字节,所以第四个参数是char型

xmm2为浮点型的第3个参数,mmword是8字节指令,所以第三个参数是double型

xmm1为浮点型的第二个参数,dword是4字节指令,所以第二个参数是float型

ecx为整型的第一个参数,dowrd是4字节指令,所以第一个参数是int型

这里参考了相关章节的知识:

【汇编逆向系列】四、函数调用包含单个参数之Double类型-mmword,movsd,mulsd,addsd指令,总结汇编的数据类型

 后面的参数应该是压入[rsp+28h]之后的地址,那么如何知道一共有多少参数?需要了解rsp是如何变化的。

2.2 rsp和参数地址变化

首先在前面章节我们知道函数传参的时候会创建一个0x20大小的影子空间[rsp]-[rsp+0x20],在使用call指令调用的时候rsp -= 0x8,由于栈的地址是向上增长的,影子空间会变化为[rsp+8]-[rsp+0x28], 所以2.1的第一个参数放入的地址变成了[rsp+8], 在调用如下两条指令后

  00000000000008B5: 57                 push        rdi      ;rsp-=8
  00000000000008B6: 48 83 EC 20        sub         rsp,20h  ; rsp-=0x20h

 rsp -= 0x28h, 所以影子空间地址变化为[rsp+0x30]-[rsp+0x50], 再看后续汇编

...
  0000000000000921: F2 0F 58 C1        addsd       xmm0,xmm1
  0000000000000925: F2 0F 2A 4C 24 60  cvtsi2sd    xmm1,dword ptr [rsp+60h]
  000000000000092B: F2 0F 58 C1        addsd       xmm0,xmm1
  000000000000092F: 8B 44 24 68        mov         eax,dword ptr [rsp+68h]

可以看到最后一个获取的参数地址为[rsp+0x68h], 所有操作指令最大为8字节操作指令, 那么从影子空间的结尾[rsp+0x50]到[rsp+0x68],一共有[rsp+0x50][rsp+0x58][rsp+0x60][rsp+0x68]4个参数,所以一共有8个参数被传入到这个函数中来。

2.3  JE,JMP指令

在前面的章节中介绍了test和movzx指令:

【汇编逆向系列】五、函数调用单个参数之char型和布尔型-TEST,JNE,JMP,SET条件设置和跳转指令

这段汇编使用了JE指令:

  00000000000008CD: 0F B6 44 24 50     movzx       eax,byte ptr [rsp+50h]
  00000000000008D2: 85 C0              test        eax,eax
  00000000000008D4: 74 10              je          00000000000008E6

movzx是零拓展,说明[rsp+0x50h]是一个bool值, 将第五个参数放到eax寄存器, test指令来判断第五个参数是否为0,为0的话将ZF标值寄存器置1.

2.3.1 JE 条件跳转

ZF标志位为1的时候,跳转到对应地址

  00000000000008CD: 0F B6 44 24 50     movzx       eax,byte ptr [rsp+50h]
  00000000000008D2: 85 C0              test        eax,eax
  00000000000008D4: 74 10              je          00000000000008E6
  00000000000008D6: F2 0F 10 05 00 00  movsd       xmm0,mmword ptr [__real@3ff0000000000000]
                    00 00
  00000000000008DE: F2 0F 11 44 24 18  movsd       mmword ptr [rsp+18h],xmm0
  00000000000008E4: EB 09              jmp         00000000000008EF
  00000000000008E6: 0F 57 C0           xorps       xmm0,xmm0
  00000000000008E9: F2 0F 11 44 24 18  movsd       mmword ptr [rsp+18h],xmm0
  00000000000008EF: F2 0F 2A 44 24 30  cvtsi2sd    xmm0,dword ptr [rsp+30h]

 当第五个参数为0的时候,跳转到00000000000008E6地址,

00000000000008E6地址执行为: xorps       xmm0,xmm0

这个操作是生成一个浮点数0.0,再将0.0存入到[rsp+18]这个地址,这个地址是sub rsp 20h中的,说明是一个临时变量。

当第五个参数不为0的时候,继续向下执行:

  00000000000008D6: F2 0F 10 05 00 00  movsd       xmm0,mmword ptr [__real@3ff0000000000000]
                    00 00
  00000000000008DE: F2 0F 11 44 24 18  movsd       mmword ptr [rsp+18h],xmm0

 给xmm0复制浮点数 1.0  <= [3ff0000000000000], 再存到临时变量[rsp+0x18h]

可以理解为这理就是一个c语言当中的?:语法

p5 == 0? 0.0 : 1.0;

2.3.2 JMP强制跳转

JMP指令为强制跳转指令,直接跳转到参数的地址的位置

2.4 cvtss2sd和cvtsi2sd指令

cvtss2sd和cvtsi2sd都是双精度浮点型的转化指令,区别在于cvtsi2sd是整型向双精度浮点型转化,而cvtss2sd是单精度浮点型向双精度浮点型的转化,以下表格是他们的区别:

2.4.1 cvtsi2sd指令

cvtsi2sd(Convert Signed Integer to Scalar Double)​

使用语法:

cvtsi2sd xmm_dest, src  ; src 可为通用寄存器(如 eax)或内存地址(如 [mem])

 将源操作数(32/64位有符号整数)转换为双精度浮点数,结果存入目标 XMM 寄存器的​​低64位​​,高64位保持不变

示例:

cvtsi2sd xmm0, eax      ; 将 eax 中的整数转为 double 存入 xmm0 低位

2.4.2 cvtss2sd指令

cvtss2sd(Convert Scalar Single to Scalar Double)​

使用语法:

cvtss2sd xmm_dest, src  ; src 可为 XMM 寄存器(如 xmm1)或内存地址(如 [mem])

 将源操作数(32位单精度浮点数)扩展为双精度浮点数,结果存入目标 XMM 寄存器的​​低64位​​,高64位不变

示例:

cvtss2sd xmm0, xmm1     ; 将 xmm1 低位的 float 转为 double 存入 xmm0 低位

2.5 xorps指令

 XORPS 是 x86/x64 架构中的一条 ​​SIMD 浮点指令​​,属于 SSE 指令集。它执行按位逻辑异或(XOR)操作,用于对 XMM 寄存器中的浮点数进行位运算。

基础语法:

XORPS xmm_dest, xmm_src
  •  操作​​:xmm_dest = xmm_dest XOR xmm_src
  • ​操作数​​:两个 128 位 XMM 寄存器
  • ​效果​​:对目标寄存器和源寄存器的每一位进行异或运算

经典用途:

XORPS xmm0, xmm0  ; 将 xmm0 置为零

 用于将寄存器快速置0

2.5 movaps指令

MOVAPS 是 x86/x64 架构中的一条 ​​SIMD 浮点数据传输指令​​,属于 SSE(Streaming SIMD Extensions)指令集。

  • ​作用​​:在 XMM 寄存器之间或 XMM 寄存器与内存之间传输 128 位数据
  • 要求 ​​16 字节对齐​​的内存地址
  • 操作对象是 ​​4 个打包的单精度浮点数​​(但实际传输原始二进制位)

语法格式:

MOVAPS xmm1, xmm2/mem128  ; 加载模式:内存/寄存器 → 寄存器
MOVAPS mem128, xmm1        ; 存储模式:寄存器 → 内存

3. 汇编转化

3.1 debug编译

eight_mixed_params:
  ; === 保存前4个参数到影子空间 ===
  ; 参数4 (char) 从 r9b 存到 [rsp+20h]
  00000000000008A0: 44 88 4C 24 20     mov         byte ptr [rsp+20h], r9b
  ; 参数3 (double) 从 xmm2 存到 [rsp+18h]
  00000000000008A5: F2 0F 11 54 24 18  movsd       mmword ptr [rsp+18h], xmm2
  ; 参数2 (float) 从 xmm1 存到 [rsp+10h]
  00000000000008AB: F3 0F 11 4C 24 10  movss       dword ptr [rsp+10h], xmm1
  ; 参数1 (int) 从 ecx 存到 [rsp+8]
  00000000000008B1: 89 4C 24 08        mov         dword ptr [rsp+8], ecx

  ; === 函数序幕 ===
  ; 保存 rdi 寄存器
  00000000000008B5: 57                 push        rdi
  ; 分配 32 字节局部空间
  00000000000008B6: 48 83 EC 20        sub         rsp, 20h
  ; 初始化栈空间为 0xCC (调试模式特有的未初始化标记)
  00000000000008BA: 48 8B FC           mov         rdi, rsp
  00000000000008BD: B9 08 00 00 00     mov         ecx, 8
  00000000000008C2: B8 CC CC CC CC     mov         eax, 0CCCCCCCCh
  00000000000008C7: F3 AB              rep stos    dword ptr [rdi]

  ; === 条件分支处理 ===
  ; 加载参数1 (int) 到 ecx (实际未使用)
  00000000000008C9: 8B 4C 24 30        mov         ecx, dword ptr [rsp+30h]  ; [rsp+30h] = 影子空间中的参数1
  ; 加载参数5 (bool) 并进行零扩展
  00000000000008CD: 0F B6 44 24 50     movzx       eax, byte ptr [rsp+50h]  ; [rsp+50h] = 参数5
  ; 测试条件值
  00000000000008D2: 85 C0              test        eax, eax
  ; 如果为0则跳转到 false_branch
  00000000000008D4: 74 10              je          false_branch

  ; === 条件为真分支 (condition != 0) ===
  ; 加载双精度常量 1.0
  00000000000008D6: F2 0F 10 05 00 00  movsd       xmm0, mmword ptr [__real@3ff0000000000000]
                    00 00
  ; 将 1.0 存入局部变量 [rsp+18h]
  00000000000008DE: F2 0F 11 44 24 18  movsd       mmword ptr [rsp+18h], xmm0
  00000000000008E4: EB 09              jmp         after_condition

  ; === 条件为假分支 (condition == 0) ===
false_branch:
  ; 将 xmm0 清零 (生成 0.0)
  00000000000008E6: 0F 57 C0           xorps       xmm0, xmm0
  ; 将 0.0 存入局部变量 [rsp+18h]
  00000000000008E9: F2 0F 11 44 24 18  movsd       mmword ptr [rsp+18h], xmm0

  ; === 参数累加阶段 ===
after_condition:
  ; 加载参数1 (int) 并转换为 double -> xmm0
  00000000000008EF: F2 0F 2A 44 24 30  cvtsi2sd    xmm0, dword ptr [rsp+30h]  ; [rsp+30h] = 参数1
  ; 加载参数2 (float) 并转换为 double -> xmm1
  00000000000008F5: F3 0F 5A 4C 24 38  cvtss2sd    xmm1, dword ptr [rsp+38h]  ; [rsp+38h] = 参数2
  ; 累加参数2: xmm0 += xmm1
  00000000000008FB: F2 0F 58 C1        addsd       xmm0, xmm1
  ; 累加参数3 (double): xmm0 += [rsp+40h] ([rsp+40h] = 参数3)
  00000000000008FF: F2 0F 58 44 24 40  addsd       xmm0, mmword ptr [rsp+40h]
  ; 加载参数4 (char) 并进行符号扩展
  0000000000000905: 0F BE 44 24 48     movsx       eax, byte ptr [rsp+48h]  ; [rsp+48h] = 参数4
  ; 将扩展后的值转换为 double -> xmm1
  000000000000090A: F2 0F 2A C8        cvtsi2sd    xmm1, eax
  ; 累加参数4: xmm0 += xmm1
  000000000000090E: F2 0F 58 C1        addsd       xmm0, xmm1
  ; 累加局部变量 (条件结果): xmm0 += [rsp+18h]
  0000000000000912: F2 0F 58 44 24 18  addsd       xmm0, mmword ptr [rsp+18h]
  ; 加载参数6 (short) 并进行符号扩展
  0000000000000918: 0F BF 44 24 58     movsx       eax, word ptr [rsp+58h]  ; [rsp+58h] = 参数6
  ; 将扩展后的值转换为 double -> xmm1
  000000000000091D: F2 0F 2A C8        cvtsi2sd    xmm1, eax
  ; 累加参数6: xmm0 += xmm1
  0000000000000921: F2 0F 58 C1        addsd       xmm0, xmm1
  ; 加载参数7 (int) 并转换为 double -> xmm1
  0000000000000925: F2 0F 2A 4C 24 60  cvtsi2sd    xmm1, dword ptr [rsp+60h]  ; [rsp+60h] = 参数7
  ; 累加参数7: xmm0 += xmm1
  000000000000092B: F2 0F 58 C1        addsd       xmm0, xmm1
  ; 加载参数8 (long) -> eax (低32位)
  000000000000092F: 8B 44 24 68        mov         eax, dword ptr [rsp+68h]  ; [rsp+68h] = 参数8的低位
  ; 将参数8转换为 double (完整64位) -> xmm1
  0000000000000933: F2 48 0F 2A C8     cvtsi2sd    xmm1, rax
  ; 累加参数8: xmm0 += xmm1
  0000000000000938: F2 0F 58 C1        addsd       xmm0, xmm1

  ; === 结果处理 ===
  ; 将累加结果存入局部变量 [rsp+10h]
  000000000000093C: F2 0F 11 44 24 10  movsd       mmword ptr [rsp+10h], xmm0
  ; 重新加载到 xmm0
  0000000000000942: F2 0F 10 44 24 10  movsd       xmm0, mmword ptr [rsp+10h]
  ; 除以双精度常量 8.0
  0000000000000948: F2 0F 5E 05 00 00  divsd       xmm0, mmword ptr [__real@4020000000000000]
                    00 00

  ; === 函数收尾 ===
  ; 释放局部空间
  0000000000000950: 48 83 C4 20        add         rsp, 20h
  ; 恢复 rdi 寄存器
  0000000000000954: 5F                 pop         rdi
  ; 返回结果在 xmm0 中
  0000000000000955: C3                 ret
  
  ; === 调试断点 ===
  0000000000000956: CC                 int         3

3.2 release编译

eight_mixed_params:
  ; ===== 条件分支处理(基于第5个参数condition) =====
  0000000000000000: 80 7C 24 28 00     cmp         byte ptr [rsp+28h],0   ; 比较第5个参数(condition)是否为0
  0000000000000005: 74 0A              je          0000000000000011        ; 若为0跳转false分支
  
  ; -- 条件为真分支(condition != 0)--
  0000000000000007: F2 0F 10 25 00 00  movsd       xmm4, mmword ptr [__real@3ff0000000000000]  ; 加载1.0到xmm4
                    00 00
  000000000000000F: EB 03              jmp         0000000000000014        ; 跳过false分支
  
  ; -- 条件为假分支(condition == 0)--
  0000000000000011: 0F 57 E4           xorps       xmm4, xmm4             ; xmm4 = 0.0

  ; ===== 开始累加参数值(全部转换为双精度浮点) =====
  0000000000000014: 0F 57 DB           xorps       xmm3, xmm3             ; 清零xmm3(用于累加)
  
  ; -- 转换并累加第4个参数(char p4)--
  0000000000000017: 41 0F BE C1        movsx       eax, r9b                ; 扩展r9b中的char参数(符号扩展)
  000000000000001B: F2 0F 2A D9        cvtsi2sd    xmm3, ecx               ; 转换第1个参数(int p1)到xmm3
  
  ; -- 转换并累加第2个参数(float p2)--
  000000000000001F: 0F 57 C0           xorps       xmm0, xmm0              ; 清零xmm0
  0000000000000022: F3 0F 5A C1        cvtss2sd    xmm0, xmm1              ; 转换float参数(p2)
  0000000000000026: 0F 57 C9           xorps       xmm1, xmm1              ; 清零xmm1(暂存)
  0000000000000029: F2 0F 58 D8        addsd       xmm3, xmm0              ; p1 + p2 → xmm3
  
  ; -- 转换并累加第4个参数(char p4)--
  000000000000002D: 0F 57 C0           xorps       xmm0, xmm0              ; 清零xmm0
  0000000000000030: F2 0F 2A C0        cvtsi2sd    xmm0, eax               ; 转换char参数(p4)
  
  ; -- 转换并累加第6个参数(short p5)--
  0000000000000034: 0F BF 44 24 30     movsx       eax, word ptr [rsp+30h] ; 加载第6个参数(栈偏移0x30,short类型)
  
  ; -- 累加第3个参数(double p3)--
  0000000000000039: F2 0F 58 DA        addsd       xmm3, xmm2             ; 累加p3
  
  ; -- 转换第7个参数(int p6)--
  000000000000003D: 0F 57 D2           xorps       xmm2, xmm2              ; 清零xmm2
  0000000000000040: F2 0F 2A 54 24 38  cvtsi2sd    xmm2, dword ptr [rsp+38h] ; 转换第7个参数(int p6)
  
  ; -- 累加第4个参数(p4)--
  0000000000000046: F2 0F 58 D8        addsd       xmm3, xmm0              ; 累加p4
  
  ; -- 转换并累加第6个参数(short p5)--
  000000000000004A: F2 0F 2A C8        cvtsi2sd    xmm1, eax               ; 转换short参数(p5)
  
  ; -- 加载第8个参数(int p7)--
  000000000000004E: 8B 44 24 40        mov         eax, dword ptr [rsp+40h] ; 加载第8个参数(栈偏移0x40,int类型)
  
  ; -- 累加条件结果值(xmm4)--
  0000000000000052: F2 0F 58 DC        addsd       xmm3, xmm4              ; 累加condition结果
  
  ; -- 累加第6个参数(p5)--
  0000000000000056: F2 0F 58 D9        addsd       xmm3, xmm1              ; 累加p5
  
  ; -- 转换第8个参数(int p7)- 存在设计缺陷 --
  000000000000005A: 0F 57 C9           xorps       xmm1, xmm1              ; 清零xmm1
  000000000000005D: F2 48 0F 2A C8     cvtsi2sd    xmm1, rax               ; 将32位整数零扩展为64位后再转换(负数会出错)
  
  ; -- 累加第7个(p6)和第8个参数(p7)--
  0000000000000062: F2 0F 58 DA        addsd       xmm3, xmm2              ; 累加p6
  0000000000000066: F2 0F 58 D9        addsd       xmm3, xmm1              ; 累加p7

  ; ===== 结果处理 =====
  000000000000006A: F2 0F 59 1D 00 00  mulsd       xmm3, mmword ptr [__real@3fc0000000000000]  ; 乘以0.125(1/8)
                    00 00
  0000000000000072: 0F 28 C3           movaps      xmm0, xmm3              ; 结果存入返回寄存器xmm0
  0000000000000075: C3                 ret                                 ; 返回结果

3.3 C语言转化

double eight_mixed_params(
    int p1,          // 参数1: 整型
    float p2,        // 参数2: 单精度浮点
    double p3,       // 参数3: 双精度浮点
    char p4,         // 参数4: 字符型
    bool condition,  // 参数5: 布尔型
    short p6,        // 参数6: 短整型
    int p7,         // 参数7: 整型
    long p8         // 参数8: 长整型
) 
{
    // 根据条件生成结果值
    double condition_result = condition ? 1.0 : 0.0;
    
    // 将所有参数转换为double并累加
    double sum = (double)p1;          // 参数1
    sum += (double)p2;                 // 参数2
    sum += p3;                         // 参数3
    sum += (double)(signed char)p4;    // 参数4(有符号扩展)
    sum += condition_result;           // 条件结果
    sum += (double)p6;                 // 参数6
    sum += (double)p7;                 // 参数7
    sum += (double)p8;                 // 参数8
    
    // 除以8.0并返回结果
    return sum / 8.0;
}


网站公告

今日签到

点亮在社区的每一天
去签到