2016-02-14 122 views
0

我有這樣的代碼轉換成裝配任務:轉換C代碼,以MIPS(彙編源代碼)

int prodArray (int A[], int n) { 
    if (!n) 
     return 1; 
    else if (n == 1) 
     return A[0]; 
    int mid = n/2; 
    int left = prodArray(A, mid); 
    int right = prodArray(A + mid, n - mid); 
    return left * right; 
} 

這裏是我到目前爲止,並注意循環,循環2和循環3相當大致相同:

main: 
    add $t0, $0, $0   # Initialize t0 
    add $t1, $0, $0   # Initialize t1 
    addi $t4, $0, 1   # Make t2 equal to 1 

# Main Loop 
loop: 
    beq $a1, $t2, exit  # If the second argument is 0 branch to exit 
    beq $a1, $0, exit2  # If the second argument is 1 branch to exit2 
    srl $t2, $a1, 1   # Divide n by 2 
    sll $t3, $a1, 1   # Multiply n by 2 
    add $a1, $t2, $0  # make n half 
    b loop2     # branch to loop 

loop2: 
    beq $a1, $t2, exit 
    beq $a1, $0, exit2 
    srl $t2, $a1, 1 
    sll $t3, $a1, 1 
    add $a0, $a0, $t2  # Make a0 point to A + mid 
    b loop3 

loop3: 
    beq $a1, $t2, exit 
    beq $a1, $0, exit2 
    srl $t2, $a1, 1 
    sll $t3, $a1, 1 
    add $a1, $t2, $0 
    b loop 

# exit 
exit: 
    ja $ra, $t4 

exit2: 
    ja $ra, 0(a1) 

我不是很擅長組裝,需要任何幫助,我可以得到。請注意,a0是第一個參數,而a1是第二個參數。

感謝您的任何指導!

+0

我看錯了,還是原來的函數可以實現爲一個簡單的線性循環?當然,對於浮點數不是這樣,但對於整數,順序應該沒有區別。 – sh1

+0

它可能是。我沒有做這個功能,我的一位教授做了。 @ sh1 – Logan

+0

在那些情況下(儘管在面試中更多),我想知道他們是否在測試你是否在修改代碼之前修改了代碼(這是一個很好的行業慣例,因爲你不需要真正想在優化算法之後再對程序進行手工編碼),或者他們只是沒有正確地考慮他們的測試用例,並會因爲改變算法而給你打分。 – sh1

回答

0

下面的幾個三分球......

  1. 有沒有你開始用C代碼的任何循環,所以不應該在你的組件中的任何環無論是。這個函數確實調用它自己,但是應該像其他子程序調用那樣執行(即使用jal),而不是試圖將函數內聯到自身中。 (事實上​​,你無法內聯這個子程序沒有一些比較重大的重構。)

    記得保存,你需要在子程序調用後恢復,包括在$v0和原始參數的堆棧上的任何寄存器$v1,返回地址$ra

  2. 沒有ja指令。在子程序末尾使用的正確指令是jr $ra,在執行該指令之前需要將返回值放入$v0

  3. 不要忘記分支延遲插槽!我看到一些指令最終會執行的地方,你不想要的;現在您可能想在每個條件分支後面粘貼一個nop

0

如果您有gcc編譯器,請使用-S開關,例如:gcc -S helloworld.c。這將生成一個帶有彙編代碼的.s文件。這個問題有更多的信息:How do you get assembler output from C/C++ source in gcc?

+0

感謝您的提示!我使用了gcc開關,但它似乎使用了我以前從未見過的命令(如:pushq,movq,cmpl,cltd),並不是我在課堂上看到的命令。但至少讓我走上正軌。 – Logan

+0

@Anon這是生成x86彙編,而不是MIPS彙編。 – duskwuff

+0

@Anon如果你使用x86主機,那麼你需要找到你的MIPS交叉編譯器版本的gcc。例如,它可能被稱爲'gcc-mips64-linux-gnuabi64'。你也可以嘗試'clang --target = mips'(或者mips64或者其他),如果你有這個方便的話,它可以配置爲MIPS。 – sh1