Loading... # 函数调用约定 x86应用程序的函数约定存在 stdcall、__cdecl、fastcall等方式。 x64应用程序的函数约定只有一种寄存器快速调用约定:前四个参数依次使用rcx(浮点对应 xmm0)、rdx(浮点对应 xmm1)、r8(浮点对应 xmm2)、r9(浮点对应 xmm3)进行传递;多于的参数通过栈进行,从左到右依次入栈。 # ret与retn区别 * ret表示执行完后,EIP即为上一层call 调用往下的地址,也就是返回地址(retaddr) * retn  举例: ``retn 10 `` 含义如下: ```汇编 pop eip add esp, 10h ret ``` # 无参无返回值 ```汇编 void function_no_ret() { 00007FF7D8101860 40 55 push rbp 00007FF7D8101862 57 push rdi 00007FF7D8101863 48 81 EC 08 01 00 00 sub rsp,108h //创建栈空间 00007FF7D810186A 48 8D 6C 24 20 lea rbp,[rsp+20h] 00007FF7D810186F 48 8B FC mov rdi,rsp 00007FF7D8101872 B9 42 00 00 00 mov ecx,42h 00007FF7D8101877 B8 CC CC CC CC mov eax,0CCCCCCCCh 00007FF7D810187C F3 AB rep stos dword ptr [rdi] //栈空间使用0xCC初始化,烫烫烫的来源 00007FF7D810187E 48 8D 0D A4 F7 00 00 lea rcx,[__BB8CE66A_testFunctionAsm@cpp (07FF7D8111029h)] 00007FF7D8101885 E8 E1 FA FF FF call __CheckForDebuggerJustMyCode (07FF7D810136Bh) //Just My Code=>http://blogs.msdn.com/b/profiler/archive/2011/05/13/vs2010-just-my-code.aspx double a; a = 3.141592653589793; 00007FF7D810188A F2 0F 10 05 B6 83 00 00 movsd xmm0,mmword ptr [__real@400921fb54442d18 (07FF7D8109C48h)] 00007FF7D8101892 F2 0F 11 45 08 movsd mmword ptr [a],xmm0 printf("function_no_ret\ta==%lf\n",a); 00007FF7D8101897 F2 0F 10 4D 08 movsd xmm1,mmword ptr [a] 00007FF7D810189C 66 48 0F 7E CA movq rdx,xmm1 00007FF7D81018A1 48 8D 0D 80 83 00 00 lea rcx,[string "function_no_ret\ta==%lf\n" (07FF7D8109C28h)] //rcx 为call prinf 参数 00007FF7D81018A8 E8 E8 F8 FF FF call printf (07FF7D8101195h) } 00007FF7D81018AD 48 8D A5 E8 00 00 00 lea rsp,[rbp+0E8h] 00007FF7D81018B4 5F pop rdi 00007FF7D81018B5 5D pop rbp 00007FF7D81018B6 C3 ret ``` # 无参有返回值 ```汇编 { 00007FF7D8102310 40 55 push rbp 00007FF7D8102312 57 push rdi 00007FF7D8102313 48 81 EC 18 01 00 00 sub rsp,118h 00007FF7D810231A 48 8D 6C 24 30 lea rbp,[rsp+30h] 00007FF7D810231F 48 8B FC mov rdi,rsp 00007FF7D8102322 B9 46 00 00 00 mov ecx,46h 00007FF7D8102327 B8 CC CC CC CC mov eax,0CCCCCCCCh 00007FF7D810232C F3 AB rep stos dword ptr [rdi] 00007FF7D810232E 48 8D 0D F4 EC 00 00 lea rcx,[__BB8CE66A_testFunctionAsm@cpp (07FF7D8111029h)] 00007FF7D8102335 E8 31 F0 FF FF call __CheckForDebuggerJustMyCode (07FF7D810136Bh) double a; a = 3.141592653589793; 00007FF7D810233A F2 0F 10 05 06 79 00 00 movsd xmm0,mmword ptr [__real@400921fb54442d18 (07FF7D8109C48h)] 00007FF7D8102342 F2 0F 11 45 08 movsd mmword ptr [a],xmm0 return 5.774 * a; 00007FF7D8102347 F2 0F 10 05 C1 78 00 00 movsd xmm0,mmword ptr [__real@4017189374bc6a7f (07FF7D8109C10h)] 00007FF7D810234F F2 0F 59 45 08 mulsd xmm0,mmword ptr [a] //返回值 } 00007FF7D8102354 48 8D A5 E8 00 00 00 lea rsp,[rbp+0E8h] 00007FF7D810235B 5F pop rdi 00007FF7D810235C 5D pop rbp 00007FF7D810235D C3 ret ``` # 带参数无返回值 ```汇编 void function_with_param(char * name,double value) { 00007FF7A23F2310 F2 0F 11 4C 24 10 movsd mmword ptr [rsp+10h],xmm1 00007FF7A23F2316 48 89 4C 24 08 mov qword ptr [rsp+8],rcx 00007FF7A23F231B 55 push rbp 00007FF7A23F231C 57 push rdi 00007FF7A23F231D 48 81 EC E8 00 00 00 sub rsp,0E8h 00007FF7A23F2324 48 8D 6C 24 20 lea rbp,[rsp+20h] 00007FF7A23F2329 48 8B FC mov rdi,rsp 00007FF7A23F232C B9 3A 00 00 00 mov ecx,3Ah 00007FF7A23F2331 B8 CC CC CC CC mov eax,0CCCCCCCCh 00007FF7A23F2336 F3 AB rep stos dword ptr [rdi] 00007FF7A23F2338 48 8B 8C 24 08 01 00 00 mov rcx,qword ptr [rsp+108h] 00007FF7A23F2340 48 8D 0D E2 EC 00 00 lea rcx,[__BB8CE66A_testFunctionAsm@cpp (07FF7A2401029h)] 00007FF7A23F2347 E8 1F F0 FF FF call __CheckForDebuggerJustMyCode (07FF7A23F136Bh) printf("name:%s\tvalue:%lf\n", name,value); 00007FF7A23F234C F2 0F 10 95 E8 00 00 00 movsd xmm2,mmword ptr [value] 00007FF7A23F2354 66 49 0F 7E D0 movq r8,xmm2 00007FF7A23F2359 48 8B 95 E0 00 00 00 mov rdx,qword ptr [name] 00007FF7A23F2360 48 8D 0D D9 78 00 00 lea rcx,[string "name:%s\tvalue:%lf\n" (07FF7A23F9C40h)] 00007FF7A23F2367 E8 29 EE FF FF call printf (07FF7A23F1195h) } 00007FF7A23F236C 48 8D A5 C8 00 00 00 lea rsp,[rbp+0C8h] 00007FF7A23F2373 5F pop rdi 00007FF7A23F2374 5D pop rbp 00007FF7A23F2375 C3 ret ``` # 带参数有返回值 ```汇编 int64_t function_with_param_ret(int64_t a,int64_t b) { 00007FF7A23F1A80 48 89 54 24 10 mov qword ptr [rsp+10h],rdx //第二个参数 00007FF7A23F1A85 48 89 4C 24 08 mov qword ptr [rsp+8],rcx //第一个参数 00007FF7A23F1A8A 55 push rbp 00007FF7A23F1A8B 57 push rdi 00007FF7A23F1A8C 48 81 EC F8 00 00 00 sub rsp,0F8h 00007FF7A23F1A93 48 8D 6C 24 20 lea rbp,[rsp+20h] 00007FF7A23F1A98 48 8B FC mov rdi,rsp 00007FF7A23F1A9B B9 3E 00 00 00 mov ecx,3Eh 00007FF7A23F1AA0 B8 CC CC CC CC mov eax,0CCCCCCCCh 00007FF7A23F1AA5 F3 AB rep stos dword ptr [rdi] 00007FF7A23F1AA7 48 8B 8C 24 18 01 00 00 mov rcx,qword ptr [rsp+118h] 00007FF7A23F1AAF 48 8D 0D 73 F5 00 00 lea rcx,[__BB8CE66A_testFunctionAsm@cpp (07FF7A2401029h)] 00007FF7A23F1AB6 E8 B0 F8 FF FF call __CheckForDebuggerJustMyCode (07FF7A23F136Bh) return a*b+a/b+a-b+a+b; 00007FF7A23F1ABB 48 8B 85 F0 00 00 00 mov rax,qword ptr [a] 00007FF7A23F1AC2 48 0F AF 85 F8 00 00 00 imul rax,qword ptr [b] //rax = a*b 00007FF7A23F1ACA 48 89 85 C0 00 00 00 mov qword ptr [rbp+0C0h],rax //[rbp+0C0h] 临时结果存储 00007FF7A23F1AD1 48 8B 85 F0 00 00 00 mov rax,qword ptr [a] 00007FF7A23F1AD8 48 99 cqo 00007FF7A23F1ADA 48 F7 BD F8 00 00 00 idiv rax,qword ptr [b] //rax = a/b 00007FF7A23F1AE1 48 8B 8D F0 00 00 00 mov rcx,qword ptr [a] 00007FF7A23F1AE8 48 8B 95 C0 00 00 00 mov rdx,qword ptr [rbp+0C0h] rdx = a*b 00007FF7A23F1AEF 48 03 CA add rcx,rdx //rcx = a*b+a 00007FF7A23F1AF2 48 03 C1 add rax,rcx //rax = a*b+a/b +a 00007FF7A23F1AF5 48 2B 85 F8 00 00 00 sub rax,qword ptr [b] //rax = a*b+a/b+a-b 00007FF7A23F1AFC 48 03 85 F0 00 00 00 add rax,qword ptr [a] //rax = a*b+a/b+a-b+a 00007FF7A23F1B03 48 03 85 F8 00 00 00 add rax,qword ptr [b] //返回值 rax = a*b+a/b+a-b+a+b } 00007FF7A23F1B0A 48 8D A5 D8 00 00 00 lea rsp,[rbp+0D8h] 00007FF7A23F1B11 5F pop rdi 00007FF7A23F1B12 5D pop rbp 00007FF7A23F1B13 C3 ret ``` 最后修改:2021 年 03 月 26 日 07 : 14 PM © 允许规范转载