QtSpim Assembler: Ошибка при работе со стеком с двойным - PullRequest
0 голосов
/ 12 июня 2018

Я пишу программу для класса.Он берет x и epsilon из консоли и должен получить приближение sin (x).Когда я запускаю его в QtSpim, я получаю ошибку:

Неизвестный тип инструкции: 0

Ошибка возникает здесь:

 floatsin:    addi    $sp, $sp, -64   # Frame
              sw      $ra, 64($ra)
              sw      $fp, 60($sp)
              s.d     $f0, 56($sp)
              s.d     $f4, 48($sp)
              s.d     $f20, 40($sp)
              s.d     $f8, 32($sp)
              s.d     $f10, 24($sp)
              s.d     $f14, 16($sp)
              s.d     $f18, 8($sp)        # ERROR HERE
              addi    $fp, $sp, 64

Что можетбыть причиной?Я в замешательстве, потому что до s.d $f18 все работает нормально.Спасибо за любые подсказки!

Ниже полной программы:

.data
xinput:      .asciiz "\nPlease enter x\n"
epsinput:    .asciiz "\nPlease enter epsilon\n"
sinxoutput:  .asciiz "\nsin(x) is: "

.text

main: la    $a0, xinput
      li    $v0, 4
      syscall
      li    $v0, 7
      syscall
      mov.d $f2, $f12
      la $a0, epsinput
      li $v0, 4
      syscall
      li    $v0, 7
      syscall
      mov.d $f0, $f12
      jal   floatsin
      la    $a0, sinxoutput
      li    $v0, 4
      syscall
      li    $v0, 3
      syscall
      li    $v0, 10
      syscall

floatsin:     addi    $sp, $sp, -64   # Frame
              sw      $ra, 64($ra)
              sw      $fp, 60($sp)
              s.d     $f0, 56($sp)
              s.d     $f4, 48($sp)
              s.d     $f20, 40($sp)
              s.d     $f8, 32($sp)
              s.d     $f10, 24($sp)
              s.d     $f14, 16($sp)
              s.d     $f18, 8($sp)
              addi    $fp, $sp, 64

              li.d    $f8,  0.0   # Initialize
              li.d    $f14, 1.0
              mov.d   $f16, $f0
              li.d    $f18, 0.0

              jal     loop_p1

main_loop:    add.d   $f18, $f18, $f4
              c.lt.d  $f2, $f4
              bc1f    exit_fsin
              jal     loop_p1
              sub.d   $f18, $f18, $f4
              c.lt.d  $f2, $f4
              bc1f    exit_fsin
              jal     loop_p1
              j       main_loop


loop_p1:      add.d   $f8, $f8, $f14
              li.d    $f10, 1.0       #for (j < 2i-1)
              mov.d   $f4,  $f16
              li.d    $f20, 0.0
              add.d   $f20, $f8, $f8
              sub.d   $f20, $f20, $f14
for:          c.lt.d  $f10, $f20
              bc1f    loop_p2
              mul.d   $f4, $f4, $f16 # (x*x)
              add.d   $f10, $f10, $f14
              j       for

loop_p2:      mov.d   $f0, $f20
              move    $t0, $ra
              jal     floatfac
              div.d   $f4, $f4, $f12
              jr      $t0

exit_fsin:    mov.d   $f12, $f18     # Write in target register
              l.d     $f18, 8($sp)   # rewrite values
              l.d     $f14, 16($sp)
              l.d     $f10, 24($sp)
              l.d     $f8,  32($sp)
              l.d     $f20, 40($sp)
              l.d     $f4,  48($sp)
              l.d     $f0,  56($sp)
              lw      $fp,  60($sp)
              lw      $ra,  64($sp)
              addi    $sp, $sp, 64
              jr      $ra           # back to caller


floatfac:     addi    $sp, $sp, -28   # Frame
              sw      $fp, 28($sp)
              s.d     $f4, 24($sp)
              s.d     $f2, 16($sp)    
              s.d     $f0,  8($sp)
              addi    $fp, $sp, 28

              li.d    $f4, 0.0
              c.le.d  $f0, $f4
              bc1t    negative
              li.d    $f12, 1.0
              li.d    $f2, 1.0

while:        c.le.d  $f0, $f2       # Break condition
              bc1t    exit_floatfact
              mul.d  $f12, $f12, $f0
              sub.d   $f0, $f0, $f2
              j       while



negative:     li.d     $f12, 0.0




exit_floatfact: l.d      $f0,  8($sp)   # rewrite values
                l.d      $f2, 16($sp)
                l.d      $f4, 24($sp)
                lw       $fp, 28($sp)
                addi     $sp, $sp, 28
                jr       $ra

1 Ответ

0 голосов
/ 13 июня 2018

Это неверно: sw $ra, 64($ra)

Здесь происходит то, что вы сохраняете текущее значение $ra (0x40005c) в 64($ra), то есть (0x40009c), тем самым перезаписывая инструкцию s.d $f14, 16($sp).

Вместо этого вы должны сделать sw $ra, 64($sp)

...