2014-12-22 48 views
1

我目前正在研究計算5階乘的簡單SPARC彙編代碼。我想知道爲什麼我使用的全局寄存器通過函數調用不一致。Sparc程序集 - 整個函數調用中的全局寄存器不一致

隨着使用的局部寄存器和輸入/輸出參數traditionnal版本(進入%O0),我沒有問題,代碼工作正常,

,但是當我想用另一個版本與全球寄存器,我有這個一致性問題。

下面的代碼:

.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使用%O0和01%,而不是%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

我的錯誤在哪裏?

感謝

回答

1

從SPARC彙編語言參考手冊(https://docs.oracle.com/cd/E26502_01/html/E28387/toc.html

6.2寄存器使用

全局寄存器%g0-%G7更加複雜。 %g0寄存器始終爲零。該%G6和G7%,始終保留操作系統,所以彙編代碼不應該對其進行修改。其他全局寄存器,%g1-%g5,調用者保存,並可供應用程序代碼使用。但請注意,%g1和%g5可用於程序鏈接表(PLT)或其他插入代碼中,因此不能用於將參數從調用者傳遞給被調用者。

(我的重點)

我覺得你的問題是,「整個功能一致稱之爲」指調用和返回指令(等)不影響寄存器(用寄存器窗口切換),但調用約定確實允許被調用者更改寄存器,因此內容可能無法通話。

0

%g1 - %g4 are volatile - 你到printf呼叫佔優你把%g1更早的價值,因爲printf的實現也使用它。

相關問題