简体   繁体   English

MIPS 存储多项式和分支

[英]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.我有一个将两个多项式相除的 mips 汇编程序,但我不确定如何存储值和余数。 I've been having trouble understanding how the offset part of the sw instruction works as well.我一直无法理解 sw 指令的偏移部分是如何工作的。 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.您没有提到您使用的是什么环境,但如果它的 MARS 或 SPIM ,例如,那么数据部分( .data )从地址0x10010000开始,而不是0x10000000 ,所以第一个全局变量将位于那里而不是你所在的位置思维。

Thus, your initial lui is off by 1. This is going to make it hard to access your global variables.因此,您的初始lui 1。这将使访问您的全局变量变得困难。 Are you successfully loading x into $11 from 0($10) ?您是否成功地将x0($10)加载到$11中? 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 .无论您使用的是 MARS 还是 SPIM 或其他东西,使用la $10, x而不是原始的lui可能会更好。


The lw and sw instructions offer a simple base register plus displacement addressing mode, and nothing more. lwsw指令提供了一个简单的基址寄存器加位移寻址模式,仅此而已。 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.处理器计算有效地址(发送到 memory 单元用于读取或写入的地址)作为指令中指定的基址寄存器的内容,加上指令的符号扩展 16 位立即数。 So you can reach +/-32k from the base register.因此,您可以从基址寄存器达到 +/-32k。 You're using the stores correctly, given if the base in $10 points to x .如果$10中的基数指向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.但是,如果基址寄存器(此处$10 )指向0x10000000您将无法访问您的变量x因为您需要一个立即值 +65536 (又名0x10000 ),该值大于 MIPS 可以在一条指令中为您提供的.


However, many would use data labels instead, eg sw $16,error to store the error instead of sw $16,4($10) .但是,许多人会改用数据标签,例如sw $16,error来存储错误而不是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.可以肯定的是,使用 label 访问全局变量是伪指令,汇编程序将其扩展为两条指令,但它们更容易让我们在汇编中阅读——而且在使用标签时,我们可以移动东西,它们仍然可以工作,而使用偏移量,您必须正确排序/编号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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