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

时间:2015-07-08 16:05:46

标签: c assembly mips mips32

我是一名硕士生,目前正在做我的夏季最终项目,该项目是关于设计带有FPU的MIPS处理器并在FPGA中实现。

我要实施的说明取决于我使用的交叉编译器。所以,从硬件设计师的角度来看,我通过首先查看可以从编译器生成的指令启动项目。

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

touchpad='SynPS/2 Synaptics TouchPad id=14 [slave pointer (2)]'
sed -r 's~.*TouchPad id=([0-9]+).*~\1~' <<< "$touchpad"
14

一个简单的补充,编译器提供汇编代码:(我刚刚在main发布了汇编代码,因为我没打算在我的MIPS上运行操作系统)

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

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

我们可以从这4条指令中看到:

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

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

好的,让我们去浮点单位,就像我一样,我写了一个非常相似的C:

浮点测试C代码

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

现在汇编代码差异很大:

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

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

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

出现了问题,我无法弄清楚-32764(gp)和f0,-32760(gp)中存储的值是什么,因为没有任何SW指令尝试将数据存储到那些地址

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

  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)

我不擅长MIPS汇编,有人可以解释一下浮点变量&#39;值1和2?

1 个答案:

答案 0 :(得分:4)

关于您的问题

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

对于MIPS系统上的ELF,你应该参考this哪里有这个漂亮的图片:

MIPS ELF Sections

正如您所看到的,$gp用于解决 .sdata .sbss 部分,其中最初的 s 代表对于

所有这些努力都是为了最小化代码大小,因为使用$gp编译器可以生成16位偏移(相对于通常使用的32位偏移)。 由于偏移已签名,$gp位于由 .sdata + .sbss 形成的(最多)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