有人可以解释__declspec(裸体)吗?

Sco*_*ott 9 c linux windows assembly calling-convention

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

我看过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) {}
Run Code Online (Sandbox Code Playgroud)

zix*_*ool 9

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

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

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

让我们来看看这个函数:

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

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

;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
Run Code Online (Sandbox Code Playgroud)

但如果我们使用 __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]
 }
}
Run Code Online (Sandbox Code Playgroud)

结果将如下所示:

    PUSHFD
    PUSHAD
    CALL jumpHookCallback
    POPAD
    POPFD
    POP EAX
    MOV AL, 1
    POP EDI
    POP ESI
    JMP [restoreJumpHook]
Run Code Online (Sandbox Code Playgroud)


Unk*_*own 8

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

有很多参考文献:这里,这里,还有这里 和更多.

GNU gcc编译器也支持裸,但显然不适用于x86:在页面中搜索"naked" (我还没试过看它是否适用于x86)

  • 更新,现在 gcc 和 clang 在 x86 上支持 `__attribute__((naked))`,但在 2010 年不支持。另外值得一提的是,大多数编译器不支持将内联 asm 以外的任何内容放入裸函数中。问题中的代码仅使用全局变量,因此通常会正常工作,但我认为裸函数比简单地启用优化没有任何好处。 (3认同)