上海網(wǎng)站建設(shè)方案2021年年度關(guān)鍵詞
寄存器
- 1、什么是寄存器
- 2、寄存器分類
- 3、windows X86寄存器命名規(guī)則
- 4、寄存器相關(guān)術(shù)語
- 5、寄存器分類
- 5.1、RAX(accumulator register)
- 5.2、RBX(Base register)
- 5.3、RDX(Data register)
- 5.4、RCX(counter register)
- 5.5、RSI(Source index)
- 5.6、RDI(Destination index)
- 5.7、RSP(stack pointer)
- 5.8、RBP(Base pointer)
- 5.9、RIP(instruction pointer)
- 6、普通寄存器
- 6.1、R8~R15
- 6.2、YMM0~15
- 7、特別說明
- 8、匯編指令
- 8.1、數(shù)據(jù)格式
- 8.2:操作數(shù)格式(尋址方式)
- 8.3:匯編指令
- 8.3.1:數(shù)據(jù)傳送指令
- 8.3.2:壓入和彈出棧數(shù)據(jù)
- 8.3.3:算術(shù)和邏輯操作
- 8.3.4:控制指令
本篇博客是:棧-寄存器和函數(shù)狀態(tài)專題第一篇文章,主要解釋計(jì)算機(jī)中寄存器相關(guān)知識技術(shù),下面的分析,我們都是基于下面這張圖。

💙💙💙💙:重點(diǎn)
%ebp 和 %esp:棧是從高地址向低地址延伸的。每個(gè)函數(shù)的每次調(diào)用,都有它自己獨(dú)立的一個(gè)棧幀,%esp總是指向當(dāng)前棧幀的頂部(低地址),而%ebp通常指向當(dāng)前棧幀的底部(高地址),用于在棧幀中尋址
1、什么是寄存器
寄存器實(shí)際上知識存儲(chǔ)數(shù)據(jù)的地方,只不過它集成在CPU里,訪問寄存器的速度比訪問內(nèi)存更快,而內(nèi)存的訪問速度比硬盤更快。
2、寄存器分類
由于寄存器屬于底層基礎(chǔ)設(shè)施,貼近硬件,因此在不同體系結(jié)構(gòu)和操作系統(tǒng)上,寄存器使用方式各異,但是基本上可以分為特殊功能寄存器和普通寄存器,特殊功能寄存器一般用于特定的功能,而普通寄存器可以隨意使用。
3、windows X86寄存器命名規(guī)則
- 前綴R:表示64位寄存器。例如:RAX
- 前綴E:表示32位寄存器。例如:EAX
- 后綴L:表示寄存器的低8位。
- 后綴H:表示寄存器的9~16位
4、寄存器相關(guān)術(shù)語
- byte:字節(jié)單位,表示8位二進(jìn)制,是計(jì)算機(jī)的最小存儲(chǔ)單元
- WORD:字。一個(gè)字通常是指;兩個(gè)字節(jié)(16位),針對windows X64平臺,這個(gè)規(guī)則總是成立的,其他一些小眾的平臺不一定滿足這一點(diǎn)。
- DWORD:windows API的類型,用于表示“double world”的數(shù)據(jù),即32位。
- QWORD:windows API的類型,用于表示“qual word”的數(shù)據(jù),即63位。
- x86_x64:這是intel最先推出的指令集
- 棧幀:用于記錄程序在某時(shí)刻棧的狀態(tài),例如在調(diào)用一個(gè)函數(shù)之前,需要保存棧幀,用于在完成調(diào)用之后恢復(fù)現(xiàn)場。
5、寄存器分類
特殊功能寄存器分為:通用寄存器,索引寄存器。(我們以64位寄存器為例介紹)
---------------------------------------------------------------🎄🎄下面介紹通用寄存器-------------------------------------
-
通用功能寄存器:主要有四種即 【AX,BX,CX,DX】
-
-
細(xì)節(jié)方面:AX,BX,CX,DX可以再往下劃分
👩AX(Accumlator Register):累加寄存器,它主要用于輸入/輸出和大規(guī)模的指令運(yùn)算
👩BX(Base Register):基址寄存器,用來存儲(chǔ)基礎(chǔ)訪問地址。
👩CX(Count Register):計(jì)數(shù)寄存器,在迭代的操作中會(huì)循環(huán)計(jì)數(shù)。
👩DX(Data Register):數(shù)據(jù)寄存器,它用于輸入/輸出操作,它還與AX一起使用,用于涉及大數(shù)值的乘法和除法運(yùn)算。 -
這四種寄存器可以分為上半部分和下半部分。
👨【AX寄存器可以分為兩個(gè)獨(dú)立的 8位 AH 和 AL寄存器】
👨【BX寄存器可以分為兩個(gè)獨(dú)立的 8位 BH 和 BL寄存器】
👨【CX寄存器可以分為兩個(gè)獨(dú)立的 8位 CH 和 CL寄存器】
👨【DX寄存器可以分為兩個(gè)獨(dú)立的 8位 DH 和 DL寄存器】
👩?🦰 AX的地位(0-7)位構(gòu)成了 AL 寄存器,高8位(8-15)位構(gòu)成了AH寄存器。 -
在認(rèn)識了寄存器之后,我們通過一個(gè)示例看一下數(shù)據(jù)的具體存儲(chǔ)方式。
比如:數(shù)據(jù) 19, 它在16 位存儲(chǔ)器中所存儲(chǔ)的表示如下:
寄存器的存儲(chǔ)方式先是存儲(chǔ) 低位,如果低位滿足不了就存儲(chǔ)高位,如果低位能夠滿足,高位就用0補(bǔ)全,在其他低位也能滿足的情況下,其余位也用0補(bǔ)全。
-------------------------------------------------------🎪🎪🎢索引寄存器---------------------------------------------------
🎈🎈下面介紹索引寄存器
- 索引寄存器主要包含段地址的偏移量,索引寄存器主要分為:
- BP (Base Pointer): 基礎(chǔ)指針,它是棧寄存器上的偏移量,用來定位棧上的變量。
- SP (Stack Point): 棧指針,它是棧寄存器上的偏移量,用來定位棧頂。
- SI (Source Index):變址寄存器,用來拷貝源字符串。
- DI(Destination Index): 目標(biāo)變址寄存器,用來復(fù)制目標(biāo)字符串。
------------------------------------------------🎭🎭🎭控制寄存器----------------------------------------------------------
🎀🎀下面介紹狀態(tài)和控制寄存器
這兩種寄存器是指令指針寄存器和 標(biāo)志寄存器
IP (Instruction Pointer):指令指針寄存器,它是從Code Segment代碼寄存器處的偏移來存儲(chǔ)執(zhí)行的下一條指令。
FLAG:FLAG寄存器用于存儲(chǔ)當(dāng)前進(jìn)程的狀態(tài),這些狀態(tài)有
- 位置(Direction):用于數(shù)據(jù)塊的傳輸方向,是向上傳輸還是向下傳輸
- 中斷標(biāo)志位(Interrupt): 1–允許,0 --禁止
- 陷入位(Trap) : 確定每條指令執(zhí)行完成后,CPU是否應(yīng)該停止。1–開啟,0—關(guān)閉
- 進(jìn)位(Carry) :設(shè)置最后一個(gè)無符號算術(shù)是否帶有進(jìn)位
- 溢出(Overflow): 設(shè)置最后一個(gè)由符號的運(yùn)算是否溢出
- 符號(Sign): 如果最后一次算術(shù)運(yùn)算為負(fù),則設(shè)置 1 —負(fù), 0 —正
- 零位(Zero) :如果最后一次算術(shù)運(yùn)算結(jié)果為零, 1–零
- 輔助進(jìn)位(Aux Carry): 用于第三位到第四位的進(jìn)位
- 奇偶校驗(yàn) (Parity):用于奇偶校驗(yàn)
5.1、RAX(accumulator register)
-
accumulator register, 累加寄存器,👩通常用于存儲(chǔ)函數(shù)的返回值,它主要用于輸入/輸出和大規(guī)模的指令運(yùn)算,AX 寄存器可以說是使用頻率最高的寄存器。
-
也可以用于存儲(chǔ)其他值,只是通過RAX存儲(chǔ)函數(shù)返回值屬于慣例。
-
上圖我們可以看到這個(gè)寄存器分為8個(gè)字節(jié)(每個(gè)字節(jié)8位),RAX是64位寄存器的稱呼。
🤶🎅🤶 但是這個(gè)寄存器是可以拆分的,例如我們操作EAX,就是在對RAX的低32位進(jìn)行操作。
同樣類推:
AX表示RAX的低16位
AH表示RAX低16位中的高8位
AL表示RAX低16位中的低8位
除了了 RIP之外,其余的寄存器都可以做類似的拆分。 -
舉例
mov ax,20 /* 將數(shù)字20存入寄存器 AX中*/
mov ah,80 /* 將數(shù)字80 存入寄存器 AX中的 AH(高位寄存器)中*/
mov al,10 /* 將數(shù)字10 存入寄存器 AX中的 AL(低位寄存器)中*/
5.2、RBX(Base register)
base register 基址寄存器,一般用于訪問內(nèi)存的基址
👩 :BX也被稱為數(shù)據(jù)寄存器,即表明其能夠暫存一般數(shù)據(jù),同樣也可以將BX當(dāng)做兩個(gè)獨(dú)立的 8位寄存器使用即 BH 和BL
👨 BX除了具有暫存數(shù)據(jù)的功能之外,還用于尋址(即尋找物理地址),這就是為什么也有人將其稱為基址寄存器,那么它存放的數(shù)據(jù)一般就用來作為偏移地址使用,因?yàn)槠频刂肥窍鄬τ诨返刂飞系钠啤?/p>
5.3、RDX(Data register)
🧑:DX也是數(shù)據(jù)寄存器,能夠暫存一般性數(shù)據(jù)。
5.4、RCX(counter register)
👧:counter register,計(jì)數(shù)寄存器。一般用于循環(huán)計(jì)數(shù)。
- 也可以稱為數(shù)據(jù)寄存器,能夠暫存一般性數(shù)據(jù),可以分為CH 和CL
- 它也有專門功能:即計(jì)數(shù)器功能,當(dāng)匯編指令使用 循環(huán)LOOP時(shí),可以通過 CX來指定需要循環(huán)的次數(shù),每次執(zhí)行循環(huán)LOOP時(shí)間,CPU會(huì)做兩件事
一件事是:計(jì)數(shù)器自動(dòng)減1
另一件事是:判斷CX中的值,如果CX中的值為0則跳出循環(huán),繼續(xù)執(zhí)行循環(huán)下面的指令,如果CX中的值不為0,則會(huì)繼續(xù)執(zhí)行循環(huán)中所指定的指令。
--------------------------------------索引寄存器--------------------------------------------------------------------
5.5、RSI(Source index)
source index : 源變址寄存器,字符串運(yùn)算時(shí)常應(yīng)用于源指針
5.6、RDI(Destination index)
destination index 目標(biāo)變址寄存器,字符串運(yùn)算時(shí)常用于目標(biāo)指針。
5.7、RSP(stack pointer)
- stack Pointer 棧指針寄存器
- 正常情況下存放棧頂?shù)刂?/li>
- 如果用于其他事務(wù),使用完成之后需要恢復(fù)原先的數(shù)據(jù)
5.8、RBP(Base pointer)
- base pointer 基址寄存器
- 正常情況用于訪問棧底地址,與RBP功能類似
- 如果用于其他事務(wù),使用完成之后需要恢復(fù)原先的數(shù)據(jù)
---------------------------------------🧶🧶🧶控制寄存器--------------------------------------------------------------
5.9、RIP(instruction pointer)
- instruction pointer 指令指針
- 只讀且不可拆分,指向下一條需要執(zhí)行指令的地址
6、普通寄存器
6.1、R8~R15
- R8,R9, R10…R15屬于普通寄存器,一般是可以任意使用的,不指定特定用途,支持拆分
- 拆分規(guī)則與特殊功能寄存器有所不同。 32位拆分寄存器以 D作為后綴(DWORD),16位寄存器以 W作為后綴 (WORD),8位則以 B作為后綴 (BYTE)。
6.2、YMM0~15
YMM015專門用于存儲(chǔ)浮點(diǎn)數(shù)(包括float和double)。單個(gè)寄存器可以存放多個(gè)浮點(diǎn)數(shù)。例如YMM#支持存放四個(gè)64位數(shù)值或者8個(gè)32位值。支持拆分成XMM015。
7、特別說明
- RSP, RBP最好只用作常規(guī)用途。
- 如果另作他用,使用完之后應(yīng)該恢復(fù)原來的數(shù)據(jù),因?yàn)檫@兩個(gè)寄存器包含棧幀信息,這對程序非常重要。
- 一般的寄存器只能存放一個(gè)值,但是XMM和YMM寄存器可以看作是數(shù)組,它們可以存放多個(gè)浮點(diǎn)數(shù)。
8、匯編指令
8.1、數(shù)據(jù)格式
intel數(shù)據(jù)類型 | 匯編代碼后綴 |
---|---|
字節(jié) | b |
字(2字節(jié)) | w |
雙字(4字節(jié)) | l |
四字(8字節(jié)) | q |
單精度(4字節(jié)) | s |
雙精度(8字節(jié)) | l |
1: Intel使用 字(word)表示 16位數(shù)據(jù)類型
2:匯編指令除了要指明操作對象,還要指明操作對象的數(shù)據(jù)類型和長度,所以為指明操作對象的數(shù)據(jù)類型和長度,可以在指令后面加上表示數(shù)據(jù)類型的后綴,如:movl 和 movq 分別表示操作對象為雙字和四字。
但是操作長度也可以通過寄存器給出,如:eax表示 32位,rax 表示64位
8.2:操作數(shù)格式(尋址方式)
8.3:匯編指令
8.3.1:數(shù)據(jù)傳送指令
------------------------💜💜 數(shù)據(jù)傳送指令舉例💜💜-----------------------
- move : 數(shù)據(jù)傳遞指令,目的操作數(shù)不能是立即數(shù),數(shù)據(jù)不能從內(nèi)存直接傳送到內(nèi)存(如一定需要,轉(zhuǎn)化成2條指令,從內(nèi)存取數(shù)據(jù)到寄存器,然后從寄存器到內(nèi)存)
💛💛💛💛 move $4, 17(%rsp) : 把數(shù)據(jù)4 存儲(chǔ)到 17(%rsp)所在內(nèi)存的地址值里。 - lea:(load effective address)其實(shí)是mov的變形,它的源操作數(shù)看上去是一個(gè)內(nèi)存引用,但并非從指定位置讀入數(shù)據(jù),而是將有效地址寫入到目的操作數(shù),目的操作時(shí)只能為寄存器。
💚💚💚💚 lea17(%rsp), %rax :把17(%rsp)的內(nèi)存地址的值寫入到 %rax寄存器中。
8.3.2:壓入和彈出棧數(shù)據(jù)
這兩個(gè)操作都會(huì)修改 %rsp的值
8.3.3:算術(shù)和邏輯操作
注意,ADD S,D 由四條加法指令組成,即 addb, addw, addl 和 addq,其他指令也是如此
Intel把16字節(jié)的數(shù)稱為八字(oct word)。下面是一些特殊的指令:
8.3.4:控制指令
-----------------------------------------💔💔條件碼💔💔---------------------------------
CPU維護(hù)著一組單個(gè)位的條件碼寄存器,它們描述了最近的算數(shù)或者邏輯操作的屬性,可以檢查這些寄存器來執(zhí)行條件分支指令。最常用的條件碼有:
-
CF:進(jìn)位標(biāo)志,最近的操作使最高位產(chǎn)生了進(jìn)位,可用于檢查無符號操作的溢出。
-
ZF:零標(biāo)志,最近的操作得出的結(jié)果為0。
-
SF:符號標(biāo)志,最近的操作得到的結(jié)果為負(fù)數(shù) 。
-
OF:溢出標(biāo)志,最近的操作導(dǎo)致一個(gè)補(bǔ)碼溢出(正溢出獲負(fù)溢出)。
算術(shù)和邏輯操作列出的指令中,除了leaq,其他指令都會(huì)修改條件碼寄存器。
除了算數(shù)和邏輯操作指令可以改變條件碼寄存器,下面的指令也可以改變:
-----------------------------------------💔💔訪問條件碼💔💔----------------------------
條件碼通常不會(huì)直接讀取,常用的使用方法有三種。
- 更具條件碼的某種組合,將一個(gè)字節(jié)設(shè)置為0或者1
- 根據(jù)條件碼進(jìn)行跳轉(zhuǎn)
- 有條件地傳送數(shù)據(jù)
-----------------------------------------💔💔跳轉(zhuǎn)指令💔💔----------------------------
--------------------------------💔💔條件傳送指令💔💔----------------------------
--------------------------------💔💔轉(zhuǎn)移控制💔💔----------------------------