int 0x80是系统调用,它在hexa中也是128。 为什么内核使用int 0x80作为中断,当我声明int x时,他知道它只是一个名为x的整数,反之亦然?
答案 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编译)如何进行系统调用?这个问题有四个补充答案:
大多数情况下,在C程序中,您不直接进行系统调用。相反,您可以调用C库中为您执行此操作的函数。在处理程序时,就C编译器而言,int
(例如)与任何其他外部函数没有什么不同。因此,它不需要来生成open
指令。它只是int
。
但是C库只是别人为你写的C,不是吗?但是,如果您反汇编call open
的实现,您确实会看到open
指令(或者可能是int
或syscall
)。编写C库的人是怎么做到的? 他们用汇编语言编写了这个函数,而不是用C语言编写。或者他们使用这种技术在C程序中嵌入汇编语言的片段,这将我们带到......
的如何运作?这是否意味着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);
}
,但它在字符串文字中表示 。编译器会将该字符串文字的内容(逐字)复制到生成的汇编语言文件中,然后将其提供给汇编器。它不需要知道它意味着什么。这是汇编程序的工作。
更一般地说,C中有很多单词意味着什么,汇编语言中有很多不同的东西。 C编译器生成汇编语言,因此必须知道&#34;知道&#34;这两个词的意思,对吧?它确实如此,但它并不会混淆它们,因为它们总是在不同的环境中使用。 &#34;添加&#34;作为C编译器知道如何使用的汇编助记符,并不意味着命名变量存在任何问题&#34;添加&#34;在C程序中,即使&#34;添加&#34;指令在该程序中使用。