從彙編角度理解C語言(三) 原

如定義以下結構體類型
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! 

以上介紹的都爲數據類型的定義和順序賦值語句,對於選擇及循環語句呢?
請看下一節。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章