2012-03-07 24 views
6

Tôi vừa mới đọc về mode_t rằng nó về cơ bản lưu trữ các thông tin sau:Tại sao chế độ sử dụng 4 byte?

  • 7 giá trị boolean cho các loại tập tin (S_IFREG, S_IFDIR, S_IFCHR, S_ISBLK, S_ISFIFO, S_ISLINK, S_ISSOCK)
  • 3 * 3 = 9 giá trị boolean cho các giấy phép truy cập (đọc, viết và thực hiện cho chủ sở hữu, nhóm và những người khác)

Vì vậy, nó cần 16 bit = 2 byte. Tôi đoán bạn thậm chí có thể có một chút ít hơn cho các loại tập tin, vì nó phải là một tập tin thường xuyên, một thư mục, một nhân vật hoặc thiết bị khối, một ổ cắm, một liên kết tượng trưng, ​​hoặc một đường ống. Hoặc các loại tệp khác tồn tại?

Vì vậy, tôi đã kiểm tra chỉ kích thước của mode_t với

printf("Size: %d byte\n", sizeof(mode_t)); 

Nó sử dụng 4 byte. Tại sao nó sử dụng 4 byte? Có thông tin bổ sung nào mà tôi không chú ý không?

chỉnh sửa: Tôi vừa mới phát hiện ra rằng mode_t được định nghĩa trong ptypes.inc:

type mode_t = cuint32; 

cuint32 là 32 bit có kích thước, số nguyên unsigned và quy định tại ctypes.inc:

type cuint32 = LongWord; 

Có lẽ điều này sẽ giúp cho câu trả lời.

+1

nếu cần thêm tùy chọn/cờ vv trong tương lai thì sao? – Nim

+0

Nó có thể là nó chỉ đơn giản là typedef'ed từ một 'int', đó là 32 bit trong hầu hết các kiến ​​trúc. Hoặc nó được làm lớn hơn để nó có thể phù hợp với cờ trong tương lai. –

+0

** ** của bạn ** loại _may_ được 4 byte ngay cả khi bạn lưu trữ trong nó số "255" ... "khối xây dựng" là kiến ​​trúc bộ vi xử lý và hơn thế nữa bạn có một số không gian trống cho bất kỳ cờ nào khác nhu cầu. OMG Tôi ghét bitflags !!! –

Trả lời

9

Hãy nhìn vào những gì một "câm" trình biên dịch sẽ làm gì khi đưa đoạn mã sau:

#include <stdio.h> 
#include <stdint.h> 

int main(int argc, char **argv) { 
    uint16_t test1 = 0x1122; 
    uint32_t test2 = 0x11223344; 
    if (test1 & 0x0100) 
    printf("yay1.\n"); 
    if (test2 & 0x00010000) 
    printf("yay2.\n"); 
} 

Điều này có vẻ giống như một trường hợp sử dụng khả năng cho các giá trị của loại mode_t, kiểm tra nếu một lá cờ được thiết lập. Bây giờ chúng ta biên dịch nó với gcc -O0 và kiểm tra lắp ráp tạo:

0000000000000000 <main>: 
      ... 
    f: 66 c7 45 fe 22 11  movw $0x1122,-0x2(%rbp) 
    15: c7 45 f8 44 33 22 11 movl $0x11223344,-0x8(%rbp) 
    1c: 0f b7 45 fe    movzwl -0x2(%rbp),%eax ; load test1 into %eax 
    20: 25 00 01 00 00   and $0x100,%eax 
    25: 85 c0     test %eax,%eax 
      ... 
    33: 8b 45 f8    mov -0x8(%rbp),%eax ; load test2 into %eax 
    36: 25 00 00 01 00   and $0x10000,%eax 
    3b: 85 c0     test %eax,%eax 
      ... 

Xem cách hướng dẫn đặc biệt movzwl là cần thiết để tải các giá trị 16-bit? Điều này là bởi vì nó cần phải được mở rộng ký hiệu thành hai byte bổ sung để vừa với thanh ghi. Rõ ràng hướng dẫn này phức tạp hơn một đơn giản mov. Điều này có thể có một tác động nhỏ đến hiệu suất, và nó có thể làm tăng kích thước thực thi bởi một số byte, mà bản thân nó sẽ không quá xấu. Tuy nhiên, nếu chúng tôi cho rằng sẽ không có lợi thế khi sử dụng giá trị 16 bit, vì nó thường chiếm 32 bit dung lượng lưu trữ do căn chỉnh, rõ ràng là tại sao các nhà thiết kế chọn sử dụng kích thước từ gốc của CPU ở đây.

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