MIPS Хранение полиномов и ветвей - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть программа сборки mips, которая делит два полинома, но я не уверен, как сохранить значение и остаток. У меня были проблемы с пониманием того, как работает смещенная часть инструкции sw. Любая помощь приветствуется.

## 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

1 Ответ

1 голос
/ 07 апреля 2020

Вы не упомянули, какую среду вы используете, но если, например, MARS или SPIM, то секция данных (.data) начинается по адресу 0x10010000, а не 0x10000000, поэтому первая глобальная переменная будет быть там, а не там, где вы думали.

Таким образом, ваш начальный lui отключен на 1. Это затруднит доступ к вашим глобальным переменным. Вы успешно загружаете x в $11 из 0($10)? Если нет, вот почему.


Независимо от того, используете ли вы MARS, SPIM или что-то еще, вам лучше использовать la $10, x, а не необработанный lui.


Инструкции lw и sw предлагают простой базовый регистр плюс режим адресации смещения, и ничего более. Процессор вычисляет эффективный адрес (адрес, отправляемый в блок памяти для чтения или записи) как содержимое базового регистра, указанного в инструкции, плюс 16-битный знак с расширенным знаком непосредственно из инструкции. Таким образом, вы можете достичь +/- 32k из базового регистра. Вы используете магазины правильно, учитывая, что база в $10 указывает на x.

Однако, если базовый регистр (здесь $10) указывает на 0x10000000, вы не сможете чтобы достичь вашей переменной x, потому что вам потребуется немедленное значение +65536 (он же 0x10000), которое больше, чем MIPS может дать вам в одной инструкции.


Однако многие вместо этого используйте метки данных, например, sw $16,error для хранения ошибки вместо sw $16,4($10).

. Конечно, использование метки для доступа к глобальным переменным является псевдоинструкциями, которые ассемблер расширит до двух инструкций, но их легче читать в сборке - а также при использовании меток мы можем перемещать объекты, и они все еще работают, тогда как со смещениями необходимо правильно упорядочить / нумеровать.

...