数据存储器中缺少浮点变量值

Floating point variable's value missing in data memory

我是一名硕士生,目前正在做我的暑期期末项目,这是关于设计一个带有 FPU 的 MIPS 处理器并在 FPGA 中实现的。

我要执行的指令取决于我使用的交叉编译器。因此,从硬件设计师的角度来看,我首先查看可以从编译器生成的指令来开始该项目。

对于整数设计(主要核心设计),我写了一些C代码,这里以简单的为例:

int main ()
{
int a,b,c;
a=1;
b=2;
c=a+2;
}

一个简单的补充,编译器给出了汇编代码:(我只是把汇编代码贴在main里面,因为我没打算运行我的MIPS操作系统)

00400168 <main>:
  400168:       27bdffe8        addiu   sp,sp,-24
  40016c:       afbe0010        sw      s8,16(sp)
  400170:       03a0f021        move    s8,sp
  400174:       24020001        li      v0,1
  400178:       afc20008        sw      v0,8(s8)
  40017c:       24020002        li      v0,2
  400180:       afc20004        sw      v0,4(s8)
  400184:       8fc20008        lw      v0,8(s8)
  400188:       00000000        nop
  40018c:       20420002        addi    v0,v0,2
  400190:       afc20000        sw      v0,0(s8)
  400194:       03c0e821        move    sp,s8
  400198:       8fbe0010        lw      s8,16(sp)
  40019c:       27bd0018        addiu   sp,sp,24
  4001a0:       03e00008        jr      ra

我喜欢看汇编代码,可以帮助我更好地理解MIPS架构,并且可以根据指令顺序设计基于编译器的危险检测单元。

从这4条指令可以看出:

  400174:       24020001        li      v0,1
  400178:       afc20008        sw      v0,8(s8)
  40017c:       24020002        li      v0,2
  400180:       afc20004        sw      v0,4(s8)

编译器将1、2加载到变量a、b中。 对于整数汇编代码,我能理解没有问题。

好的,让我们转到浮点单元,同样,我写了一个非常相似的C :

浮点测试C代码

void main ()
{
float a,b,c;
a=1;
b=2;
c=a+b;
}

现在汇编代码有很大不同:

00400168 <main>:
  400168:       27bdffe8        addiu   sp,sp,-24
  40016c:       afbe0010        sw      s8,16(sp)
  400170:       03a0f021        move    s8,sp
  400174:       c7808004        lwc1    $f0,-32764(gp)
  400178:       00000000        nop
  40017c:       e7c00008        swc1    $f0,8(s8)
  400180:       c7808008        lwc1    $f0,-32760(gp)
  400184:       00000000        nop
  400188:       e7c00004        swc1    $f0,4(s8)
  40018c:       c7c20008        lwc1    $f2,8(s8)
  400190:       c7c00004        lwc1    $f0,4(s8)
  400194:       00000000        nop
  400198:       46001000        add.s   $f0,$f2,$f0
  40019c:       e7c00000        swc1    $f0,0(s8)
  4001a0:       03c0e821        move    sp,s8
  4001a4:       8fbe0010        lw      s8,16(sp)
  4001a8:       27bd0018        addiu   sp,sp,24
  4001ac:       03e00008        jr      ra
  4001b0:       00000000        nop

不喜欢之前的代码,这 6 条指令看起来像是程序从数据存储器加载变量的值,而不是使用指令 li:

  400174:       c7808004        lwc1    $f0,-32764(gp)
  400178:       00000000        nop
  40017c:       e7c00008        swc1    $f0,8(s8)
  400180:       c7808008        lwc1    $f0,-32760(gp)
  400184:       00000000        nop
  400188:       e7c00004        swc1    $f0,4(s8)

问题来了,我只是想不通-32764(gp)和f0,-32760(gp)中存储的值是什么,因为没有任何SW指令试图将数据存储到这些地址。

编译器生成的完整汇编代码如下:

floatadd:     file format elf32-bigmips


Disassembly of section .init:

00400018 <_init>:
  400018:       27bdffe0        addiu   sp,sp,-32
  40001c:       afbf0014        sw      ra,20(sp)
  400020:       0c10003a        jal     4000e8 <frame_dummy>
  400024:       00000000        nop
  400028:       0c10006d        jal     4001b4 <__do_global_ctors_aux>
  40002c:       00000000        nop
  400030:       8fbf0014        lw      ra,20(sp)
  400034:       27bd0020        addiu   sp,sp,32
  400038:       03e00008        jr      ra
  40003c:       00000000        nop

Disassembly of section .text:

00400040 <_ftext>:
  400040:       27bdffe0        addiu   sp,sp,-32
  400044:       afb10014        sw      s1,20(sp)
  400048:       3c110040        lui     s1,0x40
  40004c:       9222126c        lbu     v0,4716(s1)
  400050:       afbf0018        sw      ra,24(sp)
  400054:       14400019        bnez    v0,4000bc <_ftext+0x7c>
  400058:       afb00010        sw      s0,16(sp)
  40005c:       3c100040        lui     s0,0x40
  400060:       8e021260        lw      v0,4704(s0)
  400064:       00000000        nop
  400068:       8c430000        lw      v1,0(v0)
  40006c:       00000000        nop
  400070:       10600009        beqz    v1,400098 <_ftext+0x58>
  400074:       24420004        addiu   v0,v0,4
  400078:       0060f809        jalr    v1
  40007c:       ae021260        sw      v0,4704(s0)
  400080:       8e021260        lw      v0,4704(s0)
  400084:       00000000        nop
  400088:       8c430000        lw      v1,0(v0)
  40008c:       00000000        nop
  400090:       1460fff9        bnez    v1,400078 <_ftext+0x38>
  400094:       24420004        addiu   v0,v0,4
  400098:       3c020000        lui     v0,0x0
  40009c:       24420000        addiu   v0,v0,0
  4000a0:       10400005        beqz    v0,4000b8 <_ftext+0x78>
  4000a4:       24020001        li      v0,1
  4000a8:       3c040040        lui     a0,0x40
  4000ac:       0c000000        jal     0 <_init-0x400018>
  4000b0:       24840244        addiu   a0,a0,580
  4000b4:       24020001        li      v0,1
  4000b8:       a222126c        sb      v0,4716(s1)
  4000bc:       8fbf0018        lw      ra,24(sp)
  4000c0:       8fb10014        lw      s1,20(sp)
  4000c4:       8fb00010        lw      s0,16(sp)
  4000c8:       03e00008        jr      ra
  4000cc:       27bd0020        addiu   sp,sp,32

004000d0 <call___do_global_dtors_aux>:
  4000d0:       27bdffe8        addiu   sp,sp,-24
  4000d4:       afbf0010        sw      ra,16(sp)
  4000d8:       8fbf0010        lw      ra,16(sp)
  4000dc:       00000000        nop
  4000e0:       03e00008        jr      ra
  4000e4:       27bd0018        addiu   sp,sp,24

004000e8 <frame_dummy>:
  4000e8:       3c020000        lui     v0,0x0
  4000ec:       27bdffe8        addiu   sp,sp,-24
  4000f0:       3c040040        lui     a0,0x40
  4000f4:       3c050040        lui     a1,0x40
  4000f8:       24420000        addiu   v0,v0,0
  4000fc:       afbf0010        sw      ra,16(sp)
  400100:       24840244        addiu   a0,a0,580
  400104:       10400003        beqz    v0,400114 <frame_dummy+0x2c>
  400108:       24a51270        addiu   a1,a1,4720
  40010c:       0c000000        jal     0 <_init-0x400018>
  400110:       00000000        nop
  400114:       3c040040        lui     a0,0x40
  400118:       8c831258        lw      v1,4696(a0)
  40011c:       3c020000        lui     v0,0x0
  400120:       10600007        beqz    v1,400140 <frame_dummy+0x58>
  400124:       24590000        addiu   t9,v0,0
  400128:       24841258        addiu   a0,a0,4696
  40012c:       13200004        beqz    t9,400140 <frame_dummy+0x58>
  400130:       00000000        nop
  400134:       8fbf0010        lw      ra,16(sp)
  400138:       03200008        jr      t9
  40013c:       27bd0018        addiu   sp,sp,24
  400140:       8fbf0010        lw      ra,16(sp)
  400144:       00000000        nop
  400148:       03e00008        jr      ra
  40014c:       27bd0018        addiu   sp,sp,24

00400150 <call_frame_dummy>:
  400150:       27bdffe8        addiu   sp,sp,-24
  400154:       afbf0010        sw      ra,16(sp)
  400158:       8fbf0010        lw      ra,16(sp)
  40015c:       00000000        nop
  400160:       03e00008        jr      ra
  400164:       27bd0018        addiu   sp,sp,24

00400168 <main>:
  400168:       27bdffe8        addiu   sp,sp,-24
  40016c:       afbe0010        sw      s8,16(sp)
  400170:       03a0f021        move    s8,sp
  400174:       c7808004        lwc1    $f0,-32764(gp)
  400178:       00000000        nop
  40017c:       e7c00008        swc1    $f0,8(s8)
  400180:       c7808008        lwc1    $f0,-32760(gp)
  400184:       00000000        nop
  400188:       e7c00004        swc1    $f0,4(s8)
  40018c:       c7c20008        lwc1    $f2,8(s8)
  400190:       c7c00004        lwc1    $f0,4(s8)
  400194:       00000000        nop
  400198:       46001000        add.s   $f0,$f2,$f0
  40019c:       e7c00000        swc1    $f0,0(s8)
  4001a0:       03c0e821        move    sp,s8
  4001a4:       8fbe0010        lw      s8,16(sp)
  4001a8:       27bd0018        addiu   sp,sp,24
  4001ac:       03e00008        jr      ra
  4001b0:       00000000        nop

004001b4 <__do_global_ctors_aux>:
  4001b4:       3c020040        lui     v0,0x40
  4001b8:       2442124c        addiu   v0,v0,4684
  4001bc:       8c44fffc        lw      a0,-4(v0)
  4001c0:       27bdffe0        addiu   sp,sp,-32
  4001c4:       2403ffff        li      v1,-1
  4001c8:       afb00010        sw      s0,16(sp)
  4001cc:       afbf0018        sw      ra,24(sp)
  4001d0:       afb10014        sw      s1,20(sp)
  4001d4:       10830008        beq     a0,v1,4001f8 <__do_global_ctors_aux+0x44>
  4001d8:       2450fffc        addiu   s0,v0,-4
  4001dc:       2411ffff        li      s1,-1
  4001e0:       0080f809        jalr    a0
  4001e4:       2610fffc        addiu   s0,s0,-4
  4001e8:       8e040000        lw      a0,0(s0)
  4001ec:       00000000        nop
  4001f0:       1491fffb        bne     a0,s1,4001e0 <__do_global_ctors_aux+0x2c>
  4001f4:       00000000        nop
  4001f8:       8fbf0018        lw      ra,24(sp)
  4001fc:       8fb10014        lw      s1,20(sp)
  400200:       8fb00010        lw      s0,16(sp)
  400204:       03e00008        jr      ra
  400208:       27bd0020        addiu   sp,sp,32

0040020c <call___do_global_ctors_aux>:
  40020c:       27bdffe8        addiu   sp,sp,-24
  400210:       afbf0010        sw      ra,16(sp)
  400214:       8fbf0010        lw      ra,16(sp)
  400218:       00000000        nop
  40021c:       03e00008        jr      ra
  400220:       27bd0018        addiu   sp,sp,24

Disassembly of section .fini:

00400224 <_fini>:
  400224:       27bdffe0        addiu   sp,sp,-32
  400228:       afbf0014        sw      ra,20(sp)
  40022c:       0c100010        jal     400040 <_ftext>
  400230:       00000000        nop
  400234:       8fbf0014        lw      ra,20(sp)
  400238:       27bd0020        addiu   sp,sp,32
  40023c:       03e00008        jr      ra
  400240:       00000000        nop

我不擅长 MIPS 汇编,谁能解释一下浮点变量的值 1 和 2 在哪里?

关于你的问题

ELF 可执行文件可以有一个或多个部分填充程序使用的静态数据(字符串、浮点数、数字等)。
这些部分由加载程序与程序的其余部分一起加载到内存中,从而避免代码和数据混合并减少代码大小。

对于 MIPS 系统上的 ELF,您应该参考 this 那里有这张漂亮的图片:

如您所见,$gp 用于寻址 .sdata.sbss 部分,其中初始 s代表small.

所有这些努力都是为了最小化代码大小,因为通过使用 $gp 编译器可以生成 16 位偏移量(与通常使用的 32 位偏移量相比)。
由于偏移量是有符号的,$gp 位于由 .sdata + .sbss[=51 形成的(最多)64 KiB 区域的中间=].

您的浮点值没有直接编码在指令中,因为 FP 指令 does not takes immediates,而是将它们保存到只读部分并从那里加载。

关于你的目的

你到底为什么关心这个?
如果您的目标是设计 MIPS ISA 的实现,只需选择特定的 ISA(MIPS32 I?MIPS32 IV?MIPS 64?),获取文档,全面了解并为其实现微体系结构。

如果根据您选择的 ISA 指令是有效指令,那么您的实现必须能够执行它,不要担心编译器在做什么,他们已经长大了,他们可以自己照顾自己最后,如果您正在执行的代码被破坏了,谁在乎呢?只要有效。

这些对你有帮助:

MIPS32™ Architecture For Programmers Volume I: Introduction to the MIPS32™ Architecture MIPS32™ Architecture For Programmers Volume II: The MIPS32™ Instruction Set