Это становится намного более очевидным, когда вы выходите из контекста эмулятора, такого как MARS или SPIM, где системные вызовы являются несколько искусственными. На реальной машине MIPS вы должны использовать ее для управления передачей ядра, чтобы вызвать определенную функцию.
Например, это базовая программа hello world в 32-битной сборке MIPS для Linux-машины (я на 95% уверен, что это было при установке 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), поэтому нам не нужно ссылаться на системные звонки по номеру. Соглашения для выполнения системного вызова здесь во многом аналогичны вызову функции, загружают регистр # с аргументами, затем мы загружаем нужный системный вызов в $ v0 и запускаем syscall. SYS_write соответствует базовой функции write (2) для linux / unix (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) имеют функцию syscall (2), которая фактически является тем же самым.
Как только вы начнете делать более сложные вещи, вы либо обнаружите, что оборачиваете вызов syscall в удобные функции, либо, что еще лучше, просто вызываете соответствующие версии libc (на удивление легко сделать, но другое обсуждение).