I have this C code:
#include <stdio.h>
 
 int BubbleSort(int *v);
 
 int main()
 {
     int x1=4,x2=2,x3=10,x4=1,x5=6;
     printf("The value of f is: %d\n", PolyCalc(x1,x2,x3,x4,x5));
     return 0;
 }
 
 int BubbleSort(int *array){
     int i,j,changes = 0,inPosition, size = 5;
     for (i = 1; i < size; i++)
     {
         inPosition = 0;
         for(j = 0; j < size - i; j++)
         {
             if(array[j] > array[j+1])
             {
                 int temp = array[j];
                 array[j] = array[j+1];
                 array[j+1] = temp;
                 inPosition = 1;
           changes++;
             }
         }
         if(!inPosition){
             break;
         }
     }
     return changes;
  }
 This is what I want to do.
1 - Calculate PolyCalc (PolyCalc is codded in Assembly - Will post code below)
2 - From the assembly PolyCalc code, jump to the C BubbleSort function and receive the return in the assembly code
3 - On the Assembly code, print the number of changes that BubbleSort made until the array was sorted
4 - Return the PolyCalc resulting value to the C code and make the final printf.
This is my Assembly code:
01          .data
 02  print:      .asciiz "Where made %d changes until the array was sorted\n"
 03          .text
 04          .globl  PolyCalc
 05
 06  PolyCalc:
 07
 08      
 09      lw      $8, 16($29)     # Goes to the stack and gets x5
 10      addi    $29,$29, -4     # Reserve space on the stack
 11      sw      $31,0($29)      # Stores the ra of the caller on the stack
 12      
 13      # Calculate this f = 2(x1+x2)(x3-3x4x5)
 14
 15      add $10,$4,$5           # Adds x1 and x2
 16      mul $10,$10,2           # Multiply by 2 the sum of x1 and x2
 17      mul $11,$7,$8           # Multiply x4 e x5
 18      mul $11,$11,3           # Multiply by 3 the multiplication of x4 by x5
 19      sub $11,$6,$11          # x3 minus the previous result
 20      mul $10,$10,$11         # Makes the final product
 21      
 22      
 23      ##### Will add some code one this space later #######
 24      
 25      
 26      
 27
 28
 29      
 30      
 31      
 32      
 33      
 34
 35      
 36      
 37      move    $2, $10         # Moves the the return value
 38  fim:    
 39      
 40      lw      $31,0($29)      # Loads the return address of the caller
 41      addi    $29,$29,4       # Restores  stack pointer
 If I compile both my main.c and prog.s I get this output
The value of f is: -96 So the first part is OK. Not only it's calculating the value as it should but also returns the value to my main.c and main.c prints the result.
Second part.
 Create a print on assembly. Added this code to the previous one.
29      #Prints the number of changes on BubbleSort
 30      la  $4,print
 31      move    $5,$10
 32      lw  $25,%call16(printf)($28)
 33      jalr    $25
 Running this the output is
Where made -96 changes until the array was sorted
The value of f is: 1
I can see now that the print is working ok. Although It's not printing the number of changes made on BubbleSort it´s printing the correct value that I've passed to printf.
The last printf it's not working as expected. If I change 33       jalr    $25 to 33     j   $25 it prints The value of f is: 50. So this is my first question:
Q1 - Why it's not returning the right value (-96) to my main.c?
Did not change nothing on my register $10 so it should return the right value...
Made this changes to the code:
10      addi    $29,$29, -8     # Reserve space on the stack
 11      sw  $31,4($29)
 22      sw  $10,0($29)          # Stores on the stack the value calculated on the above lines
 35      lw  $10,0($29)      # Restores PolyCalc value
     40      lw  $31,4($29)
 41      addi    $29,$29,8       # Restores  stack pointer
 And gives this:
Where made -96 changes until the array was sorted
Bus error
Made this:
10      addi    $29,$29, -8     # Reserve space on the stack
 11      sw  $31,0($29)
 22      sw  $10,4($29)          # Stores on the stack the value calculated on the above lines
 35      lw  $10,4($29)      # Restores PolyCalc value
 40      lw  $31,0($29)
 41      addi    $29,$29,8       # Restores  stack pointer
 Now it works but I quite understand why. The output is:
Where made -96 changes until the array was sorted
The value of f is: -96
Q2 - Why does the second solution work and not the first one?
Final step. Since the assembly code is returning the correct value to main.c and the print function is working as expected inside the assembly code, just have to call from my prog.s the BubbleSort function on main.c.
Made this:
24      la  $4,0($4)        # Stores in  `$4` the address of the first parameter 
 25      j   BubbleSort      # Calls bublesort
 26      move    $14,$2          # Moves to `$14` the number of changes made
 31      move    $5,$14                  # Print the number of changes
 It gives:
Segmentation fault
 Final attempt. Thought this way. Since 09      lw      $8, 16($29)     # Goes to the stack and gets x5gets x5 give it a try and made 08      la  $15,0($29) believing that the address of the first element of the array was here. Changed 24      la  $4,0($4) to 24        la  $4,0($15) and running this gives:
The value of f is: 6
 So no segmentation fault but still not correct.
Q3 - What am I doing wrong? How can I call bubblesort inside my assembly code?
No comments:
Post a Comment