成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

深入理解Linux系統調用

系統 Linux
這樣當CPU執行syscall執行時就會跳轉到Linux內核中的write函數,同時在執行該函數時也能知道write函數所需要的參數是什么。?

?大家好,我是小風哥。

在前兩篇文章《為什么計算機需要操作系統?》《??系統調用與函數調用有什么區別??》中我們了解了什么是系統調用、為什么需要系統調用、系統調用與函數調用有什么區別,那么在今天的文章中我們從理論來到現實,看看Linux中的系統調用是怎樣實現的。

首先我們先來簡單復習下之前講解過的知識。

系統調用和普通的函數調用沒有本質區別,普通的函數調用一般調用的是我們自己編寫的函數或者其它庫函數,而系統調用調用的則是內核中的函數,更學術一點的說法是這樣的,所謂系統調用是指用戶態程序請求操作系統提供的服務。

一提到服務,大家最先想到的一定是服務器,假設客戶端是瀏覽器,瀏覽器發送http請求,服務器接收到請求后進行解析然后調用相應的hander,從本質上講就是客戶端觸發了服務器端的某個函數的運行,這時我們說客戶端請求了服務器端上的服務。

而系統調用與此類似,只不過用戶態程序并不是通過http觸發了操作系統中某個函數的運行,而是通過機器指令來觸發的,因為用戶態的App和操作系統運行在同一臺計算機系統上,而客戶端和服務器端運行在不同的計算機系統中(絕大部分情況下),因此客戶端只能通過網絡協議http來與服務器進行通信。

圖片

更通俗的說法就是所謂系統調用是指用戶態的某個函數調用內核中的某個函數。

接下來我們用一段簡單的hello world程序看下系統調用,這段程序需要運行在x86_64下:

.datamsg:    .ascii "Hello, world!\n"    len = . - msg.text    .global _start_start:    movq  $1, %rax    movq  $1, %rdi    movq  $msg, %rsi    movq  $len, %rdxsyscall    movq  $60, %rax    xorq  %rdi, %rdisyscall

使用以下命令編譯:

$ gcc -c test.S
$ ld -o test test.o

然后執行:

./test
Hello, world!

這段匯編代碼成功的打印出了hello world,這段代碼是什么意思呢?

注意看.data這一段,這里說的是程序定義了哪些數據,.text段是說程序中包含了哪些執行,我們之前提到進程的內存布局時總是說數據段以及代碼段,這里的數據段指的就是匯編中的.data段、代碼段指的就是匯編中的.text段,現在你應該明白了吧。

圖片

在.text段我們看到了一條略顯奇怪的指令,syscall,這條指令是什么意思呢?

我們來翻看一下intel的開發手冊:

SYSCALL invokes an OS system-call handler at privilege level 0. It does so by loading RIP from the IA32_LSTAR MSR (after saving the address of the instruction following SYSCALL into RCX). (The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.)

這段話告訴我們intel處理器在執行syscall指令時會在內核態調用操作系統的某個函數,即syscall-call handler,這個過程就是所謂的系統調用,我們知道CPU執行某個函數時必須知道某個函數在內存中的地址,那么CPU是怎么知道某個syscall-call handler的內存地址呢?

原來syscall-call handler所在的內存地址存儲在寄存器MSR中,那么又是誰將這個地址存儲在了寄存器MSR中呢?很顯然是操作系統,接下來以Linux為例來講解。

Linux內核初始化時將syscall-call handler也就是Linux內核中entry_SYSCALL_64函數的地址寫入寄存器MSR中:

wrmsrl(MSR_LSTAR, entry_SYSCALL_64);

其中syscall-call handler也就是entry_SYSCALL_64定義在了Linux源碼中的arch/x86/entry/entry_64.S,上述初始化寄存器MSR的代碼定義在了arch/x86/kernel/cpu/common.c。

現在我們知道了,當CPU執行syscall時會無腦跳轉到寄存器MSR中保存的函數地址,也就是entry_SYSCALL_64函數,那么很顯然的,所有系統調用的入口都是entry_SYSCALL_64函數,那么操作系統該怎么區分到底是調用的read系統調用還是write等系統調用?

原來,操作系統中給每種系統調用分配了一個序號,就像Linux中這樣:

0  common  read      sys_read
1 common write sys_write
2 common open sys_open
3 common close sys_close
4 common stat sys_newstat
5 common fstat sys_newfstat
6 common lstat sys_newlstat
7 common poll sys_poll
8 common lseek sys_lseek
9 common mmap sys_mmap
...

可以看到,0號系統調用表示的是內核中的read函數,1號系統調用表示的內核中的write函數,在進行系統調用時會將表示系統調用類別的序號寫入通用寄存器中。

從上面這個表格中可以看到write系統調用的序號是1,因此在hello world程序中我們將1寫入寄存器rax中:

movq  $1, %rax

這條指令就表示我們將要調用第1號系統調用,也就是sys_write,hello world程序中后續三條機器指令的函數是:

# 寫入文件描述符1
movq $1, %rdi


# 保存指向字符串的指針
movq $msg, %rsi


# 寫入數據的大小
movq $len, %rdx

實際上這四條機器指令都是為執行syscall進行的鋪墊,也就是執行syscall所需要的參數,可以看到我們進行系統調用傳遞參數時都是通過寄存器來完成的。

這樣當CPU執行syscall執行時就會跳轉到Linux內核中的write函數,同時在執行該函數時也能知道write函數所需要的參數是什么。?

責任編輯:武曉燕 來源: 碼農的荒島求生
相關推薦

2023-09-18 11:34:17

Linux系統

2022-11-09 08:12:07

2022-09-01 08:08:35

Android移動操作系統

2013-06-20 10:25:56

2021-08-31 10:32:11

LinuxPage Cache命令

2010-06-01 15:25:27

JavaCLASSPATH

2016-12-08 15:36:59

HashMap數據結構hash函數

2020-07-21 08:26:08

SpringSecurity過濾器

2018-04-16 11:04:23

HBaseRegion Serv數據庫

2018-09-12 15:48:35

ext4Linux文件系統

2021-05-19 07:56:26

Linux內核搶占

2017-01-12 19:34:58

2020-09-23 10:00:26

Redis數據庫命令

2019-06-25 10:32:19

UDP編程通信

2017-01-10 08:48:21

2024-02-21 21:14:20

編程語言開發Golang

2025-05-06 00:43:00

MySQL日志文件MIXED 3

2017-08-15 13:05:58

Serverless架構開發運維

2025-06-05 05:51:33

2021-05-31 07:50:59

Linux文件系統
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩久久中文字幕 | 在线播放一区二区三区 | 韩国成人在线视频 | 亚洲成人一区二区三区 | 久久99蜜桃综合影院免费观看 | 伊人天堂网 | 黄色一级毛片 | 欧美久久电影 | 欧美一级黄色片 | 天天操夜夜拍 | 国产欧美一级 | 91在线第一页 | 91视频入口| 国产中文字幕在线 | av超碰 | 麻豆天堂| 中文字幕视频在线观看 | 亚洲综合久久精品 | 国产日韩一区二区三免费高清 | 日本a∨视频 | 国产精品久久久久久久久免费软件 | 久久久久国产一区二区三区四区 | 午夜精品一区二区三区在线播放 | 免费在线观看黄色av | 久热爱 | 美女久久久久 | 偷拍自拍在线观看 | 亚洲毛片在线观看 | 97免费视频在线观看 | 一区二区免费 | 国产一区二区三区四区hd | 亚洲综合大片69999 | 亚洲一区中文字幕 | 欧美成人一区二区三区 | 中文字幕av在线一二三区 | 精品国产乱码久久久久久牛牛 | 日韩不卡在线观看 | 99视频在线免费观看 | www.日韩| 亚洲精品一区二区 | 日韩午夜电影在线观看 |