Advertisement
slashdemonofthesword

ARM Assembly Merge Sort

Nov 11th, 2018
2,107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ARM 14.01 KB | None | 0 0
  1. @ ANGUEL ESPERANZA
  2.  
  3.  
  4. .data
  5. .balign 4
  6.    string1: .asciz "\n l= %d,r=%d"
  7. .balign 4
  8.    string2: .asciz "\n A= %d"
  9. .balign 4
  10.    A:       .skip 512 @128*4
  11. .balign 4
  12.    B:       .skip 512 @128*4
  13. .balign 4
  14.    C:       .skip 512 @128*4
  15. .balign 4
  16.    N:  .word 128
  17.  
  18. /* CODE SECTION */
  19. .text
  20. .balign 4
  21. .global main
  22. .extern printf
  23. .extern rand
  24.  
  25.  
  26. @mergeSort(int arr[], int l, int r)
  27. mergeSort: push {r0,r1,r2,LR}
  28. @    {
  29.      push {r0,r1,r2}
  30.      ldr r0,=string2
  31.      bl printf
  32.      pop {r0,r1,r2}
  33.  
  34. @    if (l < r)
  35.      cmp r1,r2
  36.      bge mergeSortEnd
  37. @    {
  38. @        // Same as (l+r)/2, but avoids overflow for
  39. @        // large l and h
  40.          push {r1,r2}   @ save L and R
  41. @        int m = l+(r-l)/2;
  42.          sub r2,r2,r1  @ This was a bug (was a 1) int the morning and afternoon versions
  43.          lsr r2,r2,#1
  44.          add r2,r2,r1
  45.          push {r2}  @ save m
  46. @        // Sort first and second halves
  47. @        mergeSort(arr, l, m);   // Remember l is R1, R2 is r=m
  48.          bl mergeSort
  49.          pop {r3}   @ put m into r3
  50.          pop  {r1,r2}  @restored l and r
  51.          push {r1,r2}
  52.          push {r3}
  53.          add  r1,r3,#1
  54. @        mergeSort(arr, m+1, r);
  55.          bl mergeSort
  56.          pop {r3}
  57.          pop  {r1,r2}
  58. @      // Not doing the merge step for now
  59. @      //  merge(arr, l, m, r);
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68. @   >>>>>    Note the formal params are r0=arr,r1=l,r3=m,r2=r <<<<<<<<<<<<<<<<<
  69. @    }
  70. mergeSortEnd: pop {r0,r1,r2,PC}  @ notice put LR into PC to force return
  71. @}
  72.  
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79. @-------------- MERGE CODE  START ------------------------
  80.  
  81. @ This line will be copied and paste around the merge function so I do not have to scroll up and down consistantly when writting the code
  82. @r1 -> 'l' | r2 -> 'r' | r3 -> 'm' | r4 -> 'i'; | r5 -> 'j' | r6 -> 'k' | r7 -> 'n1' | r8 -> 'n2' | r9 -> Array B [L] | r10 -> Array C [R] | r11 -> No use| r12 -> No use
  83. @----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  84. merge:
  85.  
  86. @    void merge(int arr[], int l, int m, int r)
  87. @{
  88. @    int i, j, k;
  89.     mov r4, #0 @ initilizing 'i'
  90. @    int n1 = m - l + 1;
  91.     mov r7, #0 @ initializing 'r1'
  92.     add r7, r3 @ r3 is 'm'. I added 'm' to n1 first as that way I don't have to push/pop 'm'
  93.    sub r7, r7, r1 @ We are taking l away from m.
  94.    add r7, r7, #1 @ Just adding 1 to the n1
  95. @    int n2 =  r - m;
  96.    mov r8, #0
  97.    add r8, r8, r1 @ Adding r to n2 for the same resason I did m into n1. Doing it this way avoids having to push/pop uncessessarily
  98.    sub r8, r8, r3 @ Just taking m away from r (essentially n2 at this point)
  99.    @^-- Do to the multiple times i've written this code and not knowing where it crashes, i'm going to be making comments periodicaly that will let me know,
  100.    @ the chunk of code up to this point work. This will help when debugging as I know where the last section of working code is.
  101.  
  102.    @^--- THIS CODE WORKS UP TO THE POINT ABOVE -----^
  103.    @ -----------------------------------------------
  104. @    /* create temp arrays */
  105. @    int L[n1], R[n2];
  106.    @ L[n1] will be array B
  107.    @ R[n2] will be array C
  108. @    /* Copy data to temp arrays L[] and R[] */
  109. @    for (i = 0; i < n1; i++)
  110.  
  111. @ This line will be copied and paste around the merge function so I do not have to scroll up and down consistantly when writting the code
  112. @r1 -> 'l' | r2 -> 'r' | r3 -> 'm' | r4 -> 'i'; | r5 -> 'j' | r6 -> 'k' | r7 -> 'n1' | r8 -> 'n2' | r9 -> Array B [L] | r10 -> Array C [R] | r11 -> No use| r12 -> No use
  113. @----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  114.  
  115. @ This is the for loop that iterates through and does the proper data assignments for L[n1], hence it's name 'forLoopL'
  116. @ For L[n1] I am going to use r4 for indexing and r11 as the index element. I must remember to push/pop after I'm done
  117.  
  118.    mov r11, #0
  119.    mov r12, #0
  120.  
  121.    @ I have set those registers outside of the for loop as it will conistently be reset to 0 each time the for loop iteration
  122. @        L[i] = arr[l + i];
  123. @forLoopL is L[i] = arr[l + i]
  124. forLoopL:
  125.    cmp r4, r7 @ checks to see if we have finished out iteration
  126.    bge forLoopLEnd @ Leave the for loop if we are doen iterating
  127.    ldr r9, =B @ Load L[i]
  128.    lsl r11, r4, #2 @ Gets our indexed value offset (i * 4)
  129.    add r11, r9, r11 @ This is the L[i] part of the array. Remember that the array has 128 elements, where each element is 4 bytes long. Thus, we are adding i to our current
  130.                        @ spot in the array.
  131.    str r11, [r11] @ Stores the value of the of our indexed element.
  132.    @^---L[i]
  133.  
  134.    ldr r0, =A @ Arr load
  135.    lsl r12, r4, #2 @ Gets our index  value offset (i * 4) : I'm doing this again as this element was never added to a register and left untouched.
  136.     add r12, r12, R1 @ We want our value that is at l + i, not just i. Which is why this extra step is done here and not with L[i]
  137.     add r12, r0, r12 @ Getting the memory address in r0 of our desired element
  138.     str r12, [r12] @ Storing the value of our indexed value.
  139.  
  140.     str r12, [r11] @ Setting L[i] to equal arr[l + i]
  141.  
  142.     add r4, r4, #1 @ i++
  143.  
  144. forLoopLEnd:
  145. @^--- THIS CODE WORKS UP TO THE POINT ABOVE ---^
  146. @ -----------------------------------------------
  147.  
  148.  
  149. @ This line will be copied and paste around the merge function so I do not have to scroll up and down consistantly when writting the code
  150. @r1 -> 'l' | r2 -> 'r' | r3 -> 'm' | r4 -> 'i'; | r5 -> 'j' | r6 -> 'k' | r7 -> 'n1' | r8 -> 'n2' | r9 -> Array B [L] | r10 -> Array C [R] | r11 -> No use| r12 -> No use
  151. @----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  152.  
  153.  
  154.     mov r11, #0
  155.     mov r12, #0
  156.     @ I'm going to use these for the j for loop. The reason I didn't push them to the stack is because I do not need to save their values. I want to overwrite them.
  157.  
  158.     @ j was set to 0 earlier in the code.
  159. @    for (j = 0; j < n2; j++)
  160. @        R[j] = arr[m + 1+ j];
  161. forLoopJ:
  162.     cmp r5, r8
  163.     bge forLoopJEnd
  164.     ldr r10, =C
  165.     lsl r11, r5, #2 @ J * 4 indexed element.
  166.     add r11, r10, r11 @ Get the memeory address of our indexed element
  167.  
  168.     str r11, [r11] @ stores our value into r11
  169.     @ ^-- This is R[j]
  170.  
  171.     ldr r0, =A
  172.     lsl r12, r8, #2 @ indexed element position in array
  173.     add r12, r12, r3 @ adding m to it
  174.     add r12, r12, #1 @ adding 1 to it
  175.     add r12, r0, r12
  176.  
  177.     str r12, [r12]
  178.  
  179.     str r12, [r11]
  180.  
  181.     add r8, r8, #1
  182.  
  183. forLoopJEnd:
  184. @^--- THIS CODE WORKS UP TO THE POINT ABOVE ---^
  185. @ ----
  186.  
  187. @ This line will be copied and paste around the merge function so I do not have to scroll up and down consistantly when writting the code
  188. @r1 -> 'l' | r2 -> 'r' | r3 -> 'm' | r4 -> 'i'; | r5 -> 'j' | r6 -> 'k' | r7 -> 'n1' | r8 -> 'n2' | r9 -> Array B [L] | r10 -> Array C [R] | r11 -> No use| r12 -> No use
  189. @----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  190.  
  191. @    /* Merge the temp arrays back into arr[l..r]*/
  192. @    i = 0; // Initial index of first subarray
  193.     mov r4, #0
  194. @    j = 0; // Initial index of second subarray
  195.     mov r5, #0
  196. @    k = l; // Initial index of merged subarray
  197.     mov r6, #0
  198.     add r6, r6, r1 @ After this I am going to pop r1. But before I did, I wanted to make sure I used it for k, which I did.
  199.  
  200.     mov r11, #0 @ This will be used for L[i]
  201.     mov r12, #0 @ This will be used for R[j]
  202.  
  203.     push {r1} @ I am going to a register for the while loops. I don't have a spare free one so I chose r1. I need to pop it from the stack after I am done using it though.
  204.                @ r1 -> arr[k]
  205.  
  206.    @ I didn't push these to the stack before setting them to 0 as I do not need the contents later on.
  207. @    while (i < n1 && j < n2)
  208. whileLoop1:
  209.         cmp r4, r7 @ i < n1
  210.         bge whileLoop1End
  211.         cmp r5, r8 @ j < n2
  212.         bge whileLoop1End
  213. @    {
  214. @
  215. @
  216. @        k++;
  217. @    }
  218.  
  219. whileLoop1End:
  220.  
  221.     bl whileLoop2 @ Branch to whileLoop2 and not run the if statements once whileLoop1 is complete
  222.  
  223. ifStatement:
  224.  
  225. @ This line will be copied and paste around the merge function so I do not have to scroll up and down consistantly when writting the code
  226. @r1 -> 'l' | r2 -> 'r' | r3 -> 'm' | r4 -> 'i'; | r5 -> 'j' | r6 -> 'k' | r7 -> 'n1' | r8 -> 'n2' | r9 -> Array B [L] | r10 -> Array C [R] | r11 -> No use| r12 -> No use
  227. @----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  228.  
  229. @if (L[i] <= R[j])
  230.  
  231. @       {
  232. @            arr[k] = L[i];
  233. @            i++;
  234. @        }
  235.  
  236.  
  237.  
  238.  
  239.  
  240.     @ This code is from an earlier point in the code. There was no point in retyping what I already had so I copied it down.
  241.     ldr r9, =B @ Load L[i]
  242.     lsl r11, r4, #2 @ Gets our indexed value offset (i * 4)
  243.     add r11, r9, r11 @ This is the L[i] part of the array. Remember that the array has 128 elements, where each element is 4 bytes long. Thus, we are adding i to our current
  244.                         @ spot in the array.
  245.  
  246.     str r11, [r11]
  247.     @^--- L[i]
  248.  
  249.  
  250.     ldr r10, =C
  251.     lsl r12, r5, #2 @ J * 4 indexed element.
  252.     add r12, r10, r12 @ Get the memeory address of our indexed element
  253.  
  254.     str r12, [r12] @ stores our value into r11
  255.     @^--- R[j]
  256.  
  257.     cmp r11, r12
  258.     bgt elseStatement
  259.     ldr r0, =A
  260.     lsl r1, r6, #2 @ indexed element position in array
  261.     add r1, r0, r1
  262.     str r1, [r1]
  263.  
  264.     str r11, [r1]
  265.  
  266.     add r4, r4, #1 @ i++
  267.     add r6, r6, #1 @ k++ | This is done after the forloop has been run. It DOES NOT matter if it was the main for loop, or the else statement. So I am adding it here
  268.                     @ and will add it to the else statement as well.
  269.  
  270.     bl whileLoop1 @ return back to the while loop
  271.  
  272.  
  273.  
  274.  
  275. elseStatement:
  276.  
  277. @ This line will be copied and paste around the merge function so I do not have to scroll up and down consistantly when writting the code
  278. @r1 -> 'l' | r2 -> 'r' | r3 -> 'm' | r4 -> 'i'; | r5 -> 'j' | r6 -> 'k' | r7 -> 'n1' | r8 -> 'n2' | r9 -> Array B [L] | r10 -> Array C [R] | r11 -> No use| r12 -> No use
  279. @----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  280.  
  281. @else
  282. @        {
  283. @            arr[k] = R[j];
  284. @            j++;
  285. @        }
  286.  
  287.  
  288.  
  289.     ldr r0, =A
  290.     lsl r1, r6, #2 @ indexed element position in array
  291.     add r1, r0, r1
  292.     str r1, [r1]
  293.     @^--- arr[k]
  294.  
  295.     str r12, [r1] @ The reason why the array for j is not in else, is because it runs before the else statement has been reached, thus already in memeory.
  296.                     @ remaking it would not make much sense.
  297.  
  298.     add r5, r5, #1 @ j++
  299.     add r6, r5, #1 @ k++
  300.  
  301.     bl whileLoop1
  302.  
  303. @^--- THIS CODE WORKS UP TO THE POINT ABOVE ---^
  304. @ ----
  305.  
  306.  
  307. @ This line will be copied and paste around the merge function so I do not have to scroll up and down consistantly when writting the code
  308. @r1 -> 'l' | r2 -> 'r' | r3 -> 'm' | r4 -> 'i'; | r5 -> 'j' | r6 -> 'k' | r7 -> 'n1' | r8 -> 'n2' | r9 -> Array B [L] | r10 -> Array C [R] | r11 -> No use| r12 -> No use
  309. @----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  310.  
  311. @ From this point on, most of the code has been copied from earlier spots in this code file.
  312. whileLoop2:
  313.  
  314. @    /* Copy the remaining elements of L[], if there
  315. @       are any */
  316. @    while (i < n1)
  317. @    {
  318. @        arr[k] = L[i];
  319. @        i++;
  320. @        k++;
  321. @    }
  322.  
  323.     cmp r4, r7
  324.     bge whileLoop2End
  325.  
  326.     ldr r9, =B @ Load L[i]
  327.     lsl r11, r4, #2 @ Gets our indexed value offset (i * 4)
  328.     add r11, r9, r11 @ This is the L[i] part of the array. Remember that the array has 128 elements, where each element is 4 bytes long. Thus, we are adding i to our current
  329.                         @ spot in the array.
  330.  
  331.     str r11, [r11]
  332.     @^---- L[i]
  333.  
  334.     ldr r0, =A
  335.     lsl r1, r6, #2 @ indexed element position in array
  336.     add r1, r0, r1
  337.     str r1, [r1]
  338.     @^--- arr[k]
  339.  
  340.     add r4, r4, #1
  341.     add r6, r6, #1
  342.  
  343.     bl whileLoop2
  344.  
  345.     str r11, [r1]
  346.  
  347.  
  348. whileLoop2End:
  349.  
  350. whileLoop3:
  351. @    /* Copy the remaining elements of R[], if there
  352. @       are any */
  353. @    while (j < n2)
  354. @    {
  355. @        arr[k] = R[j];
  356. @        j++;
  357. @        k++;
  358. @    }
  359.  
  360.  
  361.     ldr r10, =C
  362.     lsl r12, r5, #2 @ J * 4 indexed element.
  363.     add r12, r10, r12 @ Get the memeory address of our indexed element
  364.  
  365.     str r12, [r12] @ stores our value into r11
  366.     @^--- R[j]
  367.  
  368.     ldr r0, =A
  369.     lsl r1, r6, #2 @ indexed element position in array
  370.     add r1, r0, r1
  371.     str r1, [r1]
  372.     @^--- arr[k]
  373.  
  374.     str r12, [r1]
  375.  
  376.     add r5, r5, #1
  377.     add r6, r6, #1
  378.  
  379.     bl whileLoop3
  380.  
  381. @}
  382. whileLoop3End:
  383.  
  384.  
  385.     pop {r1} @ at this point, I am done with the merge function and and returning to the mergeSort code
  386.  
  387.     @bl mergeSort
  388.  
  389.  
  390. @-------------- MERGE CODE END --------------------------
  391.  
  392.  
  393. @^--- THIS CODE WORKS UP TO THE POINT ABOVE ---^
  394. @ ----
  395.  
  396.  
  397. main:
  398.     push    {ip,lr}     @ This is needed to return to the Operating System
  399.  
  400.     @ldr     r0,=A
  401.     @mov     r1,#0
  402.     @ldr     r2,=N
  403.     @ldr     r2,[r2]
  404.  
  405.     @bl      mergeSort
  406.  
  407.  
  408.     @ This part of the code was copied from OuterLoopWithMerge.s file as it prints out to the screen
  409.     mov r5,#0           @ Print out the array
  410.     ldr r4,=A
  411. printArray:
  412.     ldr r0,=N
  413.     ldr r0,[r0]
  414.     cmp r5, r0
  415.     beq printArrayEnd
  416.     ldr r0,=string2 @ string2 is a data I created to better display the output
  417.     mov r1,r5
  418.     ldr r2,[r4],#4
  419.     bl printf
  420.     add r5, r5, #1
  421.  
  422.     bl printArray                  /* Go to the beginning of the loop */
  423. printArrayEnd:
  424.  
  425.     @bl mergeSort
  426.  
  427.  
  428.     mov     r0,#0
  429.  
  430.     pop     {ip, pc}    @ This is the return to the operating system
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement