You are on page 1of 5

pe28_sum.

asm
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:

1 / 5

;===========================================================================
;===========================================================================
; PROGRAMA
: pe28_sum.asm
ex p19_suma.asm
; FUNCION
: Suma de dos numeros.
; REALIZADO POR
: Prof. Juan Jurez Fuentes
; COMPILADOR EN EL QUE SE EJECUTO: TASM 5.0
; FECHA
: 2009121116134620121219113356
;===========================================================================
;===========================================================================
; DECLARACION DE CONSTANTES
;===========================================================================
CR
EQU 13
; Constante CR (Retorno de carro)
LF
EQU 10
; Constante LF (Salto de lnea)
IMPRIMIR EQU 9
FIN
EQU 4C00H
DOS
EQU 21H
TAB
EQU 09H
BELL
EQU 07H
;===========================================================================
; DECLARACION DEL SEGMENTO DE DATOS
;===========================================================================
DATOS
SEGMENT
;----------------------------------------------------------------------ErrorCAP DB 0
;Bandera de error en la captura de las cantidades
Cantidad DB 0
;La cantidad sobre la que se opera, si es 0 mse opera sobre la cantidad 1, si es 1 se opera sobre la cantidad 2.
CantUnoR DW 0
;Variable que guarda la cantidad uno convertida a binario
CantDosR DW 0
;Variable que guarda la cantidad dos convertida a binario.
CantUnoN DB 6,0,6 DUP (?)
;Variable que almacena la cantidad uno.
CantDosN DB 6,0,6 DUP (?)
;Variable que almacena la cantidad dos
ResultaR DB 11 DUP (?)
Mensaje DB 13,10,13,10,TAB,TAB,TAB,"====================================="
DB 13,10,13,10,TAB,TAB,TAB,"PROGRAMA QUE SUMA DOS NUMEROS ENTEROS"
DB 13,10,13,10,TAB,TAB,TAB,"=====================================",13,10
DB 13,10,13,10,TAB,TAB,TAB,"(las cantidades debe ser < a 65535)",13,10,13,10,13,10,"$"
M_error1 DB BELL,13,10,"ERROR: digito invalido en cantidad 1.",13,10,13,10,"$"
M_error2 DB BELL,13,10,"ERROR: digito invalido en cantidad 2.",13,10,13,10,"$"
M_error3 DB BELL,13,10,"ERROR: cantidad fuera de rango (65535)","!!!.",13,10,13,10,"$"
M_cant_1 DB 13,10,13,10,TAB,TAB,"Dar la primera cantidad:", "$"
M_cant_2 DB 13,10,13,10,TAB,TAB,"Dar la segunda cantidad:", "$"
M_result DB 13,10,13,10,13,10,TAB,TAB,TAB,BELL,"El resultado es: ","$"
M_espaci DB 13,10,13,10,13,10,13,10,13,10,13,10,"$"
;------------------------------------------------------------;Tabla de potencias usada para convertir el resultado binario de la
; operacion en formato ASCII. Se usan las potencias de 10 (1,10,100,1000
;y 10000), porque el numero mas grande es 65535. En caso de que quiera
;operar sobre numeros mas grandes amplie la tabla.
;------------------------------------------------------------Potencia DW
001h, 000ah, 0064h, 03E8h, 2710h
PotenciaF DW
$
;----------------------------------------------------------------------DATOS
ENDS
;===========================================================================
; DECLARACION DEL SEGMENTO DE PILA
;===========================================================================
PILA
SEGMENT STACK
;----------------------------------------------------------------------DB 64 DUP('PILA')
;----------------------------------------------------------------------PILA
ENDS
;===========================================================================
; DECLARACION DEL SEGMENTO DE CODIGO
;===========================================================================
CODIGO SEGMENT
;----------------------------------------------------------------------pe28_sum PROC FAR
; Etiqueta de comienzo de programa

December 19, 2012

Crimson Editor

pe28_sum.asm
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:

2 / 5

;----------------------------------------------------------------------ASSUME CS:CODIGO,DS:DATOS,SS:PILA
;------------------------------------------------------------MOV AX, DATOS
; Inicializa DS con la direccion de @Data
MOV DS, AX
MOV DX, Offset Mensaje
; Despliega el mensaje de bienvenida
CALL IMPRIME
MOV SI,
Offset ResultaR ;Inicializa la variable ResultaR
ADD SI, 11
MOV AL, "$"
MOV [SI], AL
;------------------------------------------------------------; Se capturan las cantidades y se guardan en sus respectivas
; variables para poder trabajar sobre ellas mas adelante. La
; captura se basa en la funcion 09 de l aINT 21h. Dicha funcion
; establece que el registro AH contenga 09 y el registro PAR DS:DX
; apunte a la direccion de la variableque almacenara la estructura del
; Buffer el cual debe estar construido de la siguiente manera:
;
; BYTE 1 = Cantidad de bytes por leer
; BYTE 2 = (llenado por MS-DOS) es la cantidad debytes realmente leidos
; BYTE 3 = Buffer donde se almacen ael resultado, debe encontrarse
;
inicializado con la misma cantidad de bytes especificados
;
pr el byte 1.
;
; Las cantidades capturadas representan una cadena que es necesario
; convertir a binario antes de que se pueda operar sobre ella.
;
;------------------------------------------------------------;------------------------------------------------------------; captura primera cantidad
;------------------------------------------------------------CAPCANT1:
;------------------------------------------------------------MOV
DX, Offset M_cant_1 ; Mensaje de captura de cantidad 1.
CALL
IMPRIME
;------------------------------------------------------------MOV
AH, 0AH
; Captura la cantidad (hasta 8 digitos)
MOV
DX, Offset CantUnoN
INT
DOS
;------------------------------------------------------------MOV
ErrorCAP, 0
; Supone que no hay errores y que se esta operando sobre la cantidad 1.
MOV
Cantidad, 0
;------------------------------------------------------------CALL
ConvNUM
; Convierte cantidad uno a binario
;------------------------------------------------------------CMP
ErrorCAP, 1
;hubo error?
JZ
CAPCANT1
; Si, regresa a la captura
;------------------------------------------------------------MOV
CantUnoR, Bx
; Guarda resultado de conversion
;------------------------------------------------------------; captura segunda cantidad
;------------------------------------------------------------CAPCANT2:
;------------------------------------------------------------MOV ErrorCAP, 0
; Supone que no hay errore
MOV Cantidad, 1
; indica a ConvNUM que es la segund acantidad
;------------------------------------------------------------MOV Dx, Offset M_cant_2
; Mensaje sobre captura de cantidad dos.
CALL IMPRIME
;------------------------------------------------------------MOV AH, 0Ah
; Captura la segunda cantidad
MOV DX, Offset CantDosN
INT DOS
;-------------------------------------------------------------

December 19, 2012

Crimson Editor

pe28_sum.asm

3 / 5

131:
CALL ConvNUM
; Convierte cantidad dos a binario
132:
;------------------------------------------------------------133:
CMP ErrorCAP, 1
;hubo error?
134:
JZ
CAPCANT2
; Si, regresa a capturar la cantidad
135:
;------------------------------------------------------------136:
MOV CantDosR, BX
; Guarda conversion d ecantidad 2.
137:
;------------------------------------------------------------138:
;------------------------------------------------------------139:
CALL SUMA
; Suma las dos cantidades
140:
;------------------------------------------------------------141:
;------------------------------------------------------------142:
; TERMINA EL PROGRAMA
143:
;------------------------------------------------------------144:
MOV AX, FIN
; Termina el progrma sin error
145:
INT DOS
; 21H
146:
;----------------------------------------------------------------------147:
pe28_sum ENDP
; Fin del procedimiento p3_iden
148:
;----------------------------------------------------------------------149: ;===========================================================================
150: ; RUTINAS DE SOPORTE
151: ;===========================================================================
152:
;------------------------------------------------------------153:
; Rutina:
Suma
154:
; Proposito:
Suma dos numeros enteros sin signo
155:
; Parametros:
En el registro Ax el primer numero y en BX el segundo
156:
; Regresa:
El resultado en el registro par DX:AX, que es desplegado en la pantalla.
157:
;------------------------------------------------------------158:
SUMA PROC NEAR
159:
XOR DX, DX
; Dx = 0 Por si acaso existe acarreo.
160:
MOV AX, CantUnoR
; Primera cantidad
161:
MOV BX, CantDosR
; Segunda cantidad
162:
ADD AX, BX
; Las suma
163:
Jnc CONVERTIR_SUMA
; Hubo acarreo?
164:
Adc DX, 0
; Si
165:
CONVERTIR_SUMA:
166:
CALL ConvASCII
; Convierte resultado en ASCII
167:
MOV DX, Offset M_result
; Despliega cadena del resultado
168:
CALL IMPRIME
169:
MOV DX, Offset REsultaR
; Despliega el resultado
170:
CALL IMPRIME
171:
MOV DX, Offset M_espaci
; Despliega espacios despues del reusltado
172:
CALL IMPRIME
173:
RET
174:
SUMA ENDP
175:
;------------------------------------------------------------176:
; Rutina:
Imprime
177:
; Proposito:
Despliega una cadena
178:
; Parametros:
El registro DX contiene el desplazamiento de la cadena
179:
; Regresa:
Nada
180:
;------------------------------------------------------------181:
IMPRIME PROC NEAR
182:
MOV AH, IMPRIMIR
; Prepara para desplegar la cadena a traves de la INT 21h
183:
INT DOS
184:
RET
185:
IMPRIME ENDP
186:
;------------------------------------------------------------187:
; Rutina:
ConvNUM
188:
; Proposito:
Convertir una cadena en un entero largo
189:
; Parametros:
La longitud de la cadena y la direccion de la mism, y se pasan a la pila
190:
; Regresa:
En el registro BX la cadena convertida en un entero
191:
;------------------------------------------------------------192:
ConvNUM PROC NEAR
193:
MOV DX, 0AH
; Multiplicador es 10
194:
CMP Cantidad, 0
; Es la cantidad 1?
195:
Jnz CONVNUM1
; No, asi que es la cantidad 2
December 19, 2012

Crimson Editor

pe28_sum.asm
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:

4 / 5
MOV DI, Offset
MOV CX, [DI]
MOV SI, Offset
JMP CONVNUM2
CONVNUM1:
MOV DI, Offset
MOV CX, [DI]
MOV SI, Offset
CONVNUM2:
XOR Ch, Ch
MOV DI, Offset
Dec SI

CantUnoN + 1; Bytes leidos de la cantidad 1


CantUnoN + 2; La cantidad 1

CantDosN +1 ; Bytes leidos de la cantidad 2


CantDosN + 2; La cantidad 2

Potencia

;
;
;
;

CH = 0
Direccion de la tabla de potencias
Posiciona Si En el primer byte de la cadena capturada y le suma el desplazamiento de bytes leidos, para que podamos posiionarnos
en el final de la misma (apunta al ultimo digito capturado). BX =0 y lee la cadena en forma inversa: es decir, de atras hacia adelante.

ADD SI, CX
XOR BX, BX
Std
CONVNUM3:
LODSB
; Levanta un byte del numero (esta instruccion indica que el registro AL sera cargado con el contenido de la direccion apuntada por DS:SI.)
CMP AL, "0"
; Es menor que 0? (Entonces NO es un digito valido)
JB
CONVNUM4
; Si Despliega el mensaje de error y termina
CMP AL, "9"
; Es mayor que 9? (entonces NO e sun digito valido)
JA
CONVNUM4
; Si, despliega el error y salta
SUB Al, 30h
; convierte el digito de ascii a binario
CBW
; Convierte a palabra
MOV DX, [DI]
; obtiene la potencia de 10 que sera usada para multiplicar,
Mul DX
; Multiplica numero y lo suma a Bx
JC
CONVNUM5
; Revisa si hubo acarreo, y si lo hubo esto
ADD BX, AX
; significa que la cantidad es > 65535
JC
CONVNUM5
; Si hay acarreo la cantidad es mayor a 65535
ADD DI, 2
; Va a la siguiente potenci ade 10
LOOP CONVNUM3
; Itera hasta que Cx sea = 0.
JMP
CONVNUM6
;
CONVNUM4:
CALL HuboERROR
; Algo ocurrio, despliega mensaje y salta
JMP CONVNUM6
CONVNUM5:
MOV Cantidad, 2
; Hubo acarreo en la conversion, por lo tanto la
CALL HuboERROR
; cantidad capturada es mayor que 65535.
CONVNUM6:
CLD
; Regresa la bandera de direccion a su estado normal
RET
; y Regresa.
ConvNUM ENDP
;------------------------------------------------------------; Rutina:
ConvASCII
; Proposito:
Convertir un valor binario en ASCII
; Parametros:
El registro par DX:AX
; Regresa:
Nada, pero almacena el resultado en el buffer ResultaR
;------------------------------------------------------------ConvASCII
PROC NEAR
;------------------------------------------------------------; Lo primero que se hace es inicializar la variable que contendra al resultado de la conversion
;------------------------------------------------------------PUSH DX
PUSH AX
; Guarda el resultado
MOV SI, Offset REsultaR
;Inicializa la variable REsultaR llenandolacon CEROS.
MOV CX, 10
MOV Al, "0"
ConvASCII1:
MOV [SI], AL
INC SI
LOOP ConvASCII1
POP AX
POP DX
MOV BX, AX
; Palabra baja de la cantidad
MOV AX, DX
; Palabra alta de la cantidad

December 19, 2012

Crimson Editor

pe28_sum.asm
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:

5 / 5

MOV SI, Offset ResultaR


; Cadena donde se guardara el resultado
ADD SI, 11
MOV CX, 10
; Divisor = 10
OBTENDIGITO:
DEC SI
XOR DX, DX
; DX contendra el residuo
DIV CX
; Divide la palabra alta (AX)
MOV DI, AX
; Guarda cociaente (AX)
MOV AX, BX
; AX = palabra baja (BX)
DIV CX
; DX tenia un residuo de la division anterior
MOV BX, AX
; Gurada el cociente
MOV AX, DI
; Regresa la palabra alta
ADD Dl, 30h
; Convierte residuo en ASCII
MOV [SI], Dl
; Lo almacena
OR AX, AX
; Palabra alta es 0 ?
JNZ OBTENDIGITO
; No, sigue PROCesando
OR BX, BX
; Palabra baja es 0 ?
JNZ OBTENDIGITO
; No, sigue procesando
RET
ConvASCII ENDP
;------------------------------------------------------------; Rutina:
HuboERROR
; Proposito:
Desplegar elmensaje de error adecuado
; Parametros:
Nada
; Regresa:
Nada
;------------------------------------------------------------HuboERROR PROC NEAR
CMP Cantidad, 0
; Es la cantidad 1?
JNZ HUBOERROR2
; nO
MOV Dx, Offset M_error1
CALL IMPRIME
MOV ErrorCAP, 1
; Enciende la bandera de error
JMP HUBOERROR4
HUBOERROR2:
CMP Cantidad, 1
; Es la cantidad 2?
JNZ HUBOERROR3
; No
MOV Dx, Offset M_error2
CALL IMPRIME
MOV ErrorCAP, 1
JMP HUBOERROR4
HUBOERROR3:
CMP Cantidad, 2
; cANTIDAD CAPTURADA ESTA FUERA DE RANGO?
JNZ HUBOERROR4
; No.
MOV DX, Offset M_error3
CALL IMPRIME
MOV ErrorCAP, 1
JMP HUBOERROR4
HUBOERROR4:
RET
HuboERROR ENDP
;------------------------------------------------------------------CODIGO ENDS
;===========================================================================
END pe28_sum
;===========================================================================
;===========================================================================
;===========================================================================

December 19, 2012

Crimson Editor

You might also like