引言
博主的另一篇博文介绍了如何使用 int 0x80
指令进行Linux系统调用,这一篇博文介绍一下如何使用另一种方式: syscall
指令进行Linux系统调用,然后会简要说明二者的不同。
Linux系统调用:使用 syscall
通过 syscall
指令进行Linux系统调用与通过 int 0x80
指令进行Linux系统调用在使用上差别不大,系统调用号依然通过 eax
传递,不同之处在于二者的系统调用号和传递参数所使用的寄存器。
通过 syscall
指令进行Linux系统调用时,约定的传递参数的寄存器依次为 edi
、 esi
、 edx
、 ecx
。文末会附上 syscall
使用的系统调用号表。
示例:
; NASM
; 在显示器上输出hello, world
; write(int fd, const void *buffer, size_t nbytes)
; exit(int status)
global _start
section .text
_start:
mov eax, 1 ; write系统调用号为1
mov edi, 1 ; 第一个参数:文件描述符(fd),1代表标准输出stdout
mov esi, message ; 第二个参数:要输出的字节序列(buffer)
mov edx, message.len ; 第三个参数:字节序列的长度
syscall
mov eax, 60 ; exit系统调用号为60
mov edi, 0 ; 第一个参数:状态码(status),0代表正常退出
syscall
section .data
message:
db "hello, world", 10
.len equ $ - message
syscall 与 int 0x80 的不同
- 从使用上来看
- 约定的传递参数的寄存器不同
syscall
使用的是edi
、esi
、edx
、ecx
int 0x80
使用的是ebx
、ecx
、edx
、esi
、edi
- 系统调用号不同(见文末系统调用表)
- 约定的传递参数的寄存器不同
- 从内部机制来看
syscall
调用的是C库函数,是在用户空间的,并且最终还是会调用内核函数(入口点)int 0x80
调用的是内核函数,是在内核空间的- 所以二者的处理流程不完全相同(系统调用流程参见:Linux系统调用)
syscall 和 int 0x80 哪个更好?
这是Stack Overflow的一个问题,原问题地址为:What is better “int 0x80” or “syscall”?
更多资料
[1] syscall
所使用的系统调用号表:Linux系统调用号表