fork download
  1. section .bss
  2. input resb 10 ; Reservar 10 bytes para leer el número desde el teclado
  3. result resb 12 ; Reservar 12 bytes para almacenar el resultado convertido a texto
  4.  
  5. section .data
  6. prompt db "Ingrese un número: ", 0 ; Mensaje de entrada
  7. prompt_len equ $ - prompt ; Longitud del mensaje
  8.  
  9. newline db 0xA, 0 ; Caracter de nueva línea ('\n') seguido de nulo
  10.  
  11. section .text
  12. global _start ; Punto de entrada del programa
  13.  
  14. _start:
  15. ; --- Mostrar mensaje de entrada ---
  16. mov eax, 4 ; syscall number 4 = write
  17. mov ebx, 1 ; descriptor 1 = stdout
  18. mov ecx, prompt ; dirección del mensaje
  19. mov edx, prompt_len ; longitud del mensaje
  20. int 0x80 ; invocar syscall
  21.  
  22. ; --- Leer número desde teclado ---
  23. mov eax, 3 ; syscall number 3 = read
  24. mov ebx, 0 ; descriptor 0 = stdin
  25. mov ecx, input ; buffer donde se guarda lo leído
  26. mov edx, 10 ; leer hasta 10 caracteres
  27. int 0x80 ; invocar syscall
  28.  
  29. ; --- Convertir cadena ASCII a número entero ---
  30. mov esi, input ; puntero al inicio de la cadena leída
  31. call atoi ; resultado se devuelve en eax
  32.  
  33. ; --- Calcular el factorial del número ---
  34. push eax ; pasar el número como argumento a la pila
  35. call factorial ; llamada a función factorial
  36. add esp, 4 ; limpiar el argumento de la pila
  37.  
  38. ; --- Convertir el resultado (eax) a texto ---
  39. mov ebx, eax ; guardar el resultado en ebx
  40. mov edi, result + 11 ; puntero al final del buffer (último byte disponible)
  41. mov byte [edi], 0 ; agregar terminador nulo
  42. dec edi ; retroceder al último carácter útil
  43. call itoa ; convierte el número a texto, resultado comienza en edi
  44.  
  45. ; --- Calcular longitud del número convertido ---
  46. mov ecx, edi ; guardar puntero al inicio del texto convertido
  47. mov esi, result ; inicio del buffer
  48. add esi, 11 ; puntero al final del buffer
  49. sub esi, ecx ; longitud = fin - inicio
  50. mov edx, esi ; guardar longitud del texto en edx
  51.  
  52. ; --- Mostrar el número en pantalla ---
  53. mov eax, 4 ; syscall number 4 = write
  54. mov ebx, 1 ; descriptor 1 = stdout
  55. mov ecx, edi ; puntero al inicio del texto convertido
  56. int 0x80 ; invocar syscall
  57.  
  58. ; --- Mostrar salto de línea ---
  59. mov eax, 4 ; syscall: write
  60. mov ebx, 1 ; stdout
  61. mov ecx, newline ; dirección del caracter '\n'
  62. mov edx, 1 ; longitud = 1 byte
  63. int 0x80 ; invocar syscall
  64.  
  65. ; --- Salir del programa ---
  66. mov eax, 1 ; syscall number 1 = exit
  67. xor ebx, ebx ; código de salida = 0
  68. int 0x80 ; invocar syscall
  69.  
  70. ; ------------------------------------------------------------
  71. ; atoi: convierte cadena ASCII decimal a número entero
  72. ; Entrada: ESI apunta al inicio de la cadena
  73. ; Salida: EAX contiene el número
  74. ; ------------------------------------------------------------
  75. atoi:
  76. xor eax, eax ; inicializar acumulador a 0
  77. .next_digit:
  78. movzx ecx, byte [esi] ; cargar siguiente byte como entero sin signo
  79. cmp ecx, 10 ; ¿es fin de línea (LF)?
  80. je .done ; si sí, terminar
  81. cmp ecx, '0' ; ¿es menor que '0'?
  82. jl .done ; si sí, terminar
  83. cmp ecx, '9' ; ¿es mayor que '9'?
  84. jg .done ; si sí, terminar
  85. sub ecx, '0' ; convertir carácter ASCII a número
  86. imul eax, eax, 10 ; desplazar el acumulador decimal
  87. add eax, ecx ; sumar el nuevo dígito
  88. inc esi ; pasar al siguiente carácter
  89. jmp .next_digit ; repetir
  90. .done:
  91. ret ; devolver número en eax
  92.  
  93. ; ------------------------------------------------------------
  94. ; factorial: calcula factorial recursivamente
  95. ; Entrada: número en [esp + 4]
  96. ; Salida: resultado en eax
  97. ; ------------------------------------------------------------
  98. factorial:
  99. mov eax, [esp + 4] ; obtener argumento desde la pila
  100. cmp eax, 1 ; si eax <= 1
  101. jbe .base ; retornar 1 en ese caso
  102. dec eax ; preparar n - 1
  103. push eax ; empujar n - 1 a la pila
  104. call factorial ; llamada recursiva
  105. add esp, 4 ; limpiar la pila
  106. mov ebx, [esp + 4] ; recuperar n original desde la pila
  107. imul eax, ebx ; resultado = n * factorial(n - 1)
  108. ret ; retornar resultado
  109. .base:
  110. mov eax, 1 ; retornar 1
  111. ret
  112.  
  113. ; ------------------------------------------------------------
  114. ; itoa: convierte entero a cadena ASCII decimal
  115. ; Entrada: EBX = número, EDI = fin del buffer
  116. ; Salida: EDI apunta al inicio del texto
  117. ; ------------------------------------------------------------
  118. itoa:
  119. xor edx, edx ; limpiar resto
  120. mov eax, ebx ; mover número a dividir a eax
  121. mov ecx, 10 ; base decimal
  122. .convert:
  123. xor edx, edx ; limpiar resto antes de div
  124. div ecx ; dividir eax / 10, resto en edx
  125. add dl, '0' ; convertir dígito a ASCII
  126. mov [edi], dl ; guardar carácter en buffer
  127. dec edi ; moverse hacia atrás en el buffer
  128. test eax, eax ; ¿quedan más dígitos?
  129. jnz .convert ; si sí, continuar
  130. inc edi ; ajustar puntero al primer carácter válido
  131. ret ; retornar puntero en edi
  132.  
Success #stdin #stdout 0s 5316KB
stdin
32
stdout
Ingrese un número: 2147483648