【问题标题】:Converting to MIPS assembly Language with arrays使用数组转换为 MIPS 汇编语言
【发布时间】:2016-12-22 06:38:38
【问题描述】:

不擅长转换,尤其是转换为 MIPS 汇编语言。

这是原始代码:

void swap(int v[], int k, int j) { 
int temp; 
temp = v[k]; 
v[k] = v[j]; 
v[j] = temp; 
}

在一些帮助下,我们设法做到了这一点,现在我需要将其转换为 MIPS 汇编代码,刚刚学习完 Java 仍然是个菜鸟。欢迎任何帮助。

k = k << 2;
k = k + v
j = j << 2;
j = j + v
temp0 = load(k)
temp1 = load(j)
store(k) = temp1
store(j) = temp0

【问题讨论】:

  • 想一想编译器是如何实现它的:它只是布置了一堆连续的内存空间并保存了指向第一个内存空间的指针。为了计算地址,您只需计算一个偏移量 - 例如索引 0 是 0 * 32 (0) 的偏移量,索引 1 是 1* 32,索引 2 是 2 * 32,等等。(顺便说一句,从 C 到 MIPS 汇编语言比从 Java 到 MIPS 汇编语言容易得多) .

标签: c# arrays assembly mips pipeline


【解决方案1】:

好的,这是汇编。它基于上面的伪代码,但我是从头开始编写的,基于顶部的 HLL。

符合 mips ABI。因此,可以随意更改(即销毁)参数寄存器。因此,如果在循环中调用,调用者必须在每次调用之前设置a0-a3

#   void
#   swap(int v[],int k,int j)
#   {
#       int temp;
#
#       temp = v[k];
#       v[k] = v[j];
#       v[j] = temp;
#   }

# swap -- swap two elements in an array
#
# arguments:
#   a0 -- pointer to array
#   a1 -- array index "k"
#   a2 -- array index "j"
#
# registers:
#   t0 -- v[k]
#   t1 -- v[j]
swap:
    sll     $a1,$a1,2               # k <<= 2 (i.e. byte offset)
    addu    $a1,$a1,$a0             # get address of v[k]

    sll     $a2,$a2,2               # j <<= 2 (i.e. byte offset)
    addu    $a2,$a2,$a0             # get address of v[j]

    lw      $t0,0($a1)              # fetch v[k]
    lw      $t1,0($a2)              # fetch v[j]

    sw      $t1,0($a1)              # v[k] = v[j]
    sw      $t0,0($a0)              # v[j] = v[k]

    jr      $ra                     # return

更新:

我知道sll 代表左移。 addu 代表什么?

u“后缀”代表无符号。但是,不像在很多其他地方都使用过。

[add] 有两个版本。 签名版本是add未签名版本是addu。它们产生完全相同相同的结果,因为它们都执行相同的补码加法。

唯一的区别是,如果加法导致溢出,add 将生成处理器异常(例如“算术溢出”),但addu 不会 --它只会换行。 sub 和下溢也类似。

例如,如果一个寄存器中包含0x7FFFFFFF,而您在其中添加一个,则会导致溢出。那是因为你从最大的签名 positive 值开始,你添加一个到它,并且 voila 你在最大签名值(即称为溢出的“量子飞跃”)。

因此,当添加可能合法溢出的东西时(例如,在 32 位中“换行”),例如地址计算,最好使用无符号版本。

这是因为,在 mips 中,程序 [code/data/stack] 的某些部分可能会在 0x80000000 或更高处加载。

例如,堆栈可能从0x80001000 开始,如果您将足够多的数据压入其中(即$sp 寄存器正以sub 递减),它最终会到达0x80000000 的附近。当你在这个地址附近 push/pop 时,你会得到溢出/下溢。

没有错--这是很自然的,并且您不希望处理器在您执行sub 进行推送操作时生成异常,因此您使用subu [和/或指令subiu立即形式]。

如果您还没有找到它,这里有一个很好的指令集参考 [很多人使用]:http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html 它很容易阅读,涵盖了您可能需要的大部分指令/使用。

以下是 ABI 调用约定的简要概述:http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Mips/altReg.html

【讨论】:

  • 嘿@CraigEstey,非常感谢,你每天都能学到新东西。只是一个查询,我知道“sll”代表左移。 “addu”代表什么??
  • sll 代表“逻辑左移”
猜你喜欢
  • 1970-01-01
  • 2014-08-16
  • 1970-01-01
  • 2021-08-22
  • 2019-08-03
  • 2013-11-21
  • 2020-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多