在7条指令中编译C到MIPS程序集?

在7条指令中编译C到MIPS程序集?,c,mips,compiler-optimization,C,Mips,Compiler Optimization,我刚刚参加了期末考试,有一道题在限制条件下似乎不可能回答。我很高兴被证明是错的,但据我调查,至少我所有的同学都同意我的结论。以下是我提供的问题和答案: C程序段如下所示: 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访问。您

我刚刚参加了期末考试,有一道题在限制条件下似乎不可能回答。我很高兴被证明是错的,但据我调查,至少我所有的同学都同意我的结论。以下是我提供的问题和答案:

C程序段如下所示:

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
addi$t2,$t0,6#d=a+6
加上$s0、$t2、$t1#c=d+b
B$t2、$t0、红利(d!=a)?公司
循环:sub$s0、$s0、$t0#c=c-a;
加上$t1,$t1,1#b=b+1;
薪酬:slti$t2,$s0,6#d=(c<6)
subi$t2,$t2,1#反转旗帜
bne$t2$0,循环#!(c<6)?环
所以,这也不起作用。他采用的具体策略是,他在循环的顶部有一个保证分支,并在两行中检查底部的条件。然而,我想不出一种方法来使用
slt
slti
创建一个有效的标志来检查
bne
。教授可能在7行中对他尝试的任何东西进行了错误的评分

总之,我仍然没有答案。

这个怎么办

      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:
addi$s1,$t0,6#d=a+6
加上$s0、$s1、$t1#c=d+b
循环:slti$t2,$s0,6#while(c是否小于6?即c不大于5)

bne$t2,$zero,exit#(c基于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 

取决于,a、b和c是有符号的还是无符号的?如果a和b是无符号的,它可以简化为
do…while();
,因为c的起始值总是大于5。另外,(我认为)通过一些数学运算,你可以将+6向下拉到条件中。基于允许的指令是用于有符号整数的事实,我会有根据地猜测a、b和c是有符号的。无论如何,你都不能假设c大于5,因为可能存在整数溢出。请记住,尽管我所说的一切是考试中给我的唯一信息。你不能做的原因是因为你在使用循环。非常确定你可以在恒定时间内解决这个问题。@xaxxon请详细说明,我不确定我是否理解你的意思。b+6-(X*a)>5——解X,所以b=b+X和C=C-X*a——这里可能有一些一个接一个的错误。我不知道你是否能在小于7 MIPS的指令中做到这一点好,但是b>0又和循环有什么关系呢?这不应该是一个“while true”吗类型语句?不能使用
b
指令或
j
,所以有点抓紧它的羽毛。甚至不确定它是使用的最佳条件。你知道t2的值,对吗?为什么不在最后一行使用它呢?我知道你在尝试做什么。我喜欢这个想法,但因为我包括了整数溢出和/或b的可能性作为有符号的,我不能假设它的后增量值大于0。这是一个很好的尝试。@xaxxon,是的,t2的值在那一点上是0,但我必须使用
bne
。bne允许使用立即值吗?我可以做
bne$t2,1,loop
?我试图考虑一些可能会使这一点无效的边缘情况,但它是无效的就我所知,似乎可以工作。我想你甚至不需要第6行中的t2。只需使用$0。只需两个小的更正,你需要将第7行中的
add
更改为
addi
,因为它需要立即值。你也可以将
slti
更改为
slt
并使用$0,如果你愿意的话,但这只是个人喜好.我会在明天早上醒来的时候考虑这个问题,如果我还喜欢的话,我会接受的。这是一个投票结果。谢谢。正如你指出的,我不知道mips asm--我只是想理解概念,而不是语法:)现在我明白了,再看一遍文档。修复了add/addi.Ooh。。我刚刚意识到,第6行的
bne
不正确。公共边情况:当c正好为0时,将其加回到大于5的6,在这种情况下,它应该再次循环。不过还是不错的尝试。