2011-05-09 50 views

回答

9

系统调用用于从内核请求服务。对于MIPS,服务号码/代码必须以$ v0传递,参数在其他几个指定的寄存器中传递。例如,要打印,我们可以做:

li $v0, 1 
add $a0, $t0, $zero 
syscall 

在这种情况下,1是打印整数服务代码。第二条指令有效地执行从$ t0到$ a0的拷贝,这是保存参数的指定寄存器(在这种情况下是要打印的整数)。提供服务和相应参数的列表: http://courses.missouristate.edu/KenVollmar/Mars/Help/SyscallHelp.html

5

当您在模拟器(如MARS或SPIM)的上下文之外进行系统调用有点人为时,它变得更加明显。在真正的MIPS机器上,您可以使用它传输控制内核来调用特定功能。

例如,这是MIPS 32位汇编了一台Linux机器一个基本的Hello World程序(我敢肯定,95%,这是在mipsel体系安装,而不是它的问题太多了这个问题)

# CS341L Fall 2008 
# Lab Exercise #1 
# Matthew J. Barrick <[email protected]> 

#include <asm/regdef.h> 
#include <sys/syscall.h> 

.data 
    hello: .asciz "Hello World\n" 
    length: .word 12 
.text 
    .globl main 
    .ent main 
main: 
    li a0, 1 
    la a1, hello 
    lw a2, length 
    li v0, SYS_write 
    syscall 
    move v0, zero 
    jr ra 
    .end main 

这与C代码非常接近(如果您在遵循MIPS程序集时遇到问题)。

#include <stdio.h> 

int main(int argc, char** argv) { 
    char* hello = "Hello World\n"; 
    write(STDOUT_FILENO,hello, 12); 
    return 0; 
} 

这头包括给寄存器符号名(ASM/regdef.h),并且将在符号名称扳为系统调用(SYS/syscall.h)的标题,所以我们不要首先要注意”不得不通过编号引用系统调用。这里进行系统调用的约定与调用函数,使用参数加载#寄存器几乎相同,然后我们将要调用的系统调用加载到$ v0并调用系统调用。 SYS_write对应于linux/unix的基本写入(2)函数(1是标准输出)。

ssize_t write(int fd, const void *buf, size_t count); 

所以我们告诉内核使用长度字节写入文件句柄1(stdout),字符串hello。在linux上,你可以看到所有可用的系统调用的syscalls(2),但它们几乎与内核提供的核心函数相对应,并且(g)libc包装或为C/C++程序构建。

Linux(和大多数UNIX-喜欢回去的路线4BSD)有一个函数的系统调用(2),它实际上是一回事。一旦你开始做更复杂的事情,你会发现自己将系统调用调用到方便的函数中,或者更好的是调用相应的libc版本(令人惊讶的容易做,但另一个讨论)。