üye muhtemelen dolgu maddesiyle bellekte ardışık yerleştirilir :) bana yeter ve yapının adresi tipik adresidir İlk üyelerinden
struct Bar {
int x;
int y;
};
struct Foo {
struct Bar b;
double d;
int i;
};
struct Foo f;
en
&f
0x10
olduğunu varsayalım. Sonra,
&f.b.x
(
Foo
'un ilk üyesinin ilk üyesi) ayrıca
0x10
'dur.
&f.b.y
,
f.b.x
, 4 bayt olduğundan (32 bitlik bir makine varsayılarak)
0x14
şeklindedir.
&f.d
,
0x18
ve
&f.i
,
0x20
'dur.
f
(diğer bir deyişle
&f + 1
) tarafından işgal edilmeyen ilk adres
0x24
'dur.
Montajda yapmanız gereken tek şey, yapının üyeleri için (yığın veya yığın) alanınızın olduğundan emin olmak ve alanı uygun verilerle doldurmak ve ilk üyenin adresini işlevi.
Gerçekten de montaj gerektiren bir örnek olarak, küçük bir test programı yazıp, C kodunuz için montaj kodu üretecek olan gcc -S -O0 -g
ile derleyebilirsiniz. Eğer, diğer şeyler arasında, göreceksiniz
montaj çıktısında
int func(struct Foo * foo) {
return foo->b.x + foo->i;
}
int main() {
struct Foo foo;
foo.b.x = 42;
foo.b.y = 9;
foo.d = 3.14;
foo.i = 8;
func(&foo);
return 0;
}
, Örneğin: (not: bu 64 bit ASM'dir):
movl $42, -32(%rbp)
movl $9, -28(%rbp)
movabsq $4614253070214989087, %rax
movq %rax, -24(%rbp)
movl $8, -16(%rbp)
Gördüğünüz gibi, değerler 42, 9, (bit paterni 3.14 olan tamsayı) ve 8 -32, -28, -24 ve -16 adreslerine (taban işaretçisine göre) yüklendi. Ben sadece bir Solaris kutusu kullanıyorum, bu yüzden asmlinkage
(işlev argümanlarının yazmaçlardan ziyade yığında geçirilmesi gerektiğini belirtir) kullanamadım, böylece işlev çağrısından hemen önce, yapının etkin adresini görürüz bir kayıt içine yüklenen:
leaq -32(%rbp), %rax
movq %rax, %rdi
asmlinkage
ile, onun yerine bu etkili adres yığını üzerine itilen görürdük.
Eldhuset, bir dünya örneği mevcut mudur? –
Bence C99, bir yapının adresinin ilk üyesinin adresi olduğunu garanti eder. –
@tc .: Makul sesler; "Tipik" yazdım çünkü bu durumun% 100 olduğundan emin değildim - ancak bir yapının başlangıcında dolgu eklemek istediğim için hiçbir neden göremiyorum. –