程序本质
回忆上次内容
python3
的程序是一个 5.3M 的可执行文件
- 我们通过which命令找到这个python3.8的位置
- 将这个python3.8复制到我们的用户目录下
- 这个文件还是能够执行的
真实的cpu
- 这个东西是个实实在在存在的实体
- 这个cpu就能看懂这些字节码吗?
cpu
- 我们看不懂的
- cpu能看懂
- 这是属于cpu的机器语言
- 这就是cpu的一条条的机器指令(instruction)
反汇编-汇编语言助记符
#先把~/python3对应的机器语言输出为汇编指令形式(反汇编)
objdump -d python3.8 > python3.8.asm
vi python3.8.asm
- 可以发现当前系统的架构(指令集)是x86-64
- 这些和我们刚才的字节形态有关系吗?
对比
- 用vi分窗口分别打开打开python3 和 python3.asm
vi -o python3.8hex python3.8.asm
- 上图下半部分是机器语言对应的汇编指令助记符
- ctrl+j、ctrl+k可以上下窗口切换
- 我们来试着找找
- python3.8文件中
- 机器语言的0101和cpu的汇编指令的对应关系
找到了
- 先跳到第8行
- endbr64 意味着 64位结束分支
- 下面就是第9行
-
/48 83
找到上下的对应关系
- 也就是第一条执行的汇编指令sub
- sub对应substract 是减法
- 汇编指令是计算机 cpu 机器指令的助记符
查找对应关系
-
423000
就是初始化(init)的 cpu 开始执行指令的地址
- 我们在上面查找48 83
- 看有没有对应的字节
- /4883 ec08 488b...
- 在上面的窗格中
- 搜索这些字节形态
- 这台计算机用的是什么指令集呢?
- 什么是指令集来着?
指令集
- 指令集也叫计算机的架构
- 不同架构的 cpu 有不同的指令集
- 我们目前的这个浏览器里面的系统用的是
x86-64
- 除此之外
arm
、MIPS
、RISC-V
也是常用的指令集
回到代码
- 入口是
init
- 作用是初始化
initialization
- 为什么48 83 就可以代表减法
- 这是谁规定的呢?
查看指令集
- 首先要明确到当前机器的cpu的架构
- 反汇编里面说是x86-64
- 当前机器所用的架构指令集确实是x86-64
- 这是谁的架构呢?
搜索
查询x86_64指令集
- https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
- 先要找到x86-64指令集中 48 83 这条指令
- 100B中的B是0或1
- 100B可以是1000
- 也可以是1001
逐步搜索
-
48 83 ec 08
对应 sub $0x8,%rsp
- 确实是一条减法指令
- 确实是8位立即数和寄存器的减法运算
更多cpu指令
移植 port
- 就需要移植(port)
- 移植(port)指的是从一种指令集移植到另一种指令集
不移植
- 就是让x86架构的pc
- 去直接执行这些基于mips架构的的0101... 字节码
- 就像让一个意大利泥瓦匠看一份中文写成的烹饪书来砌墙
- 鸡同鸭讲
- 驴唇不对马嘴
- 0101的文件执行出来全是乱的
- 完全不能用
- 也涉及到硬件等方面
- 可能某个寄存器在新架构中根本就不存在
架构师
- 我们的python3.8就是这样的一系列的cpu指令
- 可以解释py文件的
python3 执行过程
- 还是hello.py这个python程序
- 都在我们的硬盘上
python3 执行的过程大致是这样
- 然后在x86-64的cpu上执行
- 模拟出一台python虚拟机
- 对py文件解释执行
- 那为什么py程序可以跨架构跨平台呢?
架构的层次
跨架构跨平台原理
- 被不同的架构的编译器 编译后
- 被部署到 不同的cpu架构和系统上
- 所以同样的py文件被加载之后
- python程序可以对py文件跨架构、跨系统进行解释执行
- 一次编写到处运行
- 汇编指令都不一样
- 怎么能正确解释执行同样的python程序呢?
跨架构跨平台原理
/usr/bin/python3.8
本身是二进制文件
- 不同的架构有不同的编译器
- 不同的编译器编译出来的python3.8
- 是不同的二进制指令序列
- 这个环境可以解释读到的
python语句
- 把
python语句
翻译成系统能读懂输入输出
- 翻译成当前架构能够执行的代码
- 然后边解释边执行
- 恭喜您完成了非常烧脑一个实验!
- 我们去总结吧!!!
总结
python3
的程序是一个 5.3M 的可执行文件
-
python3
里面全都是 cpu 指令
- 可以执行的那种
- 我们可以把指令对应的汇编找到
-
objdump -d ~/python3 > python3.asm
- 系统执行
python3
这个可执行文件
- 给了
python3
一个参数hello.py
-
python3
对于hello.py
一句句的解释执行
- 在显示器输出了
hello world
-
python3
执行完毕
- 把控制权交回给 shell
- 这就是我们执行
hello.py
的过程
- 我想输出个稍微复杂点的东西
- 我们下次再说!
- 蓝桥->https://www.lanqiao.cn/teacher/3584
- github->https://github.com/overmind1980/oeasy-python-tutorial
- gitee->https://gitee.com/overmind1980/oeasypython
- 视频->https://www.bilibili.com/video/BV1CU4y1Z7gQ 作者:oeasy