2017-09-30 564 views
-1

我试图将C程序转换为MIPS汇编程序。以下是该程序我的C代码:(注:灯泡[数字]是用于由用户输入的“数量”初始化为全零个值的数组)将C程序转换为MIPS汇编语言程序

for(int i = 1; i <= number; i++) 
      for(int j = 1; j <= number; j++) 
       if(j % i == 0) 
        Bulbs[j-1] = (Bulbs[j-1] + 1) % 2; 

什么我到目前为止是如下:

li $t0, 0     #$t0 is set to 0 to be used as index for for loop1 
li $t1, 0     #$t1 is set to 0 to be used as index for for loop2 

li $s2, 4     #integer 4 is stored in s2 
mult $s3, $s2    #input number($s3) is multiplied by 4 
mflo $s4     #result of multiplication is stored in $s4 

loop1: 
bgt $t0, $s4, end_loop1  #if t$0 > $s4(input number*4), exit loop1, 
          #performing multiplication by 4 since word occupies 4 bytes 
addi $t3, $t3, 1    #t3 is initialized to serve as "i" from for loop1 
loop2: 
    bgt $t1, $s4, end_loop2 #if $t1 > (input number*4), exit loop2 
    addi $t4, $t4, 1   #t4 is initialized to serve as "j" from for loop2 
    div $t4, $t3 
    mfhi $t5    #$t4 % $t3 is stored in $t5 
    bne $t5, $zero, if_end #checking for if condition 

    if_end: 
    addi $t1, $t1, 4  #increment $t1 by 4 to move to next array element 
    j loop2     #jump back to top of loop2 

end_loop2: 
addi $t0, $t0, 4   #increment $t0 by 4 
j loop1      #jump back to the top of loop1 

end_loop1: 

我想我的for循环实现的作品和我有,如果有条件的准确建立(纠正我,如果我错了),但我不知道我怎么能实现“灯泡[J- 1] =(灯泡[j-1] + 1)%2;'在我之后如果有条件的话。我是MIPS新手,希望得到任何帮助或反馈!

+4

“将C代码转换为汇编代码,是不是为* *编译器*工作? ;) –

+4

这个转换器被称为“编译器”,它比99.99%的人类转换器好得多 - 这里是你的代码; https://godbolt.org/g/CPZtob –

+0

嘿@ PeterJ_01,这很有意义。但是像$ LFB24 =这样的行呢。和$ LBB5 =。代表? –

回答

0

我假设你有Bulbs定义为一个数组的地方。然后

Bulbs[j-1] = (Bulbs[j-1] + 1) % 2; 

应转换为类似:

la $t7, Bulbs # Move base pointer of bulbs to $t7 
add $t7, $t7, $t1 # $t7 = &Bulbs[j] 
lw $t6, -4($t7) # $t6 = Bulbs[j - 1] 
addi $t6, $t6, 1 # $t6 = Bulbs[j - 1] + 1 
andi $t6, $t6, 1 # $t6 = (Bulbs[j - 1] + 1) % 2 
sw $t6, -4($t7) # Bulbs[j - 1] = $t6 

这是基于this information。我之前没有完成MIPS汇编,但它是RISC,所以它有多难? :)

顺便说一句,您的汇编翻译似乎有一个错误。在C版本中,您的j从1开始,而在汇编版本中它似乎从0开始($t1数组索引刚刚在第二行被初始化为0,直到循环体之后才得到修改)。修复很简单 - 将其初始化为4而不是0.

+2

你在开玩笑吗? 'rem'硬件部门的一个不变除数2? (https://stackoverflow.com/questions/40354978/why-is-this-c-code-faster-than-my-hand-written-assembly-for-testing-the-collat​​/40355466#40355466)。还是说汇编器会变成一个“AND”的伪指令?我们知道'灯泡[j-i]'是非负的。 –

+0

@PeterCordes良好的评论 - 这是一个小小的冲激响应。没有编写足够的汇编程序来快速优化(x%2)为(x&0x1),但它很明显,让我更新我的答案。但最后,与“rem”相比,差异_应该是一个单独的指令(div +移动与单一对比),而不是那么糟糕。 – K4rolis

+2

并非所有的指令都以相同的速度运行。在现代x86上,''div比'和'(1周期)大约高30倍。如果有的话,MIPS可能会更糟糕,因为高性能的硬件分割器是昂贵的(在硅芯片领域)。请参阅我链接的关于更多关于划分缓慢的答案,以及您如何知道自己在做什么以制作比编译器更好的代码。 (但是,如果你这样做,你经常可以。) –