前言
在上組合語言的時候,有個作業原本是要把一個變數初始化為十六進位的eeea,但眼殘如我不小心看成是要初始化為一個字串eeea。於是我稍微去理解了一下究竟在register以及memory中是如何儲存字串及字元的,也是因為這樣才誕生了這篇文章。
字元是如何儲存的?
一般字元是以1byte(8bits)的大小,用ascii code的編碼方式儲存在register及memory中的。
要驗證字元如何儲存的真實性可以寫簡單的assembly code加上windbg輕易的驗證。
驗證
- 首先我先寫了個簡單的程式碼,把字元A放到eax暫存器中。
TITLE example.asm
INCLUDE Irvine32.inc
.data
.code
main EQU start@0
main PROC
mov eax, 'A'
main ENDP
END main
- 利用windbg來看看eax會變成怎樣
還沒執行mov eax, ‘A’時,eax為一個隨機的初始值 執行後,eax內的值的確變成了A的ascii code編碼65。這也驗證了字元在register及memory中是以1byte、ascii code編碼的方式儲存的。
字串是如何儲存的?
先說結論,字串依然是把字元一個一個存在register或memory中,每個字元仍舊佔1個byte。所以拿"EEEA"為例,總共會佔4*1byte(32bits)。
接下來我們來猜測一下記憶體中"EEEA"會如何被儲存。
以下是我們猜測的記憶體中儲存方式的示意圖,位元組順序以常見的little endian小端序表示。
E | E | E | A |
---|---|---|---|
69 | 69 | 69 | 65 |
高 | 記憶體位置低 |
接下來我們就來驗證一下這個是否正確吧!
驗證
- 我們同樣先寫一個簡單的assembly來開始我們的實驗。
TITLE example.asm
INCLUDE Irvine32.inc
.data
.code
main EQU start@0
main PROC
mov eax, 'EEEA' ; 把字串EEEA放到eax中
main ENDP
END main
- 用windbg來看看eax暫存器狀況
還沒執行mov eax, ‘EEEA’,為隨機的初始值 咦?執行後,eax變成了1162167617
我們回想起剛剛的表格,可以得到這個公式: 符合我們剛剛表格中的的猜測。
公式解釋:
- 以16為底是因為記憶體內儲存皆是以16進位來表示。
- 指數的6, 4, 2則是在16進位之下做了shift left的動作。不懂的話可以先從二進位的shift運算來了解。