MIPS寄存器$ 0可以用于存储和检索值吗? [英] Can the MIPS register $0 be used to store and retrieve values?

查看:309
本文介绍了MIPS寄存器$ 0可以用于存储和检索值吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我了解MIPS处理器时,它被深深地吸引住了,读取$ 0寄存器总是返回0,而写入$ 0总是被丢弃.从MIPS程序员手册中:

When I learned about the MIPS processor, it was pounded into my head that reads of the $0 register always return 0, and writes to $0 are always discarded. From the MIPS Programmer's manual:

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

2.13.4.1 CPU General-Purpose Registers [...] r0 is hard-wired to a value of zero, and can be used as the target register for any instruction whose result is to be discarded. r0 can also be used as a source when a zero value is needed.

由此可知,or $0,$r31,$0指令是无操作的.

From this follows that the instructions or $0,$r31,$0 is a no-op.

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

Imagine my surprise when I was poking around in the startup code of an ELF MIPS binary, when I saw the following instruction sequence:

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.

The instruction at address 0x610 is copying the value of $ra into $r0, which according to the paragraph above is tantamount to discarding it. Then, the instruction at address 0x628 is reading the value back from $0, but since $0 is hardwired to 0, it results in setting $ra to 0.

这一切似乎都没有意义:为什么只执行0x628就执行0x610语句. glibc人士在编写此代码时显然有一些意图.看来$ 0毕竟是可写和可读的!

This all seems rather pointless: why execute statement 0x610 when it would be enough to just execute 0x628. The glibc folks clearly had some intent in mind when they wrote this code. It seems as if $0 is writeable and readable after all!

那么在什么情况下程序可以像读其他通用寄存器中的任何一个一样来读写$ 0寄存器?

So under what circumstances can a program read / write to the $0 register as if it were any one of the other general purpose registers?

查看glibc源代码没有帮助. __start的代码 使用宏:

Looking at the glibc source code isn't helpful. The code for __start uses a macro:

https://github.com/bminor /glibc/blob/master/sysdeps/mips/start.S#L80

ENTRY_POINT:
# ifdef __PIC__
    SETUP_GPX($0)
...

请注意,此处是故意指定$ 0的. SETUP_GPX宏在此处定义:

Notice how $0 is deliberately being specified here. The SETUP_GPX macro is defined here:

https://github.com /bminor/glibc/blob/master/sysdeps/mips/sys/asm.h#L75

# 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

"Save old ra"清楚地表明了保存寄存器的意图,但是为什么$ 0?

"Save old ra" clearly signals the intent of saving the register, but why $0?

推荐答案

它正在使用$0,因为在入口点没有保存$ra的理由,因此将其丢弃.由于它是来自宏的手写asm代码,因此通常情况下并没有对其进行优化.

It's using $0 because at the entry point there is no reason to save $ra, so it's just discarded. Since it's hand written asm code coming from a macro, it's not optimized away as would normally be the case.

这篇关于MIPS寄存器$ 0可以用于存储和检索值吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆