系统调用 :操作系统分为用户态和核心态,当用户调用用户态函数的时候,需要进行用户态到核心态的切换,CPU 需要对现场进行保存。如果用户直接调用系统调用,就不需要进行二态切换,提高代码运行效率。并且编译链接后生成的可执行的ELF 体积小,运行效率高。用户可以通过系统提供的C 语言API 进行系统调用,同时也可以通过0x80 中断进行调用。下面介绍通过中断进行调用的方法。
参数传递 :功能号和返回值通过%eax 来传递,参数一般在5 个以下的通过寄存器%ebx,%ecx.%edx,%esi,%edi 来传递,如果参数个数大于5 个,则要通过堆栈来传递,按照c 语言的参数传递方式,最后一个参数最先进栈。同时,把%esp 传递给%ebx 。
Linux 系统调用个数 :319 个。
例子:
.data
filename:.fill 256
filecontent:.string "Hello World!"
len:.int 12
fd:.int -1
.text
.global _start
_start:
movl $3 , %eax # 系统调用read ,从标准输入读入文件名
movl $0 , %ebx
movl $filename , %ecx
movl $1024 , %edx
int $0x80
movl $filename , %ebx # 将文件名保存
movl %eax , %ecx
xorb %al , %al
movl $filename , %ebx
movb %al , -1(%ebx , %ecx)
movl $5 , %eax # 调用系统调用open 创建文件
movl $filename , %ebx
xorl %ecx , %ecx
orl $20 , %ecx
orl $100 , %ecx
orl $10 , %ecx
movl $0x0080, %edx
int $0x80
movl $fd , %ebx # 将文件描述符保存
movl %eax , (%ebx)
movl $4 , %eax # 调用系统调用write ,向文件中写字符串
movl $fd , %ebx
movl (%ebx) , %ebx
movl $filecontent , %ecx
movl $len , %edx
movl (%edx) , %edx
int $0x80
movl $6, %eax # 调用系统调用close ,关闭文件
movl $fd , %ebx
movl (%ebx) , %ebx
int $0x80
movl $1 , %eax
movl $0 , %ebx
int $0x80
参数传递
Linux
例子:
.data
filename:.fill 256
filecontent:.string "Hello World!"
len:.int 12
fd:.int -1
.text
.global _start
_start:
movl $3 , %eax #
movl $0 , %ebx
movl $filename , %ecx
movl $1024 , %edx
int $0x80
movl $filename , %ebx #
movl %eax , %ecx
xorb %al , %al
movl $filename , %ebx
movb %al , -1(%ebx , %ecx)
movl $5 , %eax #
movl $filename , %ebx
xorl %ecx , %ecx
orl $20 , %ecx
orl $100 , %ecx
orl $10 , %ecx
movl $0x0080, %edx
int $0x80
movl $fd , %ebx #
movl %eax , (%ebx)
movl $4 , %eax #
movl $fd , %ebx
movl (%ebx) , %ebx
movl $filecontent , %ecx
movl $len , %edx
movl (%edx) , %edx
int $0x80
movl $6, %eax #
movl $fd , %ebx
movl (%ebx) , %ebx
int $0x80
movl $1 , %eax
movl $0 , %ebx
int $0x80
![](https://i-blog.csdnimg.cn/blog_migrate/2f60c0bc47d4178ac5e2b807936153ff.gif)