В настоящее время я работаю над простым кодом сборки SPARC, который вычисляет факториал 5. Я хотел бы знать, почему глобальные регистры, которые я использовал, не являются согласованными вызовами функций.Сборка Sparc - глобальные регистры не согласованы во всех функциях вызова
С традиционной французской версией с использованием локальных регистров и параметров вывода/ввода (в% о0), у меня нет никаких проблем, код прекрасно работает,
, но когда я хочу использовать другой вариант с глобальными регистрами, У меня есть проблема непротиворечивости.
Вот код:
.data
.LLC0: .asciz "fact(5) = %d\n"
.text
.global main
main:
save %sp, -96, %sp
set 5, %g1 ! value 5 into %g1 register
sethi %hi(.LLC0), %g2
or %g2, %lo(.LLC0), %o0
mov %g1, %o1
call printf
nop
mov %g1, %o0 ! set %g1 into parameter for fact function
call fact
nop
mov %o0, %g4
sethi %hi(.LLC0), %g3
or %g3, %lo(.LLC0), %o0
mov %g4, %o1
call printf
nop
ret
fact:
addcc %g1, -1, %g1 ! current index of the procedure -
! supposed to be decremented at each call -
be term ! PROBLEM : %g1 always set to 0 before decrement
nop
sethi %hi(.LLC0), %g2
or %g2, %lo(.LLC0), %o0
mov %g1, %o1
call printf ! printf the value of %g1 :
! still equal to -1 at execution
nop
call fact
nop
mov %o0, %g2
umul %g2, %g1, %g2
mov %g2, %i0
ret
term: set 1, %o0
ret
Моя проблема заключается в том, что, в fact
функции, глобальный регистр %g1
устанавливается в 0
при каждом вызове, так что печать %g1
дает всегда -1
при исполнении.
Из этого link я думал, что глобальные регистры являются постоянными во всех вызовах функций, т. Е. Их область действия глобальна и разделена любой функцией в коде.
Например, здесь я поставил set 5, %g1
в основном разделе, и, как правило, я должен получить 4
для напечатанного значения в функции fact
.
Если бы кто-нибудь мог понять, что случилось?
Благодаря
UPDATE:
вызов Printf использует% о0 и% o1, а не% g1. У меня все еще есть проблемы с объемом глобальных регистров (% g5-g7). Вот пример их использования, как это:
.data
.LLC0: .asciz "fact(5) = %d\n"
.text
.global main
main:
save %sp, -120, %sp
set 5, %g5
sethi %hi(.LLC0), %g2
or %g2, %lo(.LLC0), %o0
mov %g5, %o1
call printf
nop
mov %g5, %o0
call fact
nop
mov %o0, %g7
sethi %hi(.LLC0), %g3
or %g3, %lo(.LLC0), %o0
mov %g7, %o1
call printf
nop
ret
restore
fact:
addcc %g5, -1, %g5
be term
nop
sethi %hi(.LLC0), %g2
or %g2, %lo(.LLC0), %o0
mov %g5, %o1
call printf
nop
call fact
nop
mov %o0, %g6
smul %g6, %g5, %g6
mov %g6, %o0
ret
term: set 1, %o0
ret
В этом коде я напечатает значение global %g5 register
при каждом рекурсивном вызове и выход:
fact(5) = 5
fact(5) = 838860799
fact(5) = 838860798
fact(5) = 838860797
fact(5) = 838860796
fact(5) = 838860795
fact(5) = 838860794
fact(5) = 838860793
fact(5) = 838860792
fact(5) = 838860791
fact(5) = 838860790
...
кажется, первый вызов факта из основной вывод теряют начальное значение для %g5
(инициализировано до 5
)
Где моя ошибка?
Благодаря