Trouble with writing a very basic SPARC Assembly routine that returns whether a number is odd
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!
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
.
! 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
精彩评论