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
加载中,请稍侯......
精彩评论