为什么在系统调用位上左移?

时间:2018-07-25 21:39:35

标签: c kernel minix

kernel/ipc.h中,Tanenbaum将系统调用位定义为:

/* System call numbers that are passed when trapping to the kernel. The 
 * numbers are carefully defined so that it can easily be seen (based on 
 * the bits that are on) which checks should be done in sys_call().
 */
#define SEND           1    /* 0 0 0 1 : blocking send */
#define RECEIVE        2    /* 0 0 1 0 : blocking receive */
#define SENDREC        3    /* 0 0 1 1 : SEND + RECEIVE */
#define NOTIFY         4    /* 0 1 0 0 : nonblocking notify */
#define ECHO           8    /* 1 0 0 0 : echo a message */

但随后在kernel/table.c中,系统调用位定义为:

/* Define system call traps for the various process types. These call masks
 * determine what system call traps a process is allowed to make.
 */
#define TSK_T   (1 << RECEIVE)                   /* clock and system */
#define SRV_T   (~0)                             /* system services */
#define USR_T   ((1 << SENDREC) | (1 << ECHO))   /* user processes */

为什么所有内容都向左移? 1 << RECEIVE会是 0100 而不是 0010 。这不是说时钟和系统任务可以通知但不能接收吗?

1 个答案:

答案 0 :(得分:2)

您在kernel/table.c中显示的代码中形成的值不是系统调用的代码号的值。它们是系统调用的位掩码。

位掩码通常用于实现集合。假设我们有三个对象,例如一个苹果,一个香蕉和一个樱桃,并且我们希望记录某些集合X是否包含一个苹果,不包含一个香蕉,是否包含一个香蕉。樱桃。

我们可以通过将位置0(值1)的位表示一个苹果,位置1(值2)的位表示一个香蕉,将位置2(值4)的位表示一个苹果来做到这一点。樱桃。然后,任何集合X是否包含这些项目都可以用一个数字来表示,该数字是否设置了相应的位。例如,数字5在位置0和2处有位,因此它表示一个包含苹果和樱桃但不包含香蕉的集。

kernel/table.c中的代码在位掩码中分配位,以便代码 i 的系统调用由位置 i 处的位表示。因此,代码为 i 的系统调用的位掩码中的位的值为1 << i

这是一张表格,显示呼叫代码的值及其位掩码的值:

    Call Name    Code Number    Bit Mask
    SEND         1              2
    RECEIVE      2              4
    SENDREC      3              8
    NOTIFY       4              16
    ECHO         8              256

使用这些方法的方式是,为了表示包含多个调用的集合,请将这些调用的位掩码值相加在一起(或等效地与按位或运算结合)。因此,包含SENDRECEIVESENDREC的集合由2 + 4 + 8 = 14表示。

因此1 << SENDREC是掩码中代表SENDREC的位的值,而1 << ECHO是掩码中代表ECHO的位的值。这些值1 << SENDREC | 1 << ECHO的OR是一个位掩码,包含SENDRECECHO,但不包含SEND或其他代码。

对位掩码的一些操作是:

  • 如果i是一项的编号,则1<<i是表示集合中该项的位的值。
  • 要将一项i添加到集合X中,或使用X |= 1<<i将位添加到集合中。
  • 采用XY这两个集合的并集,或与X | Y进行或。
  • 要获取两组XY的交集,并将它们与X & Y相加。