1. 程式人生 > >10-x86彙編——大小端模式

10-x86彙編——大小端模式

組合語言實際上是和記憶體以及暫存器打交道的,當處理器執行彙編指令時,影響的不是記憶體變化就是暫存器的變化,前面我們已經詳細介紹過暫存器了,這一小節我們主要討論資料在記憶體中的儲存——大小端模式。

當我們對記憶體讀寫時,實際上是操作的記憶體地址(又可以稱為記憶體編號),每一個記憶體地址都對應著一個記憶體儲存單元,而每個記憶體單元對應1個位元組(相當於8個位元位)。

如上圖所示,假設我們需要在以0x08001為起始地址的一段記憶體區域內依次儲存9個位元組資料應該怎麼做呢?通過前面的學習,其實這很好辦。

 

下面是給出的實現程式碼:

mov ax,0x0800
mov ds,ax 				;把資料段暫存器DS定位到0x0800記憶體地址

mov byte[ds:0001],0x11		;從0x08001起始地址依次寫入位元組資料
mov byte[ds:0002],0x22
mov byte[ds:0003],0x33
mov byte[ds:0004],0x44
mov byte[ds:0005],0x55
mov byte[ds:0006],0x66
mov byte[ds:0007],0x77
mov byte[ds:0008],0x88
mov byte[ds:0009],0x99 

end:
jmp 0x07C0:end 

times 510-($-$$) db 0x00
db 0x55,0xAA 

 

執行結果:

從上圖來看,程式的執行結果是非常符合我們預期所想的,這裡我們再思考一下:首先大家都知道一個記憶體地址只能儲存一個位元組的資料,如果我們把一個16位的資料儲存到記憶體中會發生什麼?

我們可以通過word來寫入一個字,word代表一個字,一個字是2個位元組大小。

可以認為word關鍵字就是讓編譯器知道,你到底要覆蓋幾個記憶體地址。

 

修改上面的程式碼為:

mov word[ds:0001],0x1122		
mov dx,word[ds:0001]			 ;往暫存器dx中寫入一個字

執行結果如下:

還是以0x08001起始地址寫入一個十六位的資料0x1122,我們可以看到在記憶體中實際上佔用了兩個記憶體地址,0x22儲存在0x08001記憶體地址,0x11儲存在0x08002記憶體地址。

也就是說,當我們要往一個記憶體地址寫入2個位元組的時候,就會以該地址為起始地址,依次寫入資料(覆蓋下一個記憶體地址)。那如果我們要往某個記憶體地址寫4個位元組呢?

mov dword[ds:0001],0x11223344
mov edx,dword[ds:0001]

dword表示寫入4位元組,edx是一個32位的暫存器。

 

執行結果如下:

我們可以看到0x08001記憶體地址存放了0x44,0x08004記憶體地址存放了0x11。我們再換一句說法,0x08001記憶體地址儲存了一個4位元組[32位]的數字:0x11223344。

這種記憶體儲存方式稱之為小端模式,記憶體的低地址儲存了資料低位,記憶體的高地址儲存了資料高位。例如0x11223344這個資料來說,0x11代表最高位,而0x44代表最低位。

對於記憶體地址來說,0x08001是最低位,0x08004是最高位。

至於大端模式就是資料低位在記憶體高位,資料高位在記憶體低位,最後,如果CPU是大端模式工作的話,那麼大家思考一下,當執行如下指令:mov dword[ds:0001],0x11223344,資料在記憶體是如何儲存的?