繁体   English   中英

在7条指令中编译C到MIPS汇编?

[英]Compile C to MIPS Assembly in 7 instructions?

我刚参加了期末考试,鉴于这些限制,有一个问题似乎是不可能的。 我很高兴被证明是错的,但据我检查过,至少所有同学都同意我的结论。 这是我提供的问题和答案:

AC程序片段提供如下:

c = a + b + 6;
while (c > 5) {
  c = c - a;
  b = b + 1;
}

使用最多7条指令在MIPS汇编中写入等效项,仅使用以下指令集:

add, addi, sub, subi, slt, slti, bne

a,b和c分别可通过寄存器$ t0,$ t1和$ s0访问。 您可以根据需要使用其他寄存器,但您可能不会假设任何初始值。

这是我尽可能少的答案给出的答案:

      add $s0, $t0, $t1
      addi $s0, $s0, 6
loop: slti $t2, $s0, 6
      bne $t2, $0, skip
      sub $s0, $s0, $t0
      addi $t1, $t1, 1
skip: subi $t2, $t2, 1
      bne $t2, $0, loop

在3小时的考试中我想了30分钟,我想出了教授可能会误解问题的两种可能性。 我更可能的是他期待我们编写一个do-while循环。 另一个不太可能是我们被允许除了其他指令之外还使用beq 以下是我对这些问题的答案:

这样做,虽然:

      add $s0, $t0, $t1
      addi $s0, $s0, 6
loop: sub $s0, $s0, $t0
      addi $t1, $t1, 1
      slti $t2, $s0, 6
      subi $t2, $t2, 1
      bne $t2, $0, loop

beq允许:

      add $s0, $t0, $t1
      addi $s0, $s0, 6
loop: slti $t2, $s0, 6
      bne $t2, $0, skip
      sub $s0, $s0, $t0
      addi $t1, $t1, 1
skip: beq $t2, $0, loop

我挑战任何人找到一个较短的答案或最终证明一个较短的答案是不可能的,这一直困扰我很多。

更新

我和我的教授一起回顾了我的最后成绩,虽然他拒绝提供答案,但他声称有一半的课程是正确的。 我发现我的教授没有提供现有答案的证据,同时使用它作为从我的考试中扣除分数的依据,这是不公平的,但我没有太多可以证明我的观点,并且考虑到这一点并不明智。在最终的低平均曲线上,我的班级获得了4.0。

我仍然持怀疑态度,因为我发现他在我的Verilog代码片段中发现了一个我已经完全归功于我的最终评价,因此我找到了一个因MIPS汇编问题而得到充分肯定的人。 他告诉我他的策略但不记得他的确切答案所以我帮他重新创建它,基于@ Smac89的答案:

      addi $t2, $t0, 6   # d = a + 6
      add $s0, $t2, $t1  # c = d + b
      bne $t2, $t0, comp # (d != a) ? comp
loop: sub $s0, $s0, $t0  # c = c - a;
      addi $t1, $t1, 1   # b = b + 1;
comp: slti $t2, $s0, 6   # d = (c < 6)
      subi $t2, $t2, 1   # invert the flag
      bne $t2, $0, loop  # !(c < 6) ? loop

所以,这也不起作用。 他采用的具体策略是他在循环顶部有一个保证分支,并且他在两行检查底部的条件。 不过,我不能想办法用sltslti创建一个有效的标志检查与bne 教授可能会在7行中对他所尝试的任何事情进行评估。

总之,我仍然没有答案。

建立Smac89的答案,这保证了C不是0,除非循环完成,因此C的值可用于分支。

      add  $s0, $t0, $t1    # c = a + b
loop: slti $t2, $s0, 0      # while (is c less than 0? 
      bne  $t2, $zero, exit # (c > 5)
      sub  $s0, $s0, $t0    # c = c - a;
      addi $t1, $t1, 1      # b = b + 1;
      bne  $t2, $s0, loop   # Loop again unless s0 is 0 -- then we're done
exit: addi $s0, $s0, 6      # add the missing 6 

那这个呢?

      addi $s1, $t0, 6     # d = a + 6
      add $s0, $s1, $t1    # c = d + b
loop: slti $t2, $s0, 6     # while (is c less than 6? i.e. c is not greater than 5) 
      bne $t2, $zero, exit # (c <= 5)? exit
      sub $s0, $s0, $t0    # c = c - a;
      addi $t1, $t1, 1     # b = b + 1;
      bne $s1, $t0, loop   # (True condition to loop: d != a)
exit:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM