Compiler construction 在已编译的二进制文件中,数值常量是如何表示的?

Compiler construction 在已编译的二进制文件中,数值常量是如何表示的?,compiler-construction,compilation,Compiler Construction,Compilation,例如,给定一个简单的C程序: #include <stdio.h> int main() { float x = 3.14f; char* y = "abcdefghijklmnopqrstuvwxyz"; printf("%f %s", x, y); return 0; } #包括 int main(){ 浮点数x=3.14f; char*y=“abcdefghijklmnopqrstuvxyz”; printf(“%f%s”,x,y); 返回0; } 常量3.

例如,给定一个简单的C程序:

#include <stdio.h>
int main() {
  float x = 3.14f;
  char* y = "abcdefghijklmnopqrstuvwxyz";
  printf("%f %s", x, y);
  return 0;
}
#包括
int main(){
浮点数x=3.14f;
char*y=“abcdefghijklmnopqrstuvxyz”;
printf(“%f%s”,x,y);
返回0;
}
常量
3.14f
如何输出到可执行二进制文件

对于字符串,它通常直接显示在文件中(可以通过grep abcdefghijklmnopqrstuvwxyz a.out或
字符串
)查找),但对于数字,我看不到相同的结果(即使在二进制表示中)

它被编译成二进制的方式是跨编译器的通用方式,还是特定于每种编译器/语言?

一般来说,它是一种编译器(直接将机器代码写入文件,而不是生成程序集,然后在其上调用汇编程序,这将完全避免这个问题)将数字写入文件与任何其他程序将数字写入二进制文件没有任何不同:首先使用该语言的标准数字解析工具将字符串解析为数字,然后使用编写编译器所用语言的标准二进制输出方法

例如,在C中,写入浮点常量值(存储在字符串
char*exp
中)的过程可能如下所示(假设我们已经检查过给定的表达式确实是一个浮点常量,并且输出流位于应该放置浮点值的位置):

fwrite
在这里所做的只是遍历
floatValue
内存中的字节,并将它们逐个写入文件。因此,唯一有趣的一点是,当从字符串(或从文件或用户输入)中将数字读入内存中时,
scanf
会做什么

整数和浮点数之间的差异很大。对于浮动,在绝大多数平台上,使用。对于无符号整数,字符串只需转换为其正常的二进制表示形式。对于有符号整数,同样在绝大多数平台上使用,它表示与无符号情况完全相同的非负数和负数,取其绝对值,翻转其位并向其中添加1

但我看不到同样的数字(即使在它们的二进制表示中)


当您说找不到二进制表示时,您是在查找ASCII“0”和“1”字符序列,还是将文件视为二进制(或十六进制)文件并且没有找到给定的序列?在后一种情况下,您可能只是错过了它,因为不需要常量而通过优化删除了常量,或者您对正确的二进制表示形式有错误。在前一种情况下,您没有找到它,因为数是以二进制形式存储的,而不是以文本形式存储的(甚至不是表示二进制数的文本)。

您是如何搜索二进制表示的?它必须存储在程序中,因为它将被分配给一个变量。但您应该记住a)浮点二进制表示并不精确,因为它有指数、精度和符号部分b)编译器可以优化代码并去掉部分代码。我运行了
gcc-O0
进行优化。至于搜索二进制,我查找IEEE 754浮点和双精度。
float floatValue;
sscanf(exp, "%f", &floatValue);
fwrite(&floatValue, sizeof(float), 1, outfile);