数值常量如何用编译后的二进制表示?

时间:2015-04-08 06:21:25

标签: compiler-construction compilation

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

#include <stdio.h>
int main() {
  float x = 3.14f;
  char* y = "abcdefghijklmnopqrstuvwxyz";
  printf("%f %s", x, y);
  return 0;
}

如何将常量3.14f输出到可执行二进制文件?

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

它是在编译器中编译为二进制通用的方式还是特定于每个编译器/语言?

1 个答案:

答案 0 :(得分:0)

一般情况下,编译器(将机器代码直接写入文件而不是生成程序集,然后在其上调用汇编程序 - 这将完全绕过这个问题)不会将数字写入文件,不同于任何其他程序都会将数字写入二进制文件:首先使用语言的标准数字解析工具将字符串解析为数字,然后使用您正在使用的语言的标准二进制输出方法写你的编译器。

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

float floatValue;
sscanf(exp, "%f", &floatValue);
fwrite(&floatValue, sizeof(float), 1, outfile);

这里fwrite的作用只是在内存中查看floatValue个字节,然后将它们逐个写入文件。因此,唯一有趣的一点是scanf在从字符串中读取数字(或者从文件或用户输入中读取)到内存中的数字时所执行的操作。

这在整数和浮点数之间差别很大。对于浮动,在绝大多数平台上,使用IEEE floating point standard。对于无符号整数,字符串只是简单地转换为其正常的二进制表示。对于有符号整数,再次在绝大多数平台上使用Two's complement,它表示与无符号情况完全相同的非负数,通过取绝对值表示负数,翻转其位并向其添加1

  

但是我没有看到相同的数字(即使在他们的二进制表示中

当你说你没有找到二进制表示时,你是否正在寻找一系列ASCII&#39; 0&#39;和&#39; 1&#39;字符,或者您是否将文件视为二进制(或十六进制)并且未找到给定的序列?在后一种情况下,您要么只是错过了它,使用优化删除常量进行编译,因为它不需要,或者您对正确的二进制表示是错误的。在前一种情况下,你没有找到它,因为数字以二进制形式存储,而不是文本(甚至不是代表二进制数的文本)。