【问题标题】:C to MIPS translation: decoderC 到 MIPS 的翻译:解码器
【发布时间】:2019-07-21 19:14:27
【问题描述】:

我们得到以下 C 代码,并要求将其翻译成 MIPS。我们不需要处理 lo 和 hi;它们为我们存储在 $a0 和 $a1 中:

void decode_request(unsigned long int request, int* array) {

   // lo and hi are already stored for us in $a0 and $a1
  unsigned lo = (unsigned)((request << 32) >> 32);
  unsigned hi = (unsigned)(request >> 32);

  for (int i = 0; i < 6; ++i) {
    array[i] = lo & 0x0000001f;
    lo = lo >> 5;
 }
  unsigned upper_three_bits = (hi << 2) & 0x0000001f;
  array[6] = upper_three_bits | lo;
  hi = hi >> 3;

  for (int i = 7; i < 11; ++i) {
    array[i] = hi & 0x0000001f;
    hi = hi >> 5;
  }

这是我的尝试:

.globl decode_request
decode_request:
    li      $t0, 0      # int i = 0;

first_loop:
    bge $t0, 6, after_first_loop    # branch if greater than or equal to 6
    mul $t0, $t0, 4 # account for ints; storage size = word
    and $t1, $a0, 0x0000001f # lo & 0x0000001f;
    sw $t1, 4($t1) # array[i] = lo & 0x0000001f;
    srl $t2, $a0, 5 # lo >> 5;
    sw $t2, 0($t2) # lo = lo >> 5;
    add $t0, $t0, 1 # ++i
    j first_loop # jump back to top of loop

after_first_loop:
    sll $t3, $a1, 2 # (hi << 2)
    and $t3, $t3, 0x0000001f # & 0x0000001f
    mul $t3, $t3, 4 # account for ints; storage size = word
    sw $t3, 0($t3) # store back into memory
    or $t4, $t3, $a0 # array[6] = upper_three_bits | lo;
    sw $t4, 24($t4) # store back into memory; use 24 since int = 4 bytes and we have offset of 6
    srl $a1, $a1, 3 # hi >> 3;
    sw $a1, 0($a1) # hi = hi >> 3;

second_loop:
    li $t5, 7 # int i = 7;
    bge $t0, 11, end    # branch if greater than or equal to 11
    mul $t5, $t5, 4  # account for ints; storage size = word
    and $t6, $a1, 0x0000001f # hi & 0x0000001f
    sw $t6, 4($t6) # array[i] = hi & 0x0000001f;
    srl $t7, $a0, 5 # hi >> 5;
    sw $t7, 0($t7) # lo = lo >> 5;
    add $t5, $t5, 1 # ++i
    j second_loop # jump back to top of second_loop
end:
    jr  $ra

关于我可能出错的地方或其他方法的任何想法?

谢谢!

【问题讨论】:

  • 在您的程序中什么不起作用?你试过在上面使用调试器吗?
  • 我试过在上面运行 QtSpim,是的。不过,我对 MIPS 还是有点陌生​​,所以我不确定如何解释这些错误。
  • 为什么不直接使用 gcc?
  • @Swordfish,会不会是因为它可以是家庭作业?不回头寻找解决方案会是一种挑战吗?

标签: c mips code-translation


【解决方案1】:

我已更正了您代码的第一部分。并且 80%​​ 的指令在语法上不正确。这是 asm 应该告诉你的。还有很多很多逻辑错误。 主要之一是您需要管理数组元素的地址。

decode_request:
    li      $t0, 0      # int i = 0;
### we assume $t4=@array and $t5=array[i]

    add $t5, $t4, zero  ## t5=&array[0]
first_loop:
### bge is bge reg1, reg2, offset. Cant use an immediate
### slti does a compare and then a branch is possible
    sltiu $t1, $t0, 6                  # i<6 ?
    beq $t0, zero, after_first_loop    # false ? goto end first loop
### i=i*4??? what is it supposed to do?
####mul $t0, $t0, 4 # account for ints; storage size = word
### and $t1, $a0, 0x0000001f ... should be andi
    andi $t1, $a0, 0x0000001f # lo & 0x0000001f;
### not sw $t1, 4($t1) which does not make sense
### array[i] is $t5 and data to store is $t1
    sw $t1, 0($t5) # array[i] = lo & 0x0000001f;
    srl $t2, $a0, 5 # lo >> 5;
### why do you want to store lo? Just keep it is register $t2.
### And your store is anyway incorrect. Should be sw $t2,0($t6) 
####                           where $t6 is the address of lo
##    sw $t2, 0($t2) # lo = lo >> 5;
### add add $t0 ... should be addi
    addi $t0, $t0, 1 # ++i
#### and you must increment array address
    addi $t5, $t5, 4 # $t5++ -> $t5==array[i+1]
    j first_loop # jump back to top of loop

现在尝试更正程序的其余部分。 asm 中的错误应该是明确的。

【讨论】:

    【解决方案2】:

    我使用 Alain 的修正来尝试做第二个循环

    loop_two:
    # these loops go from 0-5 and then from 7-10
    # since t5 has been incremented each time, $t5 = array[5]
    # have to add 8 to get $t5 = array[7]
    # do this in between_loops
    slti $t7, $t6, 11              # i < 11 ?
    beq $t6, zero, end                       # if false, done with loop, go to end
    
    # loop body goes here
    andi $t6, $a1, 0x0000001f        # hi & 0x0000001f
    # array[i] is $t5 and data to store is $t6
    sw $t6, 0($t5)                               # array[i] = hi & 0x0000001f;
    srl $t7, $a0, 5                              # hi >> 5;
    add $t6, $t6, 1                                 # ++i
    addi $t5, $t5, 4                                # increment array address, $t5++ -> $t5==array[i+1]
    j loop_two
    

    这假设下面的代码是在 decode_request 中声明的

    li $t6, 7   # t3 is our second counter (int i = 7)
    

    【讨论】:

      猜你喜欢
      • 2013-09-23
      • 1970-01-01
      • 2016-01-15
      • 1970-01-01
      • 2020-07-28
      • 1970-01-01
      • 1970-01-01
      • 2018-10-22
      • 1970-01-01
      相关资源
      最近更新 更多