devc 无法编译循环语句_手把手教你撸一个Mini JVM系列(6)之控制流 -- 条件判断和循环...

31c33a84d5931084fec872a4683eb071.png

引子:一个程序无论多么的复杂,站在宏观角度看其实都是在三种控制流中执行:顺序执行,条件执行,循环执行。顺序执行就是一条一条的语句按照语句所在位置的顺序依次执行。条件执行就是根据条件的真假有选择的执行某一段代码,而被选择要执行的代码段是顺序执行的。 循环执行就是根据条件重复执行一段代码,而被重复执行的代码段也是顺序执行的。可以看到顺序执行是基础,另外两个是在顺序执行的基础上加了一些控制条件。之前实现的Mini JVM 已经实现了顺序执行的控制流了,现在就来看一下如何实现条件判断和循环控制流。

1. 总览

首先先来看一下这个版本的Mini JVM所要支持的控制流:

fdbd0361b10e505984f40293ff70e7de.png

没错,红色框的内容就是要实现的条件判断和循环控制流

在具体实现之前,我们先来回顾一下我们整天都在写的if,while/for的执行流程是怎么样的。对于if语句,首先先要判断一下条件,如果为true则执行if代码块,如果为false则执行if之后的代码块;对于while/for语句,首先先要判断一下条件,如果为true则执行while/for代码块,等while/for代码块执行完之后再判断一下条件,直到条件不满足时再执行while/for之后的代码块。从上面的描述可以看到,其实条件控制流和循环控制流是一会是,都是根据条件执行代码段,只是循环控制流有可能会反复执行而已。

2. 实现

知道了条件控制流和循环控制流的本质之后, 我们再来了看一下Java编译器把这两个控制流编译成了什么命令,让其可以实现对应的逻辑。

2.1 条件控制流

1d6359df18eacfd41932369d7631e482.png

可以看到,打红框框的就是if语句被编译之后的字节码,但是有同学就问了这一串数字是啥呀....?!别急,我帮这串"天书"翻译一下:

f10ddaa22378a51b701d842767df1e9c.png

2a6d2ade136135bbcdfe03e1717cb97c.png

2a31731d78d884962b329d7cfd456c84.png

这串翻译之后就是上面那个样子(其实在之前执行引擎那篇文章中已经提到过,这里再补充一下,这些数字所代表的具体意义是在oracle jvm虚拟机规范中的操作码中有定义的,所以参照那个文档就可以对这个看似无意义的数字进行翻译)。 从这些命令当中可以看到有两个命令是之前没有遇见到过的,这两个命令也是实现if控制流,甚至while/for控制流的关键。一个是if_icmpge,一个是goto

通过名字就可以知道,if_icmpge就是一个判断命令, 用于比较栈顶两 int 型数值大小,当结果大于等于 0 时跳转。同理也可以猜到类似的命令还有if_icmpgt,if_icmpne等。至于其他的类型也有类似的命令. 知道了原理之后要实现这个命令也很简单, 只要计算表达式的值是否符合跳转的条件, 如果符合条件则计算下一个命令的偏移量然后将下一个命令的值置为这个新的偏移量(如果了解操作系统的话,就类似于操作系统中函数的调用, 实际上就是改变pc(程序计数器)的值, 让其指向下一条指令的位置)。

而至于goto命令,顾名思义就是跳转,这个命令的实现更加的简单,都不需要计算,直接"无脑"跳转就好了。

所以依赖于一批if_*命令和一个goto指令就实现了if控制流。

2.2 循环控制流

知道了条件控制流之后,以及前面已经介绍过了循环控制流就可能不断执行的条件控制流,所以对于循环控制流的实现也很容易想到了。还是照旧让我们来看一下Java编译器把循环控制流编译成了什么命令:

bf113ac01b984d1a3931e2b2a4b48849.png

嗯, 还是一串数字,再来看一下翻译之后的命令:

16a2547c82081094960d6e90cf0b855d.png

08a425bc2a141ce26dd8fba482da6073.png

56532691c4c989a0dfefb97d23c8d439.png

上面就是for循环的命令,可以看到其实它和条件的判断的命令根本没有什么区别,就是使用if_*指令集和goto命令来实现的。 唯一的区别就是goto语句会跳到goto前面的命令,这样就会再次执行if_icmpgt命令,也正是这样就实现了循环. 所以实际上可以把条件判断控制流看成是特殊的循环控制流, 也即条件控制流是之会执行一次的循环控制流。

如果细心的同学仔细观察可以看到这个有一个地方比较有意思, 就是goto命令的两个偏移量是0xff0xf3,通过这个值计算出来的偏移量加上goto命令本身的偏移量得到的最后的偏移量实际上是会大于2个字节的能表示的最大值的,这个时候产生的溢出刚好可以让下一个命令的偏移量移到goto命令之前, 从而实现循环。

所以不管条件还是循环,编译成字节码之后, 在jvm看来都是一样的,没有什么区别。

3. 总结

如果同学之前看过或者学过一些汇编的知识,其实可以发现jvm这个条件,循环的实现和汇编的条件、循环跳转的实现是很相似的。都是通过一些类似if_*的命令和一个goto命令实现的。所以不管你这个语言的特性多么强大,语法可以写的多么简洁,多么花哨,到了指令这一层其实都是大同小异的。所以说即使是写java这种高级语言,了解一些底层的东西也还是有必要的。

这个版本的Mini JVM的代码也已经提交,有兴趣的,可以看看。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
图像识别技术在病虫害检测中的应用是一个快速发展的领域,它结合了计算机视觉和机器学习算法来自动识别和分类植物上的病虫害。以下是这一技术的一些关键步骤和组成部分: 1. **数据收集**:首先需要收集大量的植物图像数据,这些数据包括健康植物的图像以及受不同病虫害影响的植物图像。 2. **图像预处理**:对收集到的图像进行处理,以提高后续分析的准确性。这可能包括调整亮度、对比度、去噪、裁剪、缩放等。 3. **特征提取**:从图像中提取有助于识别病虫害的特征。这些特征可能包括颜色、纹理、形状、边缘等。 4. **模型训练**:使用机器学习算法(如支持向量机、随机森林、卷积神经网络等)来训练模型。训练过程中,算法会学习如何根据提取的特征来识别不同的病虫害。 5. **模型验证和测试**:在独立的测试集上验证模型的性能,以确保其准确性和泛化能力。 6. **部署和应用**:将训练好的模型部署到实际的病虫害检测系统中,可以是移动应用、网页服务或集成到智能农业设备中。 7. **实时监测**:在实际应用中,系统可以实时接收植物图像,并快速给出病虫害的检测结果。 8. **持续学习**:随着时间的推移,系统可以不断学习新的病虫害样本,以提高其识别能力。 9. **用户界面**:为了方便用户使用,通常会有一个用户友好的界面,显示检测结果,并提供进一步的指导或建议。 这项技术的优势在于它可以快速、准确地识别出病虫害,甚至在早期阶段就能发现问题,从而及时采取措施。此外,它还可以减少对化学农药的依赖,支持可持续农业发展。随着技术的不断进步,图像识别在病虫害检测中的应用将越来越广泛。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值