关键字如何以二进制形式表示?

时间:2014-11-13 12:21:38

标签: java assembly binary computer-science keyword

关键字如何以二进制形式表示? 对于ex ::在java中,sin()如何用二进制表示?如何表示sqrt()和其他功能。

如果不仅仅是在java中,在任何语言中它是如何表示的?因为最终所有东西都被翻译成二进制,然后转换成开关信号。

提前致谢。

4 个答案:

答案 0 :(得分:4)

首先,sin不是Java中的关键字。这是一个标识符。关键字包括ifclass等内容。

这取决于您询问时的

  • 在源代码中,sin标识符表示为字符,这些字符表示为位(即二进制)....如果您想以这种方式查看它。

  • javac编译器输出的类文件中,单词sin在常量池中表示为字符串。 (JVM规范详细说明了类文件的格式。)

  • 当JVM首次加载类文件时,单词sin将成为Java String对象。

  • 当代码由JVM链接时,对String的引用将被解析为某种方法的引用。 (详细信息是特定于实现的。您需要阅读JVM源代码以了解更多信息。)

  • 当代码是JIT编译器时,对方法的引用(通常)将转换为JIT编译方法的第一个本机指令的内存中的地址。 (严格来说,这不是“汇编语言”。但本机指令可以表示为汇编语言。汇编语言实际上只是指令的“人性友好”文本表示。)


  

那么计算机如何知道写罪时必须做一个数字的正弦。

Java运行时会加载包含该方法的类。然后它在它加载的类中查找sin(double)方法。通常发生的是命名方法解析为某些字节码,这些字节码是告诉运行时该方法应该做什么的指令。但是在sin的情况下,该方法是native方法,并且指令实际上是本机指令,它们是JVM的一个本机库的一部分。

  

如果不是方法,我们可以有关键字的二进制表示吗?像int,和float等??

这取决于实际的关键字。但一般来说,编译器会将真正的Java关键字转换为不具有各个关键字的不同/离散表示形式。

答案 1 :(得分:4)

  

如果不仅仅是在java中,在任何语言中它是如何表示的?因为最终所有东西都被翻译成二进制,然后转换成开关信号。

这告诉我你可能对如何实现编程语言有一个基本的误解。因此,不是回答这个问题(除了&#34之外它没有真正的正确答案;他们根本没有代表"),我会尽力帮助你理解为什么这个问题是错误的问一个。

您的计算机只运行machine code 机器代码。您可以随机输入任意字节序列,它并不重要,只要您将程序计数器指向它,它就会被解释为它是机器代码(当然它给它的字节数)这不是机器代码可能是一个坏主意)。作为一个运行示例,我将使用此x64代码:

48 01 F7 48 89 F8 C3 

如果你不知道发生了什么,这个级别的正常情况。大多数人都不会阅读机器代码(但如果他们学会了机器代码就可以了,但这并不神奇)。对于处理器而言,这就是零和一的地方,它甚至不是十六进制的,这正是人类喜欢阅读的内容。

在高于assembly的水平上,在大多数情况下,这实际上只是一种查看机器代码的不同方式,人类发现它更容易阅读。前面的例子在汇编中看起来更明智:

add rdi, rsi
mov rax, rdi
ret

仍然不太清楚那些不知道x64汇编的人会发生什么,但至少它给出了一些类型的线索:那里有一个{其中{1}}。它可能会增加一些东西。

在更高的层次上,你可能有java字节码或java,但我认为这个问题的java方面错过了重点,它可能存在,因为OP并没有意识到java不同于"经典图片"。 Java只是在不解释大局的情况下使问题复杂化。让我们改用C语言。 C中的示例可能如下所示:

add

如果您不了解C,但您确实了解Java,那么唯一奇怪的是int64_t foo_or_whatever(int64_t x, int64_t y) { return x + y; } ,这大致相当于Java中的int64_t

所以是的,添加的东西,正如汇编代码所示。现在关键字在哪里?

这个问题并没有像你想象的那样有意义。编译器理解关键字,并使用它们来创建实现程序的机器代码。在那之后他们就不再相关了。它们只是在您编写代码的高级语言的上下文中表示某些内容,您可以说在该级别,它们在文件中存储为ASCII或UTF8字符串。它们与机器代码无关,它们不以任何形式出现,您可以编写机器代码而无需从具有关键字的高级语言中进行翻译。 longreturn看起来有点相似,有点像红色鲱鱼,它们彼此有关,但这种关系远非简单(仅仅在示例I&#39中有效) ;使用当然不是偶然的。)

ret可能没有完全消失(尽管如此)。加法运算在64位整数上的事实在指令int64_t中编码。不是关键字48 01 F7(它甚至不是一个关键字,但是我们没有进入该关键字),"你所拥有的是64位整数和#34之间的相关事实;,这是一个概念上不同的东西,尽管这里使用了int64_t。要在跳过一些细节的同时拆分该指令(因为这是一个初学者问题),那就是

int64_t

要详细了解处理器对机器代码执行的操作(如果您的后续问题是"但它如何知道如何处理48 = 01001000 encoding REX.W, meaning this instruction is 64bit 01 = 00000001 encoding add rm64, r64 in this case D1 = 11010001 encoding the operands rdi and rsi "),请参阅计算机架构。如果你想要一本书,我推荐计算机体系结构,第五版:定量方法,这对于初学者来说非常容易理解,并且常用于有关计算机体系结构的第一年课程。

要了解有关从高级语言到机器代码的旅程的更多信息,请研究编译器构建。如果你想要一本书,我推荐编译器:原理,技术和工具,但作为初学者可能很难通过它。如果你想要一门免费课程,你可以在Coursera上关注Compilers(前几节讲座特别会给你一个关于编译器做什么的概述,而不会过于技术化。)


顺便说一下,如果你将示例C代码提供给GCC,它就会生成

48 01 F7

它仍然在做同样的事情,但是以一种不适合我的故事的方式,所以我冒昧地以一种稍微不同的方式做这件事。

答案 2 :(得分:2)

sin()是一个函数,因此它表示为其代码块所在的内存地址。 关键字(如for)未表示为二进制,for例如转换为byte code跳转指令列表,这些指令被编译为汇编指令,表示为二进制。

我的观点是,您无法将大多数关键字直接转换为二进制。您可以将它们展开为字节码,然后可以将其转换为本机机器代码和二进制文件,但不能直接转换为二进制文件。

在这里,read this然后在您了解之后转到字节码如何转换为本机代码。

关键字和功能

也就是说,Java(和大多数语言)中的关键字是保留字,如forwhilereturn,但您的示例不是关键字,它们是函数名称,如{ {1}}和sin()

答案 3 :(得分:1)

不确定你想知道什么;所以,让我们去"字节码" ...

.sin().sqrt()方法都是static类的Math方法;因此,编译器将生成一个带有两个参数的调用站点,对该方法的引用,然后调用invokestatic

invokestatic以外,您有invokevirtualinvokespecialinvokeinterface和(自Java 7开始)invokedynamic

现在,在运行时,JIT将启动;并且JIT最终可能会生成纯本机代码,但这不是保证。无论如何,代码将足够快。

JDK库本身也是如此;如果有足够的时间来分析它(逃避分析,内联等),JIT将启动并可能将字节代码转换为本机代码。

既然JIT不管它想要什么"你都可以无法拥有"二进制"任何类别的任何方法的表示。