Circuitos Digitales - Factorial

 
Vista:

Factorial

Publicado por Pedro Ignacio (1 intervención) el 28/02/2007 14:06:02
Lee un byte de la posicion 00FEh. A dicho valor le calcula el factorial y lo almacena en la direccion 0AAAh.Imprime en pantalla fila 10 y columna 20 "OPERACION FACTORIAL CONCLUIDA ", imprime en pantalla fila 23 y columna 17 'Presione cualquier tecla para SALIR '

Necesitaria saber si si este ejercicio que hice se puede optimizar de alguna forma para que funcione mejor o utilice menos lineas o ya eta lo mejor posible?. Gracias

PILA SEGMENT PARA STACK 'STACK'
DB 64 DUP ('STACK ')
PILA ENDS

DATOS SEGMENT PARA PUBLIC 'DATA'

MENSAJ1 DB 'OPERACION FACTORIAL CONCLUIDA ', '$'
MENSAJ2 DB 'Presione cualquier tecla para SALIR ', '$'

DATOS ENDS

;--------------------------------------------------------

CSEG SEGMENT PARA PUBLIC 'CODE'

PRINCIPAL PROC FAR
;
ASSUME CS:CSEG,SS:PILA,DS:DATOS
MOV AX,SEG DATOS
MOV DS,AX

MOV Ax,0005h ; ;cargar un valor entre 1 y 8 decimal.
MOV CS:[00FAh],Ax ;se supone que ya estaria cargado.

; =================================

MOV Ax,CS:[00FAh] ;Leer valor de memoria
MOV Bx,Ax
VOLVER: DEC Bx
CMP Bx,00h ; Rutina central que calcula el factorial
JE SALTO
MUL Bx
JMP VOLVER

; ===================================
SALTO: MOV DS:[0AAAh],AX ; Almacena valordel factorial en Memoria.
MOV AH,06H
MOV AL,00H
MOV CX,0000H ; Rutina para limpiar la pantalla
MOV DX,184FH
MOV BH,7
INT 10H
; ====================================
MOV AH,02h
MOV BH,00
MOV DH,10 ; Rutina de posicionamiento del cursor (f=10,c=20)
MOV DL,20
INT 10h
; ====================================
MOV AH,09H
LEA DX,MENSAJ1 ;Rutina que imprime MENSAJ1
INT 21H
; ====================================
MOV AH,02h
MOV BH,00
MOV DH,23 ; Rutina de posicionamiento del cursor (f=23,c=17)
MOV DL,17
INT 10h
; ====================================
MOV AH,09H
LEA DX,MENSAJ2 ;Rutina que imprime MENSAJ2
INT 21H

; ----------------
MOV AH,01H ; Espera que se presione cualquier tecla
INT 21H
; ----------------
MOV AX,4c00h ; Salida al DOS.
INT 21h
; ------------------
PRINCIPAL ENDP
CSEG ENDS
END principal
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Alejandro

Optimización de factorial en Assembler

Publicado por Alejandro (117 intervenciones) el 28/08/2023 15:47:39
El código que has proporcionado es un programa en ensamblador que calcula el factorial de un número y realiza algunas operaciones adicionales. Si bien ya has hecho un buen trabajo, aquí hay algunas sugerencias para optimizarlo y hacerlo más eficiente:

1. Utiliza registros: En lugar de utilizar memoria para almacenar temporalmente los valores, puedes utilizar registros para agilizar las operaciones. Los registros son más rápidos de acceder que la memoria.

2. Reducir saltos condicionales: En lugar de usar saltos condicionales (JMP) para controlar el bucle del cálculo del factorial, puedes usar un bucle de decremento y comparación. Esto puede simplificar el código y hacerlo más legible.

3. Optimización de pantalla: Puedes reducir la cantidad de llamadas a la interrupción INT 10h para posicionar el cursor y limpiar la pantalla. Solo necesitas configurar la posición del cursor una vez y realizar una llamada para limpiar la pantalla.

Aquí tienes una versión optimizada del código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
PILA SEGMENT PARA STACK 'STACK'
DB 64 DUP ('STACK ')
PILA ENDS
 
DATOS SEGMENT PARA PUBLIC 'DATA'
 
MENSAJ1 DB 'OPERACION FACTORIAL CONCLUIDA ', '$'
MENSAJ2 DB 'Presione cualquier tecla para SALIR ', '$'
 
DATOS ENDS
 
; --------------------------------------------------------
 
CSEG SEGMENT PARA PUBLIC 'CODE'
 
PRINCIPAL PROC FAR
;
ASSUME CS:CSEG,SS:PILA,DS:DATOS
MOV AX,SEG DATOS
MOV DS,AX
 
MOV Ax,0005h ; Cargar un valor entre 1 y 8 decimal.
MOV CS:[00FAh],Ax ; Se supone que ya estaría cargado.
 
; =================================
 
MOV Ax,CS:[00FAh] ; Leer valor de memoria
MOV CX,Ax         ; Usar CX como contador para el bucle
 
MOV DX, 1         ; Inicializar DX para el cálculo del factorial
MOV BX, 1         ; Inicializar BX para el multiplicador
 
CALCULO_FACTORIAL:
    MUL BX         ; DX:AX = AX * BX
    INC BX         ; Incrementar BX para el siguiente multiplicador
    LOOP CALCULO_FACTORIAL ; Repetir el bucle hasta que CX llegue a 0
 
; ===================================
    MOV DS:[0AAAh],DX ; Almacenar valor del factorial en Memoria.
 
    MOV AH,06H
    MOV AL,00H
    MOV CX,0000H ; Rutina para limpiar la pantalla
    MOV DX,184FH
    MOV BH,7
    INT 10H
; ====================================
    MOV AH,02h
    MOV BH,00
    MOV DH,10 ; Rutina de posicionamiento del cursor (f=10,c=20)
    MOV DL,20
    INT 10h
; ====================================
    MOV AH,09H
    LEA DX,MENSAJ1 ; Rutina que imprime MENSAJ1
    INT 21H
; ====================================
    MOV AH,02h
    MOV BH,00
    MOV DH,23 ; Rutina de posicionamiento del cursor (f=23,c=17)
    MOV DL,17
    INT 10h
; ====================================
    MOV AH,09H
    LEA DX,MENSAJ2 ; Rutina que imprime MENSAJ2
    INT 21H
 
; ----------------
    MOV AH,01H ; Espera que se presione cualquier tecla
    INT 21H
; ----------------
    MOV AX,4c00h ; Salida al DOS.
    INT 21h
; ------------------
PRINCIPAL ENDP
CSEG ENDS
END principal

Esta versión utiliza el registro CX como contador para el bucle del cálculo del factorial y el registro BX como multiplicador. También optimiza las llamadas a INT 10h para posicionar el cursor y limpiar la pantalla. Recuerda que la optimización puede variar según la plataforma y el compilador que estés utilizando, por lo que es importante realizar pruebas para asegurarte de que el código funcione correctamente.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar