2017-10-17 29 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; 
} 

이 코드에는 테스트 기능 내에 중첩 된 함수 호출이 들어 있습니다. 테스트 함수의 리턴 주소를 스택에 넣고 빼거나 곱한 값을 메인으로 리턴하려고합니다.

제 경우에는 제 코드가 빼기 및 곱하기 함수를 모두 실행합니다. 내 결과를 s0에 넣으려고합니다. 실행 후 s0은 항상 값의 빼기를 표시합니다. 곱셈 결과를 s1에 곱하면 s1은 참값을 나타냅니다.

나는 빼기 함수가 s0에서 값을 무시한다고 생각합니다. 그러나 case가 곱 해져서, subtract method가 호출되는 이유는 무엇입니까? 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 blah foo(); ㅋㅋ 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 

이 방법은, 당신이 당신의 스택은 $ 라를 저장할 필요는 없지만, 당신이 직접 할 수 있습니다 함수 호출은 함수의 마지막 명령 모두 있기 때문에 그러나, 다음과 같은 바로 가기를 사용할 수 있습니다 jr $ra의 빼기다중테스트발신자로 다시 이동을 사용합니다. 이렇게하면 의도 한대로 작동해야합니다.

대안 곱셈으로부터 돌아온 jal subtract 위에 이동 :

 jal multiply 
     j OUT 
ELSE: jal subtract 

OUT: ... 
+0

답장을 보내 주셔서 감사합니다.하지만 제 숙제이기 때문에 스택을 사용해야합니다 :) – mekafe

+1

@mekafe 그래, 다른 방법을 사용하면 요점은 다음과 같습니다. 곱하기에서 돌아온 후에 빼기로 이동하지 마십시오. – Ctx