为什么mode_t使用4个字节? [英] Why does mode_t use 4 byte?

查看:274
本文介绍了为什么mode_t使用4个字节?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




  • 7个文件类型的布尔值(S_IFREG, S_IFDIR,S_IFCHR,S_ISBLK,S_ISFIFO,S_ISLINK,S_ISSOCK)
  • 3 * 3 = 9访问权限的布尔值(读,写,执行所有者,组和其他)
  • >


所以它需要16位= 2个字节。我想你甚至可以少一点文件类型,因为它必须是普通文件,目录,字符或块设备,套接字,符号链接或管道。还是其他的文件类型存在?



所以我刚刚检查了mode_t的大小与

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

它使用4个字节。为什么使用4个字节?是否有任何额外的信息我没有注意到?



编辑:
我刚刚发现mode_t是在ptypes.inc中定义的:

  type mode_t = cuint32; 



cuint32是一个32位大小的无符号整数,在ctypes.inc中定义:

  type cuint32 = LongWord; 

也许这有助于解答。

解决方案

让我们来看看给定以下代码时哑编译器会做什么:

  #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.\\\
);
if(test2& 0x00010000)
printf(yay2.\\\
);



$ b $ p
$ b

类似于 mode_t ,检查是否设置了标志。现在我们用 gcc -O0 编译它,并检查生成的程序集:

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

查看特殊的 movzwl 指令是如何加载16位值?这是因为它需要符号扩展到两个额外的字节以适应寄存器。显然,这个指令比简单的 mov 复杂。这可能会对性能产生很小的影响,并且可能会使可执行文件的大小增加一些字节,本身不会太糟糕。



但是,如果我们考虑在使用16位值的时候没有任何优势,因为它们通常会由于对齐而占用32位的存储空间,这就清楚了为什么设计者选择在这里使用CPU的本地字大小。


I've just read about mode_t that it basically stores the following information:

  • 7 boolean values for the file type (S_IFREG, S_IFDIR, S_IFCHR, S_ISBLK, S_ISFIFO, S_ISLINK, S_ISSOCK)
  • 3*3 = 9 boolean values for the access permissons (read, write and execute for owner, group and others)

So it needs 16 bit = 2 bytes. I guess you could even have one bit less for the file type, as it has to be either a regular file, a directory, a character or block device, a socket, a symbolic link, or a pipe. Or do other file types exist?

So I've just checked the size of mode_t with

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

It uses 4 byte. Why does it use 4 byte? Is there any additional information I didn't notice?

edit: I've just found that mode_t is defined in ptypes.inc:

type mode_t = cuint32;

cuint32 is a 32 bits sized, unsigned integer and defined in ctypes.inc:

type cuint32 = LongWord;

Perhaps this helps for the answer.

解决方案

Let's look at what a "dumb" compiler would do when given the following code:

#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");
}

This seems like a likely use case for values of type mode_t, checking if a flag is set. Now we compile it with gcc -O0 and check the generated assembly:

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
            ...

See how the special movzwl instruction is needed to load the 16-bit value? This is because it needs to be sign-extended to two additional bytes to fit in the register. Obviously this instruction is more complex than a simple mov. This might have a tiny impact on performance, and it might increase the executable size by some bytes, which by itself wouldn't be too bad.

However, if we consider that there would be no advantage in using a 16-bit value, because it would usually take up 32 bits of storage anyway due to alignment, it's clear why the designers choose to use the native word size of the CPU here.

这篇关于为什么mode_t使用4个字节?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆