![任何编译语言代码都可以逐行追踪到二进制中每个 CPU 指令的各个位吗?](https://linux22.com/image/1390596/%E4%BB%BB%E4%BD%95%E7%BC%96%E8%AF%91%E8%AF%AD%E8%A8%80%E4%BB%A3%E7%A0%81%E9%83%BD%E5%8F%AF%E4%BB%A5%E9%80%90%E8%A1%8C%E8%BF%BD%E8%B8%AA%E5%88%B0%E4%BA%8C%E8%BF%9B%E5%88%B6%E4%B8%AD%E6%AF%8F%E4%B8%AA%20CPU%20%E6%8C%87%E4%BB%A4%E7%9A%84%E5%90%84%E4%B8%AA%E4%BD%8D%E5%90%97%EF%BC%9F.png)
我意识到我们可以使用许多调试器等从 C++ 代码中转储等效的汇编代码。
但是二进制代码呢?每个字节中位的格式组成了实际的机器指令,这些指令(可能)组成了微程序(如果微架构有微程序的话)。
如果每行 C++ 代码都必须以某种方式在程序的某个时刻转换为机器代码(例如,浮点数可能在 C++ 中定义,但在被推送到堆栈之前没有用处,因此它可能不会逐行 1:1 转换为所有机器代码,但无论如何都会被使用),则可以跟踪每个语句等。但调试器不会输出占用每个单独指令的位的形成。
如果每个程序都成为 CPU 的格式化字节/位模式指令,那么就必须能够(我假设)将您编写的所有代码追踪到电路级的实际位。
但为了获得尽可能充分的保证,是否可以达到我在这里描述的程度?现代调试器/软件不提供此功能,即使提供的似乎也没有向开发人员清楚地提供每条指令的完整二进制表示。
PS:当然,这是假设编译后的代码可以轻松执行针对目标架构的指令(而不是某些解释语言或需要另一个程序进一步翻译的字节码)。
答案1
您可以使用反汇编程序将编译后的二进制代码转换回汇编语言。这样您就可以“读取”(虽然有些困难)仅以二进制形式发布的软件。
对于问题的另一部分,您似乎想要某种硬件反编译器,它可以提供有关 CPU 如何执行特定二进制指令的更详细信息。我不知道有什么工具可以做到这一点。您可能必须阅读硬件手册并在脑海中进行这种分析。
答案2
不。
嗯,也许吧,但也不能保证,因为编译器生成的代码很少与生成的代码相同,原因有两个:人类不擅长编写高效的代码,而且人类思考代码的方式与 CPU 处理代码的方式不同。因此,编译器会在将源代码转换为汇编/二进制之前对其进行优化。这可能导致重新排序语句、删除无用的语句以及内联整个函数。
例如,给出以下伪代码:
int x = 3;
x = 3*3;
x = 4;
function mult4(number) { return number * 4; }
x = mult4(x);
可以完全简化为
int x = 16;
经过良好的优化,编译器无法与源代码完全匹配。这就是为什么调试时,您经常必须禁用编译器优化。禁用所有编译器优化后,编译器将尝试输出与源代码一一匹配的汇编代码。