Проблема с написанием очень простой процедуры сборки SPARC, которая возвращает нечетное число - PullRequest
1 голос
/ 10 октября 2011

Я пишу небольшую процедуру сборки под названием isOdd, которая, как следует из названия, возвращает, если переданное целое число нечетно, возвращая 1 из операции%.

Пока это мой код:

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

Однако я не получаю хорошего вывода;на самом деле, кажется, что он просто возвращает любое значение, которое я передаю num, вместо того, чтобы фактически выполнять операцию модуля.

Google не оказался полезным для такого основного вопроса.Это мой первый ассемблерный код, поэтому я довольно незнаком с понятием «регистры», и я думаю, что их смешивание - вот где моя ошибка.

Заранее спасибо за помощь!

Ответы [ 2 ]

8 голосов
/ 10 октября 2011

Существует целая куча регистров, которые можно рассматривать как блоки по 8. В любой момент времени три последовательных блока из 8 регистров видны как текущее окно регистров и помечены как %o0 -%o7, %l0 - %l7 и %i0 - %i7.(Существует четвертый блок из 8 регистров, %g0 - %g7, которые являются глобальными, а не являются частью механизма управления окнами.)

Когда вы save или restore, окноперемещается на два блока из 8. Перекрывающийся блок позволяет передавать параметры и результаты.Регистры с именем %o0 - %o7 в вызывающем абоненте - это те же регистры, которые называются %i0 - %i7 в вызывающем абоненте.(Два новых блока в вызываемом объекте - %l0 - %l7, которые являются частными для локального использования в этом окне, и %o0 - %o7, которые вызываемый абонент может использовать, когда он, в свою очередь, хочет вызвать другую функцию.)

Это яснее с изображением:

:                      :
+----------------------+
| 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
+----------------------+
:                      :

Ваш абонент помещает аргумент num в %o0 (в своем окне), а затем вызывает вас.Вы save настраиваете новое окно, и вы видите его в %i0 в своем окне.

.rem принимает два параметра.Вы помещаете их в свои %o0 и %o1 (в своем окне), а затем вызываете их.Он увидит их в своих %i0 и %i1 (при условии, что он установит save для установки нового окна).Ответ помещается в %i0, который является вашим %o0.

Аналогично, вы должны поместить свой результат в %i0;кто бы ни позвонил вам, вы увидите это в своих %o0.

0 голосов
/ 07 октября 2013
! 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
...