x64传参约定

前言

和学长讨论x64函数传参的问题, 用哪几个寄存器传前4个参,记不清了,做个试验.

记录

// Test1230.cpp : Defines the entry point for the console application.
//

// x64传参约定
// x64传参是fastcall调用约定
// x64传参时, 参数<=4个时,参数从右往左用寄存器传参
// x64传参时, 参数>4个时,参数从右往左前4个参数用寄存器传参, 剩下参数用栈传参(最右面的参数先入栈)
// 但是我想不起来用哪4个寄存器传参了, 做个试验.

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>

void fnTest(int iParam1, int iParam2, int iParam3, int iParam4, int iParam5, int iParam6);
int _tmain(int argc, _TCHAR* argv[])
{
    // 调用 fnTest 之前的反汇编实现
    /**
    000000013F6C10C0 | 48 89 54 24 10           | mov qword ptr ss:[rsp+10],rdx                         | test1230.cpp:15
    000000013F6C10C5 | 89 4C 24 08              | mov dword ptr ss:[rsp+8],ecx                          |
    000000013F6C10C9 | 57                       | push rdi                                              |
    000000013F6C10CA | 48 83 EC 30              | sub rsp,30                                            |
    000000013F6C10CE | 48 8B FC                 | mov rdi,rsp                                           |
    000000013F6C10D1 | B9 0C 00 00 00           | mov ecx,C                                             |
    000000013F6C10D6 | B8 CC CC CC CC           | mov eax,CCCCCCCC                                      |
    000000013F6C10DB | F3 AB                    | rep stosd dword ptr ds:[rdi],eax                      |
    000000013F6C10DD | 8B 4C 24 40              | mov ecx,dword ptr ss:[rsp+40]                         |
    000000013F6C10E1 | C7 44 24 28 06 00 00 00  | mov dword ptr ss:[rsp+28],6                           | test1230.cpp:16
    000000013F6C10E9 | C7 44 24 20 05 00 00 00  | mov dword ptr ss:[rsp+20],5                           |
    000000013F6C10F1 | 41 B9 04 00 00 00        | mov r9d,4                                             |
    000000013F6C10F7 | 41 B8 03 00 00 00        | mov r8d,3                                             |
    000000013F6C10FD | BA 02 00 00 00           | mov edx,2                                             |
    000000013F6C1102 | B9 01 00 00 00           | mov ecx,1                                             |
    000000013F6C1107 | E8 F9 FE FF FF           | call <test1230.@ILT+0(?fnTest@@YAXHHHHHH@Z)>          |
    */

    // 可以看到参数传递过程
    // 超过4个参数后, 参数从右往左入栈
    // push Param6 // 参数6
    // push Param5 // 参数5
    // 前4个参数进入寄存器,老手的口头禅, 所谓的 : cd89
    // mov r9d, 4 // 参数4
    // mov r8d, 3 // 参数3
    // mov edx, 2 // 参数2
    // mov ecx, 1 // 参数1

    // 如果一个函数很复杂, 在release版下不会优化成内联实现, 也符合这种传参约定
    fnTest(1, 2, 3, 4, 5, 6);
    return 0;
}

// 这函数太简单了, 编译成release版, 内联了.
// 用Debug版看吧
void fnTest(int iParam1, int iParam2, int iParam3, int iParam4, int iParam5, int iParam6)
{
    printf("iParam1 = %d\r\n", iParam1);
    printf("iParam2 = %d\r\n", iParam2);
    printf("iParam3 = %d\r\n", iParam3);
    printf("iParam4 = %d\r\n", iParam4);
    printf("iParam5 = %d\r\n", iParam5);
    printf("iParam6 = %d\r\n", iParam6);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值