【问题标题】:Could someone explain __declspec(naked) please?有人可以解释一下 __declspec(naked) 吗?
【发布时间】:2011-03-02 13:55:24
【问题描述】:

我正在考虑将一个为 Windows 编写的脚本引擎移植到 Linux;它用于 Winamp 的可视化平台 AVS。我不确定目前是否有可能。据我所知,代码获取了 C 函数 nseel_asm_atannseel_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) {}

【问题讨论】:

标签: c linux windows assembly calling-convention


【解决方案1】:

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

有很多参考:hereherealso here 等等。

GNU gcc 编译器也支持裸机,但显然不适用于 x86:search for "naked" in the page(我没有尝试查看它是否适用于 x86)

【讨论】:

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

来自wikipedia函数序言和尾声:

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

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

让我们看看这个函数:

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

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

;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

但是如果我们使用__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]
 }
}

结果将如下所示:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-22
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-21
    相关资源
    最近更新 更多