转自: http://it.zhans.org/04/446.htm
之所以会写篇博文说下int 80h中断, 是因为它是linux类操作系统内核在Intel类CPU架构上作为系统调用使用的中断号, 所谓系统调用是内核提供的一系列有特权功能的函数集合,为什么要有syscall是本着安全的角度来看的或者效率等等, OS把整个空间分为用户空间和内核空间,顾名思义,内核空间的特权比用户空间多, 比如系统调用就需要在内核空间运行, 可以看出系统调用只是OS提供给用户空间的一些接口,不允许用户随意进入内核区.
系统调用的时候, 是利用的软中断实现的, 就是int 0x80h指令, 当用户空间需要调系统函数的时候,用户空间只有通过系统门陷入内核执行int 0x80h指令才能执行具有一些特权级的内核函数, OS再执行另外一组特权指令(iret)返回到用户空间(其中int 0x80h指令会产生一个编号为128(16进制就为0x80)的异常,这个编号索引的IDT(中断描述符)中的第128项, 指向的是系统门描述符,里面包含了一个内核空间地址sys_call.如图:
那如何调用相应的系统调用呢? 比如想调用sys_write, 很简单, OS系统调用会相应的进行编号从0开始, 比如下面列的一些:
#define __NR_setup 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
#define __NR_open 5
#define __NR_close 6
#define __NR_waitpid 7
#define __NR_creat 8
#define __NR_link 9
当然不止上面这么多, 这些编号会保存在内核的一张系统调用表,还有编号对应的系统调用处理程序, 通过上面描述需要把系统调用编号传入给到内核(mov到eax即可),可通过下面的命令进行
mov eax, 4
这里4就代表sys_write系统调用.
我们通过程序来看下系统调用的过程:
[section .data]
strHello db "Hello CB!"
strLen equ $-strHello
[section .text]
global _start
_start:
mov edx, strLen
mov ecx, strHello
mov ebx, 0
mov eax, 4 ;sys_write
int 0x80
mov ebx, 1
mov eax, 1 ;sys_ext
int 0x80
这个程序进行了两个系统调用, 调用号分别为4(sys_write)和1(sys_exit).
可通过下面的Makefile进行汇编连接.
All:
nasm -f elf -o a.o 1.asm
ld -o a.out a.o
效果很简单,就打印个字符串.