windows 有人可以解释一下 __declspec(naked) 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3021513/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 14:38:04  来源:igfitidea点击:

Could someone explain __declspec(naked) please?

clinuxwindowsassemblycalling-convention

提问by Scott

I'm looking into porting a script engine written for Windows to Linux; it's for Winamp's visualization platform AVS. I'm not sure if it's even possible at the moment. From what I can tell the code is taking the addresses of the C functions nseel_asm_atanand nseel_asm_atan_endand storing them inside a table that it can reference during code execution.

我正在考虑将一个为 Windows 编写的脚本引擎移植到 Linux;它适用于Winamp的可视化平台AVS。我不确定目前是否有可能。从我可以告诉代码正在采取的C函数的地址nseel_asm_atan,并nseel_asm_atan_end和它们存储在表内,它可以在代码执行过程中引用。

I've looked at MS's documentation, but I'm unsure what __declspec(naked)really does. What is prolog and epilog code mentioned in the documentation? Is that related to Windows calling conventions? Is this portable? Know of any Linux-based examples using similar techniques?

我看过 MS 的文档,但我不确定它到底__declspec(naked)是做什么的。文档中提到的 prolog 和 epilog 代码是什么?这与 Windows 调用约定有关吗?这个便携吗?知道使用类似技术的任何基于 Linux 的示例吗?

static double (*__atan)(double) = &atan;
__declspec ( naked ) void nseel_asm_atan(void)
{
  FUNC1_ENTER

  *__nextBlock = __atan(*parm_a);

  FUNC_LEAVE
}
__declspec ( naked ) void nseel_asm_atan_end(void) {}

回答by Unknown

Basically the function prologue sets up a stack frame for local variables and the epilogue takes care of cleaning it up. This is usually done automatically by the compiler. If you use __declspec(naked), setting up this stack frame will be up to you so it gives you more flexibility.

基本上,函数 prologue 为局部变量设置了一个堆栈框架,epilogue 负责清理它。这通常由编译器自动完成。如果您使用__declspec(naked),则设置此堆栈框架取决于您,因此它为您提供了更大的灵活性。

There are many references: here, here, also hereand more.

有很多参考资料:这里这里还有这里等等。

The GNU gcc compiler also supports naked, but apparently not for x86: search for "naked" in the page(I haven't tried to see if it works on x86)

GNU gcc 编译器也支持裸,但显然不支持 x86:在页面中搜索“裸”(我没有尝试查看它是否适用于 x86)

回答by zerocool

from wikipediafunction prologue and epilogue :

来自维基百科功能序言和结语:

In assembly language programming, the function prologue is a few lines of code at the beginning of a function, which prepare the stack and registers for use within the function. Similarly, the function epilogue appears at the end of the function, and restores the stack and registers to the state they were in before the function was called.

在汇编语言编程中,函数序言是函数开头的几行代码,它为函数中使用的堆栈和寄存器做准备。类似地,函数结尾出现在函数末尾,并将堆栈和寄存器恢复到它们在调用函数之前所处的状态。

To ensure that the compiler does not auto generate an extra code within the your function , always declare the function using the __declspec(naked)convention.

为确保编译器不会在您的函数中自动生成额外的代码,请始终使用__declspec(naked)约定声明函数。

let's take a look at this function :

让我们来看看这个函数:

void myTrampoline()
{
__asm {
  PUSHFD
  PUSHAD
  CALL jumpHookCallback
  POPAD
  POPFD
  POP EAX
  MOV AL, 1
  POP EDI
  POP ESI
  JMP [restoreJumpHook]
 }
}

now the compiler will generate code that manipulate the stack frame of the function called as prologue and epilogue of function and the result will look like this

现在编译器将生成操作称为函数的序言和结尾的函数的堆栈帧的代码,结果将如下所示

;Prologue
push ebp
mov ebp, esp
sub esp, N

PUSHFD
PUSHAD
CALL jumpHookCallback
POPAD
POPFD
POP EAX
MOV AL, 1
POP EDI
POP ESI
JMP [restoreJumpHook]

;Epilogue
mov esp, ebp
pop ebp
ret

but if we use __declspec(naked)there will be no Prologueno Epilogue

但如果我们使用 __declspec(naked)将没有 Prologue没有 Epilogue

void __declspec(naked) myTrampoline()
{
__asm {
  PUSHFD
  PUSHAD
  CALL jumpHookCallback
  POPAD
  POPFD
  POP EAX
  MOV AL, 1
  POP EDI
  POP ESI
  JMP [restoreJumpHook]
 }
}

and the result will look like this :

结果将如下所示:

    PUSHFD
    PUSHAD
    CALL jumpHookCallback
    POPAD
    POPFD
    POP EAX
    MOV AL, 1
    POP EDI
    POP ESI
    JMP [restoreJumpHook]