0

i have written a code that permutes a string in all its possible ways. The original code is in C++, and the task of the exercise is to implement the code in C++ in MIPS.For example, if you insert "abc" the result is [abc,acb,bca,bac,cba,cab]. So in C++ looks like this:

void Permutaciones(char * cad, int l) {
char c;    
int i, j;  
int n = strlen(cad);

for(i = 0; i < n-l; i++) {
  if(n-l > 2) Permutaciones(cad, l+1);
  else cout << cad << ", ";

  c = cad[l];
  cad[l] = cad[l+i+1];
  cad[l+i+1] = c;
  if(l+i == n-1) {
     for(j = l; j < n; j++) cad[j] = cad[j+1];
     cad[n] = 0;
  }
 }
}    

and here's my code in MIPS

.data
str:    .asciiz "abc"
coma:   .asciiz ", "

.text


main:

la $a0, str
li $a1, 0   
jal perm
li $v0, 10
syscall

length:
lb $t0, 0($a0)
beq  $t0, $0, preperm
addi $v0, $v0, 1
addi $a0, $a0, 1
j length


preperm:
subu $a0, $a0, $v0                  
jr $ra

perm:
subu $sp, $sp, 32
sw $ra, 0($sp)      #salvo ra
sw $a0, 4($sp)      #salvo cad      
sw $a1, 8($sp)      #salvo L

jal length

sw $v0, 12($sp)     #salvo n
subu $v0, $v0, $v0

lw $a0, 4($sp)      #rescato cad
lw $a1, 8($sp)      #rescato L
lw $t0, 12($sp)     #rescato n

li $t2, 0       #$t2=i=0

for1:
sub $t1, $t0, $a1   # $t1= n- L
bge $t2, $t1, fin1  # i >= n- L   =>  fin1
li $t3, 2       # $t3=2  (constante)
bgt $t1, $t3, recursion #n-L >2 => recursion

mostrar:

li $v0, 4
syscall
la $a0, coma
syscall
subu $v0, $v0, $v0
jal nomostrar


recursion:
sw $t2, 16($sp)     #salvo i
addi $a1, $a1, 1    #l++
jal perm        #recurso

nomostrar:

lw $a0, 4($sp)      #rescato cad
lw $a1, 8($sp)      #rescato L
lw $t0, 12($sp)     #rescato n
lw $t2, 16($sp)     #rescato i

add $t4, $a0, $a1   #$t4 = direccion cad[L]
lb $t5, 0($t4)      #$t5=cad[L]
add $t6, $a0, $a1
add $t6, $t6, $t2
addi $t6, $t6, 1    #$t6=direccion cad [L+i+1]
lb $t7, 0($t6)      #$t7 = cad [L+i+1]
sb $t7, 0($t4)      
sb $t5, 0($t6)      #swap (cad[L],cad [L+i+1])
add $t7, $a1, $t2   #$t7 = L+i
subu $t5, $t0, 1    #$t5 = n-1

bne $t7, $t5, cola  #L+i != n-1  => cola

or $t8, $a1, $0     #t8= j = L

for2:
bge $t8, $t0, cola  # j >= n => cola
add $t5, $a0, $t8   #$t5 = dirección de cad[j]
addi $t1, $t5,1     #$t1 = dirección de cad[j+1]
lb $t7, 0($t1)      #$t7 = cad[j+1] propiamente dicho
sb $t7, 0($t5)      # cad[ j ] = cad[j+1]
addi $t8, $t8, 1    # j++
j for2          # repetir


cola:
add $t8, $a0, $t0   #$t8 = dirección de cad[n] 
sb $0, 0($t8)       # cad[n] = '\0'
addi $t2, $t2, 1    # i++
sw $t2, 16($sp)
j for1          # repetir

fin1:
lw $ra, 0($sp)      #rescato ra
sw $0, 16($sp)
addi $sp, $sp,32    #libero memoria
jr $ra          #retorno

So, the problem is that when i run the program in PCspim using F5 i get the first output "abc" then i get Exception 7 Bad data address two times, and then it shows some more letters of the string. But when I use the step by step function (F10), the code works perfectly. Please someone help me, because i`m losing my mind.

  • I couldn't reproduce the problem you describe with the exception. But the output seemed to be repeated 3 times. – Michael Nov 20 '15 at 18:31
  • Yes, I think its because of the PCSpim version, but still with yours its kind of weird getting a different result with F10 adn F5, isnt it? – Felipe Mirande Nov 20 '15 at 18:34
  • Well, I don't know what's up with that. But what you could do is set a breakpoint e.g. at `mostrar:` and then let program run up until when the last permutation is about to be printed, and then start single-stepping from there (and inspect the stack contents while doing so). That might help you find the problem. – Michael Nov 20 '15 at 18:50
  • Thanks, i'll try it out and will let you know – Felipe Mirande Nov 22 '15 at 00:27

0 Answers0