<!--
@page { margin: 0.79in }
P { margin-bottom: 0.08in }
-->
汇编语言中也需要通过某些途径来使用操作系统提供的服务,也就是系统调用;系统调用就是通过与操作系统内核通信来完成;系统调用会把用户态程序的调用转换成对系统内核服务的调用;
Linux平台下有两种方式来使用系统调用:一种是利用封装后的C库(libc),另一种是通过汇编直接调用;其中,通过汇编语言来直接调用系统调用,是最高效地使用Linux内核服务的方法,因为最终生成的程序不需要与任何库进行连接,而是直接与内核通信;
与DOS一样,Linux下的系统调用也是通过中断(int
0x80)方式来实现的;
在执行"int
$0x80"指令时,寄存器eax中存放的是系统调用的功能号(即:中断功能号,DOS下存放在AH中),所有的系统调用功能号都可以再文件/usr/include/bits/syscall.h中找到,为了便于使用,它们都是用"SYS_<name>"这样的宏来定义的;如:SYS_write、SYS_exit等;
系统调用的参数传递规则:
传递给系统调用的参数则必须按照参数顺序依次存放到寄存器ebx,ecx,edx,esi,edi中,当系统调用完成之后,返回值存放在eax中;
A.当系统调用所需参数的个数不超过5个的时候,执行"int
$0x80"指令时,需在eax中存放系统调用的功能号,传递给系统调用的参数则按照参数顺序依次存放到寄存器ebx,ecx,edx,esi,edi中,当系统调用完成之后,返回值存放在eax中;
比如,经常用到的write函数的定义如下:
ssize_t
write(int fd, const void* buf, size_t
count);
该函数的功能最终通过SYS_write这一系统调用来实现的;根据上面的参数传递规则可知,参数fd存放在ebx中,参数buf存放在ecx中,参数count存放在edx中,而系统调用功能号SYS_write则存放在寄存器eax中;系统调用执行完成之后,返回值可以从eax中得到;
B.当系统调用的参数超过5个的时候,执行"int
$0x80"指令,需在eax中存放系统调用的功能号,所不同的只是全部的参数应该依次存放在一块连续的内存区域里,同时在寄存器ebx中保存指向该内存区域的指针(即:该连续内存块的首地址),返回值仍然保存在寄存器eax中;由于只是需要一块连续的内存区域来保存系统调用所需要的参数,因此,完全可以像普通的函数调用一样使用栈来传递系统调用所需要的参数;但是要注意一点:Linux采用的是C语言的调用模式,这就意味着所有参数必须以相反的顺序进栈,即:最后一个参数最先进栈,而第一个参数最后进栈;如果采用栈来传递系统调用所需要的参数,在执行"int
$0x80"指令时,还应将栈指针的当前值(栈顶地址)复制到寄存器ebx中;
例如,系统调用mmap()的参数个数就超过5个:
void*
mmap(void* start, size_t length, int prot, int flags, int fd, off_t
offset);
使用这个系统调用时,系统调用功能号保存到eax中,mmap()所需要的所有参数存放到一块连续的内存区域中,这块连续内存区域的首地址存放到ebx中,即可;
C库函数的参数传递规则:
1、参数从右向左依次入栈(push);
2、库函数的返回值存放在寄存器eax中;
3、系统调用exit()的参数值在exit()调用结束程序退出的时候会被传递给系统shell,通过打印$?的值可看到;
汇编函数的返回值:
只要是函数,一般都需要返回值;汇编语言中约定:对于32位的返回值,存放在寄存器eax中返回;对于64位的返回值,存放在寄存器eax和edx中返回,高位字放在edx中,低位字放在eax中;
例如:
sys_fork()调用,用于创建子进程,是system_call 功能2。原形在include/linux/sys.h 中。
首先调用C 函数find_empty_process(),取得一个进程号pid。若返回负数则说明目前任务数组
已满。然后调用copy_process()复制进程。
分享到:
相关推荐
linux-0.11-devel-060625.ziplinux-0.11-devel-060625.ziplinux-0.11-devel-060625.ziplinux-0.11-devel-060625.ziplinux-0.11-devel-060625.ziplinux-0.11-devel-060625.ziplinux-0.11-devel-060625.ziplinux-0.11-...
linux 0.11 源码下载 本代码是目前能够找到的最早的Linux的...尽管Linux 0.11内核已经经历了多次更新和升级,但它的源代码仍被视为学习Unix/Linux内核的入门级材料。它是获取Unix/Linux内核设计经验和智慧的重要途径。
linux-0.11-devel-050518.ziplinux-0.11-devel-050518.ziplinux-0.11-devel-050518.ziplinux-0.11-devel-050518.ziplinux-0.11-devel-050518.ziplinux-0.11-devel-050518.ziplinux-0.11-devel-050518.ziplinux-0.11-...
自己的linux-0.11编译开发环境,增加了nasm可执行文件,增加了dos软盘,虚拟机用的是bochs-2.1.1。
linux 0.11内核下载,linux 内核
windows下面编译linux-0.11内核 MinGW32 Bochs
Linux0.11内核代码,对于学习内核的人来说,Linux0.11内核代码确实是个不错的选择。。
linux内核完全注释根据linux0.11编写的。搭配内核设计的艺术2版,学习linux内核的神组合。学习内核建议从linux0.11看起,初始版本内容比较简单,但包含的都是内核的精髓。先上手,学到了方法,后面再看最新版本就更...
LINUX0.11内核源码 真男人就读源码
《Linux 0.11内核完全注释》
Linux内核Linux内核0.11完全注解.rar0.11完全注解.rar
linux 0.11内核源代码 有注释 读linux 0.11内核源代码是学习和提高C语言编程能力的最佳途径 对以后其他语言的编程会有很大的帮助 几乎所有的优秀的编程人员都是通过此途径获得快速提高的
linux0.11内核源代码 linux0.11内核源代码 linux0.11内核源代码
本书对早期的Linux操作系统内核(v0.11)全部源代码文件进行了详细的注释和 说明,旨在让读者能够在短时间内对Linux的工作机理获得全面而深刻的理解,为进一步学习和研究Linux系统打下坚实的基础。书中首先介绍了 ...
linux-0.11-040327-rh9.diff.gz
可以直接make的linux-0.11源码,得到Image
linux0.11内核原理框图 VISIO版
linux-0.11.rar linux0.11版内核源代码 下载
linux0.11资料,linux0.11内核源码及完全注释
linux0.11内核源代码.麻雀虽小,五脏俱全,linux内核的早期版本,学习LINUX内核的好东西!