Инструкция системного вызова архитектуры MIPS - PullRequest
10 голосов
/ 09 мая 2011

Какова роль инструкции syscall в MIPS?

Ответы [ 2 ]

10 голосов
/ 09 мая 2011

Системный вызов используется для запроса сервиса от ядра.Для MIPS сервисный номер / код должен быть передан в $ v0, а аргументы переданы в нескольких других назначенных регистрах.Например, чтобы напечатать, мы могли бы сделать:

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

В этом случае 1 - сервисный код для целого числа печати.Вторая инструкция эффективно выполняет копирование из $ t0 в $ a0, которое является назначенным регистром, в котором хранится аргумент (в данном случае, целое число, которое должно быть напечатано).Приведен список услуг и соответствующие аргументы: http://courses.missouristate.edu/KenVollmar/Mars/Help/SyscallHelp.html

5 голосов
/ 23 апреля 2012

Это становится намного более очевидным, когда вы выходите из контекста эмулятора, такого как 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 (на удивление легко сделать, но другое обсуждение).

...