恢复MIPS大会的分部

时间:2014-01-16 15:02:45

标签: assembly mips

我正在尝试用MIPS汇编语言编写一个实现恢复除法算法的程序。

我找到了我必须要完成的任务的非常好的例子,该线程已经过时且已关闭,我并不完全理解它。

http://forums.extremeoverclocking.com/showthread.php?p=2693342

我几乎没有问题:

  1. 所以到底应该怎么样好的代码? 因为我明白第一篇文章中的代码是错误的吗?

  2. 什么是恢复分区的好算法?

    ” 你要划分两个数字:a / b = c,余数= d

    注册A = a 登记册B = b 寄存器P =一组“连接”的两个寄存器(64位寄存器)

    1. 将双重对手(P,A)向左移一位
      • 对无符号值使用零符号扩展
      • 强制MSB(P)脱离上端
    2. 从P
    3. 中减去b
    4. 如果结果是< 0 LSB(A)= 0 否则LSB(A)= 1
    5. 如果结果是否定的 P = P + b
    6. 重复n次(对于n位值) 寄存器A = a / b的内容 寄存器P的内容=余数(a / b)“

      这是一个很好的算法吗?有人可以用更简单的英语写出来吗?因为我不明白。

      此外:

      来自第一篇文章的代码:

      .data
          GETA:           .asciiz "Enter A "
          GETB:           .asciiz "Enter B "
          QMSG:           .asciiz "Q = "
          RMSG:           .asciiz "R = "
          NL:             .asciiz "\n"
          ERR:            .asciiz "Divide by zero error\n"
          left:           .word 1
          right:          .word 1
      .text
      .globl main
      main:
          # Prompt for an integer A: divisor
          li $v0, 4                            
          la $a0, GETA                           
          syscall                                     
          # Read A from user
          li $v0, 5                              
          syscall                              
      
          move $t0, $v0                         
          # Prompt for an integer B: dividend
          li $v0, 4                             
          la $a0, GETB                         
          syscall     
      
          # Read B from user
          li $v0, 5                               
          syscall                               
          move $a1, $v0                          
      
      # Initialize quotient register to zero
      # Initialize left half of Divisor regisiter with divisor
      # Initialize remainder register with the dividend (right aligned)
      # 1. Remainder = Remainder - Divisor
      #    Remainder >= 0 goto Step 2a.
      #    Remainder < 0 goto Step 2b.
      # 2a. Shift quotient register to the left, setting rightmost bit to 1
      # 2b. Restore the original value bu Remainder = Remainder + Divisor
      #     Shift quotient register to the left setting new LSB to zero
      # 3. Shift divisor register to the right 1 bit
      # < 33 repitions, goto step 1
      # >= 33 repititions, print result 
      #
      # Register usage:
      # $a0 = divisor
      # $a1 = dividend
      # $a2 = quotient
      # $a3 = remainder
      # $t4 = counter of 33 repetitions
      # $t0 = divisor (temp)
      initialize:
          li $a2, 0                               # $a2 = quotient = 0
          swl $t0, left
          lwl $a0, left                           # $a0 = left half of divisor
          swr $a1, right
          lwr $a3, right                          # $a3 = remainder = $a2
          li $t4, 33                              # $t4 = counter = 33
      
      step_one:
          sub $a3, $a3, $a0
          bge $a3, $zero, step_two_a
          blt $a3, $zero, step_two_b
      
      step_two_a:
          #slt $a2, $zero, $a2
          sll $a2, $a2, 1
          ori $a2, $a2, 1
          j step_three
      
      step_two_b:
      
          add $a3, $a3, $a0
          sll $a2, $a2, 1
      
      step_three:
      
          sra $a0, $a0, 1
      
      step_four:
      
          addi $t4, $t4, -1
          bge $t4, $zero, step_one
          beq $t4, $zero, print_result
      
      print_result:
      
          li $v0, 4                  
          la $a0, QMSG                     
          syscall                   
      
          move $a0, $a2                      
          li $v0, 1                         
          syscall                            
      
          li $v0, 4                          
          la $a0, NL                         
          syscall                           
      
          li $v0, 4                    
          la $a0, RMSG                     
          syscall                     
      
          move $a0, $a3                      
          li $v0, 1                          
          syscall                            
      
          li $v0, 4                          
          la $a0, NL                         
          syscall
      
          j exit_program                    
      
      exit_program:
          li $v0, 10                       
          syscall
      

      可能遗漏了像

      这样的东西

      代码:

       # shift the double register (P,A) one bit left
          slt $t2, $v0, $zero                  # store MSB of hi
          sll $v0, $v0, 1                      # shift hi left 1 bit
          slt $t3, $v1, $zero                  # store MSB of lo
          or $v0, $v0, $t2                     # move MSB of lo into LSB of hi
          sll $v1, $v1, 1                      # shift lo left 1 bit
      

      应该怎么样好的代码??

0 个答案:

没有答案
相关问题