Trouble with writing a very basic SPARC Assembly routine that returns whether a number is odd
Asked Answered
V

2

1

I'm writing a small assembly routine called isOdd, which, as the name implies, returns if the passed integer is odd, by returning 1 from a % operation.

This is my code so far:

Function prototype: int isOdd( long num )

isOdd:
    save     %sp, -96, %sp  ! Save caller's window

    mov      %i0, %o0       ! Parameter num goes to %o0
    mov      2, %l0         ! 2 goes to local register
    call     .rem           ! Call modulus subroutine
    nop

    mov      %o0, %l0       ! moves the result of the subroutine 
                            ! to output register o0
    ret
    restore

However, I don't get good output; in fact, it seems like it is just returning whatever value I pass to num, instead of actually doing the modulus operation.

Google hasn't proved helpful for such a basic question. This is my first assembly code, so I'm pretty unfamiliar with the concept of "registers," and I think mixing them up is where my error may lie.

Thanks in advance for your help!

Vomit answered 10/10, 2011 at 0:7 Comment(4)
Are you sure you've got the "source" and "destination" of the mov instruction operands the right way around in all instances? Your code appears inconsistent with your comments.Scraggy
It's mov src, dst, right? (check your last mov) Also, it's enough just to and it with 1 instead of modulo operation. Also, '2', parameter for modulo, should also go to an output register.Eterne
Hmm okay, I tried that, and now it just gives me a 0 answer for every value. Perhaps it has something to do with the registers I'm choosing? I wasn't sure which registers to use to save 2 and the result of the % call.Vomit
Why don't you just bitwise-and the input with 1? SPARC uses 2's complement like any sane architecture, so that produces the correct result.Glossary
D
8

There are a whole bunch of registers, which you can think of as being in blocks of 8. At any one time, three consecutive blocks of 8 registers are visible as the current register window, and are labelled as %o0-%o7, %l0-%l7, and %i0-%i7. (There is a fourth block of 8 registers, %g0-%g7, which are global rather than being a part of the windowing arrangement.)

When you save or restore, the window moves by two blocks of 8. The overlapping block allows for parameter and result passing. The registers which are named %o0-%o7 in the caller are the same ones that are named %i0-%i7 in the callee. (The two new blocks in the callee are %l0-%l7, which are private for local use within that window, and %o0-%o7 which the callee can use when it in turn wants to call another function.)

It's clearer with a picture:

:                      :
+----------------------+
| Block of 8 registers |      caller's window
+----------------------+  +----------------------+
| Block of 8 registers |  |      %i0 - %i7       |    ---------.
+----------------------+  +----------------------+             | save
| Block of 8 registers |  |      %l0 - %l7       |             v
+----------------------+  +----------------------+  +----------------------+
| Block of 8 registers |  |      %o0 - %o7       |  |      %i0 - %i7       |
+----------------------+  +----------------------+  +----------------------+
| Block of 8 registers |              ^             |      %l0 - %l7       |
+----------------------+      restore |             +----------------------+
| Block of 8 registers |              `---------    |      %o0 - %o7       |
+----------------------+                            +----------------------+
| Block of 8 registers |                                callee's window
+----------------------+
:                      :

Your caller places the num argument into %o0 (in its window), then calls you. You save to set up a new window, and so you see it in %i0 in your window.

.rem takes two parameters. You place these in your %o0 and %o1 (in your window), then call it. It will see them in its %i0 and %i1 (assuming it does a save to set up a new window). It puts the answer in its %i0, which is your %o0.

Similarly, you should put your result in your %i0; whoever called you will see it in their %o0.

Darla answered 10/10, 2011 at 1:33 Comment(0)
P
0
! modified based on comments 

isOdd:
  save     %sp, -96, %sp  ! Save caller's window
  mov      %i0, %o0       ! Parameter num goes to %o0
  mov      2, %o1         ! 2 goes to %o1
  call     .rem           ! Call modulus subroutine
  nop

  mov      %o0, %i0       ! moves the result of the subroutine 
                          ! to input register i0
  ret
  restore
Process answered 7/10, 2013 at 14:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.