在 MIPS 中表示大于 65535 的数字

发布于 2024-09-11 04:29:50 字数 2111 浏览 3 评论 0原文

我正在 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

我该如何解决这个问题?

I am working in MIPS, and using numbers in excess of 65535, and I'm getting an out of range error. How can I work around that in this code?

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

How can I fix this?

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

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

发布评论

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

评论(3

慵挽 2024-09-18 04:29:50

(昨天之前我不知道 MIPS 汇编,但我会尝试一下)

带有 0x3D 的 LUI,然后是带有 0x900 的 ORI(4,000,000 是 0x3D0900)?

(I had no idea of MIPS assembly before yesterday, but I'll give a shot)

LUI with 0x3D, followed by ORI with 0x900 (4,000,000 being 0x3D0900)?

手心的海 2024-09-18 04:29:50

我猜这是问题所在?

   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 位常量和 finagles 放入寄存器中,如果需要,可以使用多个指令。

I'm guessing this is the problem line?

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

MIPS instructions have only 16-bit constant fields, so you need to construct constants greater than 65535 with a more complex sequence, or else load them from memory. Something like this should work:

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

I think "sll dest, src, count" is how you shift left in MIPS assembly, but I could be wrong. You can also use the "li" macro-instruction, which takes any 32-bit constant and finagles that into a register somehow, using more than one instruction if necessary.

Saygoodbye 2024-09-18 04:29:50

我的第一个想法是使用两个寄存器,一个用于高位,一个用于低位。你必须一起跟踪它们,但这正是我想到的。

My first thought would be to use two registers, one for the higher-order bits and one-for the lower-order bits. You'd have to keep track of them together, but that's just what comes to mind for me.

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