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,資料在記憶體是如何儲存的?