简体   繁体   中英

MIPS Storing polynomials and branches

I have a mips assembly program that divides two polynomials but I'm not sure how to store the value and remainder. I've been having trouble understanding how the offset part of the sw instruction works as well. Any help is welcomed.

## Evaluate (8x^2-3x+12)/(3x^2+2x-16)
    .text
    .globl main
main:   
    lui    $10, 0x1000    # Init base register
    lw     $11, 0($10)    # Load x
    sll    $0,$0,0        # noop
    ori    $12,$0,0       # Init the accumulator
                          # during the "load delay slot"
    ori    $13,$0,2       # Evaluate second term coefficient
    mult   $11,$13        # 2x
    mflo   $13            # assume 32 bit result
    ori    $14,$0,16      # register 14 = 16
    addu   $12,$12,$13    # accumulator = 2x
    subu   $12,$12,$14    # accumulator = 2x-16
    mult   $11,$11        # x^2
    mflo   $11            # assume 32 bit result
    ori    $13,$0,3       # evaluate third term coefficient
    mult   $11,$13        # 3x^2
    addu   $12,$12,$13    # accumulator = 3x^2+2x-16

    ori    $15,$0,12      # init the accumulator
                          # during the "load delay slot"
    ori    $13,$0,3       # Evaluate second term coefficient
    mult   $11,$13        # 3x
    mflo   $13            # assume 32 bit result
    subu   $15,$15,$13    # accumulator = -3x+12
    mult   $11,$11        # x^2
    mflo   $11            # assume 32 bit result
    ori    $13,$0,8       # third term coefficient
    mult   $11,$13        # 8x^2
    mflo   $13            # assume 32 bit result
    addu   $15,$15,$13    # accumulator = 8x^2-3x+12

    addu   $13,0          # make temp 0
    beq    $12,$13,equal  # branch if denom is 0
    sll    $0,$0,0        # branch delay slot
    addu   $16,0          # set Error to 0
    div    $15,$12        # divide the two accumulators
    mflo   $12            # the quotient is in $12
    mfhi   $15            # the remainder is in $15
    sw     $12,8($10)     # store $12 in ratio
    sw     $15,12($10)    # store $15 in remain
    ori    $16,$0,1       # set Error to 1
    sw     $16,4($10)     # store 1 in error
    j      cont
    sll    $0,$0,0        # branch delay slot
    equal:  ori    $16,$0,1       # set Error to 1
    sw     $16,4($10)     # store 1 in error
    cont:   sll    $0,$0,0        # noop

    .data
    x:      .word  1              # Edit this line to change x
    error:  .word  0              # Error value is placed here
    ratio:  .word  0              # Ratio value is placed here
    remain: .word  0              # Remainder value placed here

    ## End of file

You didn't mention what environment you're using but if its MARS or SPIM, for example, then data section ( .data ) starts at address 0x10010000 , not 0x10000000 , so the first global variable will be located there rather than where you were thinking.

Thus, your initial lui is off by 1. This is going to make it hard to access your global variables. Are you successfully loading x into $11 from 0($10) ? If not, that's why.


Whether you're using MARS or SPIM or something else, you might be better off using la $10, x rather than the raw lui .


The lw and sw instructions offer a simple base register plus displacement addressing mode, and nothing more. The processor computes the effective address (the address sent to the memory unit for the read or write) as the contents of the base register named in the instruction, plus the sign-extended 16-bit immediate of the instruction. So you can reach +/-32k from the base register. You're using the stores correctly, given if the base in $10 points to x .

However, if the base register (here $10 ) points to 0x10000000 you will not be able to reach your variable x because you'd need an immediate value of +65536 (aka 0x10000 ), which is larger than MIPS can give you in one instruction.


However, many would use data labels instead, eg sw $16,error to store the error instead of sw $16,4($10) .

To be sure, using label to access the globals are pseudo instructions that will be expanded into two instructions by the assembler, but they're easier for us to read in assembly — and also when using the labels, we can move things around and they still work whereas with offsets, you have to get the ordering/numbering right.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM