如定義以下結構體類型
struct binky {
int a;
char b, c, d, e;
short f;
};
不考慮內存對齊的其況,他在內存中作如何表示呢?
圖:
假如有以下代碼
例1
{
struct binky x;
x.e = 'A';
x.f = x.a;
}
他會生成怎樣的代碼呢,假設x基地址存於R1中,則
M[R1 + 7] =.1 65 ; R1 is the base addr of x, add 7 for .e offset
; '=.1' means move one byte instead of 4
R2 = M[R1] ; load value from .a which is at offset 0
M[R1 + 8] =.2 R2 ; store .f at offset 8, =.2 to move 2 bytes
; will truncate value to the lower 2 bytes
對於數組呢,如以下代碼
例2
{
int arr[20];
arr[25] = 7;
}
其實此數組在內存中分配了80字節的存儲空間(20 * sizeof(int)),假設其基地址依然爲R1,則生成的彙編如下:
R2 = 25 * 4 ; compute offset (smart compiler can optimize)
R3 = R1 + R2 ; add to array base to get addr of 25th elem
M[R3] = 7 ; store into that location
由此也可以看到編譯器並不管數組越界的問題,所以如果不小心,有時將會使程序產生災難性的後果。
另外定義一個結構體數據,代碼如下:
例3
{
int i;
struct binky arr[50];
a[i].f = i;
}
假設其基地址仍存於R1中,則算好地址偏移量仍能夠很輕鬆的手動生成彙編代碼:
R2 = M[R1 + 500] ; load value of i
R3 = R2 * 10 ; multiply by element size to get offset
R3 = R1 + R3 ; add to array base addr to get addr of ith elem
M[R3 + 8] =.2 R2 ; don't forget the constant +8 offset for ".f"
對於指針類型變量呢,例如下代碼
例4
{
int *ptr;
*(char *)ptr = 'a' ;
}
假設ptr的地址存於R1中,則生成彙編如下:
R2 = M[R1] ; load value of ptr
M[R2] =.1 97 ; deref ptr, copy just 1 char
對於指針類型和整型都會4字節整數形式存儲,所以他們之間可以不經過任何的轉換而互相賦值(但編譯器會給出警告),
如下代碼
例5
{
char ch;
int *s;
s = (int *)&ch;
*s = (int)s;
}
假設s地址存儲於R1中,則生成彙編爲
R2 = R1 + 4 ; calculate address of ch
M[R1] = R2 ; store in s (no conversion required)
R3 = M[R1] ; load value of s
M[R3] = R3 ; deref and store val there
另外對於如下代碼呢:
例6
{
int i;
((struct binky *)i)->b = 'A';
}
假設i地址存儲於R1中,則生成彙編如下
R2 = M[R1] ; load value of i
M[R2 + 4] =.1 65 ; now treat like base address of struct!
以上介紹的都爲數據類型的定義和順序賦值語句,對於選擇及循環語句呢?
請看下一節。