15

MIPS における syscall 命令の役割は何ですか?

4

2 に答える 2

13

syscall は、カーネルからサービスを要求するために使用されます。MIPS の場合、サービス番号/コードは $v0 で渡す必要があり、引数は他の指定されたレジスタのいくつかで渡されます。たとえば、印刷するには次のようにします。

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

この場合、1 は print integer のサービス コードです。2 番目の命令は、$t0 から $a0 へのコピーを効果的に実行します。$a0 は、引数が保持される指定されたレジスタです (この場合は、表示される整数)。サービスと対応する引数のリストは次のとおりです: http://courses.missouristate.edu/KenVollmar/Mars/Help/SyscallHelp.html

于 2011-05-09T15:15:39.967 に答える
7

MARS や SPIM のような、システム コールが人工的なものであるエミュレータのコンテキストから一歩外に出ると、これはより明白になります。実際の MIPS マシンでは、これを使用してカーネルに制御を移し、特定の機能を呼び出します。

たとえば、これは Linux マシン用の MIPS 32 ビット アセンブリの基本的な hello world プログラムです (これが mipsel インストールであったことは 95% 確信していますが、この質問にとってはそれほど重要ではありません)。

# 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) のシンボリック名を取り込むヘッダーが含まれていることに注意してください。したがって、syscalls を参照する必要はありません。番号で。ここでシステム コールを作成するための規則は、関数を呼び出すのとほぼ同じです。# レジスタに引数をロードし、必要なシステム コールを $v0 にロードして、syscall を呼び出します。SYS_write は、linux/unix の基本的な write(2) 関数 (1 は標準出力) に対応します。

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

そのため、長さバイトを使用して、ファイル ハンドル 1 (stdout)、文字列 hello に書き込むようにカーネルに指示しています。Linux では、利用可能なすべての異なる syscall の syscalls(2) を見ることができますが、それらはカーネルが提供するコア関数とほぼ対応しており、(g)libc は C/C++ プログラム用にラップまたはビルドします。

Linux (および 4BSD ルートに戻るほとんどの unix ライク) には、事実上同じことである関数 syscall(2) があります。

より複雑なことを始めると、システムコール呼び出しを便利な関数にラップするか、対応する libc バージョンを呼び出すだけでよいことに気付くでしょう (驚くほど簡単に実行できますが、別の議論があります)。

于 2012-04-23T19:00:01.523 に答える