彙編中的結構體表示

我認爲,彙編中一切皆地址。

在c/c++使用很多的結構體,在彙編中是如何表示的呢?其實,在彙編中根本就沒有什麼結構體的概念,結構體本質就是一堆連在一起的數據。只不過有人把他們想象成一個整體,並以此產生結構體的概念,這與結構體中帶有變長數組時候的情形一樣:

 

其實上面這個結構體尾部帶有的變長數組,data[0]與結構體Test沒有任何關係,sizeof(Test)就知道。

 

結構體在彙編是如何表示的呢?

譬如如何訪問Test中的x成員,其實就是採用地址偏移的方式,根據定義的Test對象的起始地址,偏移一定的大小就可以訪問結構體中的不同成員了。

 

測試代碼:

 

 

gcc -S xxxx

 

產生的彙編代碼如下:

 

 

由c++filt 查看_ZN4TestC1Ev 知道爲Test::Test(),也即Test結構體的構造函數,看看這個函數的具體情況,

movl    8(%ebp), %eax //把this指針的地址放入eax

然後看它如何給第一個成員變量賦值:

movl    $0, (%eax) //將值0放入eax的值所對應的內存地址處,也就是給第一個成員變量賦值

同理:

 movl    8(%ebp), %eax

 movb    $0, 4(%eax) //4(%eax)表示eax+4所對應的內存地址處,也就是第二個成員變量處

由以上分析就很明顯了,彙編中訪問結構體成員採用的是地址偏移的方式,其實c/c++等高級語言,編譯之後都要轉換成彙編代碼,所以,結構體的底層訪問,就是採用的地址偏移的方式。

 

注意:

結構體中有一個重要的概念,內存對齊,它會改變結構體成員變量的偏移值。

windows和linux都有默認的地址對齊大小,一般4字節,以利於cpu訪問數據,因爲cpu一般數據總線32位,可以一次訪問4字節大小。

用#pragma pack(n) 可以改變內存對齊大小。

 

結構體內存對齊原則很複雜,特別是結構體中套一個結構體的時候,但是簡單說來,有兩點原則:

1,每個成員(基本數據類型,也就是int,bool,char等)的偏移值由兩個數據決定:其數據類型所佔大小(記爲變量X),例如int型佔4字節;

編譯器設置的內存對齊大小,默認的,或是你通過上述指令設置的大小(記爲變量Y),取兩者中的較小值,得到數據Z。根據內存對齊原 則,該成員變量的偏移值必須是Z的倍數。

2,假如結構體中佔內存最大的成員大小爲M,則結構體總大小必須是M的倍數。

 

綜上,用匯編要對結構體的內存模型很熟悉。

 

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