Calcular Si Un Número es Perfecto
Descargar Código X86 Descargar Código ARMPrograma ARM
Programa x86AREA ejer,CODE,READWRITE SWI_Salir EQU &11 ; salida del programa SWI_write0 EQU &2 ; muestra por pantalla SWI_ReadC EQU &4 ; leer un caracter del teclado ENTRY INICIO ADR r0, cad1 ;Obtenemos dirección de la cadena SWI SWI_write0 ;interrupción para mostrar cadena SWI SWI_ReadC ;Punto de ruptura para introducir el dato en R0 MOV r1,r0 ;Movemos el valor introducido en r0 a r1 SUB r1,r1,#48 ;Restamos 48 al valor ascii del dato introducido para ;poder operar con él MOV r2, #2 ;Para dividir el numero entre dos y no comprobar con ;números superiores a su mitad MOV r4, #0 ;Inicializamos el registro r4 a 0. Y así poder usar la ;division MOV r3, #1 ;Inicializamos el registro r3 a 1, que contendrá el ;cociente. CMP r1, #2 ;Comprobamos que el número introducido no es menor de 2 BLT NO_PERFECTO ;Saltamos cuando el número introducido sea menor de 2 MOV r7, r1 ;Duplicamos el número introducido ;Dividimos el número introducido entre 2 MITAD SUB r7, r7, r2 ;restamos 2 a r7 (contiene el numero ;introducido) ADD r3, r3, #1 ;vamos sumando 1 al divisor que será el contador del ;bucle siguiente CMP r7, r2 ;Comprobamos si podemos seguir dividiendo BGE MITAD ;salta mientras r7 sea mayor o igual que 2. MOV r8, #2 ;r8 contendrá los candidatos a divisor MOV r7, r1 ;Volvemos a introducir el número leído en r7 MOV r6, #1 ;r6 Acumulará la suma de los divisores del número ;introducido COMPROBAR ;Para comprobar si los candidatos a divisor lo son realmente SUB r7, r7, r8 ;Restamos el candidato a divisor al número ;introducido ADD r4, r4, #1 ;r4 irá almacenando el cociente CMP r7, r8 ;Comparamos dividendo con divisor BGE COMPROBAR ;Salta mientras el dividendo no sea menor que el ;divisor CMP r7, #0 ;Comprueba si el resto es cero BNE SIGUIENTE ;Si el resto es distinto de 0, salta a SIGUIENTE ADD r6, r6, r8 ;Si el resto es 0, sumamos al registro r6 el divisor ;encontrado SIGUIENTE CMP r8, r3 ;Comprobamos si ya hemos probado con todos los ;posibles divisores BEQ RESULTADO ;Salta cuando hayamos realizado todas las iteraciones ;previstas. ADD r8, r8, #1 ;Incrementamos en 1 para tener un nuevo candidato a ;divisor. MOV r7, r1 ;Reiniciamos el dividendo B COMPROBAR ;Volvemos para comprobar el siguiente candidato a divisor RESULTADO CMP r1, r6 ;Comprobamos si la suma de los divisores es igual ;al número introducido BNE NO_PERFECTO ;Si son distintos saltamos a NO_PERFECTO ADR r0, cad2 ;Obtenemos dirección de la cadena SWI SWI_write0 ;interrupción para mostrar cadena B FIN NO_PERFECTO ADR r0, cad3 ; Obtenemos dirección de la cadena SWI SWI_write0 ;interrupción para mostrar cadena FIN ADR r0, cad4 ;Para volver a ejecutar el programa SWI SWI_write0 ;Interrupción para mostrar cadena SWI SWI_ReadC ;Punto de ruptura para introducir el dato en R0 CMP r0, #49 ;Comprobamos si desea volver a ejecutar el programa BEQ INICIO ;Si el usurario ha introducido un 1 repetimos el programa SWI SWI_Salir ;Interrupción para salir cad1 = "Introduzca un número entre 1 y 9", &0a, &0d, 0 cad2 = "El numero introducido es perfecto", &0a, &0d, 0 cad3 = "El numero introducido no es perfecto", &0a, &0d, 0 cad4 = "Para volver a ejecutar el programa introduzca 1", &0a, &0d, 0 END
.Const .Data NUM DQ 0 .Code start: ;Inicio del programa principal. invoke puts, "----- Programa para comprobar si un numero es perfecto -----" invoke puts, " " invoke printf, "----- Introduzca un numero entero positivo : " invoke scanf, "%d", Addr NUM invoke puts, " " mov ebx, 2 ;Para dividir el número entre dos y así no comprobar números superiores a su mitad mov eax, [NUM] ;Introducimos el número en eax mov edx, 0 ;Para poder usar DIV sin problemas div ebx ;Lo dividimos entre dos mov ecx, eax ;Almacenamos el cociente en ecx para que sirva de contador para LOOP mov edi, 1 ;Contendrá los candidatos a divisores mov esi, 0 ;Para ir sumando los divisores comprobar: mov eax, [NUM] ;Introducimos el numero en eax para DIV div edi ;Dividimos el número entre el candidato a divisor cmp edx, 0 ;Comprobamos si el resto es cero jne > siguiente ;Salta si el resto no es cero add esi, edi ;Sumamos el divisor encontrado siguiente: inc edi ;Incrementamos en uno el candidato a divisor mov edx, 0 ;Eliminamos el posible resto almacenado para poder utilizar DIV loop comprobar ;Iteramos mientras no se comprueben todos los números entre 1 y NUM/2. cmp [NUM], esi ;Comprobamos si la suma de los divisores es igual al número introducido jne > no_perfecto ;Saltamos si no son iguales invoke puts, "----- El numero introducido es perfecto " jmp > fin no_perfecto: invoke puts, "----- El numero introducido no es perfecto " fin: invoke puts, " " Invoke system, "pause" Xor Eax, Eax Invoke ExitProcess, Eax ;Fin del programa principal ;Subprogramas: