Перевод C на MIPS: декодер - PullRequest
       30

Перевод C на MIPS: декодер

0 голосов
/ 28 февраля 2019

Мы получили следующий код на C и попросили перевести его на MIPS.Нам не нужно обращаться с Ло и Привет;они хранятся для нас в $ 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

Любые идеи относительно того, где я могу пойти не так, иливозможно другие подходы?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Я использовал исправления Алена, чтобы попытаться выполнить второй цикл

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)
0 голосов
/ 28 февраля 2019

Я исправил первую часть вашего кода.И 80% инструкций там, где синтаксически неверно.Это то, что асм должен был сказать вам.И много-много логических ошибок.Одним из основных является то, что вам нужно управлять адресами элементов массива.

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 должны быть явными.

...