2009-08-11 53 views
8

Tôi đã gặp phải một vấn đề nhỏ khi học. Tôi biết rằng các biến toàn cục chưa được khởi tạo trong C được gán cho phần .bss trong tệp ELF thực thi. Nhưng điều gì sẽ xảy ra với họ khi tôi bắt đầu sử dụng chúng? I.e. họ có được một nơi trên đống hay ở đâu đó khác không?Biến toàn cục chưa được khởi tạo ở đâu sau khi khởi tạo?

tôi đã cố gắng để tìm hiểu bằng cách in địa chỉ của (vẫn chưa được khởi tạo) biến toàn cầu với

printf("%x",&glbl); 

mà luôn luôn trả lại 0x80495bc giá trị như nhau ... Tại sao?

+1

Tôi nhận thấy rằng bạn đã chấp nhận câu trả lời 5 phút sau khi đặt câu hỏi. Bạn sẽ nhận được nhiều câu trả lời hơn nếu bạn để câu trả lời mở trong một thời gian vì mọi người sẽ có động lực hơn để cải thiện câu trả lời. – Adriaan

+0

Cảm ơn gợi ý, tôi chắc chắn sẽ làm như vậy lần sau. – Patrick

Trả lời

8

Khi hệ điều hành tải chương trình của bạn, nó phân bổ đủ dung lượng lưu trữ từ không gian địa chỉ của chương trình của bạn để lưu trữ mọi thứ trong phần .bss và số không tất cả bộ nhớ đó. Khi bạn gán hoặc đọc từ hoặc lấy địa chỉ của biến, bạn đang thao tác với bộ nhớ đã được cấp phát để cung cấp bộ nhớ cho phần .bss.

+0

Ah và điều này cũng giải thích tại sao giá trị chứa bởi biến toàn cục chưa được khởi tạo luôn bằng không. Cảm ơn! – Patrick

+0

Một số trình biên dịch/kiến ​​trúc hỗ trợ phần SBSS cho dữ liệu nhỏ. Điều này thường được thực hiện như một tối ưu hóa để dữ liệu có thể được tìm nạp bằng cách lập chỉ mục từ đầu phần SBSS. Điều này thường có thể được thực hiện bằng cách sử dụng thanh ghi gp và lập chỉ mục 16 bit – zebrabox

2

Biến chung luôn nhận được bộ nhớ tĩnh, nếu chúng chưa được khởi tạo thì chúng không có khoảng trống trong tệp nhị phân, nhưng chúng sẽ lấy nó trong bộ nhớ khi tệp nhị phân được nạp vào không gian bộ nhớ.

1

BSS là trình giữ chỗ được xác định trong định dạng có thể thực thi (hoặc ELF) của bạn. Vì vậy, nó không chiếm dung lượng đĩa, nhưng chỉ xác định vùng bộ nhớ nào nên được cấp phát bởi trình liên kết hoặc trình tải.

Thao tác chính xác tùy thuộc vào hệ điều hành. Vì bạn tham khảo ELF, tôi cho rằng nó được sử dụng trong một hệ thống nhúng. Nếu bạn xây dựng cho mã ROMmable, tập tin cmd linker của bạn sẽ ánh xạ BSS vào một vùng địa chỉ tĩnh. Trong trường hợp bạn xây dựng cho một hệ điều hành (nghĩa là Linux), trình tải từ hệ điều hành sẽ thực hiện chuyển vị trí, trong đó nó ánh xạ tất cả các vị trí được đánh dấu là tương đối ở định dạng có thể thực thi đến vị trí vật lý hoặc logic trong bộ nhớ.

Vì bạn đề cập luôn thấy cùng một giá trị, điều này cho biết rằng quá trình này có thể lặp lại cho hệ thống của bạn. Mong đợi để xem thay đổi khi bạn thay đổi tệp liên kết (tức là vùng địa chỉ), thứ tự liên kết (tức là mô-đun sẽ nhận được không gian được chỉ định theo thứ tự khác) hoặc hệ điều hành.

Nếu bạn không sử dụng các giá trị BSS, địa chỉ sẽ vẫn giữ nguyên cho quá trình bạn chạy.

1

Phần BSS đó được cấp một khối bộ nhớ trong vùng địa chỉ tiến trình giống như mã và các phần ngăn xếp (và bất kỳ ELF nào khác có thể có). Khi ở đó, họ không truy cập ở mọi nơi. Bộ nạp sắp xếp mọi thứ rồi gọi đến điểm vào của quá trình.

Các vấn đề liên quan