2017-10-17 211 views
1

我試圖將C代碼轉換爲MIPS代碼。MIPS嵌套函數調用

int main() { 
    int a; 
    int b; 
    int result = 0; 
    if (a != b) 
    result = test(a, b); 
    else 
    result = a + b; 
    return result; 
} 
int test(int a, int b) { 
    if (a > b) 
    return multiply(a, b) 
    else 
    return subtract(a, b) 
} 
int multiply(int a, int b) { 
    return a * b; 
} 
int subtract(int a, int b) { 
    return a - b; 
} 

此代碼包含測試函數內部的嵌套函數調用。 我已經把測試函數的返回地址放入堆棧,並試圖將相減或相乘的值返回給main。

但在我的情況下,我的代碼執行減法和乘法函數。 我試圖把我的結果給s0。運行s0後總是顯示減值。如果我把乘法結果放到s1,s1顯示真值。

我認爲減法函數覆蓋s0的值。但是,當案件繁多時,爲什麼減法被調用?我有一個if/else塊,但這部分似乎不起作用。

這是我的MIPS代碼,我做錯了什麼?

.data 
    numberA: .word 4 
    numberB: .word 2 
.text 
.globl main 

    main: 
    addi $s0, $0, 0 # result = 0 
    lw $a0, numberA 
    lw $a1, numberB 

    bne $a0, $a1, L1 
    add $s0, $a0, $a1 
L1: jal test 

    add $s0, $v0, $0 

    li $v0,10 
    syscall 


test: 
     addi $sp, $sp, -4 
     sw $ra, 0($sp) 

     slt $s1,$a1,$a0 
     bne $s1, 1, ELSE 
     jal multiply 
ELSE: jal subtract 

lw $ra, 0($sp) 

addi $sp, $sp, 8 

jr $ra 


subtract: 
    sub $s0, $a0, $a1 
    jr $ra 


multiply: 
    mult $a0, $a1 
    mflo $s0 
    jr $ra 
+0

這不是一個嵌套函數。這將是'int foo(){int nested(){return 1;}等等等等等等。 blah foo(); },其中'nested()'可以訪問'foo'中的局部變量。 GCC支持: https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html。你在做什麼只是從一個函數進行函數調用。這很正常。不進行任何調用的函數稱爲葉函數(它們是調用樹的葉)。所以你真的在問如何在MIPS中編寫非葉函數。 –

回答

2

的問題是,當您從回,你仍然電話下一行。在調用乘以後,您必須從功能測試返回。 然而,由於函數調用你的函數雙方的最後一條指令,你可以使用下面的快捷鍵:

test: 
     slt $s1,$a1,$a0 
     bne $s1, 1, ELSE 
     j multiply 
ELSE: j subtract 

這樣,您就不必存儲$ RA中的籌碼,但你可以直接用它jr $ra的減跳回到呼叫者測試的。這樣它應該按預期工作。

或者,跳過jal subtract從乘法返回後:

 jal multiply 
     j OUT 
ELSE: jal subtract 

OUT: ... 
+0

感謝您的快速回復,但我必須使用堆棧,因爲這是我的作業:) – mekafe

+1

@mekafe好的,然後使用替代方法,重點是:不要從乘法返回後跳到減法 – Ctx