计算机体系结构:使用MIPS交换变量

时间:2016-05-26 12:36:08

标签: architecture mips

我错过了关于这个主题的课程,因为我不在国内,而且我无法获得笔记。你可以带着这个问题引导我正确的方向吗?我使用MIPS已经有一段时间了,所以它对我来说基本上是一种外语:D

家庭作业问题:

MIPS架构支持字节和半字(16位)存储器传输操作。指令是加载字节(lb),加载字节无符号(lbu),存储字节(sb),加载半字(lh),加载半字无符号(lhu)和存储半字(sh)。

代码: char a,b; // 8位变量(@地址100)(b @地址200)

部分a)假设支持8位操作(lb,lbu,sb),编写一个交换变量的代码。

部分b)如果MIPS不支持字节和半字操作,那么我们只能使用'加载字'(lw)和'存储字'(sw),它们是32位操作。因此,仅使用(lw,sw)作为内存传输指令重写上面的代码。

注意:我真的不是在找你为我解决,我只是不知道该怎么办。我在C中编写交换函数然后转换为MIPS还是我过于复杂?谢谢!

1 个答案:

答案 0 :(得分:2)

首先编写C代码并将其用作mips程序集的伪代码是一种很好的方法。

然后,将C代码缩减为我所称的"简单的C"。没有whilefor或复杂的表达式。没有局部变量。只有使用.word定义的内容(如myvar: .word 23)或与mips寄存器对应的变量的全局变量。只有非常简单的if (expr) goto label;

请在此处查看我的答案以获取示例:Struggling with the logic in if statement

请参阅我的答案:MIPS linked list这也提供了一些关于如何编写干净的asm代码的技巧以及如何使用C /伪代码构建asm代码的示例。

因此,对于第一部分,我们正在讨论unsigned char。将值提取到寄存器变量后,应用您在C中执行的标准交换。

对于b部分,请注意地址对齐到4字节边界,因此您可以使用32位访问来获取/存储它们。所以,我们正在谈论unsigned int。皱纹是当交换完成时,必须进行适当的屏蔽/移位/拆分以交换字节,但交换32位字的其余部分,仅使用unsigned int < / p>

因此,首先编写C代码。你可以伪造100/200:

typedef union {
    unsigned int ival;
    unsigned char bval[4];
} membuf_t;

membuf_t adr100;
membuf_t adr200;

这只是为了让您编写真正的 C代码并首先进行测试。对于asm,您只需引用[hardwired]地址(例如0x100($zero))。

但是,100/200假设您只是作为一个思想实验来执行此操作而尝试使用mars之类的模拟器实际调试您的asm代码或spim [因为他们真的不喜欢你在他们模拟的代码中使用这些内存地址]。

如果是我,我会使用mars并编写可以单步执行的代码。为此,再次稍微调整一下:

adr100:     .word   0x01020304
adr200:     .word   0x05060708

然后,在所有工作之后,只需手动替换adr*引用。

<强>更新

我忘了提到的一件事是你必须要注意端点问题。也就是说,对于C代码,当您从adrXXX.ival进行32位提取时,adrXXX.bval [0]的位为0-7(小端)或位24-31(大端)?

假设您在x86 PC上执行C代码,那就是它的小端。 IIRC,mips也是小端,但老实说,我忘了[有些型号可以是大端或可以动态切换]。模拟器[可能]是小端,所以,也许,不用担心。

测试mips(或C)的一种方法是使用额外的测试单元(即创建3-4行一次性测试程序):test: .word 0。获取一个填充0x00000001的寄存器。然后,对test执行字节存储。然后从test执行32位加载。寄存器中的非零字节为您提供了机器的字节序(即它位于0-7位或24-31位)。

相关问题