不是说我目前处于那种情况,但我只是对答案感兴趣......
假设你有一些用C / C ++编写的代码,你想通过在ASM中修改它来手动优化它。
如果您在C / C ++中更改代码并从源代码重新编译,会发生什么。当然,刚编译文件的优化会丢失。您如何避免每次编译项目时都需要重做这些优化?您是否为需要优化的部件创建单独的源文件以使其不那么复杂?或者是否有某种自动工具来做到这一点......?猜猜你不能使用diff / patch ......
请分享您的经历,谢谢
答案 0 :(得分:7)
您可以在单独的ASM文件中编写一些函数,并从C / C ++代码中调用这些函数。或者直接在C / C ++代码中编写内联汇编。
换句话说,您可以从一些C / C ++代码开始获取一些基本的ASM代码,但是在您开始调整它之后,您删除了原始的C / C ++代码并替换它与您的ASM代码,使用这两种方法之一。
答案 1 :(得分:7)
为什么不在内联汇编程序中重写代码的关键部分,而不是修改输出?如何执行此操作的方法因编译器而异 - 请检查编译器文档。
在MSVC中:
// asm_overview.cpp
// processor: x86
void __declspec(naked) main()
{
// Naked functions must provide their own prolog...
__asm {
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
}
// ... and epilog
__asm {
pop ebp
ret
}
}
在海湾合作委员会:
__asm__ ("movl %eax, %ebx\n\t"
"movl $56, %esi\n\t"
"movl %ecx, $label(%edx,%ebx,$4)\n\t"
"movb %ah, (%ebx)");
另请注意,在编译和优化之后进行ASM更改只适用于那些完全了解自己正在做什么的人。编译器不仅以人类无法实现的方式优化结构(至少不是没有照明计算器能力的人),它还可以执行更复杂的代码分析。
信任您的编译器。这是你曾经使用的最好的工具;)。
答案 2 :(得分:4)
不要修改编译器生成的汇编代码。修改它,就像修改任何自动生成的代码一样,这是一个非常糟糕的主意,正是因为你发现自己的原因。
如果您希望通过在ASM中实施代码来特定部分代码,则有两种选择:
int main(void)
{
int foo = 10, bar = 15;
__asm__ __volatile__("addl %%ebx,%%eax"
:"=a"(foo)
:"a"(foo), "b"(bar)
);
printf("foo+bar=%d\n", foo);
return 0;
}
它很好地演示了如何将C代码与ASM结合,共享变量。
答案 3 :(得分:3)
如果你的编译器支持它,也许你正在寻找类似inline assembly的东西?
答案 4 :(得分:2)
对不起,对你的问题不是一个严格的答案,但我相信制作编译器的人在asm方面比我们大多数人好多了。因此,我更依赖编译器做“正确的事情”,而不是在c ++源代码中编写一些asm代码。
对于我不使用至少内联asm(有时我喜欢在代码中放置__asm int 3;
)的另一个论点是MS Visual Studio编译器不支持64位构建的内联asm。
还有一件事,你是否尝试过使用不同的算法进行优化,而不是假设说gcc(可以使用SSE_whatever_is_the_current_version优化)会产生比你写的更差的asm代码。
答案 5 :(得分:2)
使用内联汇编的另一个好理由:gcc样式内联汇编为代码生成器提供了一堆信息(clobbers,volatile等),代码生成器可以使用这些信息使您的程序集很好地(和内联!)适合您的C / C ++代码不会失去优化机会。
<小时/> 编辑:
例如,来自另一个答案的C代码:
int main(void)
{
int foo = 10, bar = 15;
__asm__ __volatile__("addl %%ebx,%%eax"
:"=a"(foo)
:"a"(foo), "b"(bar)
);
printf("foo+bar=%d\n", foo);
return 0;
}
产生
....
movl $15, %ebx
movl $10, %eax
#APP
addl %ebx,%eax
#NO_APP
movl %eax, 8(%esp)
movl $.str, (%esp)
movl %eax, 4(%esp)
call printf
....
变量foo和bar保存在寄存器中,甚至从不存储在堆栈中。
答案 6 :(得分:1)
您可以使用汇编程序显式编写的模块进行链接,也可以使用内联asm。