2016-02-14 128 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