内核如何知道" int 0x80"和" int x"

时间:2016-04-06 17:57:46

标签: linux-kernel system-calls

int 0x80是系统调用,它在hexa中也是128。 为什么内核使用int 0x80作为中断,当我声明int x时,他知道它只是一个名为x的整数,反之亦然?

1 个答案:

答案 0 :(得分:7)

您似乎对C语言和汇编语言之间的区别感到困惑。两者都是编程语言,(现在)都接受以{十六进制编写数字的0xNNNN符号,并且通常有一些方法可以在C程序中嵌入汇编语言的小片段,但它们是不同的语言。关键字int表示C语言与(x86)汇编语言完全不同。

对于C编译器,int 始终意味着声明涉及整数的内容,并且不存在可以立即跟随{{ 1}}带有数字文字。 int(或int 0x80,或int 128或其他类似内容)始终是C中的语法错误。

对于x86汇编程序,int 23 始终表示为INTerrupt指令生成机器代码,并且单个数字文字必须< / em>立即关注。 int始终是x86汇编语言中的语法错误。

明显的后续问题:如果C编译器没有将int x;识别为INTerrupt指令,那么C程序(为x86编译)如何进行系统调用?这个问题有四个补充答案:

  1. 大多数情况下,在C程序中,您不直接进行系统调用。相反,您可以调用C库中为您执行此操作的函数。在处理程序时,就C编译器而言,int(例如)与任何其他外部函数没有什么不同。因此,它不需要来生成open指令。它只是int

  2. 但是C库只是别人为你写的C,不是吗?但是,如果您反汇编call open的实现,您确实会看到open指令(或者可能是intsyscall)。编写C库的人是怎么做到的? 他们用汇编语言编写了这个函数,而不是用C语言编写。或者他们使用这种技术在C程序中嵌入汇编语言的片段,这将我们带到......

  3. 如何运作?这是否意味着C编译器 有时需要将sysenter理解为汇编助记符?不必要。让我们看看用于插入汇编的GCC语法 - 这可能是x86 / 32 / Linux的int的实现:

    open

    你不需要了解其中的大部分内容:对于这个问题而言,重要的是,它是int open(const char *path, int flags, mode_t mode) { int ret; asm ("int 0x80" : "=a" (ret) : "0" (SYS_open), "d" (path), "c" (flags), "D" (mode)); if (ret >= 0) return ret; return __set_errno(ret); } ,但它在字符串文字中表示 。编译器会将该字符串文字的内容(逐字)复制到生成的汇编语言文件中,然后将其提供给汇编器。它不需要知道它意味着什么。这是汇编程序的工作。

  4. 更一般地说,C中有很多单词意味着什么,汇编语言中有很多不同的东西。 C编译器生成汇编语言,因此必须知道&#34;知道&#34;这两个词的意思,对吧?它确实如此,但它并不会混淆它们,因为它们总是在不同的环境中使用。 &#34;添加&#34;作为C编译器知道如何使用的汇编助记符,并不意味着命名变量存在任何问题&#34;添加&#34;在C程序中,即使&#34;添加&#34;指令在该程序中使用。