首页 > 解决方案 > “系统调用”指令如何在 mips 程序集上工作?

问题描述

例如,让我们有这个代码:

.data
    msg: .asciiz "Hello world!" #message to be shown


.text
    li $v0, 4 #instruction for string printing
    la $a0, msg #indication of where the string is
    syscall #make it print

“li”将调用指令来准备打印,“la”将使变量 msg 转到寄存器“a0”,我知道 syscall 应该打印消息,但它究竟是如何做到的呢?它怎么知道它必须打印哪个寄存器?因为我没有在系统调用中的任何地方指出要打印的寄存器(例如在语言 c 中,它可能类似于 printf("%s",msg)),但它知道无论如何它必须打印 $a0 而我没有知道如何以及为什么。

标签: assemblymips

解决方案


理论上,syscall指令只是将处理器的控制(指令执行流)转移到系统/内核异常处理程序。该异常处理程序具有执行每个特定操作的软件,syscall然后返回给用户代码——正是这个软件知道查看$v0$a0。这就像一个子程序调用,但调用的是内核代码而不是用户子程序。硬件指令基本上“跳转”到那里,然后软件完成其余的工作。

更具体地说,syscall指令调用异常机制。它捕获执行用户代码的 PC,然后更改为特权模式,设置异常原因,并将 PC 更改为 0x80000800,从而开始运行内核异常处理程序。

我在理论上说,因为使用模拟器,它们的作用类似,但syscall可以作为直接在模拟器本身内的软件(而不是作为模拟异常处理程序)实现;如果以这种方式实现,软件还知道每个特定syscall的,哪些寄存器有哪些参数,以及运行操作后如何返回用户代码。


推荐阅读