何时使用汇编调试c/c++程序?
学习一些汇编语言有助于调试程序吗?
我无法告诉你“何时”,但有时候你可能会遇到奇怪的C/C++行为,而且你真的不知道发生了什么......只需要看一下汇编代码,它永远不会欺骗你。
但是我总是检查我的C程序的ASM代码......出于优化、好奇心和学习目的。
无论如何,都要学习x86汇编语言!
汇编语言可以帮助调试程序的原因在于gcc经常为你进行优化。您需要查看汇编代码,以查找任何gcc的“改进”,并确保它们不会破坏程序。
例如:
/* global */
int x = 1;
void *myFunc() {
/* do something productive */
x = 0;
return NULL;
}
int main() {
thread_create(myFunc);
while(x) continue;
exit(1);
}
while(x) continue;
会变成 jmp 0xDEADBEEF
(其中 0xDEADBEEF
是 jmp
指令)。你可以在汇编语言中看到这一点,并知道要将 x 改为 volatile。除非你怀疑编译器,否则不要降低调试的级别。最好在与算法表达意图相同的抽象级别上进行调试。
如果你用C/C++编写代码,则使用一个好的C/C++调试器。
我确实已经多次回到阅读汇编代码了。GCC使得这相当方便。
一个很好的例子是我的一个问题的主题。GCC在2.95和3.4.3之间改变了行为,而查看可疑函数的汇编代码可以解释为什么我的程序会崩溃。
在某些情况下,如果您真的需要知道某些访问是如何进行的,那么它也非常有用。例如,如果您将内存映射到总线上,则可能想知道您正在执行16位访问而不是32位访问。
我最近使用汇编的另一个案例是检查我的“易失性”变量是否真正被视为易失性。结果发现几乎所有编译器有时都会出错,因此我已经开始检查特定情况的输出,以确保汇编实际上引用了内存位置而不是某个寄存器。
这可能有助于一些高级编程内容,并且了解“引擎盖下”发生的事情总是有帮助的。但是,除非您正在进行汇编编码(如果是这样,您会知道汇编语言),否则使用汇编调试可能过度了。错误可能直接存在于您的代码中,而不是在您的代码和汇编之间的转换中。
我认为使用内存转储进行调试比学习汇编语言更有用。例如,使用Visual Studio,您可以检查在特定代码行后哪些内存位置发生了变化。在调试模式下,快捷键是ALT-6。您可以使用标准监视来获取变量位置。
我曾经利用我的汇编技能搜索由我们使用的编译器新版本引起的错误。但编译器错误非常罕见,所以我的答案是否定的,不适用于调试。
从你的源代码中观察编译器如何通过汇编解决问题是很有趣的,但那并不是真正的调试。