首頁  >  文章  >  運維  >  linux中x64和x86的差別是什麼

linux中x64和x86的差別是什麼

青灯夜游
青灯夜游原創
2022-01-11 18:03:149526瀏覽

區別:1.暫存器分配不同,x64有16個暫存器,x86只有8個暫存器;2、組譯指令不同;3、函數呼叫不同;4、參數傳遞不同;5、棧幀不同, x64沒有堆疊幀的指針,而x86用ebp作為堆疊幀指針;6、x64的運算速度比x86高。

linux中x64和x86的差別是什麼

本教學操作環境:linux5.9.8系統、Dell G3電腦。

Linux x86(32位元)和x64(64位元)的區別 

0x01:暫存器分配的不同

 

(1)64位元有16個暫存器,32位元只有8個。但32位前8個都有不同的命名,分別是e _ ,而64位前8個使用了r代替e,也就是r _。 e開頭的暫存器命名仍可直接運用於對應暫存器的低32位,而剩下的暫存器名則是從r8 - r15,其低位分別用d、w、b指定長度;
(2)32位使用堆疊幀來作為傳遞的參數的保存位置,而64位元使用暫存器,分別以rdi,rsi,rdx,rcx,r8,r9作為第1-6個參數,rax作為傳回值;
(3) 64位元沒有堆疊幀的指針,32位元以ebp作為堆疊幀指針,64位元取消了這個設定,rbp作為通用暫存器使用;
(4)64位元支援一些形式的以PC相關的尋址,而32位元只有在jmp的時候才會用到這種尋址方式;

0x02:(新增)彙編指令的不同

 

mov、push、pop擴充了movq系列的mov和pushq以及popq用來操作quad word。

補充:

(1)movabsq不是32位元的擴展,是純粹新增的指令。用來將一個64位元的字面值直接存到一個64位元暫存器。因為movq只能將32位元的值存入,所以新增了這樣一條指令

(2)64位元的彙編程式碼可能會在ret之前加上一句rep,這裡的rep沒有實際意義,只是出於AMD處理器的原因,避免jmp所到達的地方直接就是ret,這樣會使得處理器運作更快一些

0x03:函數呼叫的不同

(1)x_64的參數透過暫存器傳遞(見前文);
callq 在堆疊中存放一個8位元的回傳位址;
(2 )許多函數不再有堆疊幀,只有無法將所有本地變數放在暫存器裡的才會在堆疊上分配空間;
(3)函數可以取得到堆疊至多128位元組的空間。這樣函數就可以在不更改棧指標的情況下在堆疊上儲存資訊(也就是說,可以提前用rsp以下的128位元組空間,這段空間被稱為red zone,在x86-64裡,時刻可用);
(4)不再有堆疊幀指針,現在堆疊的位置和堆疊指針相關。大多數函數在呼叫的一開始就分配全部所需棧空間,之後保持棧指標不改變;
(5)一些暫存器被設計成為被呼叫者-儲存的暫存器,這些必須在需要改變他們值的時候儲存他們並且之後恢復他們。

0x04:參數傳遞的不同

(1)6個暫存器用來傳遞參數(見前文);

(2)剩下的暫存器按照之前的方式傳遞(不過是與rsp相關了,ebp不再作為棧幀指針,並且從rsp開始第7個參數,rsp 8開始第8個,以此類推);

(3)呼叫時,rsp向下移動8位元(存入回傳位址),暫存器參數無影響,第7個及之後的參數現在則是從rsp 8開始第7個,rsp 16開始第8個,以此類推;

0x05:棧幀的不同

很多情況下不再需要棧幀,例如在沒有呼叫別的函數,且暫存器足以儲存參數,那麼就只需要儲存回傳位址即可。
需要堆疊幀的情況:

(1)本地變數太多,暫存器不夠;
(2)一些本地變數是​​陣列或結構體;
(3)函數使用了取位址運算子來計算一個本地變數的位址;
(4)函數必須用堆疊傳送一些參數給另外一個函數;
(5)函數需要保存一些由被呼叫者儲存的暫存器的狀態(以便於恢復);

但是現在的堆疊幀經常是固定大小的,在函數呼叫的最開始就被設定,在整個呼叫期間,棧頂指標保持不變,這樣就可以透過對其再加上偏移量來對對應的值進行操作,於是EBP就不再需要作為堆疊幀指標了。雖然很多時候我們認為沒有“棧幀”,但是每次函數呼叫都一定有一個返回地址被壓棧,我們可以也認為這一個地址就是一個“棧幀”,因為它也保存了呼叫者的狀態。

0x06:運算速度不同

64位元cpu的資料寬度為64位,64位元指令集可以運行64位元資料指令,也就是說處理器一次可擷取64位元數據,比32位元提高了一倍,理論上效能會隨之提升1倍。

相關推薦:《Linux影片教學

以上是linux中x64和x86的差別是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn