当前位置: 首页 > news >正文

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

1. 汇编代码

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

1.1 debug编译

eight_mixed_params:00000000000008A0: 44 88 4C 24 20     mov         byte ptr [rsp+20h],r9b00000000000008A5: F2 0F 11 54 24 18  movsd       mmword ptr [rsp+18h],xmm200000000000008AB: F3 0F 11 4C 24 10  movss       dword ptr [rsp+10h],xmm100000000000008B1: 89 4C 24 08        mov         dword ptr [rsp+8],ecx00000000000008B5: 57                 push        rdi00000000000008B6: 48 83 EC 20        sub         rsp,20h00000000000008BA: 48 8B FC           mov         rdi,rsp00000000000008BD: B9 08 00 00 00     mov         ecx,800000000000008C2: B8 CC CC CC CC     mov         eax,0CCCCCCCCh00000000000008C7: 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,eax00000000000008D4: 74 10              je          00000000000008E600000000000008D6: F2 0F 10 05 00 00  movsd       xmm0,mmword ptr [__real@3ff0000000000000]00 0000000000000008DE: F2 0F 11 44 24 18  movsd       mmword ptr [rsp+18h],xmm000000000000008E4: EB 09              jmp         00000000000008EF00000000000008E6: 0F 57 C0           xorps       xmm0,xmm000000000000008E9: F2 0F 11 44 24 18  movsd       mmword ptr [rsp+18h],xmm000000000000008EF: 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,xmm100000000000008FF: 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,eax000000000000090E: F2 0F 58 C1        addsd       xmm0,xmm10000000000000912: 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,eax0000000000000921: F2 0F 58 C1        addsd       xmm0,xmm10000000000000925: F2 0F 2A 4C 24 60  cvtsi2sd    xmm1,dword ptr [rsp+60h]000000000000092B: F2 0F 58 C1        addsd       xmm0,xmm1000000000000092F: 8B 44 24 68        mov         eax,dword ptr [rsp+68h]0000000000000933: F2 48 0F 2A C8     cvtsi2sd    xmm1,rax0000000000000938: F2 0F 58 C1        addsd       xmm0,xmm1000000000000093C: F2 0F 11 44 24 10  movsd       mmword ptr [rsp+10h],xmm00000000000000942: 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 000000000000000950: 48 83 C4 20        add         rsp,20h0000000000000954: 5F                 pop         rdi0000000000000955: C3                 ret0000000000000956: CC                 int         30000000000000957: CC                 int         3

1.2 release编译

eight_mixed_params:0000000000000000: 80 7C 24 28 00     cmp         byte ptr [rsp+28h],00000000000000005: 74 0A              je          00000000000000110000000000000007: F2 0F 10 25 00 00  movsd       xmm4,mmword ptr [__real@3ff0000000000000]00 00000000000000000F: EB 03              jmp         00000000000000140000000000000011: 0F 57 E4           xorps       xmm4,xmm40000000000000014: 0F 57 DB           xorps       xmm3,xmm30000000000000017: 41 0F BE C1        movsx       eax,r9b000000000000001B: F2 0F 2A D9        cvtsi2sd    xmm3,ecx000000000000001F: 0F 57 C0           xorps       xmm0,xmm00000000000000022: F3 0F 5A C1        cvtss2sd    xmm0,xmm10000000000000026: 0F 57 C9           xorps       xmm1,xmm10000000000000029: F2 0F 58 D8        addsd       xmm3,xmm0000000000000002D: 0F 57 C0           xorps       xmm0,xmm00000000000000030: F2 0F 2A C0        cvtsi2sd    xmm0,eax0000000000000034: 0F BF 44 24 30     movsx       eax,word ptr [rsp+30h]0000000000000039: F2 0F 58 DA        addsd       xmm3,xmm2000000000000003D: 0F 57 D2           xorps       xmm2,xmm20000000000000040: F2 0F 2A 54 24 38  cvtsi2sd    xmm2,dword ptr [rsp+38h]0000000000000046: F2 0F 58 D8        addsd       xmm3,xmm0000000000000004A: F2 0F 2A C8        cvtsi2sd    xmm1,eax000000000000004E: 8B 44 24 40        mov         eax,dword ptr [rsp+40h]0000000000000052: F2 0F 58 DC        addsd       xmm3,xmm40000000000000056: F2 0F 58 D9        addsd       xmm3,xmm1000000000000005A: 0F 57 C9           xorps       xmm1,xmm1000000000000005D: F2 48 0F 2A C8     cvtsi2sd    xmm1,rax0000000000000062: F2 0F 58 DA        addsd       xmm3,xmm20000000000000066: F2 0F 58 D9        addsd       xmm3,xmm1000000000000006A: F2 0F 59 1D 00 00  mulsd       xmm3,mmword ptr [__real@3fc0000000000000]00 000000000000000072: 0F 28 C3           movaps      xmm0,xmm30000000000000075: C3                 ret

2. 汇编分析

2.1 调用者压栈

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

  00000000000008A0: 44 88 4C 24 20     mov         byte ptr [rsp+20h],r9b00000000000008A5: F2 0F 11 54 24 18  movsd       mmword ptr [rsp+18h],xmm200000000000008AB: F3 0F 11 4C 24 10  movss       dword ptr [rsp+10h],xmm100000000000008B1: 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-=800000000000008B6: 48 83 EC 20        sub         rsp,20h  ; rsp-=0x20h

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

...0000000000000921: F2 0F 58 C1        addsd       xmm0,xmm10000000000000925: F2 0F 2A 4C 24 60  cvtsi2sd    xmm1,dword ptr [rsp+60h]000000000000092B: F2 0F 58 C1        addsd       xmm0,xmm1000000000000092F: 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,eax00000000000008D4: 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,eax00000000000008D4: 74 10              je          00000000000008E600000000000008D6: F2 0F 10 05 00 00  movsd       xmm0,mmword ptr [__real@3ff0000000000000]00 0000000000000008DE: F2 0F 11 44 24 18  movsd       mmword ptr [rsp+18h],xmm000000000000008E4: EB 09              jmp         00000000000008EF00000000000008E6: 0F 57 C0           xorps       xmm0,xmm000000000000008E9: F2 0F 11 44 24 18  movsd       mmword ptr [rsp+18h],xmm000000000000008EF: 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 0000000000000008DE: 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, rsp00000000000008BD: B9 08 00 00 00     mov         ecx, 800000000000008C2: B8 CC CC CC CC     mov         eax, 0CCCCCCCCh00000000000008C7: 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_branch00000000000008D4: 74 10              je          false_branch; === 条件为真分支 (condition != 0) ===; 加载双精度常量 1.000000000000008D6: 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], xmm000000000000008E4: 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 -> xmm000000000000008EF: F2 0F 2A 44 24 30  cvtsi2sd    xmm0, dword ptr [rsp+30h]  ; [rsp+30h] = 参数1; 加载参数2 (float) 并转换为 double -> xmm100000000000008F5: F3 0F 5A 4C 24 38  cvtss2sd    xmm1, dword ptr [rsp+38h]  ; [rsp+38h] = 参数2; 累加参数2: xmm0 += xmm100000000000008FB: 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 -> xmm1000000000000090A: F2 0F 2A C8        cvtsi2sd    xmm1, eax; 累加参数4: xmm0 += xmm1000000000000090E: 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 -> xmm1000000000000091D: F2 0F 2A C8        cvtsi2sd    xmm1, eax; 累加参数6: xmm0 += xmm10000000000000921: F2 0F 58 C1        addsd       xmm0, xmm1; 加载参数7 (int) 并转换为 double -> xmm10000000000000925: F2 0F 2A 4C 24 60  cvtsi2sd    xmm1, dword ptr [rsp+60h]  ; [rsp+60h] = 参数7; 累加参数7: xmm0 += xmm1000000000000092B: 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位) -> xmm10000000000000933: F2 48 0F 2A C8     cvtsi2sd    xmm1, rax; 累加参数8: xmm0 += xmm10000000000000938: F2 0F 58 C1        addsd       xmm0, xmm1; === 结果处理 ===; 将累加结果存入局部变量 [rsp+10h]000000000000093C: F2 0F 11 44 24 10  movsd       mmword ptr [rsp+10h], xmm0; 重新加载到 xmm00000000000000942: F2 0F 10 44 24 10  movsd       xmm0, mmword ptr [rsp+10h]; 除以双精度常量 8.00000000000000948: 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)是否为00000000000000005: 74 0A              je          0000000000000011        ; 若为0跳转false分支; -- 条件为真分支(condition != 0)--0000000000000007: F2 0F 10 25 00 00  movsd       xmm4, mmword ptr [__real@3ff0000000000000]  ; 加载1.0到xmm400 00000000000000000F: 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              ; 清零xmm00000000000000022: 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              ; 清零xmm00000000000000030: 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              ; 清零xmm20000000000000040: 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              ; 清零xmm1000000000000005D: F2 48 0F 2A C8     cvtsi2sd    xmm1, rax               ; 将32位整数零扩展为64位后再转换(负数会出错); -- 累加第7个(p6)和第8个参数(p7)--0000000000000062: F2 0F 58 DA        addsd       xmm3, xmm2              ; 累加p60000000000000066: 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 000000000000000072: 0F 28 C3           movaps      xmm0, xmm3              ; 结果存入返回寄存器xmm00000000000000075: 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;          // 参数1sum += (double)p2;                 // 参数2sum += p3;                         // 参数3sum += (double)(signed char)p4;    // 参数4(有符号扩展)sum += condition_result;           // 条件结果sum += (double)p6;                 // 参数6sum += (double)p7;                 // 参数7sum += (double)p8;                 // 参数8// 除以8.0并返回结果return sum / 8.0;
}

相关文章:

  • 深入浅出多路归并:原理、实现与实战案例解析
  • centos7升级glibic-2.28
  • 局域网聊天软件
  • 数据结构与算法——二叉树高频题目(1)
  • 【设计模式-5】设计模式的总结
  • 【学习笔记】构造函数+重载相关
  • Halcon腐蚀例子
  • php执行系统命令的四个常用函数
  • cursor和windsurf使用体验对比
  • 国10平方拆分、数正方形
  • python --导出数据库表结构(pymysql)
  • 【Linux】awk 命令详解及使用示例:结构化文本数据处理工具
  • boost::qvm 使用示例
  • FineReport模板认证找不到模板
  • 逻辑卷和硬盘配额(补充)
  • GT接收端共模电压
  • 永磁同步电机控制算法--模糊PI转速控制器
  • Spring Cloud核心组件深度解析(2025终极指南)
  • nuScenes 数据集及同类型自动驾驶数据集介绍
  • vcs仿真产生fsdb波形的两种方式
  • 网站开发慕枫/百度关键词优化词精灵
  • 建设银行网站怎么下载/做网站的公司有哪些
  • 南昌哪里有网站建设/暴疯团队seo课程
  • 地产公司网站建设计划书/推广哪个网站好
  • 日本 男女做受网站/长沙建站seo公司
  • 上海集团平台app/seo服务是什么