Bạn đang đặt câu hỏi chi tiết thực hiện, vì vậy câu trả lời sẽ phụ thuộc vào việc thực hiện cụ thể. Hãy xem xét một phiên bản chương trình của bạn thực sự biên dịch:
class A { public int VarA; }
class X
{
static void Main(string[] args)
{
A a1 = new A();
a1.VarA = 5;
A a2 = a1;
a2.VarA = 10;
}
}
đây là những gì xảy ra trên CLR 4.0 của Microsoft, chạy C# 4.0, trong chế độ Gỡ lỗi.
Tại thời điểm này, con trỏ khung ngăn xếp đã được sao chép vào ebp đăng ký:
Ở đây chúng tôi cấp phát bộ nhớ heap cho đối tượng mới.
A a1 = new A();
mov ecx,382518h
call FFE6FD30
Điều đó trả về tham chiếu đến đối tượng đống trong eax. Chúng tôi lưu trữ các tham chiếu trong khe ngăn xếp ebp-48, đó là một khe tạm thời không liên kết với bất kỳ tên nào. Hãy nhớ rằng, a1 vẫn chưa được khởi tạo.
mov dword ptr [ebp-48h],eax
Bây giờ chúng ta tham khảo, chúng tôi chỉ được lưu trữ trên stack và sao chép nó vào ecx, mà sẽ được sử dụng cho việc "này" con trỏ đến các cuộc gọi đến ctor.
mov ecx,dword ptr [ebp-48h]
Bây giờ chúng tôi gọi cho người quản lý.
call FFE8A518
Bây giờ chúng tôi sao chép tham chiếu được lưu trữ trong ngăn xếp tạm thời vào đăng ký eax một lần nữa.
mov eax,dword ptr [ebp-48h]
Và bây giờ chúng tôi sao chép tham chiếu trong eax vào khe ngăn xếp ebp-40, là a1.
mov dword ptr [ebp-40h],eax
Bây giờ chúng ta phải lấy a1 vào eax:
a1.VarA = 5;
mov eax,dword ptr [ebp-40h]
Hãy nhớ rằng, eax bây giờ là địa chỉ của dữ liệu đống phân bổ cho điều được tham chiếu bởi a1. Các lĩnh vực Vara của điều đó là bốn byte vào đối tượng, vì vậy chúng tôi lưu trữ 5 thành rằng:
mov dword ptr [eax+4],5
Bây giờ chúng ta tạo một bản sao của tài liệu tham khảo trong khe ngăn xếp cho a1 vào eax, và sau đó sao chép đó vào khe ngăn xếp cho a2, là ebp-44.
A a2 = a1;
mov eax,dword ptr [ebp-40h]
mov dword ptr [ebp-44h],eax
Và bây giờ như bạn mong muốn một lần nữa chúng ta được a2 vào eax và sau đó tôn kính các tài liệu tham khảo bốn byte để viết 0x0A vào Vara:
a2.VarA = 10;
mov eax,dword ptr [ebp-44h]
mov dword ptr [eax+4],0Ah
Vì vậy, câu trả lời cho câu hỏi của bạn là tham chiếu đến đối tượng được lưu trữ trong ngăn xếp ở ba nơi: ebp-44, ebp-48 và ebp-40. Chúng được lưu trữ trong thanh ghi trong eax và ecx. Bộ nhớ của đối tượng, bao gồm cả trường của nó, được lưu trữ trên vùng quản lý. Đây là tất cả trên x86 trong xây dựng gỡ lỗi, của CLR v4.0 của Microsoft. Nếu bạn muốn biết làm thế nào công cụ được lưu trữ trên ngăn xếp, đống và đăng ký trong một số cấu hình khác, nó có thể hoàn toàn khác nhau. Tất cả các tài liệu tham khảo có thể được lưu trữ trên heap, hoặc tất cả trong sổ đăng ký; có thể không có ngăn xếp nào cả. Nó hoàn toàn phụ thuộc vào cách các tác giả của trình biên dịch jit quyết định triển khai ngữ nghĩa IL.
Vì mã này không biên dịch thực sự khó khăn của nó để mô tả cách thức xử lý thời gian chạy nó. Tất cả những câu nói đó có ý định nằm bên trong một thân phương pháp? Là những khai báo trường hoặc khai báo biến cục bộ? –