微軟編譯器中暫存器的使用
翻譯:乙個暫存器就像變數,只是這種變數的數量是固定的。暫存器是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...