我想知道在链接阶段之前是否存在如何修改编译器生成的汇编。我不知道该怎么做?
答案 0 :(得分:1)
Microsoft的C / C ++编译器生成的汇编代码仅供参考。通常,它不能由MASM组装成等效于编译器直接生成的.OBJ文件。
例如,考虑一下这个简单的C ++ hello world程序:
#include <iostream>
int
main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
当我使用Microsoft的C ++编译器(使用/ Fa生成程序集)编译它,然后使用MASM尝试汇编生成的.ASM文件时,这就是我得到的:
t146.asm(1277) : error A2008:syntax error : _Args_0
t146.asm(1339) : error A2008:syntax error : _Args_0
t146.asm(1773) : error A2008:syntax error : _Args_0
t146.asm(2176) : fatal error A1010:unmatched block nesting : ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z
还有更多的错误,但最后一个错误会导致汇编程序挽救并放弃尝试汇总文件的其余部分。
除了错误之外,生成的程序集中还存在某些内容,这些内容存在于生成的目标文件中。一个例子是COMDAT sections,它在生成的程序集中显示为注释,因为MASM不支持它们。
因此,如果您正在跳跃让Visual Studio生成程序集然后以编程方式修改和组装,那么它将无法工作。您可以使用GNU C / C ++编译器,因为它不直接生成目标文件。相反,GCC生成的程序集由GNU汇编程序转换为目标文件。所以它总是生成有效的汇编。另一种选择是修改生成的目标文件,这实际上可以更容易。
然而,最大的问题是,你最终要完成的任务,“修改指针访问”,是一个比你显然认为的要困难得多的任务。在编译器生成的代码中可以使用各种方法指针。你们都需要识别所有这些,然后确定哪些是你感兴趣的指针访问类型。
我建议您在程序中使用显式序列化。即使您必须从头开始编写序列化代码,它也应该比弄乱编译器生成的代码容易得多。