想象一下,我有以下代码
void A(){
// blah blah blah
}
void B(){
// blah blah blah
}
void C(){
// blah blah blah
}
当代码编译(使用Visual Studio)并加载到内存中执行时,A(),B(),C()的地址可能不按顺序排列。我们怎样才能让他们订购?在这种情况下是否有任何指令有用?
答案 0 :(得分:3)
如果您的程序包含单个翻译单元(源文件),则生成的二进制文件通常应按照翻译单元中定义的顺序包含这些函数。例如,请考虑以下程序:
int A() { return 0; }
int B() { return 1; }
int C() { return -1; }
int main() { return A() + B() + C(); }
如果编译此程序针对最小尺寸(/ O1)进行了优化并且禁用了内联函数扩展(/ Ob0),则会生成以下机器代码:
int A() { return 0; }
00F71000 33 C0 xor eax,eax
00F71002 C3 ret
int B() { return 1; }
00F71003 33 C0 xor eax,eax
00F71005 40 inc eax
00F71006 C3 ret
int C() { return -1; }
00F71007 83 C8 FF or eax,0FFFFFFFFh
00F7100A C3 ret
int main() { return A() + B() + C(); }
00F7100B E8 F0 FF FF FF call A (0F71000h)
00F71010 8B C8 mov ecx,eax
00F71012 E8 EC FF FF FF call B (0F71003h)
00F71017 03 C8 add ecx,eax
00F71019 E8 E9 FF FF FF call C (0F71007h)
00F7101E 03 C1 add eax,ecx
00F71020 C3 ret
源代码注释由调试器提供。当使用其他优化设置时,需要优化最小大小以消除函数之间放置的int 3
填充。必须禁用内联函数扩展,以确保函数实际存在于生成的二进制文件中。
据我所知,这是一个实现细节,因此不应该依赖于生产代码。
答案 1 :(得分:0)
如果你确实将它们分成单独的函数以便于阅读,并且在整个程序中只调用它们一次 - 将这些函数内联声明,那么编译器会将它们组合成一段代码而不需要任何调用指令。
否则没有理由将它们按顺序放在内存中,因为任何调用指令都会刷新CPU的管道。