编译C++代码如何产生机器代码?

ers*_*re1 3 c++ compilation machine-code

我正在使用网站learncpp.com学习 C++ 。第 0.5 章指出编译器的目的是将人类可读的源代码转换为机器可读的机器代码,由 1 和 0 组成。

\n

我编写了一个简短的 hello-world 程序并用于g++ hello-world.cpp编译它(我使用的是 macOS)。结果是a.out。它确实打印“Hello World”很好,但是,当我尝试在 vim/less/Atom/... 中查看时a.out,我没有看到 1 和 0',而是看到很多这样的内容:

\n
H\xef\xbf\xbdE\xef\xbf\xbdH\xef\xbf\xbd\xef\xbf\xbdX\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdH\xef\xbf\xbdE\xef\xbf\xbdH\xef\xbf\xbd}\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdH\xef\xbf\xbd\xef\xbf\xbdX\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdH9\xef\xbf\xbd\xef\xbf\xbd\n
Run Code Online (Sandbox Code Playgroud)\n

为什么内容a.out不只是机器代码所期望的 1 和 0?

\n

jos*_*nda 6

它们是二进制位(1 和 0),但无论您使用什么软件来查看文件的内容,都会尝试将它们读取为人类可读字符,而不是机器代码。

\n

如果您考虑一下,您在文本编辑器中打开的所有内容都是由存储在裸机上的二进制位组成的。这些 1 和 0 可以用多种不同的方式解释,大多数文本编辑器会尝试将它们作为字符读取。以字符“A”为例。它的ASCII码是65,二进制就是01000001。当文本编辑器读取计算机上的文件时,它会将这些位作为字符而不是机器指令进行处理,因此它以 01000001 模式读取 8 位(字节),它知道它刚刚读取了一个“A” 。

\n

此过程会导致您在可执行文件中看到混乱的符号。虽然某些内容恰好采用正确的模式来生成人类可读的字符,但其中大多数内容可能超出字符编码认为有效或不知道如何打印的范围,从而导致 \'\xef\xbf\ xbd\',你看到的。

\n

我不会在这里详细介绍字符编码的工作原理,但请阅读《初学者字符编码》以获取更多信息。

\n