前言

在上組合語言的時候,有個作業原本是要把一個變數初始化為十六進位的eeea,但眼殘如我不小心看成是要初始化為一個字串eeea。於是我稍微去理解了一下究竟在register以及memory中是如何儲存字串及字元的,也是因為這樣才誕生了這篇文章。

字元是如何儲存的?

一般字元是以1byte(8bits)的大小,用ascii code的編碼方式儲存在register及memory中的。

要驗證字元如何儲存的真實性可以寫簡單的assembly code加上windbg輕易的驗證。

驗證

  1. 首先我先寫了個簡單的程式碼,把字元A放到eax暫存器中。
TITLE example.asm
INCLUDE Irvine32.inc
.data

.code
main        EQU start@0
main PROC
    mov eax, 'A'
main ENDP
END main
  1. 利用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小端序表示。

EEEA
69696965
記憶體位置低

接下來我們就來驗證一下這個是否正確吧!

驗證

  1. 我們同樣先寫一個簡單的assembly來開始我們的實驗。
TITLE example.asm
INCLUDE Irvine32.inc
.data

.code
main        EQU start@0
main PROC
    mov eax, 'EEEA' ; 把字串EEEA放到eax中
main ENDP
END main
  1. 用windbg來看看eax暫存器狀況

還沒執行mov eax, ‘EEEA’,為隨機的初始值 咦?執行後,eax變成了1162167617

我們回想起剛剛的表格,可以得到這個公式: 符合我們剛剛表格中的的猜測。

公式解釋:

  • 以16為底是因為記憶體內儲存皆是以16進位來表示。
  • 指數的6, 4, 2則是在16進位之下做了shift left的動作。不懂的話可以先從二進位的shift運算來了解。