linux 系统调用

先写几行可执行的代码直观感受一下系统调用

.data
    s:
        .ascii "hello world\n"
        len = . - s
.text
    .global _start
    _start:

        movl $4, %eax   /* write system call number */
        movl $1, %ebx   /* stdout */
        movl $s, %ecx   /* the data to print */
        movl $len, %edx /* length of the buffer */
        int $0x80

        movl $1, %eax   /* exit system call number */
        movl $0, %ebx   /* exit status */
        int $0x80

编译并运行

as -o main.o main.S
ld -o main.out main.o
./main.out

整体逻辑很简单,设置必要的寄存器,触发0x80中断,调用系统功能终端输出。可见,系统调用需要操作系统的中断功能配合完成。操作系统维护一个中断向量表,用来管理各种中断处理逻辑,比如各个硬件外设的中断。而这里的0x80中断是专门处理系统调用的。

除了 0x80中断 触发系统调用,还可以通过 syscall 触发系统调用,当前 x86-64 系统默认使用这种方式。在 32 bit 系统下常用的是 sysenter。下面示例是通过 syscall 触发系统调用:

.data
hello_world:
    .ascii "hello world\n"
    hello_world_len = . - hello_world
.text
.global _start
_start:
    /* write */
    mov $1, %rax
    mov $1, %rdi
    mov $hello_world, %rsi
    mov $hello_world_len, %rdx
    syscall

    /* exit */
    mov $60, %rax
    mov $0, %rdi
    syscall

汇编运行:

as -o hello_world.o hello_world.S
ld -o hello_world.out hello_world.o
./hello_world.out

reference 这里

什么是系统调用

应用程序中使用入诸如 folk, open, read, write 这类函数时其实就是在系统调用了。

应用程序通过系统调用进入内核完成一些任务,比如创建进程,网络io,活着磁盘读写。

不通的cpu架构下,应用程序通过不同的方法和底层指令来触发系统调用,作为一个应用程序程序开发者,可以不用关系系统调用具体是如何触发的,只需要像调用普通函数一样调用glibc提供的封装库就行了。

先了解几个概念

  • CPU privilege levels
    用户进程如果想进行io操作,只能通过系统调用让内核完成。那么用户进程就不能么,当然不能,这是死规定。那么如何阻止用户进程执行此类操作呢。

cpu 权限等级 就是用来规范用户进程的操作的。

cpu 权限等级 需要长篇大论,这里简言之:

  1. 权限等级 是一种控制手段,规定一个等级中有那些cpu指令和io操作可以执行。
  2. 内核运行在 ring 0,权限最大。用户进程运行在 ring 3

用户进程如果想进行特权操作,那就需要切换cpu 权限等级以便内核运行。

reference

发布了232 篇原创文章 · 获赞 96 · 访问量 44万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览