开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜