MIPS 架构“系统调用”操作说明

发布于 2024-11-06 11:02:54 字数 29 浏览 3 评论 0原文

syscall指令在MIPS中的作用是什么?

What is the role of syscall instruction in MIPS?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

依 靠 2024-11-13 11:02:54

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

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

在这种情况下,1 是打印整数的服务代码。第二条指令有效地执行从 $t0 到 $a0 的复制,$a0 是保存参数的指定寄存器(在本例中是要打印的整数)。服务和相应参数的列表在 SYSCALL 函数中提供火星

The syscall is used to request a service from the kernel. For MIPS, the service number/code must be passed in $v0 and arguments are passed in a few of the other designated registers. For example, to print we might do:

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

In this case, 1 is the service code for print integer. The second instruction effectively performs a copy from $t0 to $a0 which is the designated register where the argument is held ( in this case, the integer to be printed ). A list of the services and corresponding arguments is given in SYSCALL functions available in MARS.

赴月观长安 2024-11-13 11:02:54

当您走出模拟器的上下文(例如 MARS 或 SPIM 其中系统调用有些人为。在真正的 MIPS 机器上,您可以使用它来传输控制内核以调用特定函数。

例如,这是一个用于 Linux 机器的 MIPS 32 位汇编的基本 Hello, World! 程序(我 95% 确定这是在 mipsel 安装上,尽管这对于 Linux 机器来说并不重要)这个问题):

# 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) em>),因此我们不必按编号引用系统调用。这里进行系统调用的约定与调用函数几乎相同,加载带有参数的a#寄存器,然后将我们想要的系统调用加载到$v0中并调用syscall SYS_write 对应于基本write(2) Linux/Unix 函数(1 为标准输出)。

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

因此,我们告诉内核使用长度字节写入文件句柄 1(标准输出)、字符串 Hello。在 Linux 上,您可以看到 syscalls(2) 来了解所有可用的不同系统调用,但是它们几乎对应于内核提供的核心功能,并且 (g)libc 要么包装要么构建于 C/C++ 程序之上。

Linux(以及大多数类 Unix 系统,回到 4BSD 路线)一个函数 syscall(2) 实际上是同一件事。

一旦你开始做更复杂的事情,你会发现自己将syscall调用包装成方便的函数,或者更好的是只调用相应的libc版本(令人惊讶地容易做到,但另一个讨论)。

It becomes a lot more obvious when you step outside the context of an emulator like MARS or SPIM where the system calls are somewhat artificial. On a real MIPS machine, you would use it transfer control the kernel to invoke a specific function.

For example, this is a basic Hello, World! program in MIPS 32-bit assembly for a Linux machine (I'm 95% sure this was on a mipsel install, though not that it matters much for this question):

# 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

This corresponds very closely to the C code (if you have trouble following the MIPS assembly).

#include <stdio.h>

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

First note that headers are included to give the registers symbolic names (asm/regdef.h) and a header that will pull in symbolic names for the system calls (sys/syscall.h), so we don't have to refer to the system calls by number. The conventions for making a system call here are pretty much the same as calling a function, load the a# register with arguments, and then we load which system call we want into $v0 and invoke syscall. SYS_write corresponds to the basic write(2) function for Linux/Unix (1 being standard output).

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

So we're telling the kernel to write to the file handle 1 (standard output), the string Hello, using length bytes. On Linux you can see syscalls(2) for all the different system calls available, but they pretty much correspond the core functions that the kernel provides and that (g)libc either wraps or builds upon for C/C++ programs.

Linux (and most Unix-like systems, going back to the 4BSD route) have a function syscall(2) which is effectively the same thing.

Once you start doing more complex stuff, you'll either find yourself wrapping the syscall invoking into handy functions, or better yet just calling the corresponding libc versions (surprisingly easy to do, but another discussion).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文