[oeasy]python0022_ python虛擬機(jī)_反編譯_cpu架構(gòu)_二進(jìn)制字節(jié)碼_匯編語言
程序本質(zhì)
回憶上次內(nèi)容
python3
的程序是一個(gè) 5.3M 的可執(zhí)行文件我們通過which命令找到這個(gè)python3.8的位置
將這個(gè)python3.8復(fù)制到我們的用戶目錄下
這個(gè)文件還是能夠執(zhí)行的
將這個(gè)文件轉(zhuǎn)化為字節(jié)形態(tài)
確實(shí)可以轉(zhuǎn)化
但是這個(gè)文件我們看不懂?。。。??

怎么才能看懂這些東西呢???
這個(gè)東西我們確實(shí)看不懂
但是有人能看懂
誰呢?
真實(shí)的cpu
無論手機(jī)還是計(jì)算機(jī)
最核心器件的器件就是cpu

這個(gè)東西是個(gè)實(shí)實(shí)在在存在的實(shí)體
這個(gè)cpu就能看懂這些字節(jié)碼嗎?
cpu
cpu能看懂這些字節(jié)碼?。?!
這些字節(jié)碼
我們看不懂的
cpu能看懂
這是屬于cpu的機(jī)器語言
這就是cpu的一條條的機(jī)器指令(instruction)

機(jī)器指令碼都是二進(jìn)制字節(jié)形式的
我們嘗試把python3.8轉(zhuǎn)化為字節(jié)表現(xiàn)形式
反匯編-匯編語言助記符
先把~/python3對(duì)應(yīng)的機(jī)器語言輸出為匯編指令形式(反匯編)objdump -d python3.8 > python3.8.asm vi python3.8.asm這次真的可以看懂了
減法(sub)
移動(dòng)(mov)
這些指令

可以發(fā)現(xiàn)當(dāng)前系統(tǒng)的架構(gòu)(指令集)是x86-64
這些和我們剛才的字節(jié)形態(tài)有關(guān)系嗎?
對(duì)比
用vi分窗口分別打開打開python3 和 python3.asm
下圖中上半部分是機(jī)器語言

上圖下半部分是機(jī)器語言對(duì)應(yīng)的匯編指令助記符
ctrl+j、ctrl+k可以上下窗口切換
我們來試著找找
python3.8文件中
機(jī)器語言的0101和cpu的匯編指令的對(duì)應(yīng)關(guān)系??
找到了
下面窗格
先跳到第8行
endbr64 意味著 64位結(jié)束分支
下面就是第9行

第9行
/48 83
找到上下的對(duì)應(yīng)關(guān)系也就是第一條執(zhí)行的匯編指令sub
sub對(duì)應(yīng)substract 是減法
匯編指令是計(jì)算機(jī) cpu 機(jī)器指令的助記符
查找對(duì)應(yīng)關(guān)系
423000
就是初始化(init)的 cpu 開始執(zhí)行指令的地址我們?cè)谏厦娌檎?8 83
看有沒有對(duì)應(yīng)的字節(jié)
/4883 ec08 488b...
在上面的窗格中
搜索這些字節(jié)形態(tài)

好像找到了對(duì)應(yīng)關(guān)系
具體怎么對(duì)應(yīng)的呢?
這臺(tái)計(jì)算機(jī)用的是什么指令集呢?
什么是指令集來著?
指令集
指令集就是指令的集合

指令集也叫計(jì)算機(jī)的架構(gòu)
不同架構(gòu)的 cpu 有不同的指令集
我們目前的這個(gè)瀏覽器里面的系統(tǒng)用的是
x86-64
除此之外
arm
、MIPS
、RISC-V
也是常用的指令集指令助記符和機(jī)器語言到底是則怎么對(duì)應(yīng)的呢?
回到代碼
代碼會(huì)有不同的
section
模塊入口是
init
作用是初始化
initialization

模塊里面是具體的指令
比如第一句
48 83 ec 08
為什么48 83 就可以代表減法
這是誰規(guī)定的呢?
查看指令集
這是cpu架構(gòu)規(guī)定的
首先要明確到當(dāng)前機(jī)器的cpu的架構(gòu)
反匯編里面說是x86-64

到shell里面驗(yàn)證一下

當(dāng)前機(jī)器所用的架構(gòu)指令集確實(shí)是x86-64
這是誰的架構(gòu)呢?
搜索
不會(huì)了就去搜索??

去intel官網(wǎng)找指令集
查詢x86_64指令集
找到cpu的手冊(cè)
https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
可以找到指令和二進(jìn)制狀態(tài)之間的關(guān)系么?
先要找到x86-64指令集中 48 83 這條指令

注意上圖中
100B中的B是0或1
100B可以是1000
也可以是1001
這確實(shí)是一條減法指令
而且是8位立即數(shù)和寄存器的減法運(yùn)算
逐步搜索

找起來真的很費(fèi)勁
48 83 ec 08
對(duì)應(yīng)sub $0x8,%rsp
確實(shí)是一條減法指令
確實(shí)是8位立即數(shù)和寄存器的減法運(yùn)算

和objdump的結(jié)果是一致的
廢話?。。??
除了減法指令sub之外
還有什么別的指令呢?
更多cpu指令
指令那可還有很多的
有運(yùn)算的
有移位的
加減乘除都有

這些指令的集合就是指令集
指令集就是cpu運(yùn)行的基礎(chǔ)!
這些機(jī)器語言的指令不能在別的指令集架構(gòu)上運(yùn)行么?
移植 port
想在別的指令集架構(gòu)上運(yùn)行程序
就需要移植(port)
移植(port)指的是從一種指令集移植到另一種指令集
從這個(gè)詞的詞源
移植
port 港口
可以看出歐美的航海文化基礎(chǔ)
也可以看出我們的農(nóng)耕文化基礎(chǔ)

不移植會(huì)如何呢?
不移植
這是playstation2的架構(gòu)圖
cpu是mips架構(gòu)的

不移植的話
就是讓x86架構(gòu)的pc
去直接執(zhí)行這些基于mips架構(gòu)的的0101... 字節(jié)碼
就像讓一個(gè)意大利泥瓦匠看一份中文寫成的烹飪書來砌墻
雞同鴨講
驢唇不對(duì)馬嘴
0101的文件執(zhí)行出來全是亂的
完全不能用
而且不全是軟件的問題
也涉及到硬件等方面
可能某個(gè)寄存器在新架構(gòu)中根本就不存在
架構(gòu)師
這個(gè)時(shí)候架構(gòu)師要解決相當(dāng)多的問題
很不容易的

落實(shí)到我們的python3.8游樂場
我們的python3.8就是這樣的一系列的cpu指令
可以解釋py文件的
python3.8 又是如何解釋py文件的來著?
python3 執(zhí)行過程
不管是python3.8這個(gè)游樂場
還是hello.py這個(gè)python程序
都在我們的硬盤上

先得把文件從硬盤讀到內(nèi)存
python3 執(zhí)行的過程大致是這樣
先把python3.8這個(gè)主解釋器加載到內(nèi)存中
然后在x86-64的cpu上執(zhí)行
模擬出一臺(tái)python虛擬機(jī)

對(duì)py文件解釋執(zhí)行
那為什么py程序可以跨架構(gòu)跨平臺(tái)呢?
架構(gòu)的層次
不同架構(gòu)的 cpu 都可以運(yùn)行 python
risc-v
arm
x64
mips
龍芯

不同系統(tǒng)的環(huán)境都可以運(yùn)行 python
win
mac
linux
freebsd
跨架構(gòu)跨平臺(tái)原理
由于python3.8 的源文件
被不同的架構(gòu)的編譯器 編譯后
被部署到 不同的cpu架構(gòu)和系統(tǒng)上
所以同樣的py文件被加載之后
python程序可以對(duì)py文件跨架構(gòu)、跨系統(tǒng)進(jìn)行解釋執(zhí)行
一次編寫到處運(yùn)行

不同的架構(gòu)下
匯編指令都不一樣
怎么能正確解釋執(zhí)行同樣的python程序呢?
跨架構(gòu)跨平臺(tái)原理
/usr/bin/python3.8
本身是二進(jìn)制文件可執(zhí)行二進(jìn)制文件
是基于當(dāng)前操作系統(tǒng)當(dāng)前架構(gòu)編譯出來的
不同的架構(gòu)有不同的編譯器
不同的編譯器編譯出來的python3.8
是不同的二進(jìn)制指令序列

python3.8
構(gòu)建了一個(gè)運(yùn)行時(shí)環(huán)境這個(gè)環(huán)境可以解釋讀到的
python語句
把
python語句
翻譯成系統(tǒng)能讀懂輸入輸出翻譯成當(dāng)前架構(gòu)能夠執(zhí)行的代碼
然后邊解釋邊執(zhí)行
恭喜您完成了非常燒腦一個(gè)實(shí)驗(yàn)!
我們?nèi)タ偨Y(jié)吧?。?!
總結(jié)
python3
的程序是一個(gè) 5.3M 的可執(zhí)行文件objdump -d ~/python3 > python3.asm
python3
里面全都是 cpu 指令可以執(zhí)行的那種
我們可以把指令對(duì)應(yīng)的匯編找到
匯編語句是和當(dāng)前機(jī)器架構(gòu)的指令集相關(guān)的
uname -a
可以查詢指令集我們執(zhí)行的過程其實(shí)就
系統(tǒng)執(zhí)行
python3
這個(gè)可執(zhí)行文件給了
python3
一個(gè)參數(shù)hello.py
python3
對(duì)于hello.py
一句句的解釋執(zhí)行在顯示器輸出了
hello world
python3
執(zhí)行完畢把控制權(quán)交回給 shell
這就是我們執(zhí)行
hello.py
的過程我想輸出個(gè)稍微復(fù)雜點(diǎn)的東西
可以做下面這個(gè)框架標(biāo)題嗎???

我們下次再說!??
藍(lán)橋->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