SPARC 汇编/SPARC 细节
外观
< SPARC 汇编
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,我们将浪费大量的处理器周期。因此,如果可以,始终最好尝试将额外的指令挤入延迟槽,这样我们就不会浪费任何处理器周期。