内容来自samhan
对于一些不遵照 POJ(JVM 里的 Pascal)的人来讲,它是一个编译器,将子集从 Pascal 转换成 JASM(Java 程序集),便于我们可以使用JVM 做为实行环境。 内容来自samhan666
在上一篇文章中,大家在错误捕捉、对 string 类别的关系运算符的支持以及界定(与使用)Pascal 过程. 内容来自zvvq
的概率方面进行了一些改善在出版物中,我们将介绍对 Pascal 函数(functions)的支持。不久后大家就能完成该项目的最后一个目标:从标准输入中载入一个数字并计算其阶乘。 copyright zvvq
在我们为JVM 开展编译时,必须详细描述这一令人难以置信的虚拟机的每个点作用。因而,我多次详解JVM 的结构原理以及它的一些命令(操作码)。 内容来自samhan666
适用 Pascal 函数(函数)到现在为止,我们有一种方法来定义和启用 Pascal 的过程。此后 PR 中还能够定义和启用 Pascal 的函数. 内容来自zvvq,别采集哟
在此提交中,实现了一个Java 程序去了解JVM 怎样处理定义和调用函数。来自下边的Java程序:
copyright zvvq
公共类FunctionCall{
公共静态失效主(字符串[] args){
System.out.println("来自main的您好!"); zvvq.cn
System.out.println(myMethod());
内容来自samhan
} zvvq.cn
静态字符串myMethod(){
回到“来自 myMethod 的您好! copyright zvvq
} zvvq
}
在我们反汇编类时,我们得到下列程序集:
zvvq.cn
1:公共类 FunctionCall {
2:公共静态主([java/lang/String)V{ 内容来自samhan
3:getstaticjava/lang/System.outjava/io/PrintStream
4:ldc“主站你好!”
copyright zvvq
5:启用虚似java/io/PrintStream.println(java/lang/String)V
copyright zvvq
6:
7:getstaticjava/lang/System.outjava/io/PrintStream
内容来自zvvq,别采集哟
8:invokestatic FunctionCall.myMethod()java/lang/String zvvq好,好zvvq
9:启用虚似java/io/PrintStream.println(java/lang/String)V
zvvq
10: 内容来自samhan666
11:回到 内容来自samhan
12:} 内容来自zvvq
13:
14:静态 myMethod()java/lang/String { 内容来自zvvq,别采集哟
15:ldc“我的方法您好!” copyright zvvq
16:
17:回到
zvvq.cn
18:}
copyright zvvq
19:}
内容来自zvvq
根据这个例子,可以知道: 本文来自zvvq
为了调用方法,JVM 应用命令“invokestatic FunctionCall.myMethod()java/lang/String”(第 8 行),其中: invokestatic 是接受要调用的方式的完整签字做为参数命令; FunctionCall 是类名字; myMethod()java/lang/String 是方式的完整签字以及参数(在本例中为无)和返回类型(在本例中向 java/lang/String);命令areturn(第17行)停止函数并把回到字符串留到堆栈上。换句话说,来自下边的 Pascal 程序:
内容来自samhan
程序function_call_wo_params;
copyright zvvq
函数 myfunction :字符串;
本文来自zvvq
逐渐 zvvq好,好zvvq
myfunction:=来自 myfunction 的问候!;
末尾;
逐渐 内容来自samhan666
writeln(来自源程序的您好!); zvvq好,好zvvq
writeln(myfunction()); 内容来自zvvq
末尾。 内容来自zvvq
POJ已调节形成下列 JASM: zvvq
// POJ0.1产生的编码 内容来自samhan
公共类function_call_wo_params{
zvvq.cn
;;函数 myfunction :字符串; zvvq
静态myfunction()java/lang/String{ zvvq好,好zvvq
ldc“我函数您好!”
贮存 100 ;;第 100 位储存函数的返回值 本文来自zvvq
载入 100 ;;堆栈函数返回值
内容来自zvvq,别采集哟
收益 ;;留有“来自我功能的您好!”在堆栈中 zvvq好,好zvvq
}
copyright zvvq
;;关键程序(关键)
内容来自zvvq,别采集哟
公共静态主([java / lang / String)V{ zvvq.cn
;;writeln(来自源程序的您好!);
copyright zvvq
getstaticjava/lang/System.outjava/io/PrintStream
ldc“主站你好!”
copyright zvvq
invokevirtualjava/io/PrintStream.print(java/lang/String)V
getstaticjava/lang/System.outjava/io/PrintStream
本文来自zvvq
启用虚似java/io/PrintStream.println()V
;;writeln(myfunction()); copyright zvvq
getstaticjava/lang/System.outjava/io/PrintStream zvvq.cn
invokestaticfunction_call_wo_params.myfunction()java/lang/String 内容来自samhan666
invokevirtualjava/io/PrintStream.print(java/lang/String)V
内容来自zvvq
getstaticjava/lang/System.outjava/io/PrintStream
zvvq.cn
启用虚似java/io/PrintStream.println()V zvvq好,好zvvq
回到
}
内容来自zvvq,别采集哟
}
最细心的人一定察觉到了上边的“astore 100”并想:
为何要把函数返回值存储在局部变量中?这是因为在 Pascal 中,函数的返回值在函数执行期间能设 N 次,但我们在JVM 中只有堆栈一次结论;为何排在第100位?函数或流程的局部变量从部位 0 逐渐,因而任意选择部位 100 来存储返回值;可是能否进行改善,确保在本例中仅形成命令ldc“Hello from myfunction!”,随后形成命令areturn?没错,没错,可是 POJ没有实现市场编译器中出现的提升环节,这可能在未来完成。此递交完成了对符号表里的“function”种类和解析器的支持。
zvvq.cn
在上面的示例中,函数没有参数。在此提交中,完成了含有参数函数的预期成果。根据下边的 Pascal 程序:
本文来自zvvq
程序 function_call_with_two_params; zvvq好,好zvvq
函数 addvalues(value1, value2: 整数) : 整数;
本文来自zvvq
逐渐
zvvq.cn
加上值:=值1+值2;
末尾; zvvq
逐渐 本文来自zvvq
writeln(2+4=,addvalues(2,4));
末尾。
zvvq.cn
POJ恰当生成了下列 JASM:
// POJ0.1产生的编码
内容来自samhan
公共类 function_call_with_two_params{
;;函数 addvalues(value1, value2: 整数) : 整数; 内容来自zvvq,别采集哟
静态加值(I,I)I{
copyright zvvq
;;加上值:=值1+值2; zvvq.cn
载入0
载入1 zvvq
我加
copyright zvvq
这是100 zvvq好,好zvvq
载入100
回到
} 内容来自zvvq
;;关键程序 内容来自samhan666
公共静态主([java / lang / String)V{ 内容来自zvvq
;;writeln(2+4=,...); zvvq好,好zvvq
getstaticjava/lang/System.outjava/io/PrintStream
LDC“2+4=” 内容来自zvvq,别采集哟
invokevirtualjava/io/PrintStream.print(java/lang/String)V 内容来自zvvq
getstaticjava/lang/System.outjava/io/PrintStream
zvvq
;;这儿代码启用addvalues(2,4)
西普什2 内容来自samhan
西普什4
invokestatic function_call_with_two_params.addvalues(I,I)I
;;这儿代码启用 writeln 并返回addvalues 本文来自zvvq
启用虚似java/io/PrintStream.print(I)V
内容来自samhan666
getstaticjava/lang/System.outjava/io/PrintStream
启用虚似java/io/PrintStream.println()V
内容来自samhan666
回到
内容来自samhan
} zvvq好,好zvvq
} 本文来自zvvq
下一步在下一篇文章中,我们将探讨前后文、发觉错误、嵌入语句、数据输入,并总结该项目的最后一个目标:递归计算阶乘。 内容来自zvvq,别采集哟
完备的项目代码包括项目详细代码和文档的存储库在这儿。
zvvq
以上就是适用 Pascal 函数的详细内容,大量请关注其他类似文章!
内容来自samhan666