2011-05-09 24 views

Respuesta

9

La llamada al sistema se utiliza para solicitar un servicio al núcleo. Para MIPS, el número/código del servicio se debe pasar en $ v0 y los argumentos se pasan en algunos de los otros registros designados. Por ejemplo, para imprimir podríamos hacer:

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

En este caso, 1 es el código de servicio para el entero de impresión. La segunda instrucción efectivamente realiza una copia de $ t0 a $ a0 que es el registro designado donde se sostiene el argumento (en este caso, el entero que se imprimirá). Se da una lista de los servicios y los argumentos correspondientes: http://courses.missouristate.edu/KenVollmar/Mars/Help/SyscallHelp.html

5

se hace mucho más evidente cuando paso fuera del contexto de un emulador como Marte o SPIM, donde las llamadas al sistema son algo artificial. En una máquina MIPS real, debería usarla para controlar el núcleo para invocar una función específica.

Por ejemplo, este es un programa hola mundo básica en MIPS de montaje de 32 bits para una máquina Linux (estoy 95% seguro de que esto era en un mipsel instalar, no es que importe mucho para esta pregunta)

# 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 

Esto se corresponde muy de cerca al código C (si tiene problemas para seguir el montaje MIPS).

#include <stdio.h> 

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

en primer lugar que los encabezados se incluyen para dar los registros de nombres simbólicos (ASM/regdef.h) y un encabezado que se tire en los nombres simbólicos para las llamadas al sistema (sys/syscall.h) por lo que don' t tiene que referirse a las llamadas de sistema por número. Las convenciones para hacer una llamada al sistema aquí son más o menos las mismas que llamar a una función, cargar un # registro con argumentos, luego cargar la llamada al sistema que queremos en $ v0 e invocar syscall. SYS_write corresponde a la función básica de escritura (2) para Linux/Unix (1 es estándar).

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

por lo que estamos diciendo al núcleo para escribir en el fichero mango 1 (stdout), la cadena hola, usando bytes de longitud. En Linux puede ver syscalls (2) para todas las diferentes syscalls disponibles, pero corresponden más o menos a las funciones principales que proporciona el núcleo y que (g) libc se ajusta o se basa en los programas C/C++.

Linux (y la mayoría de los usuarios de Unix que se remontan a la ruta 4BSD) tienen una función syscall (2) que es efectivamente la misma cosa.

Una vez que empiece a hacer cosas más complejas, se encontrará envolviendo el syscall invocando funciones útiles, o mejor aún llamando a las correspondientes versiones de libc (sorprendentemente fácil de hacer, pero otra discusión).