Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.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++ VC/C++;裸体属性是什么?_C++_C_Visual C++ - Fatal编程技术网

C++ VC/C++;裸体属性是什么?

C++ VC/C++;裸体属性是什么?,c++,c,visual-c++,C++,C,Visual C++,对于使用裸函数声明的函数 属性,编译器生成代码 没有prolog和epilog代码。你 可以使用此功能编写自己的 使用 内联汇编代码。裸函数 在写作中特别有用 虚拟设备驱动程序 什么是“序言和结束语代码”。我看到一个用C代码编写的库只在使用libc的设备或固件上运行。它调用函数没有问题,裸关键字做什么,为什么需要它 注意:我不确定这些lib中的函数使用什么调用约定。Prolog和epilog代码是设置调用堆栈的第一个/最后几个指令。在实现中断例程之类的程序时,需要严格控制该函数中出现的指令 pr

对于使用裸函数声明的函数 属性,编译器生成代码 没有prolog和epilog代码。你 可以使用此功能编写自己的 使用 内联汇编代码。裸函数 在写作中特别有用 虚拟设备驱动程序

什么是“序言和结束语代码”。我看到一个用C代码编写的库只在使用libc的设备或固件上运行。它调用函数没有问题,裸关键字做什么,为什么需要它


注意:我不确定这些lib中的函数使用什么调用约定。

Prolog和epilog代码是设置调用堆栈的第一个/最后几个指令。在实现中断例程之类的程序时,需要严格控制该函数中出现的指令

prolog和epilog代码通常会处理堆栈,参数通常会在堆栈上传递和返回。要求编译器不生成这意味着您必须自己实现访问参数的正确方法


不确定它是否还涉及为函数自身的参数分配堆栈空间,这通常是在函数开始时完成的(然后在函数退出前取消),因此这似乎是可能的。

Prolog:在函数体之前运行的代码,通常是处理函数输入和参数处理的代码。 Epilog:在函数体之后运行的代码,通常是处理函数返回和返回值的代码

使用“裸体”你必须/有机会自己写这些东西。
\uuu declspec(裸体)
指令删除自动生成的prolog/epilog

函数的prolog/epilog是样板代码,用于保存和恢复寄存器,并适当移动堆栈指针

\uu fastcall
调用约定为例。它指定前两个参数位于寄存器(ECX和EDX)中,其余参数位于堆栈的右->左。因此,对于函数:

void\uu快速调用DoFoo(int-first,int-second)

我的汇编程序有点生疏,但序言可能如下所示:

mov %ecx, first
mov %edx, second
pushl %ebp
mov %esp, %ebp
sub bytes, %esp
然而,不同的调用约定将生成不同的序言/结束语代码

如果没有\uu declspec(裸版)编译器负责正确的调用约定处理(将输入参数推送到堆栈,为局部变量保留空间等)。在某些情况下,你可以自己做

例如,如果没有\uu declspec(裸体)编译器将提供下面的前3条(prolog)和后3条(epilog)指令(假设使用了cdecl调用约定)

现在可以从C/C++代码中调用此例程,如下所示:

func(0xAA, 0xBB, 0xCC, 0xDD);
这将成为:

push 0DDh
push 0CCh
push 0BBh
push 0AAh
call func

Btw—ARGs按相反顺序被推(与调用<代码> FUNC<代码>时的顺序相比),允许可变长度函数工作

注意它不是C或C++关键字:它是VisualC++提供的语言扩展(它也不是VisualC++中的关键字,它是属性)。@Daniel给出的链接对序言和尾声进行了合理的解释。可以找到该页面的最新版本(至少乍一看是相同的)。
func(0xAA, 0xBB, 0xCC, 0xDD);
push 0DDh
push 0CCh
push 0BBh
push 0AAh
call func