MIPS系统调用指令

时间:2013-12-03 07:31:48

标签: assembly mips system-calls

我反汇编了一些MIPS机器代码,我得到了以下代码片段。

00 00 00 0C             syscall 0                # System Call
00 00 00 00             nop
03 E0 00 08             jr      $ra              # Jump Register
00 00 00 00             nop

我想知道syscall 0的含义。

我知道调用syscall需要syscall个号码。并传递syscall个号码 通过$v0注册。

没有使用$v0,只有syscall 0

这等于:

move   $v0, 0  
syscall 

5 个答案:

答案 0 :(得分:2)

是的,似乎syscall 0仅仅是li $v0,0; syscall的助记符。至于 syscall 0,这完全取决于MIPS芯片在其中运行的平台。例如,我曾经在PlayStation1游戏上工作(是的,在当天回来......叹息......),我认为 syscall用于在专门的矢量单元上执行数学计算

你在做什么平台?

答案 1 :(得分:2)

检查MIPS文档:

  

MIPS32TM架构程序员第二卷:MIPS32TM   指令集

它说:

  

格式:SYSCALL 6 MIPS32(MIPS I)目的:进行系统调用   exception描述:立即发生系统调用异常   无条件地将控制转移到异常处理程序。该   代码字段可用作软件参数,但是   异常处理程序仅通过加载内容来检索   包含指令的记忆词。

看起来指令中确实存在“立即位”,但用法是 太复杂了,所以很少用。代替: 系统调用 好像组装一样 系统调用0 而$ v0用于传递系统调用号码。更轻松,更快捷。

“立即位”的使用似乎需要“旧方法”:使用返回地址作为指针并使用位掩码/从指令中移位系统调用号。

[编辑] 也就是说:从处理器的角度来看,直接位是“不关心”。

答案 2 :(得分:0)

没有。 等于这两条指令!

MIPS的“syscall”指令始终使用立即数字参数(不是寄存器)。如果没有显式键入参数,汇编器将隐式添加0作为参数。

一个例子:

如果您输入以下代码:

move     $v0, 123
syscall

汇编程序确实创建了以下代码:

addi     $v0, $zero, 123   # MIPS CPUs do not have a "move" instruction
syscall  0                 # Implicit argument "0" added

(有些装配工使用“ori”或类似的指令代替“addi”。)

如果使用“syscall”参数,则取决于操作系统(或MIPS模拟器)。据我所知,Linux和SPIM模拟器都忽略了“syscall”指令的参数,所以你不要在汇编程序中显式地输入参数。

为什么$ v0没有初始化?

有两个可能的原因:

  1. $ v0已在执行给定代码时初始化,因此不必再初始化
  2. 使用的操作系统不使用$ v0寄存器进行系统调用
  3. 您应该知道“syscall”指令的功能取决于所使用的操作系统(或MIPS模拟器)。在Linux和IRIX下运行相同的(!)计算机,“syscall”指令的行为将完全不同!

    - 编辑 -

    许多第三方(例如大学)文档中未提及“系统调用”指令的20位参数。官方MIPS文档中提到了这一点(例如,在MIPS R4000 CPU手册中,第A-162页)。

    顺便说一句:GNU反汇编程序将指令0x0000000c(这正是程序中的指令)反汇编为“syscall”而不是“syscall 0”(而0x0000010c被反汇编为“syscall 0x4”)。

答案 3 :(得分:0)

系统调用0也不需要使用$ v0。 在过去的日子里,系统调用参数很常见 “immediates”,系统调用使用返回地址作为参数指针。

[编辑] 我检查过:MIPS Linux,SPIM和MARS都使用$ v0。

答案 4 :(得分:0)

  

虽然理论上这可以回答这个问题,但事实如此   最好包括答案的基本部分,以及   提供参考链接

删除的帖子中有一个链接。

关于Linux(不是理论,但非常实践):

(来自:http://lxr.linux.no/linux+v3.12.2/arch/mips/kernel/scall32-o32.S#L100

/* Highest syscall used of any syscall flavour */
  25#define MAX_SYSCALL_NO  __NR_O32_Linux + __NR_O32_Linux_syscalls
  26
  27        .align  5
  28NESTED(handle_sys, PT_SIZE, sp)
  29        .set    noat
  30        SAVE_SOME
  31        TRACE_IRQS_ON_RELOAD
  32        STI
  33        .set    at
  34
  35        lw      t1, PT_EPC(sp)          # skip syscall on return
  36
  37        subu    v0, v0, __NR_O32_Linux  # check syscall number
  38        sltiu   t0, v0, __NR_O32_Linux_syscalls + 1
  39        addiu   t1, 4                   # skip to next instruction
  40        sw      t1, PT_EPC(sp)

...