对于int $0x80引发的问题

时间:2021-01-29 13:47:25
------------------------------------------------------软中断--------------------------------------------------------------------------------------在Linux 的汇编语言中(AT&T,x86汇编两种语法的一种),int 指令被称为软中断指令 ,可以用此指令去故意产生一个异常 ,(异常与中断有点类似, 过程相当于CPU从用户模式切换到特权模式, 然后跳转到内核代码中执行异常处理的代码。)
在int 指令中的立即数 0x80 是一个参数 ,可以用于执行系统调用。int3则主要用于设置断点(对程序进行调试) 
------------------------------------------------------软中断实现过程-----------------------------------------------------------------------------
原因:通过限定应用程序和内核程序使用不同的内存分配函数,将用户空间程序限制在0-3G空间,将内核程序限制在3G~4G空间,这样就实现了用户空间和内核空间的隔离;
交互方式:通过 软中断(int $0x80 )实现用户空间与内核空间的交互。
 系统调用是一个软中断,中断号是0x80,它是上层应用程序与Linux系统内核进行交互通信的唯一接口。通过int 0x80,就可使用内核资源。不过,通常应用程序都是使用具有标准接口定义的C函数库间接的使用内核的系统调用,即应用程序调用C函数库中的函数,C函数 库中再通过int 0x80进行系统调用。
  所以,系统调用过程是这样的:
    应用程序调用libc中的函数->libc中的函数引用系统调用宏->系统调用宏中使用int 0x80完成系统调用并返回


----------------------------------------------------最基本代码实现-----------------------------------------------------------------------------在linux中 , int $0x80 这种异常被称作系统调用(systerm call) ,内核中也提供了许多系统服务供用户程序使用 ,但这些系统服务不能像库函数一样用的为所欲为, 原因在于 :执行用户程序的时候CPU处于用户模式 ,经由异常处理的 程序进入到内核 ,用户只能通过寄存器传递几个参数 ,之后就要按照内核设计好的代码路线走 ,调用结束后 ,CPU在切回到用户模式, 继续执行下一条 int $0x80 的下一条指令 。这个方式该不了 (除非你改系统代码)。。。这也是保证系统服务的安全。
基本的“hello world”##Simple program that exits and returns a status code back to the Linux kernel#./section .data 
./section .text.globl _start _start :movl $1 ,%eax movl $4 ,%ebx int $0x80
1.保存为hello.s 2.$as hello.s -o hello.o(编译为机器代码)3.ld hello.o -o hello(链接器链接为可执行文件 )
代码解析:----------------------------------------------------------------------------------------------------------------------------------------------------------------
  1. .section .data :以.为开头的名称不是指令的助记符 ,不会被翻译为机器指令,而是作为一种汇编提示告知汇编器 ,这个形式直接被称为 “汇编指令” 或 ”伪操作“
  2. .section .text : .text 段位保存代码, 是只读和可执行的。后面的指令都是属于 .text 段。 
  3. _start 是一个符号, 符号在汇编中表示一个地址 ,可以再指令中 ,汇编程序经过汇编器的处理后, 所有的符号都被替换成为它所代表的地址值 。(通俗说,c语言中的函数变量名都属于符号)
  4. .global 告诉编译器, _start 这个符号就像c程序中的main函数一样 ,是整个程序的入口 。故这个在程序中必须有。
  5. movl $1 ,%eax :这个是一条数据传送指令 ,这指令要求CPU内部产生一个数字1并保存到eax寄存器中 ,mov后缀l表示long形 ,说明为32位。(1表示在CPU内部产生 ,称为立即数,立即数在前面要加个$ ,寄存器就加个% 
  6. eax 和ebx 是传递给系统调用的两个参数 ,eax 是系统调用号。 Linux 各种系统调用都是有int $0x80 指令引发的,内核需要通过eax 判断用户需要哪个系统调用。 
  7. _ebx 的值是传给 _exit 的参数,表示退出状态。_exit 的系统调用号为1 。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
参考资料:《Linux C一站式编程》http://blog.csdn.net/sqhxhg/article/details/6626593http://blog.sina.com.cn/s/blog_821c73630100vhek.html