C++大会"RETN 10"

C++ Assembly "RETN 10"

本文关键字:RETN C++ 大会      更新时间:2023-10-16

我有以下功能:

int __declspec() MyFunc(SOCKET sSocket, const char* sData, int sSize, int sFlag)
{
    pSocket = sSocket;
    return send(sSocket,sData, sSize, sFlag);
}

以下是编译后的汇编代码:

PUSH EBP
MOV EBP,ESP
PUSH DWORD PTR SS:[EBP+14]               // Flags
MOV EAX,DWORD PTR SS:[EBP+8]
PUSH DWORD PTR SS:[EBP+10]               // DataSize
MOV DWORD PTR DS:[pSocket],EAX
PUSH DWORD PTR SS:[EBP+C]                // Data
PUSH EAX                                 // Socket
CALL DWORD PTR DS:[<&WS2_32.#19_send>]   // send
POP EBP
RETN

我的问题是:

  1. RETNRETN 8RETN 10之间有什么区别
  2. 我必须将最终的RETN更改为RETN 10,我应该对C++代码做什么更改

我必须将最后的RETN更改为RETN10,我应该对我的c++代码做什么更改?

要让被调用的函数在返回之前清理堆栈(使用RET(N) imm或通过其他方式),请使用stdcall调用约定。

如果你使用微软的C/C++编译器,你可以通过添加__stdcall修饰符来实现这一点,如:

void __stdcall foo(int arg1, int arg2) {
  // ...
}

如果您使用GCC,您可以使用stdcall属性实现这一点:

void __attribute__ ((stdcall)) foo(int arg1, int arg2) {
  // ...
}

当然,您可以将#define __stdcall作为__attribute__ ((stdcall)),以节省您自己的一些键入,并使代码更加可移植。

在Cygwin中使用GCC编译如上所述的函数会产生以下汇编:

_foo@8:
push    ebp
mov ebp, esp
... (omitted for brevity)
leave
ret 8
相关文章: