Представление чисел больше 65535 в MIPS - PullRequest
1 голос
/ 22 июля 2010

Я работаю в MIPS и использую числа, превышающие 65535, и я получаю ошибку вне диапазона. Как я могу обойти это в этом коде?

## p2.asm
##
## Andrew Levenson, 2010
## Problem 2 from Project Euler
## In MIPS Assembly, for SPIM
##
## Calculate the sum, s of all
## even valued terms in the
## Fibonacci sequence which
## do not exceed 4,000,000
        .text
        .globl  main

main:
    ## Registers
        ori     $t0, $0, 0x0        # $t0 will contain scratch
        ori     $t1, $0, 0x1        # $t1 will contain initial fib(N-1) 
        ori     $t2, $0, 0x2        # $t2 will contain initial fib(N) 
        ori     $t3, $0, 0x0        # $t3 will be our loop incrementor
        ori     $t4, $0, 0x0        # $t4 will be our sum
        ori     $t5, $0, 0x2        # $t5 contains two to test if even
        ori     $t8, $0, 4000000    # $t8 contains N limit

even_test:  
    ## Test to see if a given number is even
        div     $t1, $t5            # $t1 / 2
        mflo    $t6                 # $t6 = floor($t1 / 2) 
        mfhi    $t7                 # $t7 = $t1 mod 2

        bne     $t7, $0, inc        # if $t7 != 0 then bypass sum
        sll     $0, $0, $0          # no op


sum:
    ## Add a given value to the sum
        addu    $t4, $t4, $t2       # sum = sum + fib(N)

inc:
    ## Increment fib's via xor swap magic
        xor     $t1, $t1, $t2       # xor swap magic
        xor     $t2, $t1, $t2       # xor swap magic
        xor     $t1, $t1, $t2       # xor swap magic
    ## Now $t1 = $t2 and $t2 = $t1

    ## Increment $t2 to next fib
        addu    $t2, $t1, $t2

    ## Is $t2 < 4,000,000?
    ## If so, go to loop
        sltu    $8, $t2, $t8        # If $t2 < 4,000,000 
                                    # then $8 = 1
        bne     $8, $0, even_test   # if $8 == $0 then jump to even_test
        sll     $0, $0, $0          # no op

print:
        li      $v0, 0x1            # system call #1 - print int
        move    $a0, $t4
        syscall                     # execute

        li      $v0, 0xA            # system call #10 - exit
        syscall

## End of Program

Как я могу это исправить?

Ответы [ 3 ]

4 голосов
/ 22 июля 2010

(я не имел представления о сборке MIPS до вчерашнего дня, но я сделаю снимок)

LUI с 0x3D, затем ORI с 0x900 (4 000 000 - 0x3D0900)?

2 голосов
/ 22 июля 2010

Полагаю, это проблема?

   ori     $t8, $0, 4000000    # $t8 contains N limit

Инструкции MIPS имеют только 16-битные поля констант, поэтому вам нужно создать более сложные константы, превышающие 65535, или загрузить их из памяти. Примерно так должно работать:

  ori      $t8, $0, 0x3d09     # 4 000 000 >> 8
  sll      $t8, $t8, 8

Я думаю"sll dest, src, count" - это то, как вы сдвигаетесь влево в сборке MIPS, но я могу ошибаться. Вы также можете использовать макроинструкцию "li", которая принимает любую 32-битную константу и каким-либо образом вводит ее в регистр, используя при необходимости более одной инструкции.

0 голосов
/ 22 июля 2010

Моей первой мыслью было бы использовать два регистра, один для битов старшего разряда и один для битов младшего разряда. Вы должны отслеживать их вместе, но это то, что приходит мне в голову.

...