Assembly MIPS寄存器$0能否用于存储和检索值?

Assembly MIPS寄存器$0能否用于存储和检索值?,assembly,mips,glibc,Assembly,Mips,Glibc,当我了解到MIPS处理器时,我的脑海中突然闪现出这样一个事实:对$0寄存器的读取总是返回0,而对$0的写入总是被丢弃。从MIPS程序员手册: 2.13.4.1 CPU通用寄存器 [...] r0硬连接到的值为 零,并且可以用作任何指令的目标寄存器 结果将被丢弃。r0也可以用作零时的源 价值是必需的 由此可知,指令或$0、$r31、$0是不可操作的 想象一下,当我翻阅ELF MIPS二进制文件的启动代码时,当我看到以下指令序列时,我会感到惊讶: 00000610 03 E0 00 25 or

当我了解到MIPS处理器时,我的脑海中突然闪现出这样一个事实:对$0寄存器的读取总是返回0,而对$0的写入总是被丢弃。从MIPS程序员手册:

2.13.4.1 CPU通用寄存器 [...] r0硬连接到的值为 零,并且可以用作任何指令的目标寄存器 结果将被丢弃。r0也可以用作零时的源 价值是必需的

由此可知,指令
或$0、$r31、$0
是不可操作的

想象一下,当我翻阅ELF MIPS二进制文件的启动代码时,当我看到以下指令序列时,我会感到惊讶:

00000610 03 E0 00 25   or     $0,$ra,$0
00000614 04 11 00 01   bgezal $0,0000061C
00000618 00 00 00 00   nop
0000061C 3C 1C 00 02   lui    $28,+0002
00000620 27 9C 84 64   addiu  $28,$28,-00007B9C
00000624 03 9F E0 21   addu   $28,$28,$ra
00000628 00 00 F8 25   or     $ra,$0,$0
地址0x610处的指令正在将$ra的值复制到$r0中,根据上面的段落,这相当于丢弃它。然后,地址0x628处的指令正在从$0读回值,但由于$0硬连线为0,因此会将$ra设置为0

这一切似乎都毫无意义:当只执行0x628就足够了时,为什么还要执行语句0x610呢。glibc的人在编写这段代码时显然有一些意图。似乎$0毕竟是可写和可读的

那么,在什么情况下,程序可以像读/写其他通用寄存器一样读/写$0寄存器呢

编辑: 查看glibc源代码没有帮助。
\u启动的代码
使用宏:

注意这里是如何故意指定$0的。SETUP_GPX宏定义如下:


“保存旧ra”清楚地表明了保存寄存器的意图,但为什么是$0?

它使用的是
$0
,因为在入口点没有理由保存
$ra
,所以它被丢弃了。由于它是来自宏的手工编写的asm代码,因此没有像通常情况下那样进行优化。

注意,glibc仅将此用于PIC。(见附件)



MIPS
jal
(与其他
j
指令一样)不是PIC;它用
imm26替换了PC的低28位,这没有什么明显的意义,但是glibc是开源的,所以也许可以检查一下它是从哪里来的?我有过,但代码没有解释为什么要写入$0而不是其他临时寄存器。它是glibc中手工编写的asm吗?你有链接吗?如果没有源代码,这可能只是你正在反汇编的数据,就像它是指令一样。需要确认来源我已经添加了问题来源的链接和副本。我理解
bal
部分;它的x86对应项是
call$+5;弹出ebx
序列,用于在ebx
中构建全局指针。在
bal
之前写入$0似乎毫无意义,这让我很困惑。@JohnKällén:好吧,如果
$0
不总是读取为0,
bal
不可能是
bgezal$0
的伪指令。我认为值得向未来的读者指出,他们想知道在
$0
上有条件分支的意义是什么,作为Jester对你真正问题正确答案的补充。
ENTRY_POINT:
# ifdef __PIC__
    SETUP_GPX($0)
...
# define SETUP_GPX(r)                           \
        .set noreorder;                         \
        move r, $31;     /* Save old ra.  */     \
        bal 10f; /* Find addr of cpload.  */    \
        nop;                                    \
10:                                             \
        .cpload $31;                             \
        move $31, r;                             \
        .set reorder