exe并不是汇编指令那么简单哦
首先回答你操作系统是不是虚拟机的问题
说这个之前先要说CPU权限
intel的cpu一般分4级权限,0-3,不同级别可以运行的指令有不同限制。windows只用了0和3 ,0级基本无限制,是操作系统用的权限,3级限制最大,是一般app用的权限。
现代大家常用的操作系统实际是“分时多任务操作系统”,因此也有另一种“实时操作系统”,实时操作系统多用于工控,汽车,航空,航天,这里不做展开。
所谓分时操作系统,就是cpu运行时间被切分成很短时间的碎片,你的app在一直运行只是一种“假象”,实际操作系统不断切换分配cpu给不同的程序运行,从而实现了多任务,当然,一定程度牺牲了你的程序的实时性(比如别的程序cpu时间占用过高,你的程序就可能很卡)。
这是管理模式,不是虚拟机,不是解释执行,只是OS让你执行你才能执行,到了时间就无情剥夺你占用CPU时间的权力(可以通过操作系统提供的方式提高优先级)。现代多核CPU也是由操作系统统一管理的,APP基本没有选择权力(可以通过操作系统提供的方式绑定)。
这里要区分,windows在大力推广dotnet虚拟机技术,使用C#等dotnet语言开发的app都是在dotnet虚拟机上运行的。
内存是非常宝贵的(相对外存储器),为了适应同时运行更多app,提高内存利用率,扩大app可用“内存”,让app更容易开发,操作系统内存地址都是要进行抽象的,抽象可以理解为一层虚拟,在操作系统里叫内存分页管理,APP操作内存实际使用的是虚拟后的逻辑内存地址。
无论你是几百M物理内存,虚拟后的内存对每个APP来看都是同等大小的,一般至少4G(大小一般由操作系统和cpu的架构决定),具体去看操作系统原理。
为了安全,稳定性,兼容新,涉及硬件底层的必须通过API代理由内核和驱动执行,各种IO设备(显卡显示器,硬盘,网络,键盘鼠标。。。)地址和内存映射,不同系统也不一样,这个是由IO硬件和驱动开发者设计的。
细节我就不展开了,有兴趣去看《操作系统原理》。
然后回答你为什么Linux运行不了EXE
计算机硬件是由操作系统OS管理的,你可以理解exe或者app是由操作系统控制的一个动态模块。因此一个app的加载运行,申请资源,最后退出清理全部必须由OS进行调配。
还有windows是基于视窗的操作系统,linux仅仅是一个内核,桌面是在linux基础上的XServer,Xclient,不同发行版也是有所不同的,编程接口xlib目前会用的人极少,基本都用二次封装的gtk和qt,和windows机理完全不同。
而且,一个app的可执行文件格式是由不同操作系统定义的格式,不同OS,不同版本OS对格式的兼容性都不一样。这个结构在windows上叫PE格式。
Linux和各种unix使用更加公共一点的ELF格式。各种*nix虽然都是ELF格式但是OS内核完全不同,还是无法兼容的。
然后,启动点,创建进程,主线程,其他线程,向操作系统申请和释放内存,操作文件系统,访问网络,甚至错误处理等等,这些都要依赖操作系统提供的接口,不同操作系统这些都不一样。
还有,现代操作系统接口还会对你的app能否执行,调用的API做严格的限制以保障安全,cpu3级权限下直接汇编指令里面调用中断操作硬件被非常严格的进行了限制,并不是什么汇编指令都能随便执行的。不同操作系统的管控机理也有所不同。
当然,这个差别再大,要执行也是有办法的,就是做适配器嘛。类似欧标的插座插不上就来个转换适配器。
比如wine
wine可以给你适配出一个windows兼容环境,让部分要求不是高的exe可以在linux,unix,macOS上运行。
当然,真windows太复杂,wine无法完全模拟,有很多问题,简单用用还行,复杂一些的应用就很容碰到问题。
相对成熟的解决方案是硬件虚拟技术,就是虚拟机,比如virtual box,haper-v,vmware,kvm等等,linux上推荐kvm或virtual box。
最后回答你为什么不直接把EXE推给CPU执行
1.首先EXE是直接由CPU执行的,只是受到OS的严格监管和限制
2.CPU不是给一个APP独享的,具体前面说过了
3.控制计算机资源太复杂
协调多任务,资源分配,利用率,标准协议等等。如果CPU直接交给我们这些彩笔程序员些的APP可能没几秒就死机了,而交给操作系统,你写错了程序一般就是操作系统给你显示个报错提示,并强制关闭了你的程序,自动回收了你用的资源。
如果你想控制底层的资源使用cpu0权限,比如操作硬件,那就要开发驱动程序了,驱动程序拥有同操作系统同等的运行权力,当然有任何差错就是死机。
APP完全掌控CPU也是有的,那叫裸机编程,不需要任何操作系统的,全部自己来。
4.安全问题
有些执行是对硬件影响很大的,比如一些中断指令,典型的就是当年的CIH病毒,可以篡改主板bios驱动,低格硬盘,烧毁主板,烧毁显示器,导致不可逆损失。这就要限制CPU0级权限的获取,堵住各种企图获取0级权限的漏洞,堵漏洞的程序也是要牺牲性能的。win95-win98的内核架构过于简陋,app极容易获得cpu0权限,导致了CIH的爆发,烧毁无数计算机。
5.性能损失,肯定还是有的,不过总体来说利大于弊,当然随着硬件性能提升,牺牲的那点性能都能接受,从xp开始(nt内核)对硬件类指令隔离基本完善了,CIH这类攻击硬件的基本绝迹了,但是XP对驱动几乎没限制,导致恶意驱动泛滥,安全形同虚设。win7以后开始要求驱动签名,导致崩溃的病毒少了很多。win8/10以后驱动强制要求正确签名,恶意程序也大幅减少了。
6.dotnet虚拟机也不是解释执行,而是字节码虚拟机执行,vb类的才是解释执行,这类执行是会浪费一些性能,但虚拟技术的抽象特性可以大大简化程序开发,甚至对普通人写的程序还能提高性能(C/C++高性能优化对开发者要求很高),加上JIT等技术优化,以及利用现代硬件,可以获得很好的性能表现。
总结
要想完全掌控CPU就必须获得CPU0权限,该权限由操作系统管理。
开发者一般只能通过开发驱动程序获得CPU0权限。
APP只能在CPU3权限运行,切受到OS细粒度用户身份权限限制。
正常C/C++编译的程序不是虚拟机.
虚拟机不是绝对表示低性能。
简单回答就是:因为一个「可执行文件」并不能脱离操作系统依赖而执行。
它需要「调用操作系统提供的各种API」来使用操作系统提供的功能。
操作系统不是模拟器,而是提供了大量现成的库供程序员调用,告诉程序员怎么使用某些功能的。
而这些东西就是操作系统提供的「动态链接库」。
Windows的库,有微软的版权,并不能直接放进 Linux 里边使用。——当然,如果不考虑版权方面的问题,Wine其实已经实现了大部分你想要的功能。前提是你安装了 Wine 之后,自己把 Windows 的一些 DLL 复制到 Wine 的目录下。
也有一部分Linux发行版提前帮你打包好了这些属于Windows的动态链接库,让你获得了一个直接可用的wine,于是也就能够直接运行 exe 格式的文件。但个人认为这些发行版可能侵犯了微软的版权。
操作系统是给谁用的?答:操作系统是给程序员用的,操作系统提供系统基础功能的库,并且提供API调用,程序员们根据这些可以写出能在这个操作系统下运行的程序。
由于这些程序都需要调用对应操作系统相关功能,所以并不能直接脱离操作系统而运行。