Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 有人能解释一下吗?_C_Linux_Windows_Assembly_Calling Convention - Fatal编程技术网

C 有人能解释一下吗?

C 有人能解释一下吗?,c,linux,windows,assembly,calling-convention,C,Linux,Windows,Assembly,Calling Convention,我正在考虑将一个为Windows编写的脚本引擎移植到Linux;它是为Winamp的可视化平台AVS设计的。我不确定现在是否可能。从我可以看出,代码获取了C函数的地址nseel\u asm\u atan和nseel\u asm\u atan\u end,并将它们存储在一个表中,以便在代码执行过程中引用 我看过MS的文档,但我不确定declspec(裸体)到底做了什么。文档中提到的prolog和epilog代码是什么?这与Windows调用约定有关吗?这是手提的吗?知道使用类似技术的基于Linux

我正在考虑将一个为Windows编写的脚本引擎移植到Linux;它是为Winamp的可视化平台AVS设计的。我不确定现在是否可能。从我可以看出,代码获取了C函数的地址
nseel\u asm\u atan
nseel\u asm\u atan\u end
,并将它们存储在一个表中,以便在代码执行过程中引用

我看过MS的文档,但我不确定declspec(裸体)到底做了什么。文档中提到的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) {}

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

有许多参考文献:,等等

GNU gcc编译器也支持裸版,但显然不支持x86:(我还没有尝试查看它是否在x86上工作)

来自函数序言和结束语:

在汇编语言编程中,函数序言只有几行 函数开头的代码,用于准备堆栈和 在函数中使用的寄存器。同样,函数 尾声出现在函数末尾,并恢复堆栈 并注册到函数启动前的状态 打电话来

为确保编译器不会在函数中自动生成额外代码,请始终使用
\uu declspec(裸)
约定声明函数

让我们看看这个函数:

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
但是如果我们使用
\uu declspec(裸体)
就不会有
序言
no
尾声

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]

这就是他们所说的prolog和epilog的意思:,我很确定您可以通过
#define u declspec(n)
将Linux扩展为零。我认为GNUC++实现了类似的东西,但我不太清楚它是什么。我的更新是,代码“<代码>属性AtEdTeTyx((裸照))< /C>在G86和CLAN的支持下,这些天,但不是在2010。还值得一提的是,大多数编译器不支持将内联asm以外的任何内容放入裸函数中。问题中的代码只使用全局变量,因此通常会正常工作,但我看不到裸函数比简单地启用优化有任何好处。