跳转到内容

SPARC 汇编/SPARC 细节

来自维基教科书,开放的书籍,开放的世界

RISC 计算机

[编辑 | 编辑源代码]

寄存器

[编辑 | 编辑源代码]

SPARC 处理器有 32 个整数寄存器。这些寄存器被分成 4 个基本类别:全局局部输入输出。下表显示了总体细分

编号 目的 特定名称
%r0–%r7 全局:可在程序中的任何位置访问 %g0–%g7
%r8–%r15 输出:用于向子程序传递值/从子程序获取值 %o0–%o7
%r16–%r23 局部:在子程序中用于操作数据 %l0–%l7
%r24–%r31 输入:包含传递给子程序的数据 %i0–%i7

在这些类别中分散着几个特殊用途寄存器

名称 编号 目的 假名
堆栈指针 14 指向堆栈头的指针。 %sp/ %o6
帧指针 30 指向当前堆栈帧的指针。 %fp/ %i6
返回地址 31 子程序的返回地址。 %i7
被调用返回地址 15 被调用子程序的返回地址。 %o7

从上表可以看出,每个寄存器至少有两个名称,其中一些特殊用途寄存器有三个名称。对于给定寄存器,任何可用的名称在任何使用上下文中都是完全可以接受的,由程序员决定在任何特定时间使用哪些名称。此外,不建议以与预期目的不同的方式使用堆栈和帧指针寄存器,这会导致程序中的严重功能问题。

SPARC 处理器还包含一组浮点寄存器和少量特殊用途寄存器。(此处需要进一步说明)

取指和执行指令周期

[编辑 | 编辑源代码]

延迟分支

[编辑 | 编辑源代码]

SPARC 处理器是流水线的,分支是通过一种称为延迟分支执行的技术实现的。控制转移指令(CTI)是任何更改当前程序计数器的指令。例如,jmp 或 call 指令是 CTI 指令。

在 SPARC 中,当执行 CTI 指令时,跳转不会立即处理。相反,在执行分支之前会延迟一个周期。这意味着跳转指令后的第一条指令实际上是在分支发生之前处理的。以下是一个例子

add %r3, %r2, %r5
jmp SetR5ToZero
add %r4, %r5, %r2

请注意,最后一条指令是在跳转发生之前执行的,而不是在子程序返回之后执行的。跳转后的第一条指令称为延迟槽。通常的做法是在延迟槽中填充一个不执行任何任务的特殊操作,称为无操作,或nop

指令
nop

此指令不执行任何操作,因此我们不必担心它执行的顺序。但是,如果我们在每个分支指令之后都放置一个 nop,我们将浪费大量的处理器周期。因此,如果可以,始终最好尝试将额外的指令挤入延迟槽,这样我们就不会浪费任何处理器周期。

华夏公益教科书