c++ - 为什么有些函数分布密集,而另一些函数则用 int 3 指令对齐和填充?

标签 c++ visual-c++ compiler-construction linker disassembly

我用 Visual C++ 10 编译了以下程序:

include <Windows.h>
int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
    Sleep( 0 );
    return 0;
}

并研究反汇编。程序镜像中有很多 C++ 运行时函数。一些函数位置密集 - 一些函数的 ret 后面是下一个函数的第一条指令。例如,

` __declspec(noreturn) void __cdecl __report_gsfailure(ULONGLONG StackCookie)`

结束于地址 004013B7(有一个 ret 指令)并且地址 004013B8 包含调试器找不到的一些其他函数来源。与此同时

BOOL __cdecl _ValidateImageBase(PBYTE pImageBase)

结束于地址 00401554 但下一个函数

PIMAGE_SECTION_HEADER __cdecl _FindPESection( PBYTE pImageBase, DWORD_PTR rva )

从地址00401560开始,后两个地址之间有多个int 3指令。

为什么不同?为什么有的函数放得很密,有的函数用不可达的代码隔开?

最佳答案

我重现了这个行为。您还可以注意到,这些函数以 mov edi,edi 指令开头。

int 3 指令以及函数开头的 mov edi,edi 指令允许热修补。 当需要对函数进行热修补时,mov edi,edi 被替换为在函数入口点之前跳转的短跳转指令,而 int 3 指令被替换为跳转到修补函数的长跳转。

引用Anyone knows what "mov edi,edi " does?

不知道为什么 __report_gsfailure 前面只有 2 int 3,即使它以 mov edi,edi 指令开始......

关于c++ - 为什么有些函数分布密集,而另一些函数则用 int 3 指令对齐和填充?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7612430/

相关文章:

c++ - 查找大于当前数字的最接近数字的索引

c++ - 有没有办法在不重建任何项目的情况下重新链接解决方案?

C#的编译器设计——前向引用

c# - 为什么我没有收到有关未初始化的只读字段的警告?

c++ - 包含 .c 文件和 .h 文件有什么区别

c++ - 标准布局和不可复制的属性

c++ - 从文件中读取输入,将第一个字母大写,将其他字母小写,然后输出到单独的文件中

c++ - Visual C++ 不一致代码的示例?

c++ - tinyxml在vc++中包含文件错误

java - 从 Java 应用程序编译和运行源代码