Sie sind auf Seite 1von 80

1

1. Escribir un programa en ensamblador que muestre un mensaje por pantalla


mediante interrupciones:
2.
3. ;----------------------------------------------------------------------------4. ;Definicion del segmento de datos
5. ;----------------------------------------------------------------------------6. DATOS SEGMENT
7.
8.
saludo db "Hola mundo!!!","$"
9.
10. DATOS ENDS
11.
12. ;----------------------------------------------------------------------------13. ;Definicion del segmento de codigo
14. ;----------------------------------------------------------------------------15. CODE SEGMENT
16.
assume cs:code,ds:datos
17.
18. START PROC
19.
mov ax,datos
;
20.
mov ds,ax
;Inicializar
21.
22.
mov dx,offset saludo
;Cargar la direccion del saludo
23.
mov ah,9
;Opcion que va a servir a la
interrupcion 21h para
24.
;indicar que debe mostrar por
pantalla el offset
25.
;que hay en DX hasta que encuentre
el caracter '$'
26.
int 21h
;Interrupcion que lo mostrara por
pantalla
27.
28.
mov ax,4C00h
;
29.
int 21h
;Terminar el programa
30.
31. START ENDP
32.
33. CODE ENDS
34.
END START
35.

36. Escribir un programa en ensamblador que muestre un mensaje por pantalla


accediendo a la memoria de video (0B800h):
37.
38. ;----------------------------------------------------------------------------39. ;Definicion del segmento de datos
40. ;----------------------------------------------------------------------------41. DATOS SEGMENT

42.
saludo db "Hola mundo!!!"
43. DATOS ENDS
44.
45. ;----------------------------------------------------------------------------46. ;Definicion del segmento de pila
47. ;----------------------------------------------------------------------------48. PILA SEGMENT STACK "STACK"
49.
DB 40 DUP(0)
50. PILA ENDS
51.
52. ;----------------------------------------------------------------------------53. ;Definicion del segmento extra
54. ;----------------------------------------------------------------------------55. EXTRA SEGMENT
56.
RESULT DW 0,0
57. EXTRA ENDS
58.
59. ;----------------------------------------------------------------------------60. ;Definicion del segmento de codigo
61. ;----------------------------------------------------------------------------62. CODE SEGMENT
63.
assume cs:code,ds:datos,es:extra,ss:pila
64.
65. START PROC
66.
;Inicializamos los registros de segmento
67.
mov ax,datos
68.
mov ds,ax
69.
mov ax,pila
70.
mov ss,ax
71.
mov ax,extra
72.
mov es,ax
73.
;Fin de las inicializaciones
74.
75.
;Limpiamos la pantalla
76.
mov ax,0B800h
;En esta direccion comienza la memoria de
video
77.
mov es,ax
;Lo cargamos en el segmento extra
78.
xor di,di
;Ponemos DI=0. Esto equivale a mov di,0,
pero
79.
;xor di,di consume 3 ciclos de reloj y
con mov 4
80.
mov cx,80*25
;El tamao total es 2000 (80 lineas x 25
columnas)
81.
82. b_clear:
;Bucle que se encargara de recorrer los
2000
83.
;caracteres de la pantalla para limpiarla
84.
mov al,20h
;20h=" "
Rellenar la pantalla con
espacios
85.
mov ah,1bh
;Fondo azul, letras blancas
86.
mov es:[di],ax

87.
inc di
88.
inc di
89.
loop b_clear
90.
91.
mov ax,0B800h
92.
mov es,ax
93.
mov si,offset saludo
94.
mov di,(80*7+17)*2 ;Linea 7, caracter 18
95.
mov cx,13
96.
97. b_saludo:
;Bucle que se encargara de recorrer los
2000
98.
;caracteres de la pantalla para limpiarla
99.
mov al,[si]
100.
mov ah,1bh
;Fondo azul, letras blancas
101.
mov es:[di],ax
102.
inc si
;Pasamos a apuntar a la siguiente letra
del saludo
103.
inc di
104.
inc di
105.
loop b_saludo
106.
107.
108.
mov ax,4C00h
;
109.
int 21h
;Terminar el programa
110.
111. START ENDP
112.
113. CODE ENDS
114.
END START
115.

116.

Este programa pide el nombre al usuario y lo muestra por pantalla:

117.
118. ;----------------------------------------------------------------------------119. ;Definicion del segmento de datos
120. ;----------------------------------------------------------------------------121. DATOS SEGMENT
122.
mensaje
db "Ejercicios disponibles en:
www.victorsanchez2.net"
123.
pregunta_nombre db "Cual es tu nombre?: "
124.
nombre
db 64 DUP(0)
125. DATOS ENDS
126.
127. ;----------------------------------------------------------------------------128. ;Definicion del segmento de pila
129. ;----------------------------------------------------------------------------130. PILA SEGMENT STACK "STACK"
131.
db 40h DUP(0)
132. PILA ENDS
133.
134. ;----------------------------------------------------------------------------135. ;Definicion del segmento extra

136. ;----------------------------------------------------------------------------137. EXTRA SEGMENT


138.
RESULT DW 0,0
139. EXTRA ENDS
140.
141. ;----------------------------------------------------------------------------142. ;Definicion del segmento de codigo
143. ;----------------------------------------------------------------------------144. CODE SEGMENT
145.
assume cs:code,ds:datos,es:extra,ss:pila
146.
147. START PROC
148.
;Inicializamos los registros de segmento
149.
mov ax,datos
150.
mov ds,ax
151.
mov ax,pila
152.
mov ss,ax
153.
mov ax,extra
154.
mov es,ax
155.
;Fin de las inicializaciones
156.
157.
;Limpiamos la pantalla
158.
mov ax,0B800h
;En esta direccion comienza la memoria de
video
159.
mov es,ax
;Lo cargamos en el segmento extra
160.
xor di,di
;Ponemos DI=0. Esto equivale a mov di,0,
pero
161.
;xor di,di consume 3 ciclos de reloj y
con mov 4
162.
mov cx,80*25
;El tamao total es 2000 (80 lineas x 25
columnas)
163.
164. b_clear:
;Bucle que se encargara de recorrer los
2000
165.
;caracteres de la pantalla para limpiarla
166.
mov al,20h
;20h=" "
Rellenar la pantalla con
espacios
167.
mov ah,1bh
;Fondo azul, letras blancas
168.
mov es:[di],ax
169.
inc di
170.
inc di
171.
loop b_clear
172.
173.
;Mostramos un mensaje
174.
mov si,offset mensaje
175.
mov di,(80*10+10)*2 ;Linea 10, columna 10
176.
mov cx,49
;Tamao del mensaje
177.
178. b_saludo:
;Bucle que se encargara de recorrer los
2000
179.
;caracteres de la pantalla para limpiarla
180.
mov al,[si]
181.
mov ah,1bh
;Fondo azul, letras blancas
182.
mov es:[di],ax

183.
inc si
;Pasamos a apuntar a la siguiente letra
del saludo
184.
inc di
185.
inc di
186.
loop b_saludo
187.
188.
;Mensaje al usuario para que introduzca su nombre
189.
mov si,offset pregunta_nombre
190.
mov di,(80*12+10)*2
;Linea 12, columna 10
191.
mov cx,20
192.
193. b_pide_nombre:
;Bucle que se encargara de recorrer los
2000
194.
;caracteres de la pantalla para limpiarla
195.
mov al,[si]
196.
mov ah,1bh
;Fondo azul, letras blancas
197.
mov es:[di],ax
198.
inc si
;Pasamos a apuntar a la siguiente letra
del saludo
199.
inc di
200.
inc di
201.
loop b_pide_nombre
202.
203.
;Almacenamos el nombre
204.
mov ah,0Ah
205.
mov dx,offset nombre
206.
mov nombre[0],64
;Maximo numero de caracteres
207.
int 21h
208.
209.
mov bx,0
210.
211. muestra_nombre:
212.
mov dl,nombre[bx+2]
213.
mov ah,2
214.
int 21h
;Escribir un caracter del nombre
215.
inc bx
216.
cmp bl,nombre[1]
;Compara con el numero de caracteres
217.
jne muestra_nombre
218.
219.
mov ax,4C00h
;
220.
int 21h
;Terminar el programa
221.
222. START ENDP
223.
224. CODE ENDS
225.
END START
226.

227.

El mismo programa que antes, pero ahora con llamadas a funciones:

228.
229. ;----------------------------------------------------------------------------230. ;Definicion del segmento de datos
231. ;----------------------------------------------------------------------------232. DATOS SEGMENT
233.
mensaje
db "Ejercicios disponibles en:
www.victorsanchez2.net"

234.
pregunta_nombre db "Cual es tu nombre?: "
235.
nombre
db 256 DUP(0)
236. DATOS ENDS
237.
238. ;----------------------------------------------------------------------------239. ;Definicion del segmento de pila
240. ;----------------------------------------------------------------------------241. PILA SEGMENT STACK "STACK"
242.
db 40h DUP(0)
243. PILA ENDS
244.
245. ;----------------------------------------------------------------------------246. ;Definicion del segmento extra
247. ;----------------------------------------------------------------------------248. EXTRA SEGMENT
249.
RESULT DW 0,0
250. EXTRA ENDS
251.
252. ;----------------------------------------------------------------------------253. ;Definicion del segmento de codigo
254. ;----------------------------------------------------------------------------255. CODE SEGMENT
256.
assume CS:code,DS:datos,ES:extra,SS:pila
257.
258. ;----------------------------------------------------------------------------259. ;
Procedimiento inicial
260. ;----------------------------------------------------------------------------261. START PROC
262.
263.
call inicializa_seg
;Inicializa los registros de
segmento
264.
call limpia_pantalla
;Limpiamos la pantalla
265.
call muestra_mensaje
;Mensaje de informacion
266.
call pide_nombre
;Pide el nombre al usuario
267.
call muestra_nombre
;Muestra por pantalla el nombre
del usuario
268.
269.
mov ax,4C00h
;
270.
int 21h
;Terminar el programa
271.
272. START ENDP
273.
274.
275. ;----------------------------------------------------------------------------276. ; inicializa_seg
277. ;
278. ; in:
279. ; out:
Los registros de segmento quedan inicializados

280. ; machaca: AX, DS, SS, ES


281. ; make:
Inicializa los registros de segmento
282. ;
283. ;----------------------------------------------------------------------------284. inicializa_seg proc near
285.
286.
mov ax,datos
287.
mov ds,ax
288.
mov ax,pila
289.
mov ss,ax
290.
mov ax,extra
291.
mov es,ax
292.
293.
ret
294.
295. inicializa_seg endp
296.
297.
298. ;----------------------------------------------------------------------------299. ; limpia_pantalla
300. ;
301. ; in:
302. ; out:
303. ; machaca: DI, ES
304. ; make:
Limpia la pantalla escribiendo espacios en las 80x25
posiciones de
305. ;
la pantalla, accediendo a la memoria de video
306. ;
307. ;----------------------------------------------------------------------------308. limpia_pantalla proc near
309.
310.
push ax
;Guardar en la pila las variables que
queremos
311.
push cx
;conservar para cuando salgamos de la
funcion
312.
313.
mov ax,0B800h
;En esta direccion comienza la memoria de
video
314.
mov es,ax
;Lo cargamos en el segmento extra
315.
xor di,di
;Inicializar DI a 0
316.
mov cx,80*25
;El tamao total es 2000 (80 lineas x 25
columnas)
317.
318. b_clear:
;Bucle que se encargara de recorrer los
2000
319.
;caracteres de la pantalla para limpiarla
320.
mov al,20h
;20h=" "
Rellenar la pantalla con
espacios
321.
mov ah,1bh
;Fondo azul, letras blancas
322.
mov es:[di],ax
323.
inc di
324.
inc di
325.
loop b_clear
326.

327.
pop cx
;Importante sacarlas en orden contrario
al que las
328.
pop ax
;guardamos
329.
330.
ret
331.
332. limpia_pantalla endp
333.
334. ;----------------------------------------------------------------------------335. ; muestra_mensaje
336. ;
337. ; in:
338. ; out:
339. ; machaca: DI, SI
340. ; make:
Muestra un mensaje por pantalla indicando en que pagina
se pueden
341. ;
encontrar los ejercicios
342. ;
343. ;----------------------------------------------------------------------------344. muestra_mensaje proc near
345.
346.
push ax
347.
push cx
348.
push es
349.
350.
351.
mov si,offset mensaje
352.
mov di,(80*10+10)*2 ;Linea 10, columna 10
353.
mov cx,49
;Tamao del mensaje
354.
355. b_saludo:
;Bucle que se encargara de recorrer los
2000
356.
;caracteres de la pantalla para limpiarla
357.
mov al,[si]
358.
mov ah,1bh
;Fondo azul, letras blancas
359.
mov es:[di],ax
360.
inc si
;Pasamos a apuntar a la siguiente letra
del saludo
361.
inc di
362.
inc di
363.
loop b_saludo
364.
365.
pop es
366.
pop cx
367.
pop ax
368.
369.
ret
370.
371. muestra_mensaje endp
372.
373. ;----------------------------------------------------------------------------374. ; pide_nombre
375. ;
376. ; in:

377. ; out:
378. ; machaca: DI, SI, DX
379. ; make:
Pide el nombre al usuario para que lo introduzca por
pantalla
380. ;
381. ;----------------------------------------------------------------------------382. pide_nombre proc near
383.
384.
push ax
385.
push cx
386.
push es
387.
388.
389.
;Mensaje al usuario para que introduzca su nombre
390.
mov si,offset pregunta_nombre
391.
mov di,(80*12+10)*2
;Linea 12, columna 10
392.
mov cx,20
393.
394. b_pide_nombre:
;Bucle que se encargara de recorrer los
2000
395.
;caracteres de la pantalla para limpiarla
396.
mov al,[si]
397.
mov ah,1bh
;Fondo azul, letras blancas
398.
mov es:[di],ax
399.
inc si
;Pasamos a apuntar a la siguiente letra
del saludo
400.
inc di
401.
inc di
402.
loop b_pide_nombre
403.
404.
;Almacenamos el nombre
405.
mov ah,0Ah
406.
mov dx,offset nombre
407.
mov nombre[0],64
;Maximo numero de caracteres
408.
int 21h
409.
410.
pop es
411.
pop cx
412.
pop ax
413.
414.
ret
415.
416. pide_nombre endp
417.
418. ;----------------------------------------------------------------------------419. ; muestra_nombre
420. ;
421. ; in: nombre contiene el nombre de usuario que se ha introducido
422. ; out:
423. ; machaca: DI, SI
424. ; make:
Muestra el nombre al usuario por pantalla
425. ;
426. ;----------------------------------------------------------------------------427. muestra_nombre proc near

428.
429.
push ax
430.
push cx
431.
push es
432.
433.
mov ax,0B800h
434.
mov es,ax
435.
xor dx,dx
436.
mov si,offset nombre+2
437.
mov di,(80*12+31)*2
438.
439. mostrar_nombre:
440.
mov al,[si]
441.
mov ah,1bh
442.
mov es:[di],ax
443.
inc dx
444.
inc si
445.
inc di
446.
inc di
447.
cmp dl,nombre[1]
caracteres
448.
jne mostrar_nombre
449.
450.
pop es
451.
pop cx
452.
pop ax
453.
454.
ret
455.
456. muestra_nombre endp
457.
458.
459. CODE ENDS
460.
END START
461.

462.

;Linea 12, columna 31

;Fondo azul, letras blancas


;Cuenta el numero de caracteres

;Comparar con el numero de

Programa que calcula el factorial de 3 y lo muestra por pantalla:

463.
464. ;----------------------------------------------------------------------------465. ;Definicion del segmento de datos
466. ;----------------------------------------------------------------------------467. DATOS SEGMENT
468.
469.
dato
db 3 ;Numero del que calcularemos su factorial
470.
471. DATOS ENDS
472.
473. ;----------------------------------------------------------------------------474. ;Definicion del segmento de pila
475. ;----------------------------------------------------------------------------476. PILA SEGMENT STACK "STACK"
477.
db 40h dup(0)
478. PILA ENDS
479.

480. ;----------------------------------------------------------------------------481. ;Definicion del segmento extra


482. ;----------------------------------------------------------------------------483. EXTRA SEGMENT
484.
result
dw 0,0
;2 palabras (4 bytes)
485. EXTRA ENDS
486.
487. ;----------------------------------------------------------------------------488. ;Definicion del segmento de codigo
489. ;----------------------------------------------------------------------------490. CODE SEGMENT
491.
assume CS:code,DS:datos,ES:extra,SS:pila
492.
493. factorial db 0
;Variable para guardar el factorial
494.
495. START PROC
496.
497.
call inicializar
;Inicializa los registros de
segmento
498.
mov sp,64
;Carga el puntero de pila con el
valor mas alto
499.
500.
mov cl,dato
501.
call calcula_factorial
;Calcula el faltorial de dato
502.
mov factorial,al
;Almacenar el resultado en factorial
503.
call muestra_factorial
;Muestra el valor del factorial
504.
505.
mov ax,4C00h
;
506.
int 21h
;Terminar el programa
507.
508.
509. START ENDP
510.
511. ;----------------------------------------------------------------------------512. ; inicializar
513. ;
514. ; in:
515. ; out:
Los registros de segmento quedan inicializados
516. ; machaca: AX, DS, SS, ES
517. ; make:
Inicializa los registros de segmento
518. ;
519. ;----------------------------------------------------------------------------520. inicializar proc near
521.
522.
mov ax,datos
523.
mov ds,ax
524.
mov ax,pila
525.
mov ss,ax
526.
mov ax,extra
527.
mov es,ax
528.

529.
ret
530.
531. inicializar endp
532.
533. ;----------------------------------------------------------------------------534. ; calcula_factorial
535. ;
536. ; in:
CL contiene el dato
537. ; out:
Devuelve en AX el resultado de calcular el factorial
538. ; machaca: AX, CX
539. ; make:
Inicializa los registros de segmento y el puntero de
pila
540. ;
541. ;----------------------------------------------------------------------------542. calcula_factorial proc near
543.
544.
mov ax,1
545.
xor ch,ch
546.
cmp cx,0
;Si el numero es 0
547.
je
fin
;terminamos
548.
549. factor:
550.
mul cx
551.
dec cx
552.
jne factor
553.
554. fin:
555.
ret
556.
557. calcula_factorial endp
558.
559. ;----------------------------------------------------------------------------560. ; muestra_nombre
561. ;
562. ; in: nombre contiene el nombre de usuario que se ha introducido
563. ; out:
564. ; machaca: DI, SI
565. ; make:
Muestra el valor del factorial por pantalla
566. ;
567. ;----------------------------------------------------------------------------568. muestra_factorial proc near
569.
570.
push ax
571.
push cx
572.
push es
573.
574.
mov ax,0B800h
575.
mov es,ax
;Apuntar a la memoria de video
576.
mov dl,factorial
577.
mov di,(80*12+31)*2
;Linea 12, columna 31
578.
add dl,30h
;Obtener el valor en ASCII ('0'=30h)
579.
mov dh,1bh
580.
mov es:[di],dx

581.
582.
pop es
583.
pop cx
584.
pop ax
585.
586.
ret
587.
588. muestra_factorial endp
589.
590. CODE ENDS
591.
END START
592.

2
1. Escribir un programa que escriba el mismo carcter en las 2000 posiciones de
la pantalla:
2.
3. pantalla EQU 0B800h
;Direccion fsica de comienzo de la
pantalla
4.
5. ;----------------------------------------------------------------------------6. ;Definicin del segmento de codigo
7. ;----------------------------------------------------------------------------8. CODE SEGMENT
9.
assume cs:code
10.
11. START PROC
12.
mov ax,pantalla
;Cargar la direccin de la
coordenada 0,0 de la
13.
mov ds,ax
;pantalla
14.
xor bx,bx
;Ponemos bx a 0
15.
16. pinta_caracter:
17.
mov ds:[bx],byte ptr "V"
;Escribir el carcter en
su coordenada
18.
inc bx
;En lugar de sumar 2, se
incrementa 2 veces porque
19.
;consume menos ciclos de
reloj del procesador
20.
inc bx
;Cada posicion de la
pantalla son 2 bytes,
21.
cmp bx,2000*2
;por eso bx va a llegar
hasta 4000
22.
jl
pinta_caracter
;Si bx<4000 volvemos a
pintar otro carcter
23.
24.
mov ax,4C00h
;
25.
int 21h
;Terminar el programa
26.

27. START ENDP


28.
29. CODE ENDS
30.
END START

31. Hacer un programa que coja el carcter que se encuentre en la coordenada 0,0
de la pantalla en ese momento y lo copie por toda la pantalla. En los ltimos 4
caracteres mostrar la palabra ETSI:
32.
33. pantalla EQU 0B800h
34.
35. ;----------------------------------------------------------------------------36. ;Definicin del segmento de codigo
37. ;----------------------------------------------------------------------------38. CODE SEGMENT
39.
assume cs:code
40.
41. START PROC
42.
mov ax,pantalla
;Cargar la direccin de la
coordenada 0,0 de la
43.
mov ds,ax
;pantalla
44.
xor bx,bx
45.
mov dx,ds:[bx]
;Obtener el carcter de la
coordenada 0,0
46.
47. pinta_caracter:
48.
inc bx
49.
inc bx
50.
mov ds:[bx],dx
;Copiar el carcter
obtenido por toda la pantalla
51.
cmp bx,1995*2
;Dejamos los ultimos 4
caracteres sin rellenar
52.
jl
pinta_caracter
53.
54.
mov ds:[1996*2],byte ptr "E"
;En los ultimos 4
caracteres escribimos
55.
mov ds:[1997*2],byte ptr "T"
;nuestro mensaje
56.
mov ds:[1998*2],byte ptr "S"
;
57.
mov ds:[1999*2],byte ptr "I"
;
58.
59.
mov ax,4C00h
;
60.
int 21h
;Terminar el programa
61.
62. START ENDP
63.
64. CODE ENDS
65.
END START

66. Nos vemos en la necesidad ya de empezar a manejar el Turbo Debugger. No


todos los programas que hagamos tienen por qu mostrar algo por la pantalla.
Veremos ahora un programa que realiza la suma de los nmeros
1+2+3+4+5+6+7+8+9+10=55=37h. La salida de esta suma se ir guardando en
el acumulador (AX). Con el TD podremos ir viendo como el registro AX va
aumentando hasta llegar a 37 en hexadecimal, que va a ser el equivalente a 55
en decimal. Todo lo que veremos en el TD va a estar en hexadecimal. Al

principio puede parecernos un poco raro y no saber muy bien a que equivale,
pero poco a poco iremos aprendiendo a pensar en hexadecimal y binario :D.
Antes de nada les voy a mostrar los archivos .bat que he venido utilizando
durante mi aprendizaje del ensamblador: - Para debuggear un programa puede
utilizarse nicamente el programa deb.bat:
67.
68. :---------------------------------------------------------------------69. :
70. : Fichero: deb.bat
71. :
72. : Descripcion:
73. :
Ensamblar modulo fuente principal de un programa, crear modulo
74. :
objeto y debuggearlo.
75. :
76. :---------------------------------------------------------------------77. :
78. echo off
79.
if z%1 == z goto error
80.
goto check
81. :error
82.
echo *** error: falta nombre del modulo fuente ***
83.
goto fin
84. :check
85.
if exist %1.asm goto ensam
86.
echo *** error: fichero %1.asm no existe ***
87.
goto fin
88. :ensam
89.
tasm /zi %1;
90.
if exist %1.obj goto mensa
91.
echo *** error en programa fuente ***
92.
goto fin
93. :mensa
94.
tlink /v %1
95.
echo ... creado fichero %1.obj
96.
97.
td %1
98.
99. :fin

Este archivo de procesamiento por lotes lo que hace es ensamblar el archivo,


linkarlo y por ultimo lanzar el Turbo Debugger para nuestro archivo. Claro est que
todo esto puede hacerse paso por paso, pero bueno, cada uno ver lo que prefiere.
Mi fichero t.bat no se diferencia en casi nada de deb.bat, la nica diferencia es que
en lugar de td %1 debemos poner un %1 para que lo ejecute. De esta manera t.bat lo
que hace es ensamblar, linkar y ejecutar el programa. Con estos programas ya
estamos preparados para hacer frente al siguiente ejemplo, para el cual veremos su
resultado en el TD.
;----------------------------------------------------------------------------;Definicin del segmento de codigo

;----------------------------------------------------------------------------CODE SEGMENT
assume CS:code
START:
xor
mov

ax,ax
cx,1

;
;Inicializar

add
inc
cmp
jne

ax,cx
cx
cx,11
suma

;
;
;
;Sumar 1+...+10=37h

mov
int

ax,4C00h
21h

;
;Terminar el programa

suma:

CODE ENDS
END START

El siguiente programa es algo ms sofisticado y potente. La teora la


explicaremos despus de ver el ejemplo.
100.
Realizar un programa que limpie la pantalla dejando el fondo azul y los
caracteres rojos:
101.
102. pantalla EQU 0B800h
103.
104. ;----------------------------------------------------------------------------105. ;Definicin del segmento de pila
106. ;----------------------------------------------------------------------------107. PILA SEGMENT STACK "STACK"
108.
db 40h dup(0)
109. PILA ENDS
110.
111. ;----------------------------------------------------------------------------112. ;Definicin del segmento extra
113. ;----------------------------------------------------------------------------114. EXTRA SEGMENT
115.
result
dw 0,0
116. EXTRA ENDS
117.
118. ;----------------------------------------------------------------------------119. ;Definicin del segmento de codigo
120. ;----------------------------------------------------------------------------121. CODE SEGMENT
122.
assume cs:code,es:extra,ss:pila
123.

124. START PROC


125.
126.
cld
127.
mov ax,pantalla
128.
mov es,ax
129.
xor di,di
130.
mov ax,1C00h
intensidad
131.
ax,0001110000000000b
132.
mov cx,2000
133.
rep stosw
134.
135.
mov ax,4C00h
136.
int 21h
137.
138. START ENDP
139.
140. CODE ENDS
141.
END START

;DF=0 (incrementar DI)

;Fondo azul, caracteres rojos con


;Equivalente a: mov
;Repetirlo las 2000 veces
;
;Terminar el programa

Si quisiesemos poner los atributos de otra forma slo hay que cambiar una lnea.
Podramos ponerla de la siguiente manera, por ejemplo:
mov ax,1100001000000000b mov ax,0C200h

si quisiesemos poner el fondo rojo con letras verdes.


Teora para entender el ejercicio:
STOSW: Se transfiere el registro AX a la palabra ES:[DI]. DI se actualiza en dos
unidades.
Si la bandera de direccin es cero (DF=0), DI se incrementa, si DF=1, se
decrementa.
Esto lo logramos con las instrucciones CLD o STD.
En CX hemos especificado el nmero de elementos de la cadena. En este caso las
2000 posiciones, son las 80x25 posiciones de la pantalla.
Para indicar en la memoria de pantalla como queremos el fondo y los caracteres
podemos hacerlo en sus 8 bits. Para indicar el carcter tenemos otros 8 bits. Cada
nmero o letra hexadecimal equivale a un nibble (4 bits):
cdigo atributo (1 byte). Los bits son los siguientes:
7 - Utilizado para indicar si el carcter parpadea o no.
6 - Componente rojo del fondo
5 - Componente verde del fondo
4 - Componente azul del fondo
3 - Intensidad en los caracteres

2 - Componente rojo del carcter


1 - Componente verde del carcter
0 - Componente azul del carcter
Como vemos en nuestro ejemplo (0001 1100 0000 0000), hemos activado el
componente azul del fondo, la intensidad y el componente rojo de los caracteres.
cdigo carcter (1 byte): Podemos elegir de la tabla ASCII aquel carcter que
prefiramos. Como carcter elegimos el 00h, que en la tabla ASCII va a equivaler a
dejar el fondo sin ningn carcter. Si quiesiesemos que apareciese el carcter 'V' en
el fondo pues cogeramos el 56h. Cuando ejecutemos el programa, si queremos
volver a tener nuestra pantalla como antes, basta con un un simple:
C:\>cls

Volveremos a tener la pantalla con letras blancas sobre fondo negro.


1. Realizar un programa que muestre la tabla de caracteres ASCII por pantalla:
2.
3. ;----------------------------------------------------------------------------4. ; Programa que muestra la tabla de caracteres ASCII por pantalla
5. ;----------------------------------------------------------------------------6. PANTALLA equ 0B800h
7.
8. ;----------------------------------------------------------------------------9. ;Definicion del segmento de pila
10. ;----------------------------------------------------------------------------11. PILA SEGMENT STACK "STACK"
12.
db
40h dup(0)
13. PILA ENDS
14.
15. ;----------------------------------------------------------------------------16. ;Definicion del segmento de codigo
17. ;----------------------------------------------------------------------------18. CODE SEGMENT
19.
assume CS:code, SS:pila
20.
21. START:
22.
mov ax,PANTALLA
23.
mov ds,ax
24.
25.
xor bx,bx
26.
xor al,al
27.
mov cx,256
;Numero de caracteres que contiene
la tabla ASCII
28.

29. mostrar_ascii:
30.
mov [bx],al
pantalla
31.
inc bx
32.
inc bx
33.
inc al
34.
loop mostrar_ascii
35.
36.
mov ax,4C00h
37.
int 21h
38.
39. CODE ENDS
40.
END START

;Escribirlo en la coordenada de la
;
;Pasar a la siguiente coordenada
;Pasar al siguiente caracter
;
;Terminar el programa

41. Este programa se encarga de dibujar un cuadrado en la pantalla, ponerlo con


fondo blanco y rellenarlo con caracteres 'V':
42.
43. PANTALLA equ 0B800h
44.
45. ;----------------------------------------------------------------------------46. ;Definicion del segmento de pila
47. ;----------------------------------------------------------------------------48. PILA SEGMENT STACK "STACK"
49.
db
40h dup(0)
50. PILA ENDS
51.
52. ;----------------------------------------------------------------------------53. ;Definicion del segmento de codigo
54. ;----------------------------------------------------------------------------55. CODE SEGMENT
56.
assume CS:code, SS:pila
57.
58. START:
59.
mov ax,PANTALLA
60.
mov ds,ax
61.
62.
mov dl,0
;Primera linea en la que
empezaremos a pintar
63.
mov cx,10
;Numero de lineas que vamos a
tener
64.
65. BucleLineas:
66.
push cx
67.
68.
mov dh,0
;Primera columna
69.
mov cx,20
;Numero de columnas
70.
71. BucleColumnas:
72.
mov al,80*2
;Bytes por linea
73.
mul dl
;Por el numero de linea
74.
mov bx,ax
75.
mov al,2
;2 bytes por columna
76.
mul dh
;Por el numero de columna

77.
78.
79.
80.
81.
82.

add
mov
inc
loop

bx,ax
word ptr [bx],7056h
dh
BucleColumnas

;Fondo blanco y letra 'V'


;Siguiente columna

pop

cx

;Recuperamos el contador de las

lineas
83.
inc dl
84.
loop BucleLineas
85.
86.
mov ax,4C00h
87.
int 21h
88.
89. CODE ENDS
90.
END START

;Pasar a la siguiente linea

91. Este programa le pregunta al usuario si desea continuar o no hasta que se


pulse la tecla 'N' o 'n':
92.
93. cr equ 13
;retorno de carro
94. lf equ 10
;alimentacion de linea
95.
96. ;----------------------------------------------------------------------------97. ;Definicion del segmento de datos
98. ;----------------------------------------------------------------------------99. DATOS SEGMENT
100.
DeseaContinuar db cr,lf,'Desea continuar? S/N: '
101.
db'$'
102.
continuando db '
Continuando...',cr,lf
103.
db'$'
104.
LetraErronea db '
La tecla pulsada es incorrecta.',cr,lf
105.
db'$'
106. DATOS ENDS
107.
108. ;----------------------------------------------------------------------------109. ;Definicion del segmento de pila
110. ;----------------------------------------------------------------------------111. PILA SEGMENT STACK "STACK"
112.
db 40h dup(?)
113. PILA ENDS
114.
115. ;----------------------------------------------------------------------------116. ;Definicion del segmento de codigo
117. ;----------------------------------------------------------------------------118. CODE SEGMENT
119.
assume CS:code, DS:datos, SS:pila
120.
121. START:
122.
mov ax,datos
123.
mov ds,ax

124.
jmp continuar
CONTINUAR
125.
126. INICIO:
127.
lea dx,continuando
128.
mov ah,9
129.
int 21h
programa
130.
jmp continuar
desea continuar
131.
132. ERROR:
133.
lea dx,LetraErronea
134.
mov ah,9
introducida
135.
int 21h
136.
137. CONTINUAR:
138.
lea dx,DeseaContinuar
139.
mov ah,9
140.
int 21h
desea continuar
141.
142.
mov ah,1
143.
int 21h
144.
145.
cmp al, 'S'
146.
je
inicio
147.
cmp al, 's'
148.
je
inicio
149.
150.
cmp al, 'N'
151.
je
salir
152.
cmp al, 'n'
153.
je
salir
154.
155.
jmp error
'N' ni 'n'
156.
error. Saltamos
157.
158.
159. salir:
160.
mov ax, 4C00h
161.
int 21h
162.
163. CODE ENDS
164.
END START

;Saltamos a la etiqueta

;
;
;Mensaje de que seguimos en el
;Salto para preguntar si se

;
;Mensaje de que la letra
;no es correcta
;
;
;Mostrar pregunta para ver si
;Esperar a que se pulse una tecla
;y mostrarla por pantalla
;
;
;
;Desea continuar
;
;
;
;No desea continuar, terminamos
;La tecla pulsada no es 'S', 's',
;Se va a mostrar un mensaje de
;a la etiqueta ERROR

165.
Realizar un programa que cambie todas las letras de la pantalla a
minusculas:
166.
167. PANTALLA equ 0B800h
168.
169. ;----------------------------------------------------------------------------170. ;Definicion del segmento de pila

171. ;----------------------------------------------------------------------------172. PILA SEGMENT STACK "STACK"


173.
db
40h dup(0)
174. PILA ENDS
175.
176. ;----------------------------------------------------------------------------177. ;Definicion del segmento de codigo
178. ;----------------------------------------------------------------------------179. CODE SEGMENT
180.
assume CS:code, SS:pila
181.
182. START:
183.
mov ax,pantalla
;
184.
mov ds,ax
;DS apunta a la direccion de la
pantalla
185.
186.
xor bx,bx
187.
mov cx,2000
;80 filas x 25 columnas
188.
189. cambia_minus:
190.
mov al,ds:[bx]
;Obtenemos el caracter que hay en la
pantalla
191.
;en la coordenada indicada
192.
cmp al,byte ptr 'A'
;Comprobar que este entre la letra
'A'
193.
jb
siguiente
;
194.
cmp al,byte ptr 'Z'
;y la letra 'Z'
195.
ja
siguiente
;Si no es asi pasamos al siguiente
caracter
196.
add al,32
;Para pasar de mayusculas a
minusculas
197.
;hay que sumar 32 para movernos en
la
198.
;tabla ASCII de las mayusculas a las
minusculas
199.
mov ds:[bx],al
;Escribimos en la pantalla el
caracter cambiado
200.
;a minusculas
201. siguiente:
202.
inc bx
;
203.
inc bx
;Pasamos a la siguiente coordenada
204.
loop cambia_minus
205.
206.
mov ax,4C00h
;
207.
int 21h
;Terminamos el programa
208.
209. CODE ENDS
210.
END START

Vamos a ver diferentes ejemplos de instrucciones para entenderlas un poco mejor. Ser
bueno tener un libro al lado para saber qu hace cada instruccin.
1. Ejemplo de las instrucciones: CBW y CWD
2.
3. ;----------------------------------------------------------------------------4. ;Definicion del segmento de pila
5. ;----------------------------------------------------------------------------6. PILA SEGMENT STACK "STACK"
7.
db
40h dup(0)
8. PILA ENDS
9.
10. ;----------------------------------------------------------------------------11. ;Definicion del segmento de codigo
12. ;----------------------------------------------------------------------------13. CODE SEGMENT
14.
assume CS:code, SS:pila
15.
16. START:
17.
mov ah,3
;No sirve para nada, solo para ver que al
convertir
18.
;en palabra o doble palabra se machacan
los registros
19.
mov al,5
20.
cbw
;Convertir un byte en palabra
21.
cwd
;Convertir una palabra en doble palabra
22.
23.
neg al
;al pasa a ser un numero negativo
(complemento a 2)
24.
mov ah,4
;basura, igual que en caso anterior
25.
cbw
;Convertir un byte en palabra
26.
cwd
;Convertir una palabra en doble palabra
27.
28.
mov ax,4C00h
29.
int 21h
30.
31. CODE ENDS
32.
END START

33. Ejemplo de la instruccion: AAM (ajuste ASCII en multiplicacin)


34.
35. ;----------------------------------------------------------------------------36. ; Programa que prueba la instruccion: AAM
37. ;
38. ; ah <- cociente (al/10)
39. ; al <- resto
(al/10)
40. ;
41. ;----------------------------------------------------------------------------42.
43. ;-----------------------------------------------------------------------------

44. ;Definicion del segmento de codigo


45. ;----------------------------------------------------------------------------46. CODE SEGMENT
47.
assume CS:code
48.
49. START:
50.
51.
mov al,9
52.
mov cl,5
53.
mul cl
;Resultado: ax=002D
54.
aam
;En el cociente hay un 4 y en el resto un 5
55.
;Resultado es ax=0405
56.
57.
mov ax,4c00h
58.
int 21h
59.
60. CODE ENDS
61.
END START

62. Ejemplo de la instruccion: AAA (ajuste ASCII en suma)


63.
64. ;----------------------------------------------------------------------------65. ; Programa que muestra el uso de la instruccion AAA. Esta
instruccion convierte
66. ; el contenido de AL en un numero decimal ASCII (desempaquetado)
tras una
67. ; instruccion de suma. Se utiliza para ajustar el resultado
despues de una suma
68. ; de dos numeros decimales en formato ASCII
69. ;----------------------------------------------------------------------------70.
71. ;----------------------------------------------------------------------------72. ;Definicion del segmento de pila
73. ;----------------------------------------------------------------------------74. PILA SEGMENT STACK "STACK"
75.
db 40h dup(0)
76. PILA ENDS
77.
78. ;----------------------------------------------------------------------------79. ;Definicion del segmento de codigo
80. ;----------------------------------------------------------------------------81. CODE SEGMENT
82.
assume CS:code,SS:pila
83.
84. START PROC
85.
86.
mov ax,8
;
87.
add al,1
;
88.
aaa
;AX=0009h
89.
mov ax,8
;
90.
add al,2
;

91.
aaa
92.
mov ax,11110001b
93.
add al,1
94.
aaa
95.
mov ax,8
96.
add al,7
97.
aaa
98.
add al,4
99.
aaa
100.
add al,9
101.
aaa
102.
103.
104.
mov ax,4C00h
105.
int 21h
106.
107. START ENDP
108.
109. CODE ENDS
110.
END START

;AX=0100h
;
;
;AX=0002h
;
;
;AX=0105h
;
;AX=0109h
;
;AX=0208h
;
;Terminar el programa

111.
Ejemplo de la instruccion: AAA (ajuste ASCII en suma). Del examen de
ETCII del ao 2001:
112.
113. ;----------------------------------------------------------------------------114. ; Programa que prueba la instruccion: AAA
115. ;
116. ; ah <- cociente (al/0Ah)
117. ; al <- resto
(al/0Ah)
118. ;
119. ;----------------------------------------------------------------------------120. ; Ejercicio: examen ETCII - 7/11/01
121.
122. ;----------------------------------------------------------------------------123. ;Definicion del segmento de codigo
124. ;----------------------------------------------------------------------------125.
126. CODE SEGMENT
127.
assume CS:code
128.
129. start:
130.
131.
mov ax,16h
132.
mov bx,191h
133.
add ax,bx
134.
aaa
;AX=0107h
135.
add ax,7h
136.
aaa
;AX=0204h
137.
138.
mov ax,4c00h
139.
int 21h
140.
141. CODE ENDS

142.

143.

END START

Ejemplo que muestra la diferencia entre las instrucciones: AAA y DAA

144.
145. ;----------------------------------------------------------------------------146. ; Programa que prueba las instrucciones: AAA y DAA
147. ;----------------------------------------------------------------------------148. ;----------------------------------------------------------------------------149. ;Definicion del segmento de pila
150. ;----------------------------------------------------------------------------151. PILA SEGMENT STACK "STACK"
152.
db
40h dup(0)
153. PILA ENDS
154.
155. ;----------------------------------------------------------------------------156. ;Definicion del segmento de codigo
157. ;----------------------------------------------------------------------------158. CODE SEGMENT
159.
assume CS:code, SS:pila
160.
161. START:
162.
mov al,5
163.
add al,7
164.
aaa
;Ajuste BCD no empaquetado
165.
166.
xor ax,ax
167.
168.
mov al,5
169.
add al,7
170.
daa
;Ajuste BCD empaquetado
171.
172.
mov ax,4C00h
173.
int 21h
174.
175. CODE ENDS
176.
END START

177.

Ejemplo de la instruccin NEG (convertir a complemento a 2):

178.
179. ;----------------------------------------------------------------------------180. ;Definicion del segmento de pila
181. ;----------------------------------------------------------------------------182. PILA SEGMENT STACK "STACK"
183.
db
40h dup(0)
184. PILA ENDS
185.
186. ;----------------------------------------------------------------------------187. ;Definicion del segmento de codigo

188. ;----------------------------------------------------------------------------189. CODE SEGMENT


190.
assume CS:code, SS:pila
191.
192. START:
193.
194.
mov al,8
195.
neg al
;Convertir a su complemento a 2
196.
197.
mov ax,4C00h
198.
int 21h
199.
200. CODE ENDS
201.
END START

202.
Otra forma de convertir a complemento a 2 mediante las instrucciones
NOT e INC:
203.
204. ;----------------------------------------------------------------------------205. ;Definicion del segmento de pila
206. ;----------------------------------------------------------------------------207. PILA SEGMENT STACK "STACK"
208.
db
40h dup(0)
209. PILA ENDS
210.
211. ;----------------------------------------------------------------------------212. ;Definicion del segmento de codigo
213. ;----------------------------------------------------------------------------214. CODE SEGMENT
215.
assume CS:code, SS:pila
216.
217. START:
218.
219.
mov al,8
220.
not al
;
221.
inc al
;Convertir a su complemento a 2
222.
223.
mov ax,4C00h
224.
int 21h
225.
226. CODE ENDS
227.
END START

1. Realizar un programa que guarde el estado de la pantalla con todos sus


caracteres, despus rellene toda la pantalla con '*' y por ltimo vuelva a dejar
la pantalla como estaba:
2.
3. ;----------------------------------------------------------------------------4. ;Programa que guarda el estado de la pantalla con todos sus
caracteres, despues
5. ;rellena toda la pantalla con '*' y por ultimo vuelve a dejar la
pantalla como
6. ;estaba
7. ;----------------------------------------------------------------------------8.
9. PANTALLA equ 0B800h
10.
11. ;----------------------------------------------------------------------------12. ;Definicion del segmento de datos
13. ;----------------------------------------------------------------------------14. DATOS SEGMENT
15.
16. pantalla_bak db 80*25*2 DUP(?)
;Reservar una variable para
guardar toda la
17.
;informacion de la pantalla
18. DATOS ENDS
19.
20. ;----------------------------------------------------------------------------21. ;Definicion del segmento de pila
22. ;----------------------------------------------------------------------------23. PILA SEGMENT STACK "STACK"
24.
db
40h dup(0)
25. PILA ENDS
26.
27. ;----------------------------------------------------------------------------28. ;Definicion del segmento extra
29. ;----------------------------------------------------------------------------30. EXTRA SEGMENT
31.
RESULT DW 0,0
32. EXTRA ENDS
33.
34. ;----------------------------------------------------------------------------35. ;Definicion del segmento de codigo
36. ;----------------------------------------------------------------------------37. CODE SEGMENT
38.
assume DS:datos, CS:code, SS:pila
39.
40. START:
41.
mov ax,PANTALLA

42.
43.
44.
45.
46.
47.
48.
49.

mov

ds,ax

xor
mov
mov
lea

si,si
ax,datos
es,ax
di,pantalla_bak

;Apuntar a la variable

mov

cx,80*25*2

;Numero de bytes que tenemos que

copiar
50.
cld
;Direccion para incrementar DI y SI
51.
52. backup:
53.
movsb
;Mover el contenido de la direccion de
memoria apuntada
54.
;por SI a la apuntada por DI, en este
caso la variable
55.
;pantalla_bak
56.
loop backup
57.
58.
mov cx,80*25
;
59.
xor bx,bx
;
60.
mov al,'*'
;
61.
mov ah,70h
;Llenar la pantalla de '*'
62.
63. llena:
64.
mov [bx],ax
65.
inc bx
66.
inc bx
67.
loop llena
68.
69.
push ds
;
70.
push es
;
71.
pop ds
;
72.
pop es
;Intercambiar DS y ES
73.
74.
xor di,di
75.
lea si,pantalla_bak
76.
77.
xor ah,ah
;
78.
int 16h
;Esperar a que se pulse una tecla
79.
80.
mov cx,4000
;Los 4000 bytes de la pantalla
81.
82. restaura:
;
83.
movsb
;
84.
loop restaura
;Volver a dejar la pantalla como al
principio
85.
86.
mov ax,4C00h
87.
int 21h
88.
89. CODE ENDS
90.
END START

91. Realizar un programa que devuelva la primera posicin en que se ha


encontrado un carcter dado:
92.

93. ;----------------------------------------------------------------------------94. ;Devuelve la primera posicion en que se ha encontrado el caracter


a buscar
95. ;----------------------------------------------------------------------------96.
97. CARACTER equ 'v'
98.
99. ;----------------------------------------------------------------------------100. ;Definicion del segmento de datos
101. ;----------------------------------------------------------------------------102. DATOS SEGMENT
103.
mensaje
db "www.victorsanchez2.net"
104.
msg_caracter
db "El caracter: "
105.
msg_posicion
db "Se encuentra en la posicion: "
106. DATOS ENDS
107.
108. ;----------------------------------------------------------------------------109. ;Definicion del segmento de pila
110. ;----------------------------------------------------------------------------111. PILA SEGMENT STACK "STACK"
112.
db 40h DUP(0)
113. PILA ENDS
114.
115. ;----------------------------------------------------------------------------116. ;Definicion del segmento extra
117. ;----------------------------------------------------------------------------118. EXTRA SEGMENT
119.
RESULT DW 0,0
120. EXTRA ENDS
121.
122. ;----------------------------------------------------------------------------123. ;Definicion del segmento de codigo
124. ;----------------------------------------------------------------------------125. CODE SEGMENT
126.
assume cs:code,ds:datos,es:extra,ss:pila
127.
128. START PROC
129.
;Inicializamos los registros de segmento
130.
mov ax,datos
131.
mov ds,ax
132.
mov ax,pila
133.
mov ss,ax
134.
mov ax,extra
135.
mov es,ax
136.
137.
;Limpiamos la pantalla

138.
mov ax,0B800h
;En esta direccion comienza la memoria de
video
139.
mov es,ax
;Lo cargamos en el segmento extra
140.
xor di,di
;Ponemos DI=0
141.
mov cx,80*25
;80 lineas x 25 columnas
142.
xor al,al
;0=" "
Rellenar la pantalla con blancos
143.
mov ah,0Fh
;Fondo negro, letras blancas
144.
rep stosw
145.
146.
lea si,mensaje
;Cargar el mensaje donde buscaremos
147.
mov al,CARACTER
;Cargar el caracter a buscar
148.
mov cx,22
;Longitud maxima para buscar (longitud de
'mensaje')
149.
150.
call busca_fin
;Buscar la posicion en que se encuentra
el CARACTER
151.
152.
mov ax,0B800h
;
153.
mov es,ax
;Colocarnos al inicio de la memoria de
video
154.
add cl,30h
;Preparar CL para mostrar el caracter por
pantalla
155.
push cx
;Guardarlo para recuperarlo despues
156.
157.
mov di,(80*2)*2
;Colocarnos en la segunda fila
158.
lea si,mensaje
;Colocar el offset de mensaje en si
159.
mov cx,22
;Total de caracteres de mensaje
160.
call pinta
;Mostrarlo por pantalla
161.
162.
mov di,(80*4)*2
;Nos colocamos en la cuarta fila
163.
lea si,msg_caracter ;Cargar el offset
164.
mov cx,13
;Total de caracteres de mensaje
165.
call pinta
;Mostrarlo por pantalla
166.
167.
mov di,(80*4+13)*2
;Colocarnos al final del
msg_caracter
168.
mov byte ptr es:[di],CARACTER
;Mostrar el CARACTER por
pantalla
169.
170.
mov di,(80*5)*2
;Ponernos en la quinta fila
171.
lea si,msg_posicion
;Cargar el offset
172.
mov cx,29
;Total de caracteres de mensaje
173.
call pinta
;Mostrarlo por pantalla
174.
175.
mov di,(80*5+29)*2 ;Colocarnos al final del msg_posicion
176.
pop cx
;Recuperar la posicion en que se
encontraba CARACTER
177.
mov es:[di],cl
178.
179.
mov ax,4C00h
;
180.
int 21h
;Terminar el programa
181.
182. START ENDP
183.
184. ;----------------------------------------------------------------------------185. ; busca_fin

186. ;
187. ; in: AL contiene el caracter que debemos buscar
188. ;
SI contiene la cadena que debemos buscar
189. ; out: En CX se guarda la posicion donde se ha encontrado el
caracter
190. ; machaca: CX
191. ; make: Devuelve en CX la primera posicion donde se ha encontrado
el caracter
192. ;
dado en AL
193. ;----------------------------------------------------------------------------194.
195. busca_fin proc near
196.
197.
push di
198.
push dx
199.
push es
200.
push si
201.
push ax
202.
203.
mov ax,ds
;
204.
mov es,ax
;
205.
mov di,si
;Copiar DS:SI en ES:DI
206.
207.
mov dx,cx
;Copiar el limite en otro registro
208.
cld
;Direccion incremental
209.
pop ax
;Recuperar el caracter que nos han pedido
210.
push ax
;Guardarlo en la pila para no perderlo
211. repnz
scasb
;Buscar el caracter pedido
212.
sub dx,cx
;Calcular la longitud
213.
mov cx,dx
;Guardar la longitud en CX
214.
215.
pop ax
216.
pop si
217.
pop es
218.
pop dx
219.
pop di
220.
ret
221.
222. busca_fin endp
223.
224. ;----------------------------------------------------------------------------225. ; pinta
226. ;
227. ; in: SI contiene el offset del mensaje a mostrar
228. ;
DI contiene la direccion donde se ira mostrando el mensaje
229. ;
CX contiene el numero de iteraciones a realizar
230. ; out:
231. ; machaca: CX
232. ; make: Muestra por pantalla el mensaje dado
233. ;----------------------------------------------------------------------------234. pinta proc near
235.
236.
push ax
237.
push si

238.
push di
239.
240.
mov ah,0Fh
241.
242. pintar:
243.
mov al,[si]
244.
mov es:[di],ax
245.
inc si
246.
inc di
247.
inc di
248.
loop pintar
249.
250.
pop di
251.
pop si
252.
pop ax
253.
ret
254.
255. pinta endp
256.
257. CODE ENDS
258.
END START

;Fondo negro y letras blancas


;
;
;
;
;
;
;Mostrarlo por pantalla

259.
Hacer un programa que muestre la sucesin de cdigos ASCII en la
esquina superior derecha de la pantalla, intercambiando los caracteres cada
medio segundo. Este programa ya es algo ms complejo que los anteriores ya
que empezamos a trabajar con programas residentes y el RTC. Os recomiendo
que aprendais bien las caractersticas de los programas residentes y
programacin del RTC antes de intentar comprender este ejercicio por
completo. Este tipo de ejercicios van un nivel ms all, y si de verdad no
comprendeis bien este tipo de ejercicios es mejor que os cojais libros, apuntes o
lo que sea y lo domineis con soltura.
Un comando que os puede servir de ayuda es:
MEM /C
Con este podemos saber los programas que hay residentes en nuestra memoria.
Al escribir esto veremos como aparece el programa de nombre ASCII, que
ocupa 0,4K.
Para ensamblar y ejecutar este programa, al ser .COM, hay que hacerlo con
unas banderas distintas:
C:\>tasm archivo
C:\>tlink /t archivo
C:\>archivo
;----------------------------------------------------------------------------;Programa que muestra la sucesion de codigos ASCII en la esquina
superior
;derecha de la pantalla, intercambiando los caracteres cada medio
segundo

;----------------------------------------------------------------------------PANTALLA
equ 0b800h
;----------------------------------------------------------------------------;Definicion del segmento de codigo
;----------------------------------------------------------------------------CODE SEGMENT
assume CS:code
org 100h
;Dejar las 100h primeras posiciones para
el PSP
START:
jmp instalar

;Bifurcar a la rutina de instalacion

letras proc far


push ax
push es
push di

;
;
;Guardamos los registros en la pila

mov
out
in

al,0Ch
70h,al
al,71h

;
;
;Leer el RTC

mov
mov
mov
mov
inc
mov

ax,PANTALLA
es,ax
di,79*2
ax,es:[di]
al
es:[di],ax

;Guardamos en AX lo que hay en la esquina


;Pasamos al siguiente caracter
;Lo mostramos por pantalla

cli
mov
out
out
sti

al,20h
20h,al
0A0h,al

pop
pop
pop

di
es
ax

;Inhabilitar las interrupciones

;Habilitar las interrupciones


;
;
;Recuperar los registros

iret
letras endp
instalar proc far
cli
;Inhabilitar las interrupciones
xor ax,ax
;
mov es,ax
;Poner a 0 ES
mov es:[70h*4],offset letras
;Guardar el offset
mov es:[70h*4+2],cs
;y el segmento de la rutina
in
and

al,0A1h
al,11111110b

;Leer el PIC esclavo


;

out

0A1h,al

;Activamos IR0

in
and
out

al,21h
al,11111011b
21h,al

;Leer el PIC maestro


;
;Activado

al,0Ah
70h,al
al,2Fh

;Vamos a escribir en el registro A del RTC


;
;Los simbolos se intercambian cada medio

71h,al

;Lo indicamos en el registro A del RTC

al,0Bh
70h,al
al,71h
al,01000000b
71h,al

;Vamos a escribir en el registro B del RTC

mov
out
mov
segundo
out
mov
out
in
or
out
sti

;
;Activamos las interrupciones periodicas
;Habilitar las interrupciones

lea dx,instalar
int 27h
instalar endp
CODE ENDS
END START

260.
Algo muy importante es el programa que sirve para desinstalar y
restaurar todo lo que hizo el programa anterior. Si no lo hacemos seguir
mostrndose la sucesin de los caracteres ASCII mientras mantengamos
encendido el ordenador. Despus de ensamblar y ejecutar el programa con:
C:\>tasm /zi archivo
C:\>tlink /v archivo
C:\>archivo
Este programa no es .COM, por lo tanto usamos las banderas habituales.
Despus de ejecutarlo, si volvemos a escribir "MEM /C" veremos que nuestro
programa ha desaparecido, ya no se encuentra residente en memoria.
;----------------------------------------------------------------------------;Desactiva las interrupciones periodicas del RTC y elimina el
programa anterior
;de la memoria.
;----------------------------------------------------------------------------;----------------------------------------------------------------------------;Definicion del segmento de pila

;----------------------------------------------------------------------------PILA SEGMENT STACK "STACK"


DB 40h dup(0)
PILA ENDS
;----------------------------------------------------------------------------;Definicion del segmento extra
;----------------------------------------------------------------------------EXTRA SEGMENT
RESULT DW 0,0
EXTRA ENDS
;----------------------------------------------------------------------------;Definicion del segmento de codigo
;----------------------------------------------------------------------------CODE SEGMENT
ASSUME CS:CODE,SS:pila
START PROC FAR
call desinstalar
mov
int

ax,4C00h
21h

;
;Terminar el programa

START ENDP
;----------------------------------------------------------------------------; desinstalar
;
; in:
; out:
; machaca:
; make: Desinstala las interrupciones periodicas (PIE), desconecta
la
;
interrupcion del RTC al PIC esclavo, restaura los vectores
de
;
interrupcion y desinstala el programa residente
;
;----------------------------------------------------------------------------desinstalar PROC
push ax
push es
push ds
cli

;Inhabilitar las interrupciones

;Antes de proceder a desinstalarlo comprobamos si existe


cmp word ptr es:[70h*4],0
je FIN

mov al,0Bh
out 70h,al
and al,10111111b
out 71h,al
periodicas (PIE)
in
al,0A1h
OR
al,00000001B
out 0A1h,al
PIC esclavo

;Registro B del PIC


;
;
;Deshabilitamos las interrupciones
;Leer el PIC esclavo
;
;desconectamos la interrupcion del RTC al

xor
mov
mov
mov
xor
mov
mov

;Restaurar los vectores de interrupcion


ax,ax
es,ax
ax,es:[70h*4+2]
;Copia en DS el segmento de codigo del
ds,ax
;programa a desinstalar
ax,ax
es:[70h*4],ax
;Poner el offset a 0
es:[70h*4+2],ax
;Poner CS a 0

mov
mov
mov
int
mov
mov
mov
int

;Desinstalar el programa residente


ax,ds:[2Ch]
;
es,ax
;
ah,49h
;
21h
;Desinstalar el PSP
ax,ds
;
es,ax
;
ah,49h
;
21h
;Desinstalar CS
sti

FIN:
pop
pop

;Habilitar las interrupciones


pop

ds

es
ax
ret

desinstalar ENDP
CODE ENDS
END START

6 Estos ejercicios van a ser algo ms complejos y son del nivel que se va a exigir a
aquellos que estn cursando la asignatura de ETCII en la Universidad Autnoma de
Madrid.
1. Hallar cual es el valor de AX tras la segunda instruccin AAA:
2.
3. ; Ejercicio: examen ETCII - 7/11/01
4.

5. ;----------------------------------------------------------------------------6. ;Definicion del segmento de codigo


7. ;----------------------------------------------------------------------------8.
9. CODE SEGMENT
10.
assume CS:code
11.
12. start:
13.
14.
mov ax,16h
15.
mov bx,191h
16.
add ax,bx
17.
aaa
18.
add ax,7h
19.
aaa
20.
21.
mov ax,4c00h
22.
int 21h
23.
24. CODE ENDS
25.
END START

26. Hallar cual es el valor de AX tras la segunda instruccin AAA:


27.
28. ; Ejercicio: examen ETCII - Febrero 2000
29.
30. ;----------------------------------------------------------------------------31. ;Definicion del segmento de codigo
32. ;----------------------------------------------------------------------------33.
34. CODE SEGMENT
35.
assume CS:code
36.
37. start:
38.
39.
mov ax,123h
40.
mov bx,77h
41.
add ax,bx
42.
aaa
43.
add ax,5h
44.
aaa
45.
46.
mov ax,4c00h
47.
int 21h
48.
49. CODE ENDS
50.
END START

51. Hallar el valor de AX tras la instruccin "div bl":


52.
53. ;----------------------------------------------------------------------------54. ;Definicion del segmento de pila

55. ;----------------------------------------------------------------------------56. PILA SEGMENT STACK "STACK"


57.
db 40h DUP(0)
58. PILA ENDS
59.
60. ;----------------------------------------------------------------------------61. ;Definicion del segmento de codigo
62. ;----------------------------------------------------------------------------63. CODE SEGMENT
64.
assume cs:code,ss:pila
65.
66. START PROC
67.
;Inicializamos los registros de segmento
68.
mov ax,pila
69.
mov ss,ax
70.
71.
mov ax,905h
72.
mov bx,2h
73.
aad
74.
mov ah,10h
75.
div bl
76.
77.
mov ax,4C00h
;
78.
int 21h
;Terminar el programa
79.
80. START ENDP
81.
82. CODE ENDS
83.
END START

84. Hallar el valor de AX tras la instruccin "aam":


85.
86. ;----------------------------------------------------------------------------87. ;Definicion del segmento de codigo
88. ;----------------------------------------------------------------------------89. CODE SEGMENT
90.
assume CS:code
91.
92. START:
93.
94.
mov al,9
95.
mov cl,5
96.
mul cl
97.
aam
98.
99.
mov ax,4c00h
100.
int 21h
101.
102. CODE ENDS
103.
END START

104.
105.

Hallar el valor de AX tras la instruccin "daa":

106. ;----------------------------------------------------------------------------107. ;Definicion del segmento de pila


108. ;----------------------------------------------------------------------------109. PILA SEGMENT STACK "STACK"
110.
db 40h DUP(0)
111. PILA ENDS
112.
113. ;----------------------------------------------------------------------------114. ;Definicion del segmento de codigo
115. ;----------------------------------------------------------------------------116. CODE SEGMENT
117.
assume cs:code,ss:pila
118.
119. START PROC
120.
121.
mov ax,23h
122.
mov bx,77h
123.
add ax,bx
124.
xor ah,ah
125.
daa
126.
127.
mov ax,4C00h
;
128.
int 21h
;Terminar el programa
129.
130. START ENDP
131.
132. CODE ENDS
133.
END START

7 Las soluciones y archivos fuente de todos los ejercicios podis obtenerlos escribindome
un e-mail para pedrmelos.
1. Hallar el valor de AX tras la instruccin "mov ax,[bp+1]":
2.
3. ;----------------------------------------------------------------------------4. ;Definicion del segmento de pila
5. ;----------------------------------------------------------------------------6. PILA SEGMENT STACK "STACK"
7.
db 40h DUP(0)
8. PILA ENDS
9.
10. ;----------------------------------------------------------------------------11. ;Definicion del segmento de codigo
12. ;----------------------------------------------------------------------------13. CODE SEGMENT

14.
assume cs:code,ss:pila
15.
16. START PROC
17.
;Inicializamos los registros de segmento
18.
mov ax,pila
19.
mov ss,ax
20.
21.
mov cx,37FFh
22.
xor bx,bx
23.
push cx
24.
push bx
25.
mov bp,sp
26.
mov ax,[bp+1]
27.
28.
mov ax,4C00h
;
29.
int 21h
;Terminar el programa
30.
31. START ENDP
32.
33. CODE ENDS
34.
END START

35. Hallar el valor de AX tras la instruccin "mov ax,[bp+1]":


36.
37. ;----------------------------------------------------------------------------38. ;Definicion del segmento de pila
39. ;----------------------------------------------------------------------------40. PILA SEGMENT STACK "STACK"
41.
db 40h DUP(0)
42. PILA ENDS
43.
44. ;----------------------------------------------------------------------------45. ;Definicion del segmento de codigo
46. ;----------------------------------------------------------------------------47. CODE SEGMENT
48.
assume cs:code,ss:pila
49.
50. START PROC
51.
;Inicializamos los registros de segmento
52.
mov ax,pila
53.
mov ss,ax
54.
55.
mov ax,3759h
56.
xor bx,bx
57.
push ax
58.
push bx
59.
mov bp,sp
60.
mov ax,[bp+1]
61.
62.
mov ax,4C00h
;
63.
int 21h
;Terminar el programa
64.
65. START ENDP
66.

67. CODE ENDS


68.
END START

69. Hallar el valor de AX tras la instruccin "stosb":


70.
71. ;----------------------------------------------------------------------------72. ;Definicion del segmento de pila
73. ;----------------------------------------------------------------------------74. PILA SEGMENT STACK "STACK"
75.
db 40h DUP(0)
76. PILA ENDS
77.
78. ;----------------------------------------------------------------------------79. ;Definicion del segmento extra
80. ;----------------------------------------------------------------------------81. EXTRA SEGMENT
82.
RESULT DW 0,0
83. EXTRA ENDS
84.
85. ;----------------------------------------------------------------------------86. ;Definicion del segmento de codigo
87. ;----------------------------------------------------------------------------88. CODE SEGMENT
89.
assume CS:code,ES:extra,SS:pila
90.
91. ;----------------------------------------------------------------------------92. ;
Procedimiento inicial
93. ;----------------------------------------------------------------------------94. START PROC
95.
96.
mov si,40h
97.
cld
98.
mov byte ptr ds:[si],0Fh
99.
xor cx,cx
100.
mov al,0F0h
101.
rep scasb
102.
std
103.
mov di,si
104.
mov bx,ds
105.
mov es,bx
106.
stosb
107.
108.
mov ax,4C00h
;
109.
int 21h
;Terminar el programa
110.
111. START ENDP
112.
113. CODE ENDS
114.
END START

115.

Hallar el valor de AX tras la instruccin "rep lodsw":

116.
117. ;----------------------------------------------------------------------------118. ;Definicion del segmento de datos
119. ;----------------------------------------------------------------------------120. DATOS SEGMENT
121.
texto
db "Cadena_de_texto"
122. DATOS ENDS
123.
124. ;----------------------------------------------------------------------------125. ;Definicion del segmento de pila
126. ;----------------------------------------------------------------------------127. PILA SEGMENT STACK "STACK"
128.
db 40h DUP(0)
129. PILA ENDS
130.
131. ;----------------------------------------------------------------------------132. ;Definicion del segmento de codigo
133. ;----------------------------------------------------------------------------134. CODE SEGMENT
135.
assume cs:code,ds:datos,ss:pila
136.
137. START PROC
138.
;Inicializamos los registros de segmento
139.
mov ax,datos
140.
mov ds,ax
141.
mov ax,pila
142.
mov ss,ax
143.
144.
mov si,offset texto
145.
cld
146.
mov cx,5
147.
rep lodsw
148.
149.
mov ax,4C00h
;
150.
int 21h
;Terminar el programa
151.
152. START ENDP
153.
154. CODE ENDS
155.
END START

156.

Otro ejercicio como el anterior:

157.
158. ;----------------------------------------------------------------------------159. ;Definicion del segmento de datos
160. ;----------------------------------------------------------------------------161. DATOS SEGMENT
162.
texto
db "Esto_es_una_cadena_de_texto",0

163. DATOS ENDS


164.
165. ;----------------------------------------------------------------------------166. ;Definicion del segmento de pila
167. ;----------------------------------------------------------------------------168. PILA SEGMENT STACK "STACK"
169.
db 40h DUP(0)
170. PILA ENDS
171.
172. ;----------------------------------------------------------------------------173. ;Definicion del segmento de codigo
174. ;----------------------------------------------------------------------------175. CODE SEGMENT
176.
assume cs:code,ds:datos,ss:pila
177.
178. START PROC
179.
;Inicializamos los registros de segmento
180.
mov ax,datos
181.
mov ds,ax
182.
mov ax,pila
183.
mov ss,ax
184.
185.
mov si,offset texto
186.
add si,19h
187.
std
188.
mov cx,5
189.
rep lodsw
190.
191.
mov ax,4C00h
;
192.
int 21h
;Terminar el programa
193.
194. START ENDP
195.
196. CODE ENDS
197.
END START

198.
Y otro ms. Las instrucciones de cadena son bastante potentes y como
podreis ver es mejor saber manejarlas con soltura:
199.
200. ;----------------------------------------------------------------------------201. ;Definicion del segmento de datos
202. ;----------------------------------------------------------------------------203. DATOS SEGMENT
204.
texto
db "Cadena_de_texto"
205. DATOS ENDS
206.
207. ;----------------------------------------------------------------------------208. ;Definicion del segmento de pila
209. ;-----------------------------------------------------------------------------

210. PILA SEGMENT STACK "STACK"


211.
db 40h DUP(0)
212. PILA ENDS
213.
214. ;----------------------------------------------------------------------------215. ;Definicion del segmento de codigo
216. ;----------------------------------------------------------------------------217. CODE SEGMENT
218.
assume cs:code,ds:datos,ss:pila
219.
220. START PROC
221.
;Inicializamos los registros de segmento
222.
mov ax,datos
223.
mov ds,ax
224.
mov ax,pila
225.
mov ss,ax
226.
227.
mov si,offset texto
228.
add si,0Dh
229.
std
230.
mov cx,5
231.
rep lodsw
232.
233.
mov ax,4C00h
;
234.
int 21h
;Terminar el programa
235.
236. START ENDP
237.
238. CODE ENDS
239.
END START

240.

Hallar el valor de AX tras salir del bucle:

241.
242. ;----------------------------------------------------------------------------243. ;Definicion del segmento de pila
244. ;----------------------------------------------------------------------------245. PILA SEGMENT STACK "STACK"
246.
db 40h DUP(0)
247. PILA ENDS
248.
249. ;----------------------------------------------------------------------------250. ;Definicion del segmento de codigo
251. ;----------------------------------------------------------------------------252. CODE SEGMENT
253.
assume cs:code,ss:pila
254.
255. START PROC
256.
;Inicializamos los registros de segmento
257.
mov ax,pila
258.
mov ss,ax
259.
260.
mov bx,10h

261.
xor ax,ax
262.
mov cx,0FFFFh
263. L1:
264.
add ax,bx
265.
loop L1
266.
267.
mov ax,4C00h
268.
int 21h
269.
270. START ENDP
271.
272. CODE ENDS
273.
END START

;
;Terminar el programa

8
1. El siguiente programa le pide al usuario la confirmacin de si desea continuar
y dependiendo de la respuesta se har una cosa u otra:
2.
3. ;----------------------------------------------------------------------------4. ;Programa que le pregunta al usuario si desea continuar o no hasta
que se pulse
5. ;la tecla 'N' o 'n'
6. ;----------------------------------------------------------------------------7.
8. cr equ 13
;retorno de carro
9. lf equ 10
;alimentacion de linea
10.
11. ;----------------------------------------------------------------------------12. ;Definicion del segmento de datos
13. ;----------------------------------------------------------------------------14. DATOS SEGMENT
15.
DeseaContinuar db cr,lf,'Desea continuar? S/N: '
16.
db'$'
17.
continuando db '
Continuando...',cr,lf
18.
db'$'
19.
LetraErronea db '
La tecla pulsada es incorrecta.',cr,lf
20.
db'$'
21. DATOS ENDS
22.
23. ;----------------------------------------------------------------------------24. ;Definicion del segmento de pila
25. ;----------------------------------------------------------------------------26. PILA SEGMENT STACK "STACK"
27.
db 40h dup(?)
28. PILA ENDS
29.

30. ;----------------------------------------------------------------------------31. ;Definicion del segmento de codigo


32. ;----------------------------------------------------------------------------33. CODE SEGMENT
34.
assume CS:code, DS:datos, SS:pila
35.
36. START:
37.
mov ax,datos
38.
mov ds,ax
39.
jmp continuar
;Saltamos a la etiqueta
CONTINUAR
40.
41. INICIO:
42.
lea dx,continuando
;
43.
mov ah,9
;
44.
int 21h
;Mensaje de que seguimos en el
programa
45.
jmp continuar
;Salto para preguntar si se
desea continuar
46.
47. ERROR:
48.
lea dx,LetraErronea
;
49.
mov ah,9
;Mensaje de que la letra
introducida
50.
int 21h
;no es correcta
51.
52. CONTINUAR:
53.
lea dx,DeseaContinuar ;
54.
mov ah,9
;
55.
int 21h
;Mostrar pregunta para ver si
desea continuar
56.
57.
mov ah,1
;Esperar a que se pulse una tecla
58.
int 21h
;y mostrarla por pantalla
59.
60.
cmp al, 'S'
;
61.
je
inicio
;
62.
cmp al, 's'
;
63.
je
inicio
;Desea continuar
64.
65.
cmp al, 'N'
;
66.
je
salir
;
67.
cmp al, 'n'
;
68.
je
salir
;No desea continuar, terminamos
69.
70.
jmp error
;La tecla pulsada no es 'S', 's',
'N' ni 'n'
71.
;Se va a mostrar un mensaje de
error. Saltamos
72.
;a la etiqueta ERROR
73.
74. salir:
75.
mov ax, 4C00h
76.
int 21h
77.

78. CODE ENDS


79.
END START

80. Este programa cambia el color de fondo de una posicin determinada de


pantalla. Si se ejecuta varias veces seguidas veremos como cambia de blanco a
negro y viceversa:
81.
82. PANTALLA equ 0B800h
83.
84. ;----------------------------------------------------------------------------85. ;Definicion del segmento de pila
86. ;----------------------------------------------------------------------------87. PILA SEGMENT STACK "STACK"
88.
db
40h dup(0)
89. PILA ENDS
90.
91. ;----------------------------------------------------------------------------92. ;Definicion del segmento de codigo
93. ;----------------------------------------------------------------------------94. CODE SEGMENT
95.
assume CS:code, SS:pila
96.
97. START:
98.
mov ax,PANTALLA
99.
mov ds,ax
100.
mov bx,(80*24+5)*2+1
;Ultima linea, caracter 5
101.
;Utilizamos el '+1' para acceder
102.
;directamente al fondo
103.
104.
cmp byte ptr [bx],07h
;Vemos si el fondo es negro
105.
jz
CambiaFondo
106.
107.
mov byte ptr [bx],07h
;Si no es negro lo ponemos
108.
jmp fin
109.
110. CambiaFondo:
111.
mov byte ptr [bx],70h
;Ponemos el fondo blanco
112.
113. fin:
114.
mov ax,4C00h
115.
int 21h
116.
117. CODE ENDS
118.
END START

119.
Otro programa .COM (no os olvideis de compilar con las banderas
antes mencionadas). En este caso se trata de mostrar las letras V y S con un
intervalo de medio segundo, siendo una letra roja y la otra azul:
120.
121.
122.
123.
124.
125.

PANTALLA
ROJO
LETRA_ROJA
LETRA_AZUL
AZUL

equ
equ
equ
equ
equ

0b800h
4
'V'
'S'
1

126.
127. ;----------------------------------------------------------------------------128. ;Definicion del segmento de codigo
129. ;----------------------------------------------------------------------------130. CODE SEGMENT
131.
assume CS:code
132.
org 100h
;Dejar las 100h primeras posiciones para
el PSP
133.
134. START:
135.
jmp instalar
;Bifurcar a la rutina de instalacion
136.
137.
138. ;----------------------------------------------------------------------------139. ; letras
140. ;
141. ; in:
142. ; out:
143. ; machaca:
144. ; make: Hace que se intercambien las letras V y S cada medio
segundo en
145. ;
colores diferentes.
146. ;
147. ;----------------------------------------------------------------------------148. letras proc far
149.
150.
push ax
;
151.
push es
;
152.
push di
;Guardamos los registros en la pila
153.
154.
cli
;Inhabilitar las interrupciones
155.
156.
mov al,0Ch
;
157.
out 70h,al
;
158.
in
al,71h
;Leer el RTC
159.
160.
mov ax,pantalla
161.
mov es,ax
162.
mov di,79*2
;Esquina superior derecha
163.
mov ax,es:[di]
;Guardamos en AX lo que hay en la esquina
164.
165.
cmp ah,AZUL
;Si era azul ahora debemos mostrar
166.
je
muestra_v_rojo ;la 'V' de color rojo
167.
168.
mov ah,AZUL
169.
mov al,LETRA_AZUL
170.
mov es:[di],ax
;Guardar en ES:[DI] que hemos puesto la
letra
171.
;de color azul
172.
jmp fin
;Terminar el procedimiento
173.
174. muestra_v_rojo:
175.
mov ah,ROJO

176.
mov al,LETRA_ROJA
177.
mov es:[di],ax
;Guardar en ES:[DI] que hemos puesto la
letra
178.
;de color rojo
179.
180. fin:
181.
mov al,20h
;
182.
out 20h,al
;
183.
out 0A0h,al
;EOI al maestro y al esclavo
184.
185.
sti
;Habilitar las interrupciones
186.
187.
pop di
;
188.
pop es
;
189.
pop ax
;Recuperar los registros
190.
191.
iret
192. letras endp
193.
194.
195. ;----------------------------------------------------------------------------196. ; instalar
197. ;
198. ; in:
199. ; out:
200. ; machaca: ax, dx, es
201. ; make: Instala el programa dejandolo residente
202. ;
203. ;----------------------------------------------------------------------------204. instalar proc
205.
206.
cli
;Inhabilitar las interrupciones
207.
208.
xor ax,ax
;
209.
mov es,ax
;Poner a 0 ES
210.
mov es:[70h*4],offset letras
;Guardar el offset
211.
mov es:[70h*4+2],cs
;y el segmento de la rutina
212.
213.
in
al,0A1h
;Leer el PIC esclavo
214.
and al,11111110b
;
215.
out 0A1h,al
;Activamos IR0
216.
217.
in
al,21h
;Leer el PIC maestro
218.
and al,11111011b
;
219.
out 21h,al
;Activado
220.
221.
mov al,0Ah
;Vamos a escribir en el registro A del
RTC
222.
out 70h,al
;
223.
mov al,2Fh
;Los simbolos se intercambian cada medio
segundo
224.
out 71h,al
;Lo indicamos en el registro A del RTC
225.
226.
mov al,0Bh
;Vamos a escribir en el registro B del
RTC

227.
out 70h,al
228.
in
al,71h
229.
or
al,01000000b
230.
out 71h,al
231.
232.
sti
233.
234.
lea dx,instalar
235.
int 27h
236.
237. instalar endp
238.
239. CODE ENDS
240.
END START

;
;
;
;Activamos las interrupciones periodicas
;Habilitar las interrupciones
;
;Dejar residente

241.
El siguiente ejercicio de examen nos pide conocer la instruccin scasb.
Hallar cul es el valor de AX tras la instruccin NOP:
242.
243. ;----------------------------------------------------------------------------244. ;Definicion del segmento de datos
245. ;----------------------------------------------------------------------------246. DATOS SEGMENT
247.
Cadena1
db 50 dup(0)
248.
Cadena2
db 50 dup(?)
249. DATOS ENDS
250.
251. ;----------------------------------------------------------------------------252. ;Definicion del segmento de pila
253. ;----------------------------------------------------------------------------254. PILA SEGMENT STACK "STACK"
255.
db 40h DUP(0)
256. PILA ENDS
257.
258. ;----------------------------------------------------------------------------259. ;Definicion del segmento de codigo
260. ;----------------------------------------------------------------------------261. CODE SEGMENT
262.
assume cs:code,ds:datos,ss:pila
263.
264. START PROC
265.
;Inicializamos los registros de segmento
266.
mov ax,datos
267.
mov ds,ax
268.
mov ax,pila
269.
mov ss,ax
270.
271.
xor ax,ax
272.
mov cx,10h
273.
lea si,Cadena1
274.
lea di,Cadena2
275. otro:

276.
push ds
277.
inc ax
278.
pop es
279.
scasb
280.
loop otro
281.
nop
282.
283.
mov ax,4C00h
284.
int 21h
285.
286. START ENDP
287.
288. CODE ENDS
289.
END START

;AX=10h, SI=0, DI=42h


;
;Terminar el programa

290.
Otro ejercicio como el anterior, pero usando la instruccin repne.
Recordar que la instruccin LOOP primero decrementa y despues compara
CX con 0, as que cuidado con este ejercicio:
291.
292. ;----------------------------------------------------------------------------293. ;Definicion del segmento de datos
294. ;----------------------------------------------------------------------------295. DATOS SEGMENT
296.
Cadena1
db 50 dup(0)
297.
Cadena2
db 50 dup(?)
298. DATOS ENDS
299.
300. ;----------------------------------------------------------------------------301. ;Definicion del segmento de pila
302. ;----------------------------------------------------------------------------303. PILA SEGMENT STACK "STACK"
304.
db 40h DUP(0)
305. PILA ENDS
306.
307. ;----------------------------------------------------------------------------308. ;Definicion del segmento de codigo
309. ;----------------------------------------------------------------------------310. CODE SEGMENT
311.
assume cs:code,ds:datos,ss:pila
312.
313. START PROC
314.
;Inicializamos los registros de segmento
315.
mov ax,datos
316.
mov ds,ax
317.
mov ax,pila
318.
mov ss,ax
319.
320.
xor ax,ax
321.
mov cx,10h
322.
lea si,Cadena1
323.
lea di,Cadena2

324. otro:
325.
push ds
326.
inc ax
327.
pop es
328.
repne scasb
329.
loop otro
330.
nop
331.
332.
mov ax,4C00h
333.
int 21h
334.
335. START ENDP
336.
337. CODE ENDS
338.
END START

;
;Terminar el programa

339.
Hallar cual es el contenido de las posiciones de memoria: 1000, 1001,
1002 y 1003 tras la ejecucion del bucle:
340.
341. ;----------------------------------------------------------------------------342. ; Ejercicio 1: examen ETCII - 12/02/96
343. ;----------------------------------------------------------------------------344.
345. ;----------------------------------------------------------------------------346. ;Definicion del segmento de codigo
347. ;----------------------------------------------------------------------------348. CODE SEGMENT
349.
assume CS:code
350.
351. START:
352.
353.
;Inicializar
354.
mov byte ptr ds:[1000h],0
355.
mov byte ptr ds:[1001h],0
356.
mov byte ptr ds:[1002h],0
357.
mov byte ptr ds:[1003h],0
358.
359.
mov si,1000h
360.
mov cx,4
361. l1:
362.
add [si],si
363.
inc si
364.
loop l1
365.
366.
mov ax,4C00h
367.
int 21h
368.
369. CODE ENDS
370.
END START

371.

Hallar el contenido de SI tras la ejecucin de los bucles:

372.
373. ;-----------------------------------------------------------------------------

374. ; Ejercicio: examen ETCII - 12/02/96


375. ;----------------------------------------------------------------------------376.
377. ;----------------------------------------------------------------------------378. ;Definicion del segmento de codigo
379. ;----------------------------------------------------------------------------380. CODE SEGMENT
381.
assume CS:code
382.
383. START:
384.
385.
mov si,0
386.
mov cx,4
387. L2: push cx
388.
mov cx,100h
389. L1: dec cx
390.
inc si
391.
loop l1
392.
pop cx
393.
loop l2
394.
395.
mov ax,4C00h
396.
int 21h
397.
398. CODE ENDS
399.
END START

9
1. Otro problema de examen. Hallar el valor de AX tras la instruccin mov
ax,word ptr ds:[3]
2.
3. ;----------------------------------------------------------------------------4. ;Definicion del segmento de datos
5. ;----------------------------------------------------------------------------6. DATOS SEGMENT
7.
dw
3Ah,7Bh,9Ch
8.
db
34h,76h,65h
9.
org 1
10.
db
67h,31h,56h,"SE ACABO"
11. DATOS ENDS
12.
13. ;----------------------------------------------------------------------------14. ;Definicion del segmento de pila
15. ;----------------------------------------------------------------------------16. PILA SEGMENT STACK "STACK"
17.
db 40h DUP(0)

18. PILA ENDS


19.
20. ;----------------------------------------------------------------------------21. ;Definicion del segmento de codigo
22. ;----------------------------------------------------------------------------23. CODE SEGMENT
24.
assume cs:code,ds:datos,ss:pila
25.
26. START PROC
27.
;Inicializamos los registros de segmento
28.
mov ax,datos
29.
mov ds,ax
30.
mov ax,pila
31.
mov ss,ax
32.
33.
mov ax,word ptr ds:[3]
34.
35.
mov ax,4C00h
;
36.
int 21h
;Terminar el programa
37.
38. START ENDP
39.
40. CODE ENDS
41.
END START

42. Muy similar al anterior:


43.
44. ;----------------------------------------------------------------------------45. ;Definicion del segmento de datos
46. ;----------------------------------------------------------------------------47. DATOS SEGMENT
48.
dw
3Ah,7Bh,9Ch
49.
db
34h,76h,65h
50.
org 2
51.
db
67h,31h,56h,"SE ACABO"
52. DATOS ENDS
53.
54. ;----------------------------------------------------------------------------55. ;Definicion del segmento de pila
56. ;----------------------------------------------------------------------------57. PILA SEGMENT STACK "STACK"
58.
db 40h DUP(0)
59. PILA ENDS
60.
61. ;----------------------------------------------------------------------------62. ;Definicion del segmento de codigo
63. ;----------------------------------------------------------------------------64. CODE SEGMENT
65.
assume cs:code,ds:datos,ss:pila
66.

67. START PROC


68.
;Inicializamos los registros de segmento
69.
mov ax,datos
70.
mov ds,ax
71.
mov ax,pila
72.
mov ss,ax
73.
74.
mov ax,word ptr ds:[3]
75.
76.
mov ax,4C00h
;
77.
int 21h
;Terminar el programa
78.
79. START ENDP
80.
81. CODE ENDS
82.
END START

83. Cul es el valor de AX tras la instruccin NOP?:


84.
85. ; Ejercicio: examen ETCII - febrero 2002
86.
87. ;----------------------------------------------------------------------------88. ;Definicion del segmento de pila
89. ;----------------------------------------------------------------------------90. PILA SEGMENT STACK "STACK"
91.
db 40h DUP(0)
92. PILA ENDS
93.
94. ;----------------------------------------------------------------------------95. ;Definicion del segmento extra
96. ;----------------------------------------------------------------------------97. EXTRA SEGMENT
98.
RESULT DW 0,0
99. EXTRA ENDS
100.
101. ;----------------------------------------------------------------------------102. ;Definicion del segmento de codigo
103. ;----------------------------------------------------------------------------104. CODE SEGMENT
105.
assume CS:code,ES:extra,SS:pila
106.
107. ;----------------------------------------------------------------------------108. ;
Procedimiento inicial
109. ;----------------------------------------------------------------------------110. START PROC
111.
112.
mov ax,1Fh
113.
push ax
114.
inc sp
115.
push ax

116.
dec sp
117.
pop ax
118.
pop ax
119.
nop
120.
121.
mov ax,4C00h
122.
int 21h
123.
124. START ENDP
125.
126. CODE ENDS
127.
END START

;
;Terminar el programa

128.
Muy importantes tambin son los ejercicios de pila. Hallar el valor de
AX tras la instruccin NOP:
129.
130. ;----------------------------------------------------------------------------131. ;Definicion del segmento de pila
132. ;----------------------------------------------------------------------------133. PILA SEGMENT STACK "STACK"
134.
db 40h DUP(0)
135. PILA ENDS
136.
137. ;----------------------------------------------------------------------------138. ;Definicion del segmento de codigo
139. ;----------------------------------------------------------------------------140. CODE SEGMENT
141.
assume cs:code,ss:pila
142.
143. START PROC
144.
;Inicializamos los registros de segmento
145.
mov ax,pila
146.
mov ss,ax
147.
148.
mov al,5
149.
mov bx,0FA45h
150.
push bx
151.
push ax
152.
mov bp,sp
153.
mov al,[bp+3]
154.
nop
155.
156.
mov ax,4C00h
;
157.
int 21h
;Terminar el programa
158.
159. START ENDP
160.
161. CODE ENDS
162.
END START

163.
Estos ejercicios de pilas suelen tener truco la mayora de las veces ;)
Hallar el valor de AX tras el ltimo POP:
164.

165. ;----------------------------------------------------------------------------166. ;Definicion del segmento de pila


167. ;----------------------------------------------------------------------------168. PILA SEGMENT STACK "STACK"
169.
db 40h DUP(0)
170. PILA ENDS
171.
172. ;----------------------------------------------------------------------------173. ;Definicion del segmento de codigo
174. ;----------------------------------------------------------------------------175. CODE SEGMENT
176.
assume cs:code,ss:pila
177.
178. START PROC
179.
;Inicializamos los registros de segmento
180.
mov ax,pila
181.
mov ss,ax
182.
183.
push 0F34h
184.
push 63h
185.
pop ax
186.
inc sp
187.
pop ax
188.
189.
mov ax,4C00h
;
190.
int 21h
;Terminar el programa
191.
192. START ENDP
193.
194. CODE ENDS
195.
END START

10
1. Hallar el valor de AX tras la instruccin div bl:
2.
3. ;----------------------------------------------------------------------------4. ;Definicion del segmento de codigo
5. ;----------------------------------------------------------------------------6. CODE SEGMENT
7.
assume cs:code
8.
9. START PROC
10.
11.
mov ah,1
12.
mov al,0D7h
13.
xor bx,bx
14.
stc

15.
rcr bx,1
16.
rcr bx,1
17.
div bl
18.
19.
mov ax,4C00h
20.
int 21h
21.
22. START ENDP
23.
24. CODE ENDS
25.
END START

;
;Terminar el programa

26. De nuevo un ejercicio sencillito para dejar a un lado los exmenes (por el
momento) y relajarnos un poco y ver otra forma de inicializar variables. Este
programa muestra dos lneas, una llena de '5' y otra de '@':
27.
28. ;----------------------------------------------------------------------------29. ;Definicion del segmento de datos
30. ;----------------------------------------------------------------------------31. DATOS SEGMENT
32.
Cadena1
db 80 dup("5"),"$"
33.
Cadena2
db 80 dup("@"),"$"
34. DATOS ENDS
35.
36. ;----------------------------------------------------------------------------37. ;Definicion del segmento de pila
38. ;----------------------------------------------------------------------------39. PILA SEGMENT STACK "STACK"
40.
db 40h DUP(0)
41. PILA ENDS
42.
43. ;----------------------------------------------------------------------------44. ;Definicion del segmento de codigo
45. ;----------------------------------------------------------------------------46. CODE SEGMENT
47.
assume cs:code,ds:datos,ss:pila
48.
49. START PROC
50.
;Inicializamos los registros de segmento
51.
mov ax,datos
52.
mov ds,ax
53.
mov ax,pila
54.
mov ss,ax
55.
56.
mov dx,offset Cadena1
57.
mov ah,9
58.
int 21h
59.
60.
mov dx,offset Cadena2
61.
mov ah,9
62.
int 21h

63.
64.
mov ax,4C00h
65.
int 21h
66.
67. START ENDP
68.
69. CODE ENDS
70.
END START

;
;Terminar el programa

71. Volvemos con ms instrucciones de cadena y otro ejercicio de examen. Hallar


el valor de CX tras la instruccin repnz scasb:
72.
73. ;----------------------------------------------------------------------------74. ;Definicion del segmento de datos
75. ;----------------------------------------------------------------------------76. DATOS SEGMENT
77.
texto
db "Esto es un texto",0,"Y este otro",0
78. DATOS ENDS
79.
80. ;----------------------------------------------------------------------------81. ;Definicion del segmento de pila
82. ;----------------------------------------------------------------------------83. PILA SEGMENT STACK "STACK"
84.
db 40h DUP(0)
85. PILA ENDS
86.
87. ;----------------------------------------------------------------------------88. ;Definicion del segmento de codigo
89. ;----------------------------------------------------------------------------90. CODE SEGMENT
91.
assume cs:code,ds:datos,ss:pila
92.
93. START PROC
94.
;Inicializamos los registros de segmento
95.
mov ax,datos
96.
mov ds,ax
97.
mov ax,pila
98.
mov ss,ax
99.
100.
push ds
101.
pop es
102.
cld
103.
mov ax,4C00h
104.
lea di,texto
105.
mov cx,14h
106.
repnz scasb
107.
108.
mov ax,4C00h
;
109.
int 21h
;Terminar el programa
110.
111. START ENDP

112.
113. CODE ENDS
114.
END START

115.
Que es lo que encuentra el programa? "to" de la palabra "Esto" "ot"
de la palabra "otra"
116.
117. ;----------------------------------------------------------------------------;Definicion del segmento de datos
;----------------------------------------------------------------------------DATOS SEGMENT
cadena
db
"Esto es otra cadena"
DATOS ENDS
;----------------------------------------------------------------------------;Definicion del segmento de pila
;----------------------------------------------------------------------------PILA SEGMENT STACK "STACK"
db 40h DUP(0)
PILA ENDS
;----------------------------------------------------------------------------;Definicion del segmento de codigo
;----------------------------------------------------------------------------CODE SEGMENT
assume cs:code,ds:datos,ss:pila
START PROC
;Inicializamos los registros de segmento
mov ax,datos
mov ds,ax
cld
mov ax,datos
mov es,ax
mov cx,100h
mov ax,"ot"
lea di,cadena
repnz scasw
mov
int

ax,4C00h
21h

;
;Terminar el programa

START ENDP
CODE ENDS
END START

Hallar el valor de AX tras la instruccin mov al,byte ptr tabla[si]:

;----------------------------------------------------------------------------;Definicion del segmento de datos


;----------------------------------------------------------------------------DATOS SEGMENT
db
10,'A',32,45h,10001101b,16
tabla dw 15,'Dk','27',4F5h
DATOS ENDS
;----------------------------------------------------------------------------;Definicion del segmento de pila
;----------------------------------------------------------------------------PILA SEGMENT STACK "STACK"
db 40h DUP(0)
PILA ENDS
;----------------------------------------------------------------------------;Definicion del segmento de codigo
;----------------------------------------------------------------------------CODE SEGMENT
assume cs:code,ds:datos,ss:pila
START PROC
;Inicializamos los registros de segmento
mov ax,datos
mov ds,ax
mov ax,pila
mov ss,ax
xor
mov
sub
mov

si,si
ax,[si]
ax,[si]
al,byte ptr tabla[si]

mov
int

ax,4C00h
21h

;
;Terminar el programa

START ENDP
CODE ENDS
END START

Instruccin JMP
Propsito: Salto incondicional

Sintaxis:
JMP destino
Esta instruccin se utiliza para desviar el flujo de un programa sin tomar en
cuenta las condiciones actuales de las banderas ni de los datos.
Instruccin JA (JNBE)
Propsito: Brinco condicional
Sintaxis:
JA Etiqueta
Despus de una comparacin este comando salta si est arriba o salta si no est
abajo o si no es igual.
Esto significa que el salto se realiza solo si la bandera CF esta desactivada o si la
bandera ZF esta desactivada (que alguna de las dos sea igual a cero).
Instruccin JAE (JNB)
Propsito: salto condicional
Sintaxis:
JAE etiqueta
Salta si est arriba o si es igual o salta si no est abajo.
El salto se efectua si CF esta desactivada.
Instruccin JB (JNAE)
Propsito: salto condicional
Sintaxis:
JB etiqueta
Salta si est abajo o salta si no est arriba o si no es igual.

Se efecta el salto si CF esta activada.


Instruccin JBE (JNA)
Propsito: salto condicional
Sintaxis:
JBE etiqueta
Salta si est abajo o si es igual o salta si no est arriba.
El salto se efecta si CF est activado o si ZF est activado (que cualquiera sea
igual a 1).
Instruccin JE (JZ)
Propsito: salto condicional
Sintaxis:
JE etiqueta
Salta si es igual o salta si es cero.
El salto se realiza si ZF est activada.
Instruccin JNE (JNZ)
Propsito: salto condicional
Sintaxis:
JNE etiqueta
Salta si no es igual o salta si no es cero.
El salto se efectua si ZF est desactivada.
Instruccin JG (JNLE)
Propsito: salto condicional, se toma en cuenta el signo.

Sintaxis:
JG etiqueta
Salta si es ms grande o salta si no es menor o igual.
El salto ocurre si ZF = 0 u OF = SF.
Instruccin JGE (JNL)
Propsito: salto condicional, se toma en cuenta el signo.
Sintaxis:
JGE etiqueta
Salta si es ms grande o igual o salta si no es menor que.
El salto se realiza si SF = OF
Instruccin JL (JNGE)
Propsito: salto condicional, se toma en cuenta el signo.
Sintaxis:
JL etiqueta
Salta si es menor que o salta si no es mayor o igual.
El salto se efecta si SF es diferente a OF.
Instruccin JLE (JNG)
Propsito: salto condicional, se toma en cuenta el signo.
Sintaxis:
JLE etiqueta
Salta si es menor o igual o salta si no es ms grande.
El salto se realiza si ZF = 1 o si SF es diferente a OF

Instruccin JC
Propsito: salto condicional, se toman en cuenta las banderas.
Sintaxis:
JC etiqueta
Salta si hay acarreo.
El salto se realiza si CF = 1
Instruccin JNC
Propsito: salto condicional, se toma en cuenta el estado de las banderas.
Sintaxis:
JNC etiqueta
Salta si no hay acarreo.
El salto se efecta si CF = 0.
Instruccin JNO
Propsito: salto condicional, se toma en cuenta el estado de las banderas.
Sintaxis:
JNO etiqueta
Salta si no hay desbordamiento.
El salto se efectua si OF = 0.
Instruccin JNP (JPO)
Propsito: salto condicional, toma en cuenta el estado de las banderas.
Sintaxis:
JNP etiqueta

Salta si no hay paridad o salta si la paridad es non.


El salto ocurre si PF = 0.
Instruccin JNS
Propsito: salto condicional, toma en cuenta el estado de las banderas.
Sintaxis:
JNP etiqueta
Salta si el signo esta desactivado.
El salto se efecta si SF = 0.
Instruccin JO
Propsito: salto condicional, toma en cuenta el estado de las banderas.
Sintaxis:
JO etiqueta
Salta si hay desbordamiento (overflow).
El salto se realiza si OF = 1.
Instruccin JP (JPE)
Propsito: salto condicional, toma en cuenta el estado de las banderas.
Sintaxis:
JP etiqueta
Salta si hay paridad o salta si la paridad es par.
El salto se efecta si PF = 1.
Instruccin JS
Propsito: salto condicional, toma en cuenta el estado de las banderas.

Sintaxis:
JS etiqueta
Salta si el signo est prendido.
El salto se efecta si SF = 1.
Instruccin LOOP
Propsito: Generar un ciclo en el programa.
Sintaxis:
LOOP etiqueta
La instruccin loop decrementa CX en 1, y transfiere el flujo del programa a la
etiqueta dada como operando si CX es diferente a 1.
Instruccin LOOPE
Propsito: Generar un ciclo en el programa considerando el estado de ZF
Sintaxis:
LOOPE etiqueta
Esta instruccin decrementa CX en 1. Si CX es diferente a cero y ZF es igual a 1,
entonces el flujo del programa se transfiere a la etiqueta indicada como operando.
Instruccin LOOPNE
Propsito: Generar un ciclo en el programa, considerando el estado de ZF
Sintaxis:
LOOPNE etiqueta
Esta instruccin decrementa en uno a CX y transfiere el flujo del programa solo
si ZF es diferente a 0.
Instruccin DEC

Propsito: Decrementar el operando


Sintaxis:
DEC destino
Esta operacin resta 1 al operando destino y almacena el nuevo valor en el
mismo oeprando.
Instruccin INC
Propsito: Incrementar el operando.
Sintaxis:
INC destino
La instruccin suma 1 al operando destino y guarda el resultado en el mismo
operando destino.
Instruccin CMP
Propsito: Comparar los operandos.
Sintaxis:
CMP destino, fuente
Esta instruccin resta el operando fuente al operando destino pero sin que ste
almacene el resultado de la operacin, solo se afecta el estado de las banderas.
Instruccin CMPS (CMPSB) (CMPSW)
Propsito: Comparar cadenas de un byte o palabra.
Sintaxis:
CMP destino, fuente
Con esta instruccin la cadena de caracteres fuente se resta de la cadena destino.
Se utilizan DI como indice para el segmento extra de la cadena fuente y SI como
indice de la cadena destino.

Solo se afecta el contenido de las banderas y tanto DI como SI se incrementan.


Instruccin CLC
Propsito: Limpiar bandera de acarreo.
Sintaxis:
CLC
Esta instruccin apaga el bit correspondiente a la bandera de acarreo, o sea, lo
pone en cero.
Instruccin CLD
Propsito: Limpiar bandera de direccin
Sintaxis:
CLD
La instruccin CLD pone en cero el bit correspondiente a la bandera de
direccin.
Instruccin CLI
Propsito: Limpiar bandera de interrupcin
Sintaxis:
CLI
CLI pone en cero la bandera de interrupciones, desabilitando as aquellas
interrupciones enmascarables.
Una interrupcin enmascarable es aquella cuyas funciones son desactivadas
cuando IF = 0.
Instruccin CMC
Propsito: Complementar la bandera de acarreo.
Sintaxis:

CMC
Esta instruccin complementa el estado de la bandera CF, si CF = 0 la
instruccin la iguala a 1, y si es 1 la instruccin la iguala a 0.
Podemos decir que unicamente "invierte" el valor de la bandera.
Instruccin STC
Propsito: Activar la bandera de acarreo.
Sintaxis:
STC
Esta instruccin pone la bandera CF en 1.
Instruccin STD
Propsito: Activar la bandera de direccin.
Sintaxis:
STD
La instruccin STD pone la bandera DF en 1.
Instruccin STI
Propsito: Acticar la bandera de interrupcin.
Sintaxis:
STI
La instruccin activa la bandera IF, esto habilita las interrupciones externas
enmascarables (las que funcionan unicamente cuando IF = 1 ).

Ejercicio 1: Escribir un cdigo que verifique si dos cadenas son iguales


org 100h
comienzo:
mov si, x
mov al, msg2[si]
cmp msg[si], al ;comparar letra por letra las cadenas, si uno no coincide
manda directamente a fin y termina el programa
jne fin:
cmp msg[si], "$" ;si es el final y el programa llega aca, quiere decir
que son iguales
jz final:
inc x
loop comienzo
final:
mov dx, offset msg3
mov ah, 9
int 21h
fin:
ret
msg db "hello world $"
msg2 db "hello world $"
msg3 db "Son iguales $"
x dw 0

Ejercicio 2: Escribir un cdigo que verifique si una cadena es subcadena de otra.


Por ejemplo: la Mu es subcadena de Hola Mundo.
La cadena: 233 es subcadena de la cadena 2122432234
org 100h
mov si, 0 ;ponemos si en 0
comienzo:
mov al, msg2[0] ;copiar la primera letra de la palabra a al
cmp msg[si],"$" ;si es el fin de la cadena mandar a final
jz final
cmp msg[si], al ;comparar si encuentra la primera letra de la cadena
jne seguir
mov di, 1 ;poner en 1 di
comprobar:
mov al, msg2[di]
mov bx, di
cmp msg[si+bx], al ;posicion de la letra coincidente + di, comparar con
la cadena
jne seguir ;si no coincide mandar a seguir
inc di ;incrementar di para seguir recorriendo cadena
cmp msg2[di],"$" ;si es el fin de la cadena y el programa llego aca
quiere decir que la cadena es parte de la palabra
jz resultado
loop comprobar ;bucle para recorrer cadena

seguir:
inc si ;para seguir recorriendo la palabra
loop comienzo ;bucle principal para recorrer palabra
resultado:
mov dx, offset msg3 ;copiar msg3 a dx
mov ah, 9 ;preparar ah con 9 para la interrupcion 21h
int 21h ;mostrar contenido en dx
final:
ret
msg db "Hola Mundo$"
msg2 db "ola$"
msg3 db "Si es subcadena$"

Ejercicio 3: Escribir un cdigo que verifique que todas los caracteres de una cadena se
encuentran en otra.
Por ejemplo: todas las letras de la cadena casa se encuentran en escaso. Pero no todas
las letras de cerro se en cuentran en recanate
org 100h
mov si, 0 ;ponemos si en 0
comienzo:
cmp msg[si],"$" ;si es el fin de la cadena mandar a final
jz resultado
mov di, 0 ;poner en 0 di
comprobar:
mov al, msg2[di] ;copiar msg2 con su posicion a al
cmp msg[si], al ;comparar msg con su posicion con al
jz seguir ;si se encuentra entonces continua
inc di ;incrementar di para seguir recorriendo cadena
cmp msg2[di], "$" ;si es que llega al final y no encontro coincidencia,
entonces ya termina el programa
jz final
loop comprobar ;bucle para recorrer
seguir:
inc si ;para seguir recorriendo la palabra
loop comienzo ;bucle principal para recorrer palabra
resultado:
mov dx, offset msg3 ;copiar msg3 a dx
mov ah, 9 ;preparar ah con 9 para la interrupcion 21h
int 21h ;mostrar contenido en dx
final:
ret
msg db "cerro$"
msg2 db "recanate$"
msg3 db "Si se encuentran todos los caracteres$"

Ejercicio 4: Escribir una programa que reciba una cadena ingresada por teclado, terminada
en ENTER. Luego que elimine todos los caracteres que no son dgitos, sin utilizar una
variable auxiliar.
ORG 100H
mov si, 0
lectura:
mov ah,1
int 21h
cmp al,13
jz resultado:
cmp al, 57 ;si tecla es mayor a 57 entonces ir a fin3 (tecla > 57)
ja fin3
cmp al,47 ;si tecla no es mayor a 47 ir a fin3 (tecla <= 47)
jng fin3
mov bx[si], al ;si es un digito entonces guardo en bx
inc si ;incrementa si
fin3:
jmp lectura
resultado:
mov ah,00h ;limpia la pantalla
mov al,03h
int 10h
mov bx[si], "$"
mov dx, offset bx
mov ah, 9 ;preparar ah con 9 para la interrupcion 21h
int 21h ;mostrar contenido en dx
ret

Ejercicio 5: Escribir un programa que tome una cadena que representa un nmero decimal
y escriba su equivalente octal
org 100h ; inicio de programa
mov si, 0
mov al, 0
cadAnum:
cmp cad[si], "$"
jz seguir
mov bl, 10
mul bl
sub cad[si], '0'
add al, cad[si]
inc si
loop cadAnum
seguir:

mov cx, si
mov si, 0
mov bl, 8
pasar:
div bl ;dividir al con bl
mov oct[si], ah ;copiar a la cadena oct el resultado sobrante de la
division
inc si ;incrementar si
loop pasar
fina:
cmp ah, 0
jnz final
mov oct[si], al
final:
;mov dx, offset res
;mov ah, 9 ;preparar ah con 9 para la interrupcion 21h
;int 21h ;mostrar contenido en dx
ret
cad db "64$"
oct db 0

Ejercicio 6: Escribir un programa que tome tres cadenas, la primera y la tercera


representan un nmero y la segunda una operacin, por ejemplo: 329, -, 21 e
imprima el resultado 308
org 100h ; inicio de programa
include 'emu8086.inc' ;Incluye funciones de libreria emu8086
; DEFINE_SCAN_NUM
; DEFINE_PRINT_STRING
DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_UNS
mov si, 0
mov al, 0
;Convertir primera cadena a numero
cadAnum:
cmp cad1[si], "$"
jz seguir
mov bl, 10
mul bl
sub cad1[si], '0'
add al, cad1[si]
inc si
loop cadAnum
seguir:
mov aux1, al
;Convertir segunda cadena a numero
mov si, 0
mov al, 0
cadAnum2:
cmp cad3[si], "$"
jz seguir2
mov bl, 10

mul bl
sub cad3[si], '0'
add al, cad3[si]
inc si
loop cadAnum2
seguir2:
mov bl, al
mov al, aux1
;realizar operaciones normalmente teniendo ya los dos numeros decimales
cmp cad2, "-"
jz resta
cmp cad2, "+"
jz suma
cmp cad2, "*"
jz multi
cmp cad2, "/"
jz divi
resta:
sub al, bl
jmp fin
suma:
add al, bl
jmp fin
multi:
mul bl
jmp fin
divi:
div bl
jmp fin
fin:
mov bx, ax
mov ah,09
lea dx,msg
int 21h
mov ax, bx
call PRINT_NUM
ret
cad1 db "10$"
cad2 db "-"
cad3 db "2$"
aux1 db ?
aux2 dw ?
msg dw "El resultado es: $"

Ejercicio 7: Escribir un programa que imprima X en la pantalla hasta que se presiones


ESC.
name "keybrd"
org 100h
; print a welcome message:
mov dx, offset msg
mov ah, 9
int 21h

;============================
; eternal loop to get
; and print keys:
wait_for_key:
; check for keystroke in
; keyboard buffer:
mov dh, pos
mov dl, pos
mov bh, 0
mov ah, 2
int 10h ;Movemos el cursor
mov al,'X'
mov bh,0
mov bl,1
mov cx,1
mov ah,09h
inc pos ;Imprimimos una x
int 10h
mov ah, 1
int 16h
jz wait_for_key
; get keystroke from keyboard:
; (remove from the buffer)
mov ah, 0
int 16h
; print the key:
mov ah, 0eh
int 10h
; press 'esc' to exit:
cmp al, 1bh
jz exit
jmp wait_for_key
;============================
exit:
ret
msg db "Type anything...", 0Dh,0Ah
db "[Enter] - carriage return.", 0Dh,0Ah
db "[Ctrl]+[Enter] - line feed.", 0Dh,0Ah
db "You may hear a beep", 0Dh,0Ah
db " when buffer is overflown.", 0Dh,0Ah
db "Press Esc to exit.", 0Dh,0Ah, "$"
pos db 1
end

Ejercicio 8: Escribir un programa que ordene un vector de mayor a menor.


name "arreglo-mayor"
org 100h
mov cx, 8
bucle1:
mov c, cx
mov bx, cx
mov cx, 9
bucle2:

mov si, cx
mov ah, v[si-1]
cmp ah,v[bx-1]
jnge seguir ;Si
mov dh, v[bx-1]
mov dl, v[si-1]
mov v[bx-1], dl
mov v[si-1], dh
seguir:
loop bucle2

v[8] < v[7] no hacer nada, sino:


;Copiar v[7] en dh
;Copiar v[8] en dl
;Copiar dl en v[7]
;Copiar dh en v[8]

mov cx, c
loop bucle1
ret
v db 2,32,64,32,98,12,5,21,91
c dw 0

Ejercicio 9: Escribir un programa que halle el MCM Y MCD


; Programa que calcula el MCD y MCM de dos numeros decimales (soporta
numeros de 8 bits o 1 byte)
mov cont,1 ;inicializar variable cont en 1
bucle:
mov ah,0
mov al,cont
mov bl,nro1
div bl
cmp ah,0 ;si el resto de la division del contador con el nro1 es igual 0
je parte1
bc:
inc cont ;incrementar el contador
jmp bucle ;bucle hasta que encuentre el MCM
parte1: ;si nro1 es multiplo del contador
mov ah,0
mov al,cont
mov bl,nro2
div bl
cmp ah,0 ;compara si el resto de la division del contador con el nro2 es
0
je parte2
jmp bc ;si el nro2 no es multiplo del contador regresa a bucle1
parte2: ;si el nro1 y el nro2 son multiplos del contador
mov al,cont
mov MCM,al ;guarda el MCM
jmp parte3 ;ir a final
parte3: ;una vez que tengamos el MCM primero multiplicar nro1 * nro 2
mov al, nro1 ;con ese resultado, dividir por el MCM de nro1 y nro2 y
tenemos el MCD
mov bl, nro2
mul bl
mov bl, MCM
div bl
mov MCD, al
ret ;fin del programa

cont db 0 ;cont = contador


MCM db 0 ;en esta variable se guarda el MCM
MCD db 0 ;en esta variable se guarda el MCD
nro1 db 48 ;numero1 decimal
nro2 db 60 ;numero2 decimal

Ejercicio 10: Escribir un programa que dibuje una diagonal en la pantalla.


mov cx,1
mov al, 13h
mov ah, 0
int 10h ; set graphics video mode.
bucle1:
mov dx,
mov al,
mov ah,
int 10h

cx
color ;AL = pixel color
0ch ;Change color for a single pixel
;set pixel

cmp cx, 101 ;llegar hasta 100 x 100 (va en diagonal)


jz fin
inc cx ;DX = row.
add color, 2 ;para cambiar colores
jmp bucle1 ;CX = column
fin:
ret
color db 1

Ejercicio 11: Escribir un programa que lea un archivo y cuente cuantas palabras terminan
con la letra a.
name "archivo3"
org 100h
mov al, 0 ;modo de acceso para abrir arhivo, modo lectura/escritura
mov dx, offset archivo ;offset lugar de memoria donde esta la variable
mov ah, 3dh ;se intenta abrir el archivo
int 21h ;llamada a la interrupcion DOS
jc error ; si se prendio la bandera c ir a error
mov handle, ax ;si no paso mover a lo que le dio el SO
jmp leer
error:
; ....
;leer archivo
leer:
mov bx, handle
mov cx, 1
mov dx, offset leido
mov ah, 3fh
int 21h

cmp ax, 0 ;ax queda en 0 cuando llega a EOF


jz FIN ;si es 0 entonces va a fin para cerrar archivo
;Detectar palabras que terminan con a
mov dl, leido[0]
cmp dl, " " ;comparar si es espacio
jz mostrar ;si es espacio entonces ir a mostrar
jmp abajo ;si no es espacio entonces ir a abajo
mostrar:
cmp aux, "a" ;compara si el anterior es a
jnz abajo
inc cont ;si es a entonces incrementar contador
abajo:
mov aux, dl ;guardar en aux lo que hay en dl para comparar en la proxima
vuelta
jmp leer
FIN:
;cerramos archivo
mov bx, handle
mov ah, 3eh
int 21h
ret
archivo db "C:\prueba.txt", 0 ;ascii del nombre del archivo
leido db "$"
handle dw ? ;identificador del arhivo
aux db "$"
cont db 0

Das könnte Ihnen auch gefallen