彙編語言中的系統調用

linux內核

  • 內核組成

    • 內存管理
      • /proc/meminfo 可以查看物理內存以及交換區大小
      • ipcs -m 可以查看共享內存使用情況
    • 設備管理
      • 插入設備驅動代碼
        • 將驅動代碼編譯進內核代碼
        • 將驅動代碼插入到運行的內核
      • 設備文件類型
        • 字節類型
        • 塊類型
        • 網絡類型
    • 文件系統管理
      • 文件類型
    文件系統 描述
    affs Amiga 文件系統
    ext linux擴展文件系統
    ext2 二代
    ext3 3代
    hpfs OS/2 高性能文件系統
    iso9660 ISO 9660 文件系統
    minix MINIX文件系統
    msdos Microsoft FAT16
    ncp Netware 文件系統
    proc 訪問系統信息
    reiserfs Journaling 文件系統
    sysv 老一代UNIX文件系統
    ufs BSD文件系統
    umsdos 類UNIX文件系統
    vfat Windows 95文件系統
    • 進程管理
      • 命令
        ps options
  • 內核版本

    • 內核格式
      linux-a.b.c
    • 命令
      uname -a

系統調用

  • 查找系統調用

    • 查找文件
      /usr/include/asm/unistd.h
  • 查找系統調用定義

    • 命令示例
      man 2 exit
    • 說明
      2 : 幫助文檔的第二部分
    • 結構
      • 名稱: 系統調用的名稱
      • 大綱: 系統調用的用法
      • 描述: 系統調用的基本描述
      • 返回值: 系統調用的返回值
  • 一般的系統調用

    • 內存訪問相關
系統調用 描述
brk 變更數據段大小
mlock 關閉部分內存的分頁
mlockall 關閉調度進程的分頁
mmap 映射文件或設備到內存
mprotect 控制一段內存的訪問
mremap 重新映射一段虛擬內存
msync 同步文件和內存的映射
munlock 打開一段內存的分頁
munlockall 打開調用進程的所有分頁
munmap 關閉文件或者設備到內存的映射
* 設備訪問相關
系統調用 描述
access 檢查設備的權限
chmod 改變一個設備的權限
chown 改變一個設備的所有者
close 關閉設備的文件描述符
dup 複製設備文件描述符
fcntl 管理文件描述符
fstat 獲得設備狀態
ioctl 控制設備參數
link 給文件描述符分配一個新名字
lseek 重新分配文件描述符的偏移
mknod 爲一個設備新建一個文件描述符
open 爲一個文件或設備打開一個文件描述符
read 從一個設備文件描述符讀數據
write 向一個設備文件描述符寫數據
  • 文件系統相關

|系統調用| 描述|
|chdir| 改變工作目錄|
|chroot| 改變根目錄|
|flock|應用或移除一個文件的公告鎖|
|statfs|獲得一個文件系統的狀態|
|getcwd|獲得當前工作目錄|
|mkdir|創建目錄|
|rmdir|移除目錄|
|symlink|爲一個文件重新命名|
|umask|設置文件的掩碼|
|mount|掛載或者解除掛載文件系統|
|swpon|開始交換內存到文件系統|
|swapoff|結束交換內存到文件系統|

  • 進程系統相關
系統調用 描述
acct 打開或關閉文件計數
capget 獲得進程權限
capset 設置進程權限
clone 克隆一個子進程
execve 執行一個程序
exit 結束當前進程
fork 創建一個子進程
getgid 獲得組id
getpgrp 獲得或設置進程組
getppid 獲得進程標識
getpriority 獲得進程調度級別
getuid 獲得用戶標識
kill 發送一個信號殺死進程
nice 改變進程的優先級
vfork 創建一個子進程並阻塞父進程

使用系統調用

  • 系統調用的格式
    • 系統調用的值
      • movl $1, %eax #1 系統調用的值
      • int $0x80
    • 系統調用輸入值
      • EBX (第一個參數)
      • ECX(第二個參數)
      • EDX(第三個參數)
      • ESI(第四個參數)
      • EDI(第五個參數)
      • 如果超過五個參數使用ebx存儲參數的內存指針,參數在內存中順序存儲
      • 示例
# syscalltest.s - An example of passing input values to a system call
# ssize_t write(int fd, const void *buf, size_t count)
.section .data
output:
	ascii "This is a test message.\n"
output_end
	.equ len, out_end - output
.section .text
.globl _start
_start:
	movl $4, %eax
	movl $1, %ebx
	movl $output, %ecx
	movl $len, %edx
	int $0x80
	
	movl $1, %eax
	movl $0, %ebx
	int $0x80
* 系統調用返回值
	* 格式
		EAX存儲返回值
	* 示例
#syscalltest.s - An example of getting a return value from a system call

.section .bss
	.lcomm pid, 4
	.lcomm uid, 4
	.lcomm gid, 4
.section .text
.globl _start
_start:
	movl $20, %eax # getpid
	int $0x80
	movl %eax, pid

	movl $24, %eax # getuid
	int $0x80
	movl %eax, uid

	movl $47, %eax # getgid
	int $0x80
	movl %eax, pid

	movl $1, %eax
	movl $0, %ebx
	int $0x80

高級系統調用返回值

  • sysinfo 系統調用
    • 說明
      NAME
      sysinfo -return information on overall system statistics
      SYNOPSIS
      #include<sys/sysinfo.h>

        int sysinfo(struct sysinfo *info);
      
        struct sysinfo{
        	long uptime;       /*運行的秒數*/
        	unsigned long loads[3]; /*1,5,15分鐘的平均負載*/
        	unsigned long totalram; /* 當前使用的內存*/
        	unsigned long freeram; /*可用內存數*/
        	unsigned long sharedram; /*共享內存數*/
        	unsigned long bufferram; /* 緩存內存大小*/
        	unsigned long totalswap; /* 交換空間大小*/
        	unsigned long freeswap; /* 可用的交換空間大小*/
        	unsigned long procs; /*當前進程數*/
        	unsigned long totalhigh; /*當前高內存數*/
        	unsigned long mem_unit;/*內存單元字節數*/
        	char _f[20-2*sizeof(long)-sizeof(int)]; /*libc5的填充
      
      • 示例
# sysinfo.s - Retrieving system information via kernal system calls
.section .data
result:
uptime:
	.int 0
load1:
	.int 0
load5:
	.int 0
load15:
	.int 0
totalram:
	.int 0
freeram:
	.int 0
sharedram:
	.int 0
bufferram:
	.int 0
totalswap:
	.int 0
freeswap:
	.int 0
procs:
	.byte 0x00, 0x00
totalhigh:
	.int 0
memuint:
	.int 0
.section .text
.globl _start
_start:
	nop
	movl $result, %ebx
	movl $116, %eax
	int $0x80

	movl $0, %ebx
	movl $1, %eax
	int $0x80

跟蹤系統調用

  • strace 程序
    • strace ./exec
    • strace -c ./exec
  • strace 的高級參數
參數 描述
-c 統計每個系統調用的時間,錯誤信息等
-d 顯示strace的調試信息
-e 指定一個輸出的過濾器
-f 跟蹤子進程
-ff 如果寫入輸出文件,每個進程寫一個單獨文件
-i 打印系統調用的指令指針
-o 指定輸出文件
-p 附加到一個pid
-q 抑制附加信息
-r 打印一個相對的時間戳
-t 每一行附加時間
-tt 附加毫秒時間
-ttt 附加微妙時間
-T 顯示每個系統調用的耗時
-v 打印詳細的系統調用版本
-x 用16進制打印非ASCII字符
-xx 用16進制打印所有字符串
  • 跟蹤一個運行的程序
    • 示例
# nanotest.s - Another example of using system calls
.section .data
timespec:
	.int 5, 0
output:
	.ascii "This is a test\n"
output_end:
	.equ len, output_end - output
.section .bss
	.lcomm rem, 8
.section .text
.globl _start
_start:
	nop
	movl $10, %ecx
loop1:
	pushl %ecx
	movl $4, %eax
	movl $1, %ebx
	movl $output, %ecx
	movl $len, %edx
	int $0x80

	movl $162, %eax # nanosleep
	movl $timespec, %ebx
	movl $rem, %ecx
	int $0x80
	popl %ecx
	loop loop1

	movl $1, %eax
	movl $0, %ebx
	int $0x80
* 說明
	SYNOPSIS:
		#include <time.h>
		int nanosleep(const struct *req, struct timespec *rem);

		struct timespec
		{
			time_t tv_sec;   /* 秒*/
			long    tv_nsec; /* 納秒*/
		};

* 運行
	./nanotest &
	ps ax | grep nanotest
	strace -p $pid

系統調用和C庫

  • 使用c庫實現上節功能
#cfunctest.s - An example of using C functions */
.section .data
output:
	.asciz "This is a test\n"
.section .text
.globl _start
_start:
	movl $10, %ecx
loop1:
	pushl %ecx
	pushl $output
	call printf
	addl $4, %esp
	pushl $5
	call sleep
	addl $4, %esp
	popl %ecx
	loop loop1
	pushl $0
	call exit
  • 運行

    • as -o cfunctest.o cfunctest.s
    • ld -dynamic-linker /lib/ld-linux.so.2 -lc -o cfunctest cfunctest.o
    • strace -c ./cfunctest
  • 對比使用C庫和直接使用系統調用發現

    • 使用系統調用的優點
      • 由於不引入外部庫,因此可執行文件小
      • 執行速度快
      • 不依賴外部庫
    • 使用c庫的優點
      • C庫方法比較豐富
      • c庫可移植性好
      • c庫可以使用動態鏈接庫從而減少內存使用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章