微軟編譯器中暫存器的使用

2021-08-24 17:14:48 字數 3681 閱讀 8558

微軟編譯器中暫存器的使用

翻譯:乙個暫存器就像變數,只是這種變數的數量是固定的。暫存器是cpu中用來儲存資料的地方。數學計算(加法、減法..)只能在暫存器中進行;暫存器常常儲存著記憶體位址;暫存器與記憶體中資料的相互轉移也是經常的事情。

intel cpu有8個32位通用暫存器:eax, ebx, ecx, edx, esi, edi, ebp, esp.雖然資料可以再這些暫存器之間互相移動,但是編譯器常常對於特定功能使用特定的暫存器,而且一些指令(比如乘法、除法)只能使用的cpu設計時指定的暫存器。

不同的編譯器在如何使用不同暫存器時會有完全不同的習慣。本文的目的主要討論微軟的編譯器如何使用這些暫存器的。

內容

1.易失性(volatility)

2.通用暫存器

2.1 eax

2.2 ebx

2.3 ecx

2.4 edx

2.5 esi

2.6 edi

2.7 ebp

2.8 esp

3.16

位和8位暫存器

4. 64

位暫存器

1.易失性

一些暫存器在函式中常常是變化的,而另外一些卻是不變的。這是編譯器所決定的。因為暫存器是不會自動儲存的(雖然有些組合語言會自動儲存,但是x86是不會的),所以編碼時要自己儲存。這句話的意思是:當乙個函式被呼叫,是不保證在函式返回時,易失暫存器上的值不變的;但是函式必須負責儲存非易失暫存器中的值。

微軟編譯器的暫存器使用習慣如下: 1)

易失暫存器:ecx, edx 2)

非易失暫存器: ebx, esi, edi, ebp 3)

其他特殊暫存器: eax, esp (discussed later)

2.通用暫存器

本節來了解一下x86架構下的8個通用暫存器。至於其他的特殊暫存器和浮點暫存器,可以參看wikipedia中的文章或其他**。

2.1 eax

eax是乙個32為通用暫存器,一般的用途有兩個:儲存函式的返回值或者作為計算用的專用暫存器。在技術上來說,eax是乙個易失暫存器,因為他的值是不能儲存的,eax的值會在函式返回前設定為函式的返回值。除了esp暫存器,eax的這個功能(即儲存返回值)可能是最重要的值得被記住的。eax還會在資料計算時要用,比如乘法和除法。這種用法我們會在指令使用一文講解。

下面是c語言中函式返回的例子:

return 3; // 返回3

對應的組合語言:

mov eax, 3; 置eax=3

ret ; 返回

2.2 ebx

ebx是乙個非易失通用暫存器。它沒有特定的用途,但是常被置為乙個函式中常用的值(如0),以此來加快計算速度。

2.3 ecx

ecx是乙個易失通用暫存器。常被用作函式的引數或者是迴圈的計數器。

__fastcall的函式會將第一和第二個引數放置在ecx和edx暫存器中。另外,當呼叫乙個類中的成員函式時,不管呼叫習慣是什麼,指向類的指標常常是放在ecx中。

另外,ecx常被用作迴圈計算器。for迴圈一般(儘管不是總是)會將迴圈計數放在ecx中。rep指令也會將ecx作為計數器,自動減少直到為0.這類功能將在後面討論。

2.4 edx

edx是乙個易失通用暫存器,偶爾會被用作函式的引數。就像ecx,edx常用在__fastcall呼叫的函式中。

除了fastcall呼叫中存放引數,編譯器通常會將區域性(短期)變數儲存在edx中。

2.5 esi

esi是乙個非易失通用暫存器,常被用作指標。特別的,在rep一類的指令中,esi通常指向「源」。因為esi中資料是不會改變的,所以esi通常會儲存不會變的資料。

2.6 edi

esi是乙個非易失通用暫存器,常被用作指標。它和esi差不多,只不過一般是作為「目標」指標。

2.7 ebp

ebp是乙個非易失通用暫存器,根據編譯器的設定,它有兩個截然不同的用途:要麼作為框架指標,要麼作為一般暫存器。

若沒有優化編譯或者**是手工寫的,ebp會在函式開頭就儲存著堆疊的位置(關於堆疊下文會詳細討論)。因為堆疊在整個函式過程中是不停變換的,將ebp指向堆疊的原始位置可以使得方便使用儲存在堆疊中的變數。這會在討論堆疊是詳談。

如果編譯被優化,當堆疊指標的計算通過指標的移動值計算時(這可能有點亂——ida就是自動偵測並校準乙個移動的堆疊指標),ebp就會作為乙個儲存任何資料的通用暫存器了。。

2.8 esp

最後說說esp,esp是乙個儲存著堆疊底端指標的特殊暫存器(堆疊是向低位址生長)。很少直接對esp進行數學計算(加減),而且函式的開始和結束時的esp值必須一致。esp下文介紹。

3.16

位和8

位暫存器

除了有8個有效的32位暫存器,cpu還有一些16位和8位暫存器。有點讓人困惑的是,他們(16/8位暫存器)和32位暫存器使用相同的儲存空間。換句話說,每個16位暫存器是32位暫存器的一半,所以改變16位暫存器同樣會改變32位暫存器的值。同樣的,8位暫存器是16位暫存器的一半。

比如,eax是32位暫存器。eax的低一半是乙個16暫存器ax,ax被分成兩個8位暫存器:ah,al.

1)8個32位暫存器:eax, ebx, ecx, edx, esi, edi, ebp, esp

2)8個16位暫存器:ax, bx, cx, dx, si, di, bp, sp.

3)8個8位暫存器:ah, al, bh, bl, ch, cl, dh, dl.

這些暫存器的關係如下:

32位eax

ebx

ecx

edx16位 ax

bx cx

dx 8位

ah al

bhbl

ch cl

dhdl

32位esi

edi

ebp

esp

16位 si

di

bp sp

舉兩個例子:

eax

0x12345678 ax

0x5678 ah

0x56 al

0x78

ebx

0x00000025 bx

0x0025 bh

0x00 bl

0x25

4. 64位暫存器

乙個64位暫存器由2個32個暫存器組成,在兩個暫存器中用「:」隔開。

最普通的64位暫存器(在乘除法中用到)是edx:eax.這表示32位暫存器edx放在32位暫存器eax前面,用來建立8位元組暫存器。

舉例如下:

edx0x11223344

eax0xaabbccdd

edx:eax

0x11223344aabbccdd

微軟編譯器中暫存器的使用

微軟編譯器中暫存器的使用 翻譯 本文是組合語言指南的第一篇,若你準備閱讀整個指南,你必將有所收穫。乙個暫存器就像變數,只是這種變數的數量是固定的。暫存器是cpu中用來儲存資料的地方。數學計算 加法 減法.只能在暫存器中進行 暫存器常常儲存著記憶體位址 暫存器與記憶體中資料的相互轉移也是經常的事情。i...

Vim中暫存器的使用

vim中的暫存器 register 作用和windows中的剪貼簿類似,不過vim中的暫存器不止乙個,有不同的類別,有不同的用處。例如,ayy命令會將yy命令的結果放入暫存器a中,也就是複製該行文字到暫存器a中。然後 ap命令則表示貼上暫存器a中的內容。具體而言,vim中常用的暫存器包括 預設暫存器...

LCC編譯器的源程式分析 48 暫存器分配

在 lcc裡是使用非常簡單的暫存器分配演算法,並且侷限於森林裡的臨時變數的分配。下面就來分析暫存器分配的 001 int askregvar symbol p,symbol regs 011 else if p temporary 015 else if r askreg regs,vmask nu...