2017-07-16 21 views
6

Tôi có cấu trúc dữ liệu cần được căn chỉnh 4 KiB. Tôi có thể thực thi điều này bằng cách sử dụng __attribute__ ((aligned (4096))).Sắp xếp thứ tự các đối tượng được sắp xếp để sử dụng không gian tối thiểu

Vấn đề là yêu cầu căn chỉnh này khiến bộ nhớ bị lãng phí. Đây là cách mối liên kết đặt những biểu tượng (pg_dir là cấu trúc dữ liệu liên kết):

00011000 <cursor_loc>: 
00012000 <pg_dir>: 
00013000 <idt>: 

cursor_loc chỉ là bốn byte trong kích thước. Đây sẽ là tốt hơn:

00011000 <pg_dir>: 
00012000 <cursor_loc>: 
00012008 <idt>: 

(idt phải 8-byte aligned ở đây.)


Bạn có thể tái tạo nó bằng cách sử dụng nhiều file như thế này:

test1.c:

char aligned[4096] __attribute__ ((aligned (4096))); 
int i; 

test2.c:

int j; 

int main(void) { } 

Sau đó xây dựng nó với

gcc test1.c test2.c 

objdump -D a.out in này:

0000000000602004 <j>: 
     ... 

0000000000603000 <aligned>: 
     ... 

0000000000604000 <i>: 

Làm thế nào tôi có thể di chuyển GNU ld để sắp xếp lại biểu tượng cho sự lãng phí không gian tối thiểu? Tôi thực sự tự hỏi tại sao nó không được thực hiện tự động.

Trả lời

2

Có một số thành ngữ yêu cầu đối tượng được sắp xếp theo thứ tự được chỉ định trên dòng lệnh (đó là lý do tại sao kết quả của bạn hơi lạ, có thể do biểu tượng chung) và định nghĩa đối tượng trong không sắp xếp lại. Để làm việc xung quanh đó, bạn cần một cái gì đó như thế này:

gcc -fno-common -fdata-sections -Wl,--sort-section=alignment test1.c test2.c 

-fno-common vô hiệu hóa những biểu tượng thông thường, cho phép -fdata-sections linker để sắp xếp lại các biểu tượng từ cùng một tập tin, và -Wl,--sort-section=alignment cuối cùng cho phép sắp xếp theo sự liên kết.

+0

Điều đó hoạt động gọn gàng, cảm ơn. Tôi tự hỏi tại sao các biểu tượng vẫn xuất hiện trong '.bss' khi tôi' objdump' chúng, mặc dù tôi sử dụng '-fno-common' và' -fdata-sections'. Tôi cần chúng ở trong mục '.ss' cho mục đích của tôi, chỉ là tôi không hiểu tại sao những công tắc đó không thay đổi phần mà chúng thuộc về. – Downvoter

+0

Vâng, tôi đã nhầm lẫn về '.bss'. Bạn chỉ có thể nhận được các ký hiệu zero-initialized ra khỏi '.bss' nếu bạn chỉ định một initializer, và nếu đó vẫn là số không, biên dịch' -fno-zero-initialized-in-bss' (để ức chế tối ưu '.ss') . Rất vui khi bạn cần ký hiệu '.bss'. –

+0

Sẽ không '-Wl, - phân loại phổ biến' cũng hoạt động? – Hasturkun

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