/* * main.s * * Programa en esnsamblador ARM para Raspberry Pi * Genera 1024 bytes aleatorios * Y posteriormente los ordena con el algoritmo Merge Sort * * * Creado : 18 octubre 2019 * Autor : tranki * Licencia : haced lo que os de la gana con este código * Responsabilidad : ninguna */ /* Funciones globales */ .global main, rand, printArray, mergeSort, merge /* Funciones externas */ .global printf, putchar /* Constantes */ .equ ARRAY_LEN, 1024 /* Area de datos */ .data .balign 4 mensaje: .asciz "Esto es la ostia \n" .balign 4 mascara: .asciz "%3d " /* array de 1024 bytes para almacenar los números aleatorios */ .balign 4 array: .skip (ARRAY_LEN * 4) .balign 4 auxarr: .skip (ARRAY_LEN * 4) .balign 4 index: .word 0 /* area de código */ .text /* ------------------------------------------------------------- * Función main * Entrada principal del programa ------------------------------------------------------------- */ main: push {lr} ldr r1, =array /* dirección del array */ mov r2, #0 /* R2 como contador */ /* * Aquí generamos los 1024 enteros aleatorios * y los almacenamos en el bloque "array" */ carga: cmp r2, #ARRAY_LEN /* ¿tenemos los 1024 bytes? */ beq fincarga /* si, salimos del bucle */ bl rand /* extraemos un número aleatorio en R0 */ add r3, r1, r2, LSL #2 /* Actualizamos el índice R3 = R1 + (R2*4) */ str r0, [r3] /* almacenamos el número en el array *R3 ← R0 */ add r2, r2, #1 /* R2 = R2 + 1 */ b carga /* cerramos el bucle */ fincarga: bl printArray /* muestra el array aleatorio por consola */ ldr r0, =array mov r1, #0 mov r2, #ARRAY_LEN sub r2, r2, #1 bl mergeSort /* ordena el array */ mov r0, #0x0A /* añadimos un retorno de carro */ bl putchar /* con la función putchar */ bl putchar /* con la función putchar otra vez*/ bl printArray /* muestra el array ordenado por consola */ mov r0, #0x0A /* añadimos un retorno de carro */ bl putchar /* con la función putchar */ ldr r0, =mensaje bl printf mov r0, #0 pop {lr} bx lr /* Return de main */ /* ------------------------------------------------------------- * Función mergeSort * Ordena un array de enteros * Valores de entrada: * r0 = dirección del array * r1 = índice de inicio de los datos en el array = p * r2 = longitud de los datos = r * retorna: nada ------------------------------------------------------------- */ mergeSort: push {lr} cmp r1, r2 /* (p < r) ? */ blt sigueMerge b outMerge sigueMerge: add r3, r1, r2 /* q = p + r */ asr r3, r3, #1 /* q = q / 2 */ push {r0, r1, r2, r3} //mergeSort(a, p, q); ldr r0, =array /* dirección array */ mov r2, r3 bl mergeSort /* llamada recursiva */ pop {r0, r1, r2, r3} add r4, r3, #1 /* q + 1 */ push {r0, r1, r2, r3} ldr r0, =array /* dirección array */ mov r1, r4 /* mergeSort(a, q+1, r) */ bl mergeSort /* llamada recursiva */ pop {r0, r1, r2, r3} ldr r0, =array /* dirección array */ push {r0, r1, r2, r3} mov r4, r2 /* R4 = r */ mov r5, r3 /* R5 = q */ mov r2, r5 /* R2 = q */ mov r3, r4 /* R3 = r */ /* R1 = p, R2 = q * R3= r */ bl merge /* merge(a, p, q, r) */ pop {r0, r1, r2, r3} outMerge: pop {lr} bx lr /* Return de mergeSort */ /* ------------------------------------------------------------- * Función merge * Ordena un array de enteros * Valores de entrada: * r0 = dirección del array * r1 = índice de inicio de los datos mitad izquierda p * r2 = índice de inicio de los datos mitad derecha q * r3 = longitud de los datos r * retorna: nada ------------------------------------------------------------- */ .data .balign 4 i: .word 0 .balign 4 j: .word 0 .balign 4 k: .word 0 .balign 4 p: .word 0 .balign 4 q: .word 0 .balign 4 r: .word 0 .text merge: push {lr} ldr r4, =p /* *R4 variable p */ str r1, [r4] /* variable p guardada */ ldr r4, =q /* *R4 variable q */ str r2, [r4] /* variable q guardada */ ldr r4, =r /* *R4 variable r */ str r3, [r4] /* variable r guardada */ ldr r4, =i /* *R4 variable i */ ldr r5, =j /* *R5 variable j */ ldr r6, =k /* *R6 variable k arrayAux[k-p]*/ str r1, [r4] /* i = p */ add r2, r2, #1 /* q = q + 1*/ str r2, [r5] /* j = q + 1 */ mov r1, #0 str r1, [r6] /* k = 0 */ loopM1: ldr r4, =q /* *R4 variable q */ ldr r1, [r4] /* carga q */ ldr r4, =i /* *R4 variable i */ ldr r2, [r4] /* carga i */ cmp r2, r1 /* compara i <= q */ bgt outloopM1 /* sale si i > q */ ldr r4, =r /* *R4 variable r */ ldr r1, [r4] /* carga r */ ldr r4, =j /* *R4 variable j */ ldr r2, [r4] /* carga j */ cmp r2, r1 /* compara j <= r */ bgt outloopM1 /* sale si j > r */ ldr r4, =i /* *R4 variable i */ ldr r1, [r4] /* carga i */ ldr r0, =array /* dirección array */ add r3, r0, r1, LSL #2 /* índice al array[i] en R3 */ ldr r1, [r3] /* valor del array en [i] */ add r3, r0, r2, LSL #2 /* índice al array[j] en R3 */ ldr r2, [r3] /* valor del array en [J] */ cmp r1, r2 /* ¿array[i] < array[j]? */ blt maspeq /* si, salta a mas pequeño */ ldr r2, =k /* *R2 variable k */ ldr r2, [r2] /* R2 = k */ ldr r1, =j ldr r1, [r1] ldr r0, =array add r3, r0, r1, LSL #2 /* índice al array[j] en R3 */ ldr r1, [r3] ldr r0, =auxarr /* dirección array auxiliar */ add r3, r0, r2, LSL #2 /* índice al arrayAux[k] en R3 */ str r1, [r3] /* arrayAux[k] = array[j] */ ldr r1, =j /* *R1 variable j */ ldr r2, [r1] /* cargamos variable j */ add r2, r2, #1 /* j = j + 1 */ str r2, [r1] /* guardamos variable j */ b outIf1 maspeq: ldr r2, =k /* *R2 variable k */ ldr r2, [r2] /* R2 = k */ ldr r1, =i ldr r1, [r1] ldr r0, =array add r3, r0, r1, LSL #2 /* índice al array[i] en R3 */ ldr r1,[r3] ldr r0, =auxarr /* dirección array auxiliar */ add r3, r0, r2, LSL #2 /* índice al arrayAux[k] en R3 */ str r1,[r3] ldr r1, =i /* *R1 variable i */ ldr r2, [r1] /* cargamos variable */ add r2, r2, #1 /* i = i + 1 */ str r2, [r1] /* guardamos variable i */ outIf1: ldr r1, =k /* *R1 variable k */ ldr r2, [r1] /* cargamos variable k */ add r2, r2, #1 /* k = k + 1 */ str r2, [r1] /* guardamos variable k */ b loopM1 outloopM1: ldr r1, =q /* *R1 variable q */ ldr r2, =i /* *R2 variable i */ ldr r1, [r1] /* R1 variable q */ ldr r2, [r2] /* R2 variable i */ cmp r2, r1 bgt outloopM2 ldr r1, =k /* *R1 variable k */ ldr r1, [r1] /* R1 variable k */ ldr r2, =i /* *R2 variable i */ ldr r2, [r2] /* R2 variable i */ ldr r0, =array /* dirección array */ add r3, r0, r2, LSL #2 /* índice al array[i] en R3 */ ldr r2, [r3] /* cargamos valor en array[i] */ ldr r0, =auxarr /* dirección array auxiliar */ add r3, r0, r1, LSL #2 /* índice al arrayAux[k] en R3 */ str r2, [r3] /* arrayAux[k] = array[i] */ ldr r1, =i /* *R1 variable i */ ldr r2, [r1] /* cargamos vararrayAux[k-p]iable i */ add r2, r2, #1 /* i = i + 1 */ str r2, [r1] /* guardamos variable i */ ldr r1, =k /* *R1 variable k */ ldr r2, [r1] /* cargamos variable k */ add r2, r2, #1 /* k = k + 1 */ str r2, [r1] /* guardamos variable k */ b outloopM1 outloopM2: ldr r1, =r /* *R1 variable r */ ldr r2, =j /* *R2 variable j */ ldr r1, [r1] /* R1 variable r */ ldr r2, [r2] /* R2 variable j */ cmp r2, r1 /* compara j <= r */ bgt outloopM3 ldr r1, =k /* *R1 variable k */ ldr r1, [r1] /* R1 variable k */ ldr r2, =j /* *R2 variable j */ ldr r2, [r2] /* R2 variable j */ ldr r0, =array /* dirección array */ add r3, r0, r2, LSL #2 /* índice al array[j] en R3 */ ldr r2, [r3] /* cargamos valor en array[j] */ ldr r0, =auxarr /* dirección array auxiliar */ add r3, r0, r1, LSL #2 /* índice al arrayAux[k] en R3 */ str r2, [r3] /* arrayAux[k] = array[j] */ ldr r1, =j /* *R1 variable j */ ldr r2, [r1] /* cargamos variable j */ add r2, r2, #1 /* j = j + 1 */ str r2, [r1] /* guardamos variable j */ ldr r1, =k /* *R1 variable k */ ldr r2, [r1] /* cargamos variable k */ add r2, r2, #1 /* k = k + 1 */ str r2, [r1] /* guardamos variable k */ b outloopM2 outloopM3: ldr r1, =p /* *R1 variable p */ ldr r1, [r1] /* R1 variable p */ ldr r2, =k /* *R2 variable k */ str r1, [r2] /* k = p */ for1: ldr r2, =k /* *R2 variable k */ ldr r2, [r2] /* R2 variable k */ ldr r1, =r /* *R1 variable r */ ldr r1, [r1] /* R1 variable r */ cmp r2, r1 /* ¿ k<=r ? */ bgt outFor1 /* k > r, sale */ ldr r1, =p /* *R1 variable p */ ldr r1, [r1] /* R1 variable p */ sub r1, r2, r1 /* R1 indice k - p */ ldr r0, =auxarr /* dirección array auxiliar */ add r3, r0, r1, LSL #2 /* índice al arrayAux[k-p] en R3 */ ldr r1, [r3] /* carga valor arrayAux[k-p] en R1 */ ldr r0, =array /* dirección array */ add r3, r0, r2, LSL #2 /* índice al array[k] en R3 */ str r1, [r3] /* array[k] = arrayAux[k-p] */ add r2, r2, #1 /* k = k + 1 */ ldr r1, =k /* *R2 variable k */ str r2, [r1] b for1 outFor1: pop {lr} bx lr /* Return de merge */ /* ------------------------------------------------------------- * Función printArray * Muestra por la terminal el array de enteros ------------------------------------------------------------- */ printArray: push {r1, r2, r4, r5, r7, lr} /* Procedimiento de llamada estándar para la arquitectura ARM */ ldr r4, =array /* dirección del array */ mov r5, #0 /* R5 como contador */ mov r6, #0 /* R6 números por linea */ escribe: cmp r5, #ARRAY_LEN /* ¿tenemos los 1024 bytes? */ beq finprint /* si, salimos del bucle */ add r3, r4, r5, LSL #2 /* actualizamos el índice, entonces R3 = R1 + (R2*4) */ ldr r1, [r3] /* carga el valor del array en R1 apuntado por *R3 */ ldr r0, =mascara /* r0 ← &mascara */ bl printf /* llamada a printf, escribe el número*/ add r5, r5, #1 /* R5 = R5 + 1 */ add r6, r6, #1 /* R6 = R6 + 1 */ cmp r6, #16 /* ¿16 números escritos? */ bne sigue /* no, seguimos */ mov r6, #0 /* si, ponemos el contador a 0 R&=0 */ mov r0, #0x0A /* añadimos un retorno de carro */ bl putchar /* con la función putchar */ sigue: b escribe finprint: pop {r1, r2, r4, r5, r7, lr} /* recupera la llamada estándard */ bx lr /* retorno de subrutina */ b fincarga /* borrar */ /* ------------------------------------------------------------- * Función rand * Lee un número aleatorio del archivo /dev/urandom * Devuelve el número en R0 ------------------------------------------------------------- */ .data /* Modos de lectura / escritura para el archivo */ .equ open, 5 /* Abrir archivo */ .equ RdWr, 02 /* Acceso lectura escrtura */ .equ Apnd, 02000 /* Abrir archivo */ .equ read, 3 /* Leer archivo */ .equ close, 6 /* Cerrar archivo */ .balign 4 dir_file: .asciz "/dev/urandom" .balign 4 Open: .word dir_file, RdWr | Apnd, open .balign 4 Buf: .word 0 .balign 4 Read: .word Buf, 1, read /* * Empieza área de código */ .text rand: push {r1, r2, r4, r5, r7, lr} /* Procedimiento de llamada estándar para la arquitectura ARM */ ldr r3, =Open /* dirección de Open */ ldm r3, {r0, r1, r7} /* carga los registros */ svc #0 /* el SO abre el archivo */ mov r4, r0 /* el número de archivo se almacena en R4 (fd) */ ldr r3, =Read /* dirección de Read */ ldm r3, {r1, r2, r7} /* carga los registros */ svc #0 /* el SO lee el archivo */ mov r0, r4 /* carga el fd en R0 */ mov r7, #close /* núm. para cerrar */ svc #0 /* el SO cierra el archivo */ ldr r0, =Buf /* dirección del dato leído */ ldr r0, [r0] /* carga el valor en R0 */ pop {r1, r2, r4, r5, r7, lr} /* recupera la llamada estándard */ bx lr /* retorno de subrutina */