64位和32位的寄存器和匯編的比較


轉載於http://blog.csdn.net/qq_29343201/article/details/51278798

 

64位(新增)匯編指令的不同

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

注意:movabsq不是32位的擴展,是純新增的指令。用來將一個64位的字面值直接存到一個64位寄存器中。因為movq只能將32位的值存入,所以新增了這樣一條指令。

 

順帶提一個小問題,64位的匯編代碼在ret之前可能會加一句rep,這里的rep沒有實際意義,只是出於amd處理器的原因,避免jmp所到達的地方直接就是ret,這樣會使得處理器運行更快一些。

過程(函數)調用的不同

  • 參數通過寄存器傳遞(見前文)
  • callq 在棧里存放一個8位的返回地址
  • 許多函數不再有棧幀,只有無法將所有本地變量放在寄存器里的才會在棧上分配空間。
  • 函數可以獲取到棧至多128字節的空間。這樣函數就可以在不更改棧指針的情況下在棧上存儲信息(也就是說,可以提前用rsp以下的128字節空間,這段空間被稱為red zone,在x86-64里,時刻可用)
  • 不再有棧幀指針。現在棧的位置和棧指針相關。大多數函數在調用的一開始就分配全部所需棧空間,之后保持棧指針不改變。
  • 一些寄存器被設計成為被調用者-存儲的寄存器。這些必須在需要改變他們值的時候存儲他們並且之后恢復他們。

    參數傳遞的不同

  • 6個寄存器用來傳遞參數(見前文)
  • 剩下的寄存器按照之前的方式傳遞(不過是與rsp相關了,ebp不再作為棧幀指針,並且從rsp開始第7個參數,rsp+8開始第8個,以此類推)
  • 調用時,rsp向下移動8位(存入返回地址),寄存器參數無影響,第7個及之后的參數現在則是從rsp+8開始第7個,rsp+16開始第8個,以此類推

棧幀的不同

很多情況下不再需要棧幀,比如在沒有調用別的函數,且寄存器足以存儲參數,那么就只需要存儲返回地址即可。 
需要棧幀的情況:

  • 本地變量太多,寄存器不夠
  • 一些本地變量是數組或結構體
  • 函數使用了取地址操作符來計算一個本地變量的地址
  • 函數必須用棧傳送一些參數給另外一個函數
  • 函數需要保存一些由被調用者存儲的寄存器的狀態(以便於恢復)

但是現在的棧幀經常是固定大小的,在函數調用的最開始就被設定,在整個調用期間,棧頂指針保持不變,這樣就可以通過對其再加上偏移量來對相應的值進行操作,於是EBP就不再需要作為棧幀指針了。

雖然很多時候我們認為沒有“棧幀”,但是每次函數調用都一定有一個返回地址被壓棧,我們可以也認為這一個地址就是一個“棧幀”,因為它也保存了調用者的狀態。

 

 

轉載於http://blog.csdn.net/qq_29343201/article/details/51278798

 

64位ASM教程參考:

http://cs.lmu.edu/~ray/notes/nasmtutorial/

http://asmtutor.com/#lesson1

https://cs.nyu.edu/courses/fall11/CSCI-GA.2130-001/x64-intro.pdf

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM