int 0x80是一个系统调用,它在hexa中也是128.为什么内核使用int 0x80作为中断,当我声明int x时,他知道它只是一个名为x的整数,反之亦然?
您似乎对C语言和汇编语言之间的区别感到困惑.两者都是编程语言,(现在)都接受0xNNNN以十六进制编写数字的符号,并且通常有一些方法可以在C程序中嵌入汇编语言的小片段,但它们是不同的语言.关键字int在C中意味着与(x86)汇编语言完全不同.
对于C编译器,int 始终并且仅表示声明涉及整数的内容,并且不存在可以立即跟随int数字文字的情况.int 0x80(或者int 128,或者int 23,或者其他任何类型的东西)总是C中的语法错误.
要在x86汇编,int 一直和唯一的手段,产生的中断指令的机器代码,和一个数字文字必须立即执行. int x;在x86汇编语言中始终是语法错误.
明显的后续问题:如果C编译器不能识别int为INTerrupt指令,那么C程序(为x86编译)如何进行系统调用?这个问题有四个补充答案:
大多数情况下,在C程序中,您不直接进行系统调用.相反,您可以调用C库中为您执行此操作的函数.处理程序时,就C编译器而言,open(例如)与任何其他外部函数没有什么不同.所以它不需要生成int指令.它就是这样call open.
但是C库只是其他人为你写的C,不是吗?然而,如果您反汇编的实现open,您确实会看到一条int指令(或者可能syscall或者sysenter相反).编写C库的人是怎么做到的? 他们用汇编语言编写了这个函数,而不是用C. 或者他们使用这种技术在C程序中嵌入汇编语言的片段,这使我们...
这有什么用?难道这不是意味着C编译器也需要了解int作为一个组件有时记忆?不必要.让我们看一下插入程序集的GCC语法 - 这可能是openx86/32/Linux的一个实现:
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);
}
Run Code Online (Sandbox Code Playgroud)
你不需要理解其中的大部分内容:对于这个问题而言,重要的是,是的,它说int 0x80,但它在字符串文字中表示.编译器会将该字符串文字的内容(逐字)复制到生成的汇编语言文件中,然后将其提供给汇编器.它不需要知道它意味着什么.这是汇编程序的工作.
更一般地说,有许多单词在C中表示一件事,在汇编语言中表示完全不同的东西.AC编译器生成汇编语言,因此它必须"知道"这两个词的含义,对吧?它确实如此,但它并不会混淆它们,因为它们总是在不同的环境中使用."add"是C编译器知道如何使用的汇编助记符,并不意味着在C程序中命名变量"add"存在任何问题,即使在该程序中使用了"add"指令也是如此.