系统调用是操作系统提供给我们的一个接口,通过该接口我们可以使用操作系统所管理的计算机资源。
早期使用接口的方式是为了方便了我们使用计算机,比如当我们需要获取当前时间可以直接使用time_t time(time_t *tm)系统调用获取时间,而不用与定时器硬件打交道。DOS系统也提供了许多的系统调用可以直接使用中断代码来操作。而现在多任务系统下,系统调用接口多了一层意义。当我们使用内核接口的方式使用硬件而不是自己来操作硬件,这保证了使用的安全性,只要内核代码正确,我们就可以安全的使用计算机。
linux下接口使用int 0x80实现,也就是软中断。用户可以使用int 0x80指令切入内核获取资源。切入内核后,将执行内核已写好的代码。代码执行完成在返回给用户。int 0x80执行前需要设置相应的寄存器来调用相应的系统调用,来传递相应的参数。Linux会有6个寄存器被用来传递这些参数:eax(存放系统调用号)、ebx、ecx、edx、esi及edi来存放这些额外的参数(以字母递增的顺序)。linux提供一些宏以便于我们调用系统调用,原理就是使用嵌入式汇编设置eax,ebx…寄存器并调用0x80。可以看以下宏代码:
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">unistd.h文件 <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#ifndef _LINUX_UNISTD_H</span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> _LINUX_UNISTD_H</span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> __NR_setup 0 </span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> __NR_exit 1</span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> __NR_fork 2</span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> __NR_read 3</span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> __NR_write 4</span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> __NR_open 5</span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> __NR_close 6</span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> __NR_waitpid 7</span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> __NR_creat 8</span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> __NR_link 9</span> <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> __NR_unlink 10</span> ... 还有的在此处省略 <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extern</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> errno; <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> _syscall0(type,name) \</span> type name(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>) \ { \ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> __res; \ __asm__ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">volatile</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"int $0x80"</span> \ : <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"=a"</span> (__res) \ : <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"0"</span> (__NR_<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">##name)); \</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (__res >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) \ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> (type) __res; \ errno = -__res; \ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; \ } <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> _syscall1(type,name,atype,a) \</span> type name(atype a) \ { \ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> __res; \ __asm__ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">volatile</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"int $0x80"</span> \ : <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"=a"</span> (__res) \ : <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"0"</span> (__NR_<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">##name),"b" ((long)(a))); \</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (__res >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) \ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> (type) __res; \ errno = -__res; \ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; \ } <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">define</span> _syscall2(type,name,atype,a,btype,b) \</span> type name(atype a,btype b) \ { \ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> __res; \ __asm__ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">volatile</span> (<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"int $0x80"</span> \ : <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"=a"</span> (__res) \ : <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"0"</span> (__NR_<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">##name),"b" ((long)(a)),"c" ((long)(b))); \</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (__res >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) \ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> (type) __res; \ errno = -__res; \ <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>; \ } </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li></ul>
我们平时调用的大量的系统调用都以这样的原理来实现的,我们使用的代码库可能包含了大量的这样的实现,但有时当我们要使用代码库中没有的系统调用是就要自己来实现调用了。
版权声明:本文为博主原创文章,未经博主允许不得转载。