系统调用指令在MIPS中的作用是什么?
答案 0 :(得分:10)
syscall用于从内核请求服务。对于MIPS,服务号/代码必须在$ v0中传递,并且参数在少数其他指定寄存器中传递。例如,要打印我们可能会这样做:
li $v0, 1
add $a0, $t0, $zero
syscall
在这种情况下,1是打印整数的服务代码。第二条指令有效地执行从$ t0到$ a0的复制,这是保存参数的指定寄存器(在这种情况下,是要打印的整数)。给出了服务列表和相应的参数: http://courses.missouristate.edu/KenVollmar/Mars/Help/SyscallHelp.html
答案 1 :(得分:5)
当你走出像MARS或SPIM这样的仿真器的上下文时系统调用有点人为,这一点变得更加明显。在真正的MIPS机器上,您将使用它来转移控制内核来调用特定的函数。
例如,这是一个用于Linux机器的MIPS 32位程序集的基本hello world程序(我敢肯定这是一个mipsel安装,而不是这个问题很重要)
# CS341L Fall 2008
# Lab Exercise #1
# Matthew J. Barrick <barrick@cs.unm.edu>
#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)引入符号名称的头文件,因此我们不必引用按号码到系统调用。在这里进行系统调用的约定与调用函数,使用参数加载#register几乎相同,然后我们将所需的系统调用加载到$ v0并调用syscall。 SYS_write对应于linux / unix的基本write(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-like返回4BSD路由)都有一个函数syscall(2)实际上是同一个东西。
一旦你开始做更复杂的事情,你会发现自己将syscall调用包装到方便的函数中,或者更好的只是调用相应的libc版本(非常容易做到,但另一个讨论)。