MIPS:如何排序

发布于 2024-10-26 18:54:50 字数 527 浏览 8 评论 0原文

我需要您帮助解决 MIPS 程序集中的排序问题:

如何编写 MIPS 程序来读取仅包含十进制整数的文本文件并按降序对它们进行排序。

该程序应执行以下操作:

■ 打开文本文件并将其内容读入字符数组。该数组应限制为 1000 个字符。 MARS 提供用于打开和读取文本文件的系统调用。

■ 逐个字符地遍历数组。将每个十进制字符串转换为二进制。十进制字符串由一个或多个十进制字符组成。它应该以空格或换行符结尾。忽略并跳过所有其他字符。将所有十进制整数存储到一个字数组中。整数数组的大小应限制为 100 个字。

■ 按降序对整数数组进行排序。

■ 显示排序后的数组


实际上,我对数组进行排序没有问题,因为我拥有它,但处理文本文件、从中读取数据、转换为十进制插入数组时出现问题。

你有什么想法吗?评论 ?建议?

提前谢谢


更新:有些人问了问题是什么? 问题是如何从txt文件中读取数字,将数字转换为十进制?这就是问题所在。

I need your help with this problem of sorting in MIPS assembly :

how to write a MIPS program to read a text file containing only decimal integers and sort them in descending order.

The program should do the following:

■ Open a text file and read its content into an array of characters. The array should be limited to 1000 characters. MARS provides the system calls for opening and reading from a text file.

■ Traverse the array character by character. Convert each decimal string into binary. A decimal string consists of one or multiple decimal characters. It should terminate by white space or a newline character. Ignore and skip all other characters. Store all the decimal integers into an array of words. The size of the integer array should be limited to 100 words.

■ Sort the integer array in descending order.

■ Display the sorted array


Actualy I have no problem with sorting the array since I have it, but the problem with dealing with the text file, reading from it, converting to decimal plugging in the array.

Do you have any ideas ? comments ? suggestions ?

Thx in advance


Update: some has asked what is the question?
the question is how to read from a txt file, convert the numbers to decimal ? this is the question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

听风念你 2024-11-02 18:54:50

好吧,,,我将发布与您的问题类似的问题的解决方案的一些部分(虽然很复杂),,,

数据初始化

# Data Buffers
  m1Buff:       .space  20000           # File 1 Data Buffer
  numBuff:       .space  200             # String Number Buffer
# Arrays
  m1:            .double    1:100

从文件读取并保存到缓冲区的代码


############################################################
#### Open the file for reading 
li  $v0, 13             # system call for open file
la  $a0,m1File          # input file name
li  $a1, 0              # flags
li  $a2, 0              # Open for reading (mode is 0: read, 1: write)
syscall                # open a file (file descriptor returned in $a0)
move $t0, $a0            # save the fd (syscall below will overwrite $a0)
############################################################
#### read from file just opened
li  $v0, 14             # system call to read from file
la  $a1,m1Buff          # address of buffer to store read data.
li  $a2, 20000      # max num of cahrs to read.
syscall                # read from file

############################################################
  #### Getting number of characters read from file.
  move $s0,$a0         # $s0 = number of read characters
############################################################
#### Close the file 
li  $v0, 16             # system call for close file
move $a0, $t0        # Restore fd
syscall                # close file
############################################################

至于转换为十进制数,,, 我在 2 年前编写了这个过程,将字符串转换为浮点数(它还读取指数,即 2.23E5),,, 在您的情况下,您需要将字符串转换为十进制数,其中更容易,,,你应该能够弄清楚如何自己做,给出以下过程,,,


#####################################################################################################
#####################################################################################################
## String To FP Procedure
##  
## INPUTS : A String That Is Terminated With Null Char.
##   $a0 = address of String
##
## Author : Manaf Abu.Rous
#####################################################################################################
#####################################################################################################
str2float:

    move    $t1,$a0             # load Address Of Sttring In $t1

    li      $t0,10              # t0 = 10
    mtc1    $t0,$f2             # move $t0 to $f2
    cvt.d.w $f2,$f2             # f2 = 10 ( Used for Multiplication & Division )

    li      $t0,0               # t0 = 0
    mtc1    $t0,$f4             # move $t0 to $f4
    cvt.d.w $f4,$f4             # f4 = 0 = Integer Part. (Used To Generage The Integer Part Of The Number)

    li      $t0,0               # t0 = 0
    mtc1    $t0,$f6             # move $t0 to $f6
    cvt.d.w $f6,$f6             # f6 = 0 = Fraction Part. (Used To Generage The Fraction Part Of The Number)

    li      $t6,0               # $t6 = 0 = Exponent Part. (Used To Generage The Exponent Part Of The Number)

    li      $t3,0               # $t3 = 0 ( Used To Determine The Sign Of The Number, +ve = 0, -ve = 1 )
    li      $t4,0               # $t4 = 0 ( Used To Count The Number of Digits In a Fraction )
    li      $t5,0               # $t5 = 0 ( Used To Determine If The Next Char Is a Fraction , Yes = 1, No = 0)
    li      $t7,0               # $t5 = 0 ( Used To Determine If The Next Char Is an Exponent , Yes = 1, No = 0)

    #---------------------------------------------------------

    #------------------------------------------------------------------------------
    #  Loop for visiting the buffer Char by Char and Constructing an Integer String
    #------------------------------------------------------------------------------

readLoop:

    lb      $t2,0($t1)          # load byte (char) in $t2

    #--------------------------------------------------------------------
    # -------- Check For "-" Sign
    bne     $t2,0x2d,skipNeg    # check if char = "-" ? if yes > sign reg = 1.
    li      $t3,1               # $t3 = 1 ( Used To Determine The Sign Of The Number )
    j       NextChar
    skipNeg:    
    #--------------------------------------------------------------------

    #--------------------------------------------------------------------
    # -------- Check For "." Dot
    bne $t2,0x2e,skipDot        # check if char = "." ? if yes > Go Read Fraction
    li      $t5,1               # $t3 = 1 > Next Chars Are Fractinos
    j       NextChar
    skipDot:
    #--------------------------------------------------------------------

    #--------------------------------------------------------------------
    # -------- Check For "E" Exponent 
    bne $t2,0x45,skipE          # check if char = "E" ? if yes > Go Read Exponent
    li      $t7,1               # $t3 = 1 > Next Chars Are Exponent
    j       NextChar
    skipE:
    #--------------------------------------------------------------------

    #--------------------------------------------------------------------
    # -------- Check For Null Char ( End Of String) 
    beq     $t2,0x00,FinishNumber   # check if char = Null ? if yes > we are done with the number.
    #--------------------------------------------------------------------   

    #---------------------------------
    # Check What's The Current Char
    #---------------------------------
    beq     $t7,1,readExponent      # if $t7 = 1 (Next Char is Exponenet) Jump To ReadExponent
    beq     $t5,1,readFraction      # if $t7 = 1 (Next Char is Exponenet) Jump To ReadFraction

    #-------------------------------------------------------------------------
    # --------- Read Integer Part Of Char And Convert Them To Float
readInteger:
    subi    $t2,$t2,0x30        # subtract 0x30 from char to convert it to a number.
    mtc1    $t2,$f10            # move $t2 to $f6
    cvt.d.w $f10,$f10           # f6 = converte integer to a FP number.
    mul.d   $f4,$f4,$f2         # =((old)+2 X 10)   
    add.d   $f4,$f4,$f10        # =((old)+ 2)
    j       NextChar
    #-------------------------------------------------------------------------
    #-------------------------------------------------------------------------
    # --------- Read Fraction Part Of Char And Convert Them To Float
readFraction:
    subi    $t2,$t2,0x30        # subtract 0x30 from char to convert it to a number.
    mtc1    $t2,$f10                # move $t2 to $f6
    cvt.d.w $f10,$f10           # f6 = converte integer to a FP number.
    mul.d   $f6,$f6,$f2         # =((old)+2 X 10)   
    add.d   $f6,$f6,$f10            # =((old)+ 2)
    addi    $t4,$t4,1           # Increment Fractions Digits Counter
    j       NextChar
    #-------------------------------------------------------------------------
    #-------------------------------------------------------------------------
    # --------- Read Exponenet Part Of Char And Convert Them To Integer
readExponent:
    li      $t0,10
    subi    $t2,$t2,0x30        # subtract 0x30 from char to convert it to a number.
    mult    $t6,$t0             # =((old)+2 X 10)
    mflo    $t6 
    add     $t6,$t6,$t2         # =((old)+ 2)
    j       NextChar
    #-------------------------------------------------------------------------


NextChar:
    addiu   $t1,$t1,1           # increment the address for the next buffer byte.
    j       readLoop        

###################################### Finish Number Code ######################################

FinishNumber:   
    # Finalizing Fraction Part And Adding It To Integer Part ------------------
    beq     $t5,0,skipFrac      # If There's No Fraction Part Then Skip. ($t5 != 1) > Skip

    li      $t0,1               # $t0  = 1
    mtc1    $t0,$f20            # move $t0 (Counter) to $f20
    cvt.d.w $f20,$f20           # f20 = 1

FracLoop:       #-------- Loop To Multiply 10 By It Self (Fraction Ditigs Counter) Times 
                mul.d   $f20,$f20,$f2       # $f20 = $f20 X $f2 ($f20 = $f20 X 10)
                addi    $t4,$t4,-1          # Decrement Fraction Digits Counter
                bgtz $t4,FracLoop

    div.d   $f6,$f6,$f20        # $f6 = $f6 / $f20 ($f6 = Fraction Part / FractionsDigits X 10 )
    add.d   $f4,$f4,$f6         # $f4 = $f4 + $f6 ( $f4 = IntegerPart + Fraction Part )
    skipFrac:
    # -------------------------------------------------------------------------


    # Exponent Part -----------------------------------------------------------
    beq     $t7,0,skipExp       # If There's No Exponenet Part Then Skip. ($t7 != 1) > Skip
    beq     $t6,1,skipExp       # If The Exponent Is = 1 Then Skip
    addi    $t6,$t6,-1          # Correct Exponent.
    mov.d   $f18,$f4

ExpLoop:    #-------- Loop To Compute The Exponenet (Multiply Number By It Self (Expoenet) Times)
            mul.d   $f4,$f4,$f18        # $f4 = $f4 X $f4 ( Multiply Number By It Self )
            addi    $t6,$t6,-1          # Decrement Fraction Digits Counter
            bgtz $t6,ExpLoop

    skipExp:    
    # -------------------------------------------------------------------------


    # Checking Sign Register --------------------------------------------------
    bne     $t3,1,skipSign      # if $t3 != 1  Then Skip    
    neg.d   $f4,$f4             # $f4 = - $f4
    skipSign:   
    # -------------------------------------------------------------------------

    # Save The Number In $f0 To Be Returned
    mov.d   $f0,$f4             # $f0 = Converted String ( To Be Returned )

################################### End Of Finish Number Code ##################################
    jr      $ra         # Return

#####################################################################################################
#                                        End Of Procedure
#####################################################################################################

现在剩下的是从文件缓冲区读取,,,循环遍历字符,,,将它们转换为十进制数字、、、并将它们保存到数组中。

Ok ,,, I will post some parts of the solution to a problem that is similar to yours (much complicated though) ,,,

Data Initialization

# Data Buffers
  m1Buff:       .space  20000           # File 1 Data Buffer
  numBuff:       .space  200             # String Number Buffer
# Arrays
  m1:            .double    1:100

Code to read from a file and save into a buffer


############################################################
#### Open the file for reading 
li  $v0, 13             # system call for open file
la  $a0,m1File          # input file name
li  $a1, 0              # flags
li  $a2, 0              # Open for reading (mode is 0: read, 1: write)
syscall                # open a file (file descriptor returned in $a0)
move $t0, $a0            # save the fd (syscall below will overwrite $a0)
############################################################
#### read from file just opened
li  $v0, 14             # system call to read from file
la  $a1,m1Buff          # address of buffer to store read data.
li  $a2, 20000      # max num of cahrs to read.
syscall                # read from file

############################################################
  #### Getting number of characters read from file.
  move $s0,$a0         # $s0 = number of read characters
############################################################
#### Close the file 
li  $v0, 16             # system call for close file
move $a0, $t0        # Restore fd
syscall                # close file
############################################################

As for converting to decimal numbers ,,, I've written this procedure 2 years ago to convert a string to a floating point number (it also reads exponents i.e. 2.23E5) ,,, In your case you need to convert a string to a decimal which is much easier ,,, you should be able to figure out how to do it on your own giving the following procedure ,,,


#####################################################################################################
#####################################################################################################
## String To FP Procedure
##  
## INPUTS : A String That Is Terminated With Null Char.
##   $a0 = address of String
##
## Author : Manaf Abu.Rous
#####################################################################################################
#####################################################################################################
str2float:

    move    $t1,$a0             # load Address Of Sttring In $t1

    li      $t0,10              # t0 = 10
    mtc1    $t0,$f2             # move $t0 to $f2
    cvt.d.w $f2,$f2             # f2 = 10 ( Used for Multiplication & Division )

    li      $t0,0               # t0 = 0
    mtc1    $t0,$f4             # move $t0 to $f4
    cvt.d.w $f4,$f4             # f4 = 0 = Integer Part. (Used To Generage The Integer Part Of The Number)

    li      $t0,0               # t0 = 0
    mtc1    $t0,$f6             # move $t0 to $f6
    cvt.d.w $f6,$f6             # f6 = 0 = Fraction Part. (Used To Generage The Fraction Part Of The Number)

    li      $t6,0               # $t6 = 0 = Exponent Part. (Used To Generage The Exponent Part Of The Number)

    li      $t3,0               # $t3 = 0 ( Used To Determine The Sign Of The Number, +ve = 0, -ve = 1 )
    li      $t4,0               # $t4 = 0 ( Used To Count The Number of Digits In a Fraction )
    li      $t5,0               # $t5 = 0 ( Used To Determine If The Next Char Is a Fraction , Yes = 1, No = 0)
    li      $t7,0               # $t5 = 0 ( Used To Determine If The Next Char Is an Exponent , Yes = 1, No = 0)

    #---------------------------------------------------------

    #------------------------------------------------------------------------------
    #  Loop for visiting the buffer Char by Char and Constructing an Integer String
    #------------------------------------------------------------------------------

readLoop:

    lb      $t2,0($t1)          # load byte (char) in $t2

    #--------------------------------------------------------------------
    # -------- Check For "-" Sign
    bne     $t2,0x2d,skipNeg    # check if char = "-" ? if yes > sign reg = 1.
    li      $t3,1               # $t3 = 1 ( Used To Determine The Sign Of The Number )
    j       NextChar
    skipNeg:    
    #--------------------------------------------------------------------

    #--------------------------------------------------------------------
    # -------- Check For "." Dot
    bne $t2,0x2e,skipDot        # check if char = "." ? if yes > Go Read Fraction
    li      $t5,1               # $t3 = 1 > Next Chars Are Fractinos
    j       NextChar
    skipDot:
    #--------------------------------------------------------------------

    #--------------------------------------------------------------------
    # -------- Check For "E" Exponent 
    bne $t2,0x45,skipE          # check if char = "E" ? if yes > Go Read Exponent
    li      $t7,1               # $t3 = 1 > Next Chars Are Exponent
    j       NextChar
    skipE:
    #--------------------------------------------------------------------

    #--------------------------------------------------------------------
    # -------- Check For Null Char ( End Of String) 
    beq     $t2,0x00,FinishNumber   # check if char = Null ? if yes > we are done with the number.
    #--------------------------------------------------------------------   

    #---------------------------------
    # Check What's The Current Char
    #---------------------------------
    beq     $t7,1,readExponent      # if $t7 = 1 (Next Char is Exponenet) Jump To ReadExponent
    beq     $t5,1,readFraction      # if $t7 = 1 (Next Char is Exponenet) Jump To ReadFraction

    #-------------------------------------------------------------------------
    # --------- Read Integer Part Of Char And Convert Them To Float
readInteger:
    subi    $t2,$t2,0x30        # subtract 0x30 from char to convert it to a number.
    mtc1    $t2,$f10            # move $t2 to $f6
    cvt.d.w $f10,$f10           # f6 = converte integer to a FP number.
    mul.d   $f4,$f4,$f2         # =((old)+2 X 10)   
    add.d   $f4,$f4,$f10        # =((old)+ 2)
    j       NextChar
    #-------------------------------------------------------------------------
    #-------------------------------------------------------------------------
    # --------- Read Fraction Part Of Char And Convert Them To Float
readFraction:
    subi    $t2,$t2,0x30        # subtract 0x30 from char to convert it to a number.
    mtc1    $t2,$f10                # move $t2 to $f6
    cvt.d.w $f10,$f10           # f6 = converte integer to a FP number.
    mul.d   $f6,$f6,$f2         # =((old)+2 X 10)   
    add.d   $f6,$f6,$f10            # =((old)+ 2)
    addi    $t4,$t4,1           # Increment Fractions Digits Counter
    j       NextChar
    #-------------------------------------------------------------------------
    #-------------------------------------------------------------------------
    # --------- Read Exponenet Part Of Char And Convert Them To Integer
readExponent:
    li      $t0,10
    subi    $t2,$t2,0x30        # subtract 0x30 from char to convert it to a number.
    mult    $t6,$t0             # =((old)+2 X 10)
    mflo    $t6 
    add     $t6,$t6,$t2         # =((old)+ 2)
    j       NextChar
    #-------------------------------------------------------------------------


NextChar:
    addiu   $t1,$t1,1           # increment the address for the next buffer byte.
    j       readLoop        

###################################### Finish Number Code ######################################

FinishNumber:   
    # Finalizing Fraction Part And Adding It To Integer Part ------------------
    beq     $t5,0,skipFrac      # If There's No Fraction Part Then Skip. ($t5 != 1) > Skip

    li      $t0,1               # $t0  = 1
    mtc1    $t0,$f20            # move $t0 (Counter) to $f20
    cvt.d.w $f20,$f20           # f20 = 1

FracLoop:       #-------- Loop To Multiply 10 By It Self (Fraction Ditigs Counter) Times 
                mul.d   $f20,$f20,$f2       # $f20 = $f20 X $f2 ($f20 = $f20 X 10)
                addi    $t4,$t4,-1          # Decrement Fraction Digits Counter
                bgtz $t4,FracLoop

    div.d   $f6,$f6,$f20        # $f6 = $f6 / $f20 ($f6 = Fraction Part / FractionsDigits X 10 )
    add.d   $f4,$f4,$f6         # $f4 = $f4 + $f6 ( $f4 = IntegerPart + Fraction Part )
    skipFrac:
    # -------------------------------------------------------------------------


    # Exponent Part -----------------------------------------------------------
    beq     $t7,0,skipExp       # If There's No Exponenet Part Then Skip. ($t7 != 1) > Skip
    beq     $t6,1,skipExp       # If The Exponent Is = 1 Then Skip
    addi    $t6,$t6,-1          # Correct Exponent.
    mov.d   $f18,$f4

ExpLoop:    #-------- Loop To Compute The Exponenet (Multiply Number By It Self (Expoenet) Times)
            mul.d   $f4,$f4,$f18        # $f4 = $f4 X $f4 ( Multiply Number By It Self )
            addi    $t6,$t6,-1          # Decrement Fraction Digits Counter
            bgtz $t6,ExpLoop

    skipExp:    
    # -------------------------------------------------------------------------


    # Checking Sign Register --------------------------------------------------
    bne     $t3,1,skipSign      # if $t3 != 1  Then Skip    
    neg.d   $f4,$f4             # $f4 = - $f4
    skipSign:   
    # -------------------------------------------------------------------------

    # Save The Number In $f0 To Be Returned
    mov.d   $f0,$f4             # $f0 = Converted String ( To Be Returned )

################################### End Of Finish Number Code ##################################
    jr      $ra         # Return

#####################################################################################################
#                                        End Of Procedure
#####################################################################################################

Now what's left is reading from the file buffer ,,, looping through the chars ,,, converting them to decimal numbers ,,,, and saving them into the array.

穿透光 2024-11-02 18:54:50

使用 $v0=13,$a1=0,$a2=0 的系统调用来打开文件。

然后使用 $v0=14 的系统调用将其读入缓冲区。

Use syscall with $v0=13,$a1=0,$a2=0 to open a file.

Then use syscall with $v0=14 to read it into a buffer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文