官术网_书友最值得收藏!

2.5 內(nèi)存訪問

32位(或64位)的系統(tǒng)只有有限的寄存器。忽略用于追蹤棧的特殊寄存器和通用寄存器(如esp和ebp)后,只剩下六個可用于一般計算的寄存器(如eax、ebx、ecx、edx、esi和edi),這就是程序還需要能夠讀取內(nèi)存數(shù)據(jù)和向內(nèi)存中寫入數(shù)據(jù)的原因。

在x86匯編Intel語法中,內(nèi)存訪問是使用[]符號來表示的。例如,存儲在0x12345678地址的數(shù)據(jù)可以通過[0x12345678]來訪問。內(nèi)存地址也可以存儲在寄存器中,如指令[eax]。

指定數(shù)據(jù)長度

當(dāng)從內(nèi)存獲取數(shù)據(jù)時,不僅需要知道數(shù)據(jù)的存儲地址,還需要知道要訪問的內(nèi)存量。例如,指令[0x12345678]并沒有指明程序需要一個字節(jié)、一個字、一個雙字,還是更多。

圖2.7 x64常用的寄存器

來源:Bobmon/Wikimedia Commons/CC BY-SA 4.0.

圖2.8 r8寄存器的各個部分

在某些情況下,可以從上下文中推斷出需要訪問的數(shù)據(jù)的長度。例如,在指令mov eax,[0x12345678]中,從內(nèi)存中獲取的數(shù)據(jù)將被儲存在eax中。由于eax是一個32位寄存器,程序必然需要請求32位的數(shù)據(jù)。

事實并非總是這樣。例如,考慮指令mov[0x12345678], 1,它會將值1放到內(nèi)存中的特定地址。但是,這個指令并沒有明確被設(shè)定的值的長度。我們應(yīng)該將1看作是一個字節(jié)(00000001)、一個字(0000000000000001),還是一個雙字(00000000000000000000000000000001)呢?為了明確和精簡,我們經(jīng)常會去除前導(dǎo)零,所以以上都是有效解釋。

提示:傳統(tǒng)上,32位的x86架構(gòu)應(yīng)該有32位的字。然而,為了向后兼容16位的x86架構(gòu),所以字的長度是16位,而雙字則是32位。

當(dāng)內(nèi)存訪問的大小沒有被隱式地指出時,必須在指令內(nèi)明確指明。例如,指令byte[100]訪問位于地址100的字節(jié),word[ebx]訪問ebx指向的字,dword[ax]訪問ax指向的雙字。圖2.9展示了以下三條指令之間的區(qū)別。

圖2.9 比較不同大小的mov指令

主站蜘蛛池模板: 东阿县| 阿拉善左旗| 吐鲁番市| 德阳市| 调兵山市| 忻城县| 台北县| 五寨县| 五原县| 陵川县| 怀仁县| 疏附县| 嵊泗县| 博客| 清原| 特克斯县| 临沧市| 若尔盖县| 莱阳市| 介休市| 犍为县| 靖安县| 怀仁县| 巴中市| 新民市| 德阳市| 林口县| 邮箱| 常熟市| 清水河县| 尼木县| 滦南县| 星子县| 河源市| 旅游| 本溪市| 荆州市| 亚东县| 平湖市| 古蔺县| 金阳县|