Bộ nhớ được phân bổ tại thời gian biên dịch có nghĩa là trình biên dịch giải quyết tại thời gian biên dịch trong đó một số thứ nhất định sẽ được phân bổ bên trong bản đồ bộ nhớ quy trình.
Ví dụ, hãy xem xét một mảng toàn cầu:
int array[100];
Trình biên dịch biết tại thời gian biên dịch kích thước của mảng và kích thước của một int
, vì vậy nó biết toàn bộ kích thước của mảng tại thời gian biên dịch. Ngoài ra, một biến toàn cục có thời lượng lưu trữ tĩnh theo mặc định: nó được phân bổ trong vùng bộ nhớ tĩnh của không gian bộ nhớ quá trình (phần .data / .bss). Với thông tin đó, trình biên dịch quyết định trong quá trình biên dịch trong địa chỉ của vùng bộ nhớ tĩnh mà mảng sẽ có .
Tất nhiên địa chỉ bộ nhớ là địa chỉ ảo. Chương trình giả định rằng nó có toàn bộ không gian bộ nhớ (ví dụ: từ 0x00000000 đến 0xFFFFFFFF). Đó là lý do tại sao trình biên dịch có thể thực hiện các giả định như "Được rồi, mảng sẽ ở địa chỉ 0x00A33211". Trong thời gian chạy, địa chỉ đó được dịch sang địa chỉ thực / phần cứng bởi MMU và HĐH.
Giá trị khởi tạo lưu trữ tĩnh mọi thứ là một chút khác nhau. Ví dụ:
int array[] = { 1 , 2 , 3 , 4 };
Trong ví dụ đầu tiên của chúng tôi, trình biên dịch chỉ quyết định nơi mảng sẽ được phân bổ, lưu trữ thông tin đó trong tệp thực thi.
Trong trường hợp các thứ được khởi tạo giá trị, trình biên dịch cũng đưa giá trị ban đầu của mảng vào tệp thực thi và thêm mã thông báo cho trình tải chương trình rằng sau khi cấp phát mảng khi bắt đầu chương trình, mảng phải được điền với các giá trị này.
Dưới đây là hai ví dụ về lắp ráp được tạo bởi trình biên dịch (GCC4.8.1 với mục tiêu x86):
Mã C ++:
int a[4];
int b[] = { 1 , 2 , 3 , 4 };
int main()
{}
Lắp ráp đầu ra:
a:
.zero 16
b:
.long 1
.long 2
.long 3
.long 4
main:
pushq %rbp
movq %rsp, %rbp
movl $0, %eax
popq %rbp
ret
Như bạn có thể thấy, các giá trị được đưa trực tiếp vào tổ hợp. Trong mảng a
, trình biên dịch tạo ra khởi tạo 0 byte 16 byte, bởi vì Standard nói rằng những thứ được lưu trữ tĩnh nên được khởi tạo về 0 theo mặc định:
8.5.9 (Bộ khởi tạo) [Lưu ý]:
Mọi đối tượng có thời lượng lưu trữ tĩnh đều được khởi tạo bằng 0 khi khởi động chương trình trước khi bất kỳ khởi tạo nào khác diễn ra. Trong một số trường hợp, khởi tạo bổ sung được thực hiện sau.
Tôi luôn đề nghị mọi người tháo gỡ mã của họ để xem trình biên dịch thực sự làm gì với mã C ++. Điều này áp dụng từ các lớp lưu trữ / thời lượng (như câu hỏi này) cho đến tối ưu hóa trình biên dịch nâng cao. Bạn có thể hướng dẫn trình biên dịch của mình tạo ra lắp ráp, nhưng có những công cụ tuyệt vời để thực hiện việc này trên Internet một cách thân thiện. Yêu thích của tôi là GCC Explorer .