Ejercicios Emu8086

97
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.

Transcript of Ejercicios Emu8086

Page 1: Ejercicios Emu8086

1

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

2.3. ;------------------------------------------------------------------

------------4. ;Definicion del segmento de datos5. ;------------------------------------------------------------------

------------6. DATOS SEGMENT7.8. saludo db "Hola mundo!!!","$"9.10. DATOS ENDS11.12. ;-----------------------------------------------------------------

-------------13. ;Definicion del segmento de codigo14. ;-----------------------------------------------------------------

-------------15. CODE SEGMENT16. assume cs:code,ds:datos17.18. START PROC19. mov ax,datos ;20. mov ds,ax ;Inicializar21.22. mov dx,offset saludo ;Cargar la direccion del saludo23. mov ah,9 ;Opcion que va a servir a la

interrupcion 21h para24. ;indicar que debe mostrar por

pantalla el offset25. ;que hay en DX hasta que encuentre

el caracter '$'26. int 21h ;Interrupcion que lo mostrara por

pantalla27.28. mov ax,4C00h ;29. int 21h ;Terminar el programa30.31. START ENDP32.33. CODE ENDS34. END START35.

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 datos40. ;-----------------------------------------------------------------

-------------41. DATOS SEGMENT

Page 2: Ejercicios Emu8086

42. saludo db "Hola mundo!!!"43. DATOS ENDS44.45. ;-----------------------------------------------------------------

-------------46. ;Definicion del segmento de pila47. ;-----------------------------------------------------------------

-------------48. PILA SEGMENT STACK "STACK"49. DB 40 DUP(0)50. PILA ENDS51.52. ;-----------------------------------------------------------------

-------------53. ;Definicion del segmento extra54. ;-----------------------------------------------------------------

-------------55. EXTRA SEGMENT56. RESULT DW 0,057. EXTRA ENDS58.59. ;-----------------------------------------------------------------

-------------60. ;Definicion del segmento de codigo61. ;-----------------------------------------------------------------

-------------62. CODE SEGMENT63. assume cs:code,ds:datos,es:extra,ss:pila64.65. START PROC66. ;Inicializamos los registros de segmento67. mov ax,datos68. mov ds,ax69. mov ax,pila70. mov ss,ax71. mov ax,extra72. mov es,ax73. ;Fin de las inicializaciones74.75. ;Limpiamos la pantalla76. mov ax,0B800h ;En esta direccion comienza la memoria de

video77. mov es,ax ;Lo cargamos en el segmento extra78. xor di,di ;Ponemos DI=0. Esto equivale a mov di,0,

pero79. ;xor di,di consume 3 ciclos de reloj y

con mov 480. mov cx,80*25 ;El tamaño total es 2000 (80 lineas x 25

columnas)81.82. b_clear: ;Bucle que se encargara de recorrer los

200083. ;caracteres de la pantalla para limpiarla84. mov al,20h ;20h=" " Rellenar la pantalla con

espacios85. mov ah,1bh ;Fondo azul, letras blancas86. mov es:[di],ax

Page 3: Ejercicios Emu8086

87. inc di88. inc di89. loop b_clear90.91. mov ax,0B800h92. mov es,ax93. mov si,offset saludo94. mov di,(80*7+17)*2 ;Linea 7, caracter 1895. mov cx,1396.97. b_saludo: ;Bucle que se encargara de recorrer los

200098. ;caracteres de la pantalla para limpiarla99. mov al,[si]100. mov ah,1bh ;Fondo azul, letras blancas101. mov es:[di],ax102. inc si ;Pasamos a apuntar a la siguiente letra

del saludo103. inc di104. inc di105. loop b_saludo106.107.108. mov ax,4C00h ;109. int 21h ;Terminar el programa110.111. START ENDP112.113. CODE ENDS114. END START115.

116. Este programa pide el nombre al usuario y lo muestra por pantalla: 117.118. ;-----------------------------------------------------------------

-------------119. ;Definicion del segmento de datos120. ;-----------------------------------------------------------------

-------------121. DATOS SEGMENT122. mensaje db "Ejercicios disponibles en:

www.victorsanchez2.net" 123. pregunta_nombre db "Cual es tu nombre?: " 124. nombre db 64 DUP(0)125. DATOS ENDS126.127. ;-----------------------------------------------------------------

-------------128. ;Definicion del segmento de pila129. ;-----------------------------------------------------------------

-------------130. PILA SEGMENT STACK "STACK"131. db 40h DUP(0)132. PILA ENDS133.134. ;-----------------------------------------------------------------

-------------135. ;Definicion del segmento extra

Page 4: Ejercicios Emu8086

136. ;------------------------------------------------------------------------------

137. EXTRA SEGMENT138. RESULT DW 0,0139. EXTRA ENDS140.141. ;-----------------------------------------------------------------

-------------142. ;Definicion del segmento de codigo143. ;-----------------------------------------------------------------

-------------144. CODE SEGMENT145. assume cs:code,ds:datos,es:extra,ss:pila146.147. START PROC148. ;Inicializamos los registros de segmento149. mov ax,datos150. mov ds,ax151. mov ax,pila152. mov ss,ax153. mov ax,extra154. mov es,ax155. ;Fin de las inicializaciones156.157. ;Limpiamos la pantalla158. mov ax,0B800h ;En esta direccion comienza la memoria de

video159. mov es,ax ;Lo cargamos en el segmento extra160. xor di,di ;Ponemos DI=0. Esto equivale a mov di,0,

pero161. ;xor di,di consume 3 ciclos de reloj y

con mov 4162. mov cx,80*25 ;El tamaño total es 2000 (80 lineas x 25

columnas)163.164. b_clear: ;Bucle que se encargara de recorrer los

2000165. ;caracteres de la pantalla para limpiarla166. mov al,20h ;20h=" " Rellenar la pantalla con

espacios167. mov ah,1bh ;Fondo azul, letras blancas168. mov es:[di],ax169. inc di170. inc di171. loop b_clear172. 173. ;Mostramos un mensaje174. mov si,offset mensaje175. mov di,(80*10+10)*2 ;Linea 10, columna 10176. mov cx,49 ;Tamaño del mensaje177.178. b_saludo: ;Bucle que se encargara de recorrer los

2000179. ;caracteres de la pantalla para limpiarla180. mov al,[si]181. mov ah,1bh ;Fondo azul, letras blancas182. mov es:[di],ax

Page 5: Ejercicios Emu8086

183. inc si ;Pasamos a apuntar a la siguiente letra del saludo

184. inc di185. inc di186. loop b_saludo187.188. ;Mensaje al usuario para que introduzca su nombre189. mov si,offset pregunta_nombre190. mov di,(80*12+10)*2 ;Linea 12, columna 10191. mov cx,20192.193. b_pide_nombre: ;Bucle que se encargara de recorrer los

2000194. ;caracteres de la pantalla para limpiarla195. mov al,[si]196. mov ah,1bh ;Fondo azul, letras blancas197. mov es:[di],ax198. inc si ;Pasamos a apuntar a la siguiente letra

del saludo199. inc di200. inc di201. loop b_pide_nombre202.203. ;Almacenamos el nombre204. mov ah,0Ah205. mov dx,offset nombre206. mov nombre[0],64 ;Maximo numero de caracteres207. int 21h208.209. mov bx,0210.211. muestra_nombre:212. mov dl,nombre[bx+2]213. mov ah,2214. int 21h ;Escribir un caracter del nombre215. inc bx216. cmp bl,nombre[1] ;Compara con el numero de caracteres217. jne muestra_nombre218.219. mov ax,4C00h ;220. int 21h ;Terminar el programa221.222. START ENDP223.224. CODE ENDS225. END START226.

227. El mismo programa que antes, pero ahora con llamadas a funciones: 228.229. ;-----------------------------------------------------------------

-------------230. ;Definicion del segmento de datos231. ;-----------------------------------------------------------------

-------------232. DATOS SEGMENT233. mensaje db "Ejercicios disponibles en:

www.victorsanchez2.net"

Page 6: Ejercicios Emu8086

234. pregunta_nombre db "Cual es tu nombre?: " 235. nombre db 256 DUP(0)236. DATOS ENDS237. 238. ;-----------------------------------------------------------------

-------------239. ;Definicion del segmento de pila240. ;-----------------------------------------------------------------

-------------241. PILA SEGMENT STACK "STACK"242. db 40h DUP(0)243. PILA ENDS244.245. ;-----------------------------------------------------------------

-------------246. ;Definicion del segmento extra247. ;-----------------------------------------------------------------

-------------248. EXTRA SEGMENT249. RESULT DW 0,0250. EXTRA ENDS251.252. ;-----------------------------------------------------------------

-------------253. ;Definicion del segmento de codigo254. ;-----------------------------------------------------------------

-------------255. CODE SEGMENT256. assume CS:code,DS:datos,ES:extra,SS:pila257.258. ;-----------------------------------------------------------------

-------------259. ; Procedimiento inicial260. ;-----------------------------------------------------------------

-------------261. START PROC262.263. call inicializa_seg ;Inicializa los registros de

segmento264. call limpia_pantalla ;Limpiamos la pantalla265. call muestra_mensaje ;Mensaje de informacion266. call pide_nombre ;Pide el nombre al usuario267. call muestra_nombre ;Muestra por pantalla el nombre

del usuario268.269. mov ax,4C00h ;270. int 21h ;Terminar el programa271.272. START ENDP273.274.275. ;-----------------------------------------------------------------

-------------276. ; inicializa_seg277. ;278. ; in:279. ; out: Los registros de segmento quedan inicializados

Page 7: Ejercicios Emu8086

280. ; machaca: AX, DS, SS, ES281. ; make: Inicializa los registros de segmento282. ;283. ;-----------------------------------------------------------------

-------------284. inicializa_seg proc near285.286. mov ax,datos287. mov ds,ax288. mov ax,pila289. mov ss,ax290. mov ax,extra291. mov es,ax292.293. ret294.295. inicializa_seg endp296.297.298. ;-----------------------------------------------------------------

-------------299. ; limpia_pantalla300. ;301. ; in:302. ; out:303. ; machaca: DI, ES304. ; make: Limpia la pantalla escribiendo espacios en las 80x25

posiciones de305. ; la pantalla, accediendo a la memoria de video306. ;307. ;-----------------------------------------------------------------

-------------308. limpia_pantalla proc near309.310. push ax ;Guardar en la pila las variables que

queremos311. push cx ;conservar para cuando salgamos de la

funcion312.313. mov ax,0B800h ;En esta direccion comienza la memoria de

video314. mov es,ax ;Lo cargamos en el segmento extra315. xor di,di ;Inicializar DI a 0316. mov cx,80*25 ;El tamaño total es 2000 (80 lineas x 25

columnas)317.318. b_clear: ;Bucle que se encargara de recorrer los

2000319. ;caracteres de la pantalla para limpiarla320. mov al,20h ;20h=" " Rellenar la pantalla con

espacios321. mov ah,1bh ;Fondo azul, letras blancas322. mov es:[di],ax323. inc di324. inc di325. loop b_clear326.

Page 8: Ejercicios Emu8086

327. pop cx ;Importante sacarlas en orden contrario al que las

328. pop ax ;guardamos329.330. ret331.332. limpia_pantalla endp333.334. ;-----------------------------------------------------------------

-------------335. ; muestra_mensaje336. ;337. ; in:338. ; out:339. ; machaca: DI, SI 340. ; make: Muestra un mensaje por pantalla indicando en que pagina

se pueden341. ; encontrar los ejercicios 342. ;343. ;-----------------------------------------------------------------

-------------344. muestra_mensaje proc near345.346. push ax347. push cx348. push es349. 350. 351. mov si,offset mensaje352. mov di,(80*10+10)*2 ;Linea 10, columna 10353. mov cx,49 ;Tamaño del mensaje354.355. b_saludo: ;Bucle que se encargara de recorrer los

2000356. ;caracteres de la pantalla para limpiarla357. mov al,[si]358. mov ah,1bh ;Fondo azul, letras blancas359. mov es:[di],ax360. inc si ;Pasamos a apuntar a la siguiente letra

del saludo361. inc di362. inc di363. loop b_saludo364. 365. pop es366. pop cx367. pop ax368.369. ret370.371. muestra_mensaje endp372.373. ;-----------------------------------------------------------------

-------------374. ; pide_nombre375. ;376. ; in:

Page 9: Ejercicios Emu8086

377. ; out:378. ; machaca: DI, SI, DX379. ; make: Pide el nombre al usuario para que lo introduzca por

pantalla380. ;381. ;-----------------------------------------------------------------

-------------382. pide_nombre proc near383.384. push ax385. push cx386. push es387. 388.389. ;Mensaje al usuario para que introduzca su nombre390. mov si,offset pregunta_nombre391. mov di,(80*12+10)*2 ;Linea 12, columna 10392. mov cx,20393.394. b_pide_nombre: ;Bucle que se encargara de recorrer los

2000395. ;caracteres de la pantalla para limpiarla396. mov al,[si]397. mov ah,1bh ;Fondo azul, letras blancas398. mov es:[di],ax399. inc si ;Pasamos a apuntar a la siguiente letra

del saludo400. inc di401. inc di402. loop b_pide_nombre403.404. ;Almacenamos el nombre405. mov ah,0Ah406. mov dx,offset nombre407. mov nombre[0],64 ;Maximo numero de caracteres408. int 21h409. 410. pop es411. pop cx412. pop ax413.414. ret415.416. pide_nombre endp417.418. ;-----------------------------------------------------------------

-------------419. ; muestra_nombre420. ;421. ; in: nombre contiene el nombre de usuario que se ha introducido422. ; out:423. ; machaca: DI, SI424. ; make: Muestra el nombre al usuario por pantalla425. ;426. ;-----------------------------------------------------------------

-------------427. muestra_nombre proc near

Page 10: Ejercicios Emu8086

428.429. push ax430. push cx431. push es432.433. mov ax,0B800h434. mov es,ax435. xor dx,dx436. mov si,offset nombre+2437. mov di,(80*12+31)*2 ;Linea 12, columna 31438.439. mostrar_nombre:440. mov al,[si]441. mov ah,1bh ;Fondo azul, letras blancas442. mov es:[di],ax443. inc dx ;Cuenta el numero de caracteres444. inc si445. inc di446. inc di447. cmp dl,nombre[1] ;Comparar con el numero de

caracteres448. jne mostrar_nombre449.450. pop es451. pop cx452. pop ax453.454. ret455.456. muestra_nombre endp457.458.459. CODE ENDS460. END START461.

462. Programa que calcula el factorial de 3 y lo muestra por pantalla: 463.464. ;-----------------------------------------------------------------

-------------465. ;Definicion del segmento de datos466. ;-----------------------------------------------------------------

-------------467. DATOS SEGMENT468.469. dato db 3 ;Numero del que calcularemos su factorial470.471. DATOS ENDS472.473. ;-----------------------------------------------------------------

-------------474. ;Definicion del segmento de pila475. ;-----------------------------------------------------------------

-------------476. PILA SEGMENT STACK "STACK"477. db 40h dup(0)478. PILA ENDS479.

Page 11: Ejercicios Emu8086

480. ;------------------------------------------------------------------------------

481. ;Definicion del segmento extra482. ;-----------------------------------------------------------------

-------------483. EXTRA SEGMENT484. result dw 0,0 ;2 palabras (4 bytes)485. EXTRA ENDS486.487. ;-----------------------------------------------------------------

-------------488. ;Definicion del segmento de codigo489. ;-----------------------------------------------------------------

-------------490. CODE SEGMENT491. assume CS:code,DS:datos,ES:extra,SS:pila492.493. factorial db 0 ;Variable para guardar el factorial494.495. START PROC496.497. call inicializar ;Inicializa los registros de

segmento498. mov sp,64 ;Carga el puntero de pila con el

valor mas alto499.500. mov cl,dato501. call calcula_factorial ;Calcula el faltorial de dato502. mov factorial,al ;Almacenar el resultado en factorial503. call muestra_factorial ;Muestra el valor del factorial504.505. mov ax,4C00h ;506. int 21h ;Terminar el programa507.508.509. START ENDP510. 511. ;-----------------------------------------------------------------

-------------512. ; inicializar513. ;514. ; in:515. ; out: Los registros de segmento quedan inicializados516. ; machaca: AX, DS, SS, ES517. ; make: Inicializa los registros de segmento518. ;519. ;-----------------------------------------------------------------

-------------520. inicializar proc near521.522. mov ax,datos523. mov ds,ax524. mov ax,pila525. mov ss,ax526. mov ax,extra527. mov es,ax528.

Page 12: Ejercicios Emu8086

529. ret530.531. inicializar endp532.533. ;-----------------------------------------------------------------

-------------534. ; calcula_factorial535. ;536. ; in: CL contiene el dato537. ; out: Devuelve en AX el resultado de calcular el factorial538. ; machaca: AX, CX539. ; make: Inicializa los registros de segmento y el puntero de

pila540. ;541. ;-----------------------------------------------------------------

-------------542. calcula_factorial proc near543.544. mov ax,1545. xor ch,ch546. cmp cx,0 ;Si el numero es 0547. je fin ;terminamos548. 549. factor:550. mul cx551. dec cx552. jne factor553. 554. fin:555. ret556.557. calcula_factorial endp558.559. ;-----------------------------------------------------------------

-------------560. ; muestra_nombre561. ;562. ; in: nombre contiene el nombre de usuario que se ha introducido563. ; out:564. ; machaca: DI, SI565. ; make: Muestra el valor del factorial por pantalla566. ;567. ;-----------------------------------------------------------------

-------------568. muestra_factorial proc near569.570. push ax571. push cx572. push es573.574. mov ax,0B800h575. mov es,ax ;Apuntar a la memoria de video576. mov dl,factorial577. mov di,(80*12+31)*2 ;Linea 12, columna 31578. add dl,30h ;Obtener el valor en ASCII ('0'=30h)579. mov dh,1bh 580. mov es:[di],dx

Page 13: Ejercicios Emu8086

581.582. pop es583. pop cx584. pop ax585.586. ret587.588. muestra_factorial endp589.590. CODE ENDS591. END START592.

2

1. Escribir un programa que escriba el mismo carácter en las 2000 posiciones de la pantalla:

2.3. pantalla EQU 0B800h ;Direccion física de comienzo de la

pantalla4.5. ;------------------------------------------------------------------

------------6. ;Definición del segmento de codigo7. ;------------------------------------------------------------------

------------8. CODE SEGMENT9. assume cs:code10.11. START PROC12. mov ax,pantalla ;Cargar la dirección de la

coordenada 0,0 de la13. mov ds,ax ;pantalla14. xor bx,bx ;Ponemos bx a 015.16. pinta_caracter:17. mov ds:[bx],byte ptr "V" ;Escribir el carácter en

su coordenada18. inc bx ;En lugar de sumar 2, se

incrementa 2 veces porque19. ;consume menos ciclos de

reloj del procesador20. inc bx ;Cada posicion de la

pantalla son 2 bytes,21. cmp bx,2000*2 ;por eso bx va a llegar

hasta 400022. jl pinta_caracter ;Si bx<4000 volvemos a

pintar otro carácter23.24. mov ax,4C00h ;25. int 21h ;Terminar el programa26.

Page 14: Ejercicios Emu8086

27. START ENDP28.29. CODE ENDS30. END START

31. Hacer un programa que coja el carácter 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 0B800h34.35. ;-----------------------------------------------------------------

-------------36. ;Definición del segmento de codigo37. ;-----------------------------------------------------------------

-------------38. CODE SEGMENT39. assume cs:code40.41. START PROC42. mov ax,pantalla ;Cargar la dirección de la

coordenada 0,0 de la43. mov ds,ax ;pantalla44. xor bx,bx45. mov dx,ds:[bx] ;Obtener el carácter de la

coordenada 0,046.47. pinta_caracter:48. inc bx49. inc bx50. mov ds:[bx],dx ;Copiar el carácter

obtenido por toda la pantalla51. cmp bx,1995*2 ;Dejamos los ultimos 4

caracteres sin rellenar52. jl pinta_caracter53.54. mov ds:[1996*2],byte ptr "E" ;En los ultimos 4

caracteres escribimos55. mov ds:[1997*2],byte ptr "T" ;nuestro mensaje56. 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 programa61.62. START ENDP63.64. CODE ENDS65. 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 números 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

Page 15: Ejercicios Emu8086

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.bat71. :72. : Descripcion:73. : Ensamblar modulo fuente principal de un programa, crear modulo74. : objeto y debuggearlo.75. :76. :-----------------------------------------------------------------

------77. :78. echo off79. if z%1 == z goto error80. goto check81. :error82. echo *** error: falta nombre del modulo fuente ***83. goto fin84. :check85. if exist %1.asm goto ensam86. echo *** error: fichero %1.asm no existe ***87. goto fin88. :ensam89. tasm /zi %1;90. if exist %1.obj goto mensa91. echo *** error en programa fuente ***92. goto fin93. :mensa94. tlink /v %195. echo ... creado fichero %1.obj96.97. td %198.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.

;------------------------------------------------------------------------------;Definición del segmento de codigo

Page 16: Ejercicios Emu8086

;------------------------------------------------------------------------------CODE SEGMENT assume CS:code

START:

xor ax,ax ; mov cx,1 ;Inicializar

suma: add ax,cx ; inc cx ; cmp cx,11 ; jne suma ;Sumar 1+...+10=37h

mov ax,4C00h ; int 21h ;Terminar el programa

CODE ENDS END START

El siguiente programa es algo más sofisticado y potente. La teoría la explicaremos después de ver el ejemplo.

100. Realizar un programa que limpie la pantalla dejando el fondo azul y los caracteres rojos:

101.102. pantalla EQU 0B800h103.104. ;-----------------------------------------------------------------

-------------105. ;Definición del segmento de pila106. ;-----------------------------------------------------------------

-------------107. PILA SEGMENT STACK "STACK"108. db 40h dup(0)109. PILA ENDS110.111. ;-----------------------------------------------------------------

-------------112. ;Definición del segmento extra113. ;-----------------------------------------------------------------

-------------114. EXTRA SEGMENT115. result dw 0,0116. EXTRA ENDS117.118. ;-----------------------------------------------------------------

-------------119. ;Definición del segmento de codigo120. ;-----------------------------------------------------------------

-------------121. CODE SEGMENT122. assume cs:code,es:extra,ss:pila

Page 17: Ejercicios Emu8086

123.124. START PROC125. 126. cld ;DF=0 (incrementar DI)127. mov ax,pantalla128. mov es,ax129. xor di,di130. mov ax,1C00h ;Fondo azul, caracteres rojos con

intensidad131. ;Equivalente a: mov

ax,0001110000000000b132. mov cx,2000133. rep stosw ;Repetirlo las 2000 veces134.135. mov ax,4C00h ;136. int 21h ;Terminar el programa137.138. START ENDP139.140. CODE ENDS141. END START

Si quisiesemos poner los atributos de otra forma sólo hay que cambiar una línea. Podríamos ponerla de la siguiente manera, por ejemplo:

mov ax,1100001000000000b ó mov ax,0C200h

si quisiesemos poner el fondo rojo con letras verdes.

Teoría 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 dirección 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 número 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 carácter tenemos otros 8 bits. Cada número o letra hexadecimal equivale a un nibble (4 bits):

código atributo (1 byte). Los bits son los siguientes: 7 - Utilizado para indicar si el carácter parpadea o no.6 - Componente rojo del fondo5 - Componente verde del fondo4 - Componente azul del fondo

Page 18: Ejercicios Emu8086

3 - Intensidad en los caracteres2 - Componente rojo del carácter1 - Componente verde del carácter0 - Componente azul del carácter

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.

código carácter (1 byte): Podemos elegir de la tabla ASCII aquel carácter que prefiramos. Como carácter elegimos el 00h, que en la tabla ASCII va a equivaler a dejar el fondo sin ningún carácter. Si quiesiesemos que apareciese el carácter 'V' en el fondo pues cogeríamos 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 pantalla5. ;------------------------------------------------------------------

------------6. PANTALLA equ 0B800h7.8. ;------------------------------------------------------------------

------------9. ;Definicion del segmento de pila10. ;-----------------------------------------------------------------

-------------11. PILA SEGMENT STACK "STACK"12. db 40h dup(0)13. PILA ENDS14.15. ;-----------------------------------------------------------------

-------------16. ;Definicion del segmento de codigo17. ;-----------------------------------------------------------------

-------------18. CODE SEGMENT19. assume CS:code, SS:pila20.21. START:22. mov ax,PANTALLA23. mov ds,ax24.25. xor bx,bx26. xor al,al

Page 19: Ejercicios Emu8086

27. mov cx,256 ;Numero de caracteres que contiene la tabla ASCII

28.29. mostrar_ascii:30. mov [bx],al ;Escribirlo en la coordenada de la

pantalla31. inc bx ;32. inc bx ;Pasar a la siguiente coordenada33. inc al ;Pasar al siguiente caracter34. loop mostrar_ascii35. 36. mov ax,4C00h ;37. int 21h ;Terminar el programa38.39. CODE ENDS40. END START

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 0B800h44.45. ;-----------------------------------------------------------------

-------------46. ;Definicion del segmento de pila47. ;-----------------------------------------------------------------

-------------48. PILA SEGMENT STACK "STACK"49. db 40h dup(0)50. PILA ENDS51.52. ;-----------------------------------------------------------------

-------------53. ;Definicion del segmento de codigo54. ;-----------------------------------------------------------------

-------------55. CODE SEGMENT56. assume CS:code, SS:pila57.58. START:59. mov ax,PANTALLA60. mov ds,ax61.62. mov dl,0 ;Primera linea en la que

empezaremos a pintar63. mov cx,10 ;Numero de lineas que vamos a

tener64.65. BucleLineas:66. push cx67.68. mov dh,0 ;Primera columna69. mov cx,20 ;Numero de columnas70.71. BucleColumnas:72. mov al,80*2 ;Bytes por linea73. mul dl ;Por el numero de linea

Page 20: Ejercicios Emu8086

74. mov bx,ax75. mov al,2 ;2 bytes por columna76. mul dh ;Por el numero de columna77. add bx,ax78. mov word ptr [bx],7056h ;Fondo blanco y letra 'V'79. inc dh ;Siguiente columna80. loop BucleColumnas81.82. pop cx ;Recuperamos el contador de las

lineas83. inc dl ;Pasar a la siguiente linea84. loop BucleLineas85.86. mov ax,4C00h87. int 21h88.89. CODE ENDS90. END START

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 carro94. lf equ 10 ;alimentacion de linea95.96. ;-----------------------------------------------------------------

-------------97. ;Definicion del segmento de datos98. ;-----------------------------------------------------------------

-------------99. DATOS SEGMENT100. DeseaContinuar db cr,lf,'Desea continuar? S/N: '101. db'$'102. continuando db ' Continuando...',cr,lf103. db'$'104. LetraErronea db ' La tecla pulsada es incorrecta.',cr,lf105. db'$'106. DATOS ENDS107.108. ;-----------------------------------------------------------------

-------------109. ;Definicion del segmento de pila110. ;-----------------------------------------------------------------

-------------111. PILA SEGMENT STACK "STACK"112. db 40h dup(?)113. PILA ENDS114.115. ;-----------------------------------------------------------------

-------------116. ;Definicion del segmento de codigo117. ;-----------------------------------------------------------------

-------------118. CODE SEGMENT119. assume CS:code, DS:datos, SS:pila120.121. START:

Page 21: Ejercicios Emu8086

122. mov ax,datos123. mov ds,ax124. jmp continuar ;Saltamos a la etiqueta

CONTINUAR125.126. INICIO:127. lea dx,continuando ;128. mov ah,9 ;129. int 21h ;Mensaje de que seguimos en el

programa130. jmp continuar ;Salto para preguntar si se

desea continuar131.132. ERROR:133. lea dx,LetraErronea ;134. mov ah,9 ;Mensaje de que la letra

introducida135. int 21h ;no es correcta136.137. CONTINUAR:138. lea dx,DeseaContinuar ;139. mov ah,9 ;140. int 21h ;Mostrar pregunta para ver si

desea continuar141. 142. mov ah,1 ;Esperar a que se pulse una tecla143. int 21h ;y mostrarla por pantalla144. 145. cmp al, 'S' ;146. je inicio ;147. cmp al, 's' ;148. je inicio ;Desea continuar149. 150. cmp al, 'N' ;151. je salir ;152. cmp al, 'n' ;153. je salir ;No desea continuar, terminamos154. 155. jmp error ;La tecla pulsada no es 'S', 's',

'N' ni 'n'156. ;Se va a mostrar un mensaje de

error. Saltamos157. ;a la etiqueta ERROR158. 159. salir:160. mov ax, 4C00h161. int 21h162.163. CODE ENDS164. END START

165. Realizar un programa que cambie todas las letras de la pantalla a minusculas:

166.167. PANTALLA equ 0B800h168.

Page 22: Ejercicios Emu8086

169. ;------------------------------------------------------------------------------

170. ;Definicion del segmento de pila171. ;-----------------------------------------------------------------

-------------172. PILA SEGMENT STACK "STACK"173. db 40h dup(0)174. PILA ENDS175.176. ;-----------------------------------------------------------------

-------------177. ;Definicion del segmento de codigo178. ;-----------------------------------------------------------------

-------------179. CODE SEGMENT180. assume CS:code, SS:pila181.182. START:183. mov ax,pantalla ;184. mov ds,ax ;DS apunta a la direccion de la

pantalla185.186. xor bx,bx187. mov cx,2000 ;80 filas x 25 columnas188.189. cambia_minus:190. mov al,ds:[bx] ;Obtenemos el caracter que hay en la

pantalla191. ;en la coordenada indicada192. 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

caracter196. add al,32 ;Para pasar de mayusculas a

minusculas197. ;hay que sumar 32 para movernos en

la198. ;tabla ASCII de las mayusculas a las

minusculas199. mov ds:[bx],al ;Escribimos en la pantalla el

caracter cambiado200. ;a minusculas201. siguiente:202. inc bx ;203. inc bx ;Pasamos a la siguiente coordenada204. loop cambia_minus205.206. mov ax,4C00h ;207. int 21h ;Terminamos el programa208.209. CODE ENDS210. END START

Page 23: Ejercicios Emu8086

4Vamos a ver diferentes ejemplos de instrucciones para entenderlas un poco mejor. Será bueno tener un libro al lado para saber qué hace cada instrucción.

1. Ejemplo de las instrucciones: CBW y CWD 2.3. ;------------------------------------------------------------------

------------4. ;Definicion del segmento de pila5. ;------------------------------------------------------------------

------------6. PILA SEGMENT STACK "STACK"7. db 40h dup(0)8. PILA ENDS9.10. ;-----------------------------------------------------------------

-------------11. ;Definicion del segmento de codigo12. ;-----------------------------------------------------------------

-------------13. CODE SEGMENT14. assume CS:code, SS:pila15.16. START:17. mov ah,3 ;No sirve para nada, solo para ver que al

convertir18. ;en palabra o doble palabra se machacan

los registros19. mov al,520. cbw ;Convertir un byte en palabra21. cwd ;Convertir una palabra en doble palabra22.23. neg al ;al pasa a ser un numero negativo

(complemento a 2)24. mov ah,4 ;basura, igual que en caso anterior25. cbw ;Convertir un byte en palabra26. cwd ;Convertir una palabra en doble palabra27.28. mov ax,4C00h29. int 21h30.31. CODE ENDS32. END START

33. Ejemplo de la instruccion: AAM (ajuste ASCII en multiplicación) 34.35. ;-----------------------------------------------------------------

-------------36. ; Programa que prueba la instruccion: AAM37. ;38. ; ah <- cociente (al/10)39. ; al <- resto (al/10)40. ;41. ;-----------------------------------------------------------------

-------------42.

Page 24: Ejercicios Emu8086

43. ;------------------------------------------------------------------------------

44. ;Definicion del segmento de codigo45. ;-----------------------------------------------------------------

-------------46. CODE SEGMENT47. assume CS:code48.49. START:50.51. mov al,952. mov cl,553. mul cl ;Resultado: ax=002D54. aam ;En el cociente hay un 4 y en el resto un 555. ;Resultado es ax=040556. 57. mov ax,4c00h58. int 21h59.60. CODE ENDS61. 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 convierte66. ; 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 suma68. ; de dos numeros decimales en formato ASCII69. ;-----------------------------------------------------------------

-------------70.71. ;-----------------------------------------------------------------

-------------72. ;Definicion del segmento de pila73. ;-----------------------------------------------------------------

-------------74. PILA SEGMENT STACK "STACK"75. db 40h dup(0)76. PILA ENDS77.78. ;-----------------------------------------------------------------

-------------79. ;Definicion del segmento de codigo80. ;-----------------------------------------------------------------

-------------81. CODE SEGMENT82. assume CS:code,SS:pila83.84. START PROC85.86. mov ax,8 ;87. add al,1 ; 88. aaa ;AX=0009h

Page 25: Ejercicios Emu8086

89. mov ax,8 ;90. add al,2 ;91. aaa ;AX=0100h92. mov ax,11110001b ;93. add al,1 ;94. aaa ;AX=0002h95. mov ax,8 ;96. add al,7 ;97. aaa ;AX=0105h98. add al,4 ;99. aaa ;AX=0109h100. add al,9 ;101. aaa ;AX=0208h102.103.104. mov ax,4C00h ;105. int 21h ;Terminar el programa106.107. START ENDP108.109. CODE ENDS110. END START

111. Ejemplo de la instruccion: AAA (ajuste ASCII en suma). Del examen de ETCII del año 2001:

112.113. ;-----------------------------------------------------------------

-------------114. ; Programa que prueba la instruccion: AAA115. ;116. ; ah <- cociente (al/0Ah)117. ; al <- resto (al/0Ah)118. ;119. ;-----------------------------------------------------------------

-------------120. ; Ejercicio: examen ETCII - 7/11/01121.122. ;-----------------------------------------------------------------

-------------123. ;Definicion del segmento de codigo124. ;-----------------------------------------------------------------

-------------125.126. CODE SEGMENT127. assume CS:code128.129. start:130.131. mov ax,16h 132. mov bx,191h133. add ax,bx134. aaa ;AX=0107h135. add ax,7h136. aaa ;AX=0204h137.138. mov ax,4c00h139. int 21h

Page 26: Ejercicios Emu8086

140.141. CODE ENDS142. END START

143. Ejemplo que muestra la diferencia entre las instrucciones: AAA y DAA 144.145. ;-----------------------------------------------------------------

-------------146. ; Programa que prueba las instrucciones: AAA y DAA147. ;-----------------------------------------------------------------

-------------148. ;-----------------------------------------------------------------

-------------149. ;Definicion del segmento de pila150. ;-----------------------------------------------------------------

-------------151. PILA SEGMENT STACK "STACK"152. db 40h dup(0)153. PILA ENDS154.155. ;-----------------------------------------------------------------

-------------156. ;Definicion del segmento de codigo157. ;-----------------------------------------------------------------

-------------158. CODE SEGMENT159. assume CS:code, SS:pila160.161. START:162. mov al,5163. add al,7164. aaa ;Ajuste BCD no empaquetado165.166. xor ax,ax167.168. mov al,5169. add al,7170. daa ;Ajuste BCD empaquetado171.172. mov ax,4C00h173. int 21h174.175. CODE ENDS176. END START

177. Ejemplo de la instrucción NEG (convertir a complemento a 2): 178.179. ;-----------------------------------------------------------------

-------------180. ;Definicion del segmento de pila181. ;-----------------------------------------------------------------

-------------182. PILA SEGMENT STACK "STACK"183. db 40h dup(0)184. PILA ENDS185.186. ;-----------------------------------------------------------------

-------------

Page 27: Ejercicios Emu8086

187. ;Definicion del segmento de codigo188. ;-----------------------------------------------------------------

-------------189. CODE SEGMENT190. assume CS:code, SS:pila191.192. START:193.194. mov al,8 195. neg al ;Convertir a su complemento a 2196.197. mov ax,4C00h198. int 21h199.200. CODE ENDS201. END START

202. Otra forma de convertir a complemento a 2 mediante las instrucciones NOT e INC:

203.204. ;-----------------------------------------------------------------

-------------205. ;Definicion del segmento de pila206. ;-----------------------------------------------------------------

-------------207. PILA SEGMENT STACK "STACK"208. db 40h dup(0)209. PILA ENDS210.211. ;-----------------------------------------------------------------

-------------212. ;Definicion del segmento de codigo213. ;-----------------------------------------------------------------

-------------214. CODE SEGMENT215. assume CS:code, SS:pila216.217. START:218.219. mov al,8 220. not al ;221. inc al ;Convertir a su complemento a 2222.223. mov ax,4C00h224. int 21h225.226. CODE ENDS227. END START

5

Page 28: Ejercicios Emu8086

1. Realizar un programa que guarde el estado de la pantalla con todos sus caracteres, después 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, despues5. ;rellena toda la pantalla con '*' y por ultimo vuelve a dejar la

pantalla como6. ;estaba7. ;------------------------------------------------------------------

------------8.9. PANTALLA equ 0B800h10.11. ;-----------------------------------------------------------------

-------------12. ;Definicion del segmento de datos13. ;-----------------------------------------------------------------

-------------14. DATOS SEGMENT15.16. pantalla_bak db 80*25*2 DUP(?) ;Reservar una variable para

guardar toda la17. ;informacion de la pantalla18. DATOS ENDS19.20. ;-----------------------------------------------------------------

-------------21. ;Definicion del segmento de pila22. ;-----------------------------------------------------------------

-------------23. PILA SEGMENT STACK "STACK"24. db 40h dup(0)25. PILA ENDS26.27. ;-----------------------------------------------------------------

-------------28. ;Definicion del segmento extra29. ;-----------------------------------------------------------------

-------------30. EXTRA SEGMENT31. RESULT DW 0,032. EXTRA ENDS33.34. ;-----------------------------------------------------------------

-------------35. ;Definicion del segmento de codigo36. ;-----------------------------------------------------------------

-------------37. CODE SEGMENT38. assume DS:datos, CS:code, SS:pila39.40. START:41. mov ax,PANTALLA

Page 29: Ejercicios Emu8086

42. mov ds,ax43.44. xor si,si45. mov ax,datos46. mov es,ax47. lea di,pantalla_bak ;Apuntar a la variable48.49. mov cx,80*25*2 ;Numero de bytes que tenemos que

copiar50. cld ;Direccion para incrementar DI y SI51.52. backup:53. movsb ;Mover el contenido de la direccion de

memoria apuntada54. ;por SI a la apuntada por DI, en este

caso la variable55. ;pantalla_bak56. loop backup57.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],ax65. inc bx66. inc bx67. loop llena68. 69. push ds ;70. push es ;71. pop ds ;72. pop es ;Intercambiar DS y ES73.74. xor di,di75. lea si,pantalla_bak76.77. xor ah,ah ;78. int 16h ;Esperar a que se pulse una tecla79.80. mov cx,4000 ;Los 4000 bytes de la pantalla81.82. restaura: ;83. movsb ;84. loop restaura ;Volver a dejar la pantalla como al

principio85.86. mov ax,4C00h87. int 21h88.89. CODE ENDS90. END START

91. Realizar un programa que devuelva la primera posición en que se ha encontrado un carácter dado:

92.

Page 30: Ejercicios Emu8086

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 datos101. ;-----------------------------------------------------------------

-------------102. DATOS SEGMENT103. mensaje db "www.victorsanchez2.net" 104. msg_caracter db "El caracter: "105. msg_posicion db "Se encuentra en la posicion: "106. DATOS ENDS107.108. ;-----------------------------------------------------------------

-------------109. ;Definicion del segmento de pila110. ;-----------------------------------------------------------------

-------------111. PILA SEGMENT STACK "STACK"112. db 40h DUP(0)113. PILA ENDS114.115. ;-----------------------------------------------------------------

-------------116. ;Definicion del segmento extra117. ;-----------------------------------------------------------------

-------------118. EXTRA SEGMENT119. RESULT DW 0,0120. EXTRA ENDS121.122. ;-----------------------------------------------------------------

-------------123. ;Definicion del segmento de codigo124. ;-----------------------------------------------------------------

-------------125. CODE SEGMENT126. assume cs:code,ds:datos,es:extra,ss:pila127.128. START PROC129. ;Inicializamos los registros de segmento130. mov ax,datos131. mov ds,ax132. mov ax,pila133. mov ss,ax134. mov ax,extra135. mov es,ax136.137. ;Limpiamos la pantalla

Page 31: Ejercicios Emu8086

138. mov ax,0B800h ;En esta direccion comienza la memoria de video

139. mov es,ax ;Lo cargamos en el segmento extra140. xor di,di ;Ponemos DI=0141. mov cx,80*25 ;80 lineas x 25 columnas142. xor al,al ;0=" " Rellenar la pantalla con blancos143. mov ah,0Fh ;Fondo negro, letras blancas144. rep stosw145.146. lea si,mensaje ;Cargar el mensaje donde buscaremos147. mov al,CARACTER ;Cargar el caracter a buscar148. mov cx,22 ;Longitud maxima para buscar (longitud de

'mensaje')149.150. call busca_fin ;Buscar la posicion en que se encuentra

el CARACTER151.152. mov ax,0B800h ;153. mov es,ax ;Colocarnos al inicio de la memoria de

video154. add cl,30h ;Preparar CL para mostrar el caracter por

pantalla155. push cx ;Guardarlo para recuperarlo despues156.157. mov di,(80*2)*2 ;Colocarnos en la segunda fila158. lea si,mensaje ;Colocar el offset de mensaje en si159. mov cx,22 ;Total de caracteres de mensaje160. call pinta ;Mostrarlo por pantalla161.162. mov di,(80*4)*2 ;Nos colocamos en la cuarta fila163. lea si,msg_caracter ;Cargar el offset164. mov cx,13 ;Total de caracteres de mensaje165. call pinta ;Mostrarlo por pantalla166.167. mov di,(80*4+13)*2 ;Colocarnos al final del

msg_caracter168. mov byte ptr es:[di],CARACTER ;Mostrar el CARACTER por

pantalla169.170. mov di,(80*5)*2 ;Ponernos en la quinta fila171. lea si,msg_posicion ;Cargar el offset172. mov cx,29 ;Total de caracteres de mensaje 173. call pinta ;Mostrarlo por pantalla174.175. mov di,(80*5+29)*2 ;Colocarnos al final del msg_posicion176. pop cx ;Recuperar la posicion en que se

encontraba CARACTER177. mov es:[di],cl178.179. mov ax,4C00h ;180. int 21h ;Terminar el programa181.182. START ENDP183.184. ;-----------------------------------------------------------------

-------------185. ; busca_fin

Page 32: Ejercicios Emu8086

186. ;187. ; in: AL contiene el caracter que debemos buscar188. ; SI contiene la cadena que debemos buscar189. ; out: En CX se guarda la posicion donde se ha encontrado el

caracter190. ; machaca: CX191. ; make: Devuelve en CX la primera posicion donde se ha encontrado

el caracter 192. ; dado en AL193. ;-----------------------------------------------------------------

-------------194.195. busca_fin proc near196.197. push di198. push dx199. push es200. push si201. push ax202.203. mov ax,ds ;204. mov es,ax ;205. mov di,si ;Copiar DS:SI en ES:DI206.207. mov dx,cx ;Copiar el limite en otro registro208. cld ;Direccion incremental209. pop ax ;Recuperar el caracter que nos han pedido210. push ax ;Guardarlo en la pila para no perderlo 211. repnz scasb ;Buscar el caracter pedido212. sub dx,cx ;Calcular la longitud213. mov cx,dx ;Guardar la longitud en CX214.215. pop ax216. pop si217. pop es218. pop dx219. pop di220. ret221.222. busca_fin endp223.224. ;-----------------------------------------------------------------

-------------225. ; pinta226. ;227. ; in: SI contiene el offset del mensaje a mostrar228. ; DI contiene la direccion donde se ira mostrando el mensaje229. ; CX contiene el numero de iteraciones a realizar230. ; out: 231. ; machaca: CX232. ; make: Muestra por pantalla el mensaje dado233. ;-----------------------------------------------------------------

-------------234. pinta proc near235.236. push ax237. push si

Page 33: Ejercicios Emu8086

238. push di239.240. mov ah,0Fh ;Fondo negro y letras blancas241. 242. pintar: ;243. mov al,[si] ;244. mov es:[di],ax ;245. inc si ;246. inc di ;247. inc di ;248. loop pintar ;Mostrarlo por pantalla249.250. pop di251. pop si252. pop ax 253. ret254.255. pinta endp256.257. CODE ENDS258. END START

259. Hacer un programa que muestre la sucesión de códigos ASCII en la esquina superior derecha de la pantalla, intercambiando los caracteres cada medio segundo. Este programa ya es algo más complejo que los anteriores ya que empezamos a trabajar con programas residentes y el RTC. Os recomiendo que aprendais bien las características de los programas residentes y programación del RTC antes de intentar comprender este ejercicio por completo. Este tipo de ejercicios van un nivel más 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 archivoC:\>tlink /t archivoC:\>archivo

;------------------------------------------------------------------------------;Programa que muestra la sucesion de codigos ASCII en la esquina superior ;derecha de la pantalla, intercambiando los caracteres cada medio segundo

Page 34: Ejercicios Emu8086

;------------------------------------------------------------------------------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 al,0Ch ; out 70h,al ; in al,71h ;Leer el RTC

mov ax,PANTALLA mov es,ax mov di,79*2 mov ax,es:[di] ;Guardamos en AX lo que hay en la esquina inc al ;Pasamos al siguiente caracter mov es:[di],ax ;Lo mostramos por pantalla

cli ;Inhabilitar las interrupciones mov al,20h out 20h,al out 0A0h,al sti ;Habilitar las interrupciones

pop di ; pop es ; pop ax ;Recuperar los registros

iretletras 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 al,0A1h ;Leer el PIC esclavo and al,11111110b ;

Page 35: Ejercicios Emu8086

out 0A1h,al ;Activamos IR0

in al,21h ;Leer el PIC maestro and al,11111011b ; out 21h,al ;Activado

mov al,0Ah ;Vamos a escribir en el registro A del RTC out 70h,al ; mov al,2Fh ;Los simbolos se intercambian cada medio segundo out 71h,al ;Lo indicamos en el registro A del RTC

mov al,0Bh ;Vamos a escribir en el registro B del RTC out 70h,al in al,71h or al,01000000b ; out 71h,al ;Activamos las interrupciones periodicas

sti ;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á mostrándose la sucesión de los caracteres ASCII mientras mantengamos encendido el ordenador. Después de ensamblar y ejecutar el programa con:

C:\>tasm /zi archivoC:\>tlink /v archivoC:\>archivo

Este programa no es .COM, por lo tanto usamos las banderas habituales. Después 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

Page 36: Ejercicios Emu8086

;------------------------------------------------------------------------------PILA SEGMENT STACK "STACK" DB 40h dup(0)PILA ENDS

;------------------------------------------------------------------------------;Definicion del segmento extra;------------------------------------------------------------------------------EXTRA SEGMENT RESULT DW 0,0EXTRA ENDS

;------------------------------------------------------------------------------;Definicion del segmento de codigo;------------------------------------------------------------------------------CODE SEGMENT ASSUME CS:CODE,SS:pila

START PROC FAR call desinstalar

mov ax,4C00h ; int 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 axpush espush ds

cli ;Inhabilitar las interrupciones

;Antes de proceder a desinstalarlo comprobamos si existe cmp word ptr es:[70h*4],0je FIN

Page 37: Ejercicios Emu8086

mov al,0Bh ;Registro B del PICout 70h,al ;and al,10111111b ;out 71h,al ;Deshabilitamos las interrupciones

periodicas (PIE)

in al,0A1h ;Leer el PIC esclavoOR al,00000001B ;out 0A1h,al ;desconectamos la interrupcion del RTC al

PIC esclavo

;Restaurar los vectores de interrupcionxor ax,axmov es,axmov ax,es:[70h*4+2] ;Copia en DS el segmento de codigo delmov ds,ax ;programa a desinstalarxor ax,axmov es:[70h*4],ax ;Poner el offset a 0mov es:[70h*4+2],ax ;Poner CS a 0

;Desinstalar el programa residentemov ax,ds:[2Ch] ;mov es,ax ;mov ah,49h ;int 21h ;Desinstalar el PSPmov ax,ds ;mov es,ax ;mov ah,49h ;int 21h ;Desinstalar CS

sti ;Habilitar las interrupciones

FIN: pop dspop espop ax

ret

desinstalar ENDP

CODE ENDS END START

6 Estos ejercicios van a ser algo más complejos y son del nivel que se va a exigir a aquellos que estén cursando la asignatura de ETCII en la Universidad Autónoma de Madrid.

1. Hallar cual es el valor de AX tras la segunda instrucción AAA: 2.3. ; Ejercicio: examen ETCII - 7/11/014.

Page 38: Ejercicios Emu8086

5. ;------------------------------------------------------------------------------

6. ;Definicion del segmento de codigo7. ;------------------------------------------------------------------

------------8.9. CODE SEGMENT10. assume CS:code11.12. start:13.14. mov ax,16h15. mov bx,191h16. add ax,bx17. aaa18. add ax,7h19. aaa20.21. mov ax,4c00h22. int 21h23.24. CODE ENDS25. END START

26. Hallar cual es el valor de AX tras la segunda instrucción AAA: 27.28. ; Ejercicio: examen ETCII - Febrero 200029.30. ;-----------------------------------------------------------------

-------------31. ;Definicion del segmento de codigo32. ;-----------------------------------------------------------------

-------------33.34. CODE SEGMENT35. assume CS:code36.37. start:38.39. mov ax,123h 40. mov bx,77h41. add ax,bx42. aaa 43. add ax,5h44. aaa 45.46. mov ax,4c00h47. int 21h48.49. CODE ENDS50. END START

51. Hallar el valor de AX tras la instrucción "div bl": 52.53. ;-----------------------------------------------------------------

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

Page 39: Ejercicios Emu8086

55. ;------------------------------------------------------------------------------

56. PILA SEGMENT STACK "STACK"57. db 40h DUP(0)58. PILA ENDS59.60. ;-----------------------------------------------------------------

-------------61. ;Definicion del segmento de codigo62. ;-----------------------------------------------------------------

-------------63. CODE SEGMENT64. assume cs:code,ss:pila65.66. START PROC67. ;Inicializamos los registros de segmento68. mov ax,pila69. mov ss,ax70.71. mov ax,905h72. mov bx,2h73. aad74. mov ah,10h75. div bl76.77. mov ax,4C00h ;78. int 21h ;Terminar el programa79.80. START ENDP81.82. CODE ENDS83. END START

84. Hallar el valor de AX tras la instrucción "aam": 85.86. ;-----------------------------------------------------------------

-------------87. ;Definicion del segmento de codigo88. ;-----------------------------------------------------------------

-------------89. CODE SEGMENT90. assume CS:code91.92. START:93.94. mov al,995. mov cl,596. mul cl97. aam98.99. mov ax,4c00h100. int 21h101.102. CODE ENDS103. END START

104. Hallar el valor de AX tras la instrucción "daa": 105.

Page 40: Ejercicios Emu8086

106. ;------------------------------------------------------------------------------

107. ;Definicion del segmento de pila108. ;-----------------------------------------------------------------

-------------109. PILA SEGMENT STACK "STACK"110. db 40h DUP(0)111. PILA ENDS112.113. ;-----------------------------------------------------------------

-------------114. ;Definicion del segmento de codigo115. ;-----------------------------------------------------------------

-------------116. CODE SEGMENT117. assume cs:code,ss:pila118.119. START PROC120.121. mov ax,23h122. mov bx,77h123. add ax,bx124. xor ah,ah125. daa126.127. mov ax,4C00h ;128. int 21h ;Terminar el programa129.130. START ENDP131.132. CODE ENDS133. END START

7 Las soluciones y archivos fuente de todos los ejercicios podéis obtenerlos escribiéndome un e-mail para pedírmelos.

1. Hallar el valor de AX tras la instrucción "mov ax,[bp+1]": 2.3. ;------------------------------------------------------------------

------------4. ;Definicion del segmento de pila5. ;------------------------------------------------------------------

------------6. PILA SEGMENT STACK "STACK"7. db 40h DUP(0)8. PILA ENDS9.10. ;-----------------------------------------------------------------

-------------11. ;Definicion del segmento de codigo12. ;-----------------------------------------------------------------

-------------13. CODE SEGMENT

Page 41: Ejercicios Emu8086

14. assume cs:code,ss:pila15.16. START PROC17. ;Inicializamos los registros de segmento18. mov ax,pila19. mov ss,ax20. 21. mov cx,37FFh22. xor bx,bx23. push cx24. push bx25. mov bp,sp26. mov ax,[bp+1]27.28. mov ax,4C00h ;29. int 21h ;Terminar el programa30.31. START ENDP32.33. CODE ENDS34. END START

35. Hallar el valor de AX tras la instrucción "mov ax,[bp+1]": 36.37. ;-----------------------------------------------------------------

-------------38. ;Definicion del segmento de pila39. ;-----------------------------------------------------------------

-------------40. PILA SEGMENT STACK "STACK"41. db 40h DUP(0)42. PILA ENDS43.44. ;-----------------------------------------------------------------

-------------45. ;Definicion del segmento de codigo46. ;-----------------------------------------------------------------

-------------47. CODE SEGMENT48. assume cs:code,ss:pila49.50. START PROC51. ;Inicializamos los registros de segmento52. mov ax,pila53. mov ss,ax54.55. mov ax,3759h56. xor bx,bx57. push ax58. push bx59. mov bp,sp60. mov ax,[bp+1]61.62. mov ax,4C00h ;63. int 21h ;Terminar el programa64.65. START ENDP66.

Page 42: Ejercicios Emu8086

67. CODE ENDS68. END START

69. Hallar el valor de AX tras la instrucción "stosb": 70.71. ;-----------------------------------------------------------------

-------------72. ;Definicion del segmento de pila73. ;-----------------------------------------------------------------

-------------74. PILA SEGMENT STACK "STACK"75. db 40h DUP(0)76. PILA ENDS77.78. ;-----------------------------------------------------------------

-------------79. ;Definicion del segmento extra80. ;-----------------------------------------------------------------

-------------81. EXTRA SEGMENT82. RESULT DW 0,083. EXTRA ENDS84.85. ;-----------------------------------------------------------------

-------------86. ;Definicion del segmento de codigo87. ;-----------------------------------------------------------------

-------------88. CODE SEGMENT89. assume CS:code,ES:extra,SS:pila90.91. ;-----------------------------------------------------------------

-------------92. ; Procedimiento inicial93. ;-----------------------------------------------------------------

-------------94. START PROC95.96. mov si,40h97. cld98. mov byte ptr ds:[si],0Fh99. xor cx,cx100. mov al,0F0h101. rep scasb102. std103. mov di,si104. mov bx,ds105. mov es,bx106. stosb107.108. mov ax,4C00h ;109. int 21h ;Terminar el programa110.111. START ENDP112.113. CODE ENDS114. END START

Page 43: Ejercicios Emu8086

115. Hallar el valor de AX tras la instrucción "rep lodsw": 116.117. ;-----------------------------------------------------------------

-------------118. ;Definicion del segmento de datos119. ;-----------------------------------------------------------------

-------------120. DATOS SEGMENT121. texto db "Cadena_de_texto"122. DATOS ENDS123.124. ;-----------------------------------------------------------------

-------------125. ;Definicion del segmento de pila126. ;-----------------------------------------------------------------

-------------127. PILA SEGMENT STACK "STACK"128. db 40h DUP(0)129. PILA ENDS130.131. ;-----------------------------------------------------------------

-------------132. ;Definicion del segmento de codigo133. ;-----------------------------------------------------------------

-------------134. CODE SEGMENT135. assume cs:code,ds:datos,ss:pila136.137. START PROC138. ;Inicializamos los registros de segmento139. mov ax,datos140. mov ds,ax141. mov ax,pila142. mov ss,ax143. 144. mov si,offset texto145. cld146. mov cx,5147. rep lodsw148.149. mov ax,4C00h ;150. int 21h ;Terminar el programa151.152. START ENDP153.154. CODE ENDS155. END START

156. Otro ejercicio como el anterior: 157.158. ;-----------------------------------------------------------------

-------------159. ;Definicion del segmento de datos160. ;-----------------------------------------------------------------

-------------161. DATOS SEGMENT162. texto db "Esto_es_una_cadena_de_texto",0

Page 44: Ejercicios Emu8086

163. DATOS ENDS164.165. ;-----------------------------------------------------------------

-------------166. ;Definicion del segmento de pila167. ;-----------------------------------------------------------------

-------------168. PILA SEGMENT STACK "STACK"169. db 40h DUP(0)170. PILA ENDS171.172. ;-----------------------------------------------------------------

-------------173. ;Definicion del segmento de codigo174. ;-----------------------------------------------------------------

-------------175. CODE SEGMENT176. assume cs:code,ds:datos,ss:pila177.178. START PROC179. ;Inicializamos los registros de segmento180. mov ax,datos181. mov ds,ax182. mov ax,pila183. mov ss,ax184. 185. mov si,offset texto186. add si,19h187. std188. mov cx,5189. rep lodsw190.191. mov ax,4C00h ;192. int 21h ;Terminar el programa193.194. START ENDP195.196. CODE ENDS197. END START

198. Y otro más. Las instrucciones de cadena son bastante potentes y como podreis ver es mejor saber manejarlas con soltura:

199.200. ;-----------------------------------------------------------------

-------------201. ;Definicion del segmento de datos202. ;-----------------------------------------------------------------

-------------203. DATOS SEGMENT204. texto db "Cadena_de_texto"205. DATOS ENDS206.207. ;-----------------------------------------------------------------

-------------208. ;Definicion del segmento de pila209. ;-----------------------------------------------------------------

-------------

Page 45: Ejercicios Emu8086

210. PILA SEGMENT STACK "STACK"211. db 40h DUP(0)212. PILA ENDS213.214. ;-----------------------------------------------------------------

-------------215. ;Definicion del segmento de codigo216. ;-----------------------------------------------------------------

-------------217. CODE SEGMENT218. assume cs:code,ds:datos,ss:pila219.220. START PROC221. ;Inicializamos los registros de segmento222. mov ax,datos223. mov ds,ax224. mov ax,pila225. mov ss,ax226. 227. mov si,offset texto228. add si,0Dh229. std230. mov cx,5231. rep lodsw232.233. mov ax,4C00h ;234. int 21h ;Terminar el programa235.236. START ENDP237.238. CODE ENDS239. END START

240. Hallar el valor de AX tras salir del bucle: 241.242. ;-----------------------------------------------------------------

-------------243. ;Definicion del segmento de pila244. ;-----------------------------------------------------------------

-------------245. PILA SEGMENT STACK "STACK"246. db 40h DUP(0)247. PILA ENDS248.249. ;-----------------------------------------------------------------

-------------250. ;Definicion del segmento de codigo251. ;-----------------------------------------------------------------

-------------252. CODE SEGMENT253. assume cs:code,ss:pila254.255. START PROC256. ;Inicializamos los registros de segmento257. mov ax,pila258. mov ss,ax259. 260. mov bx,10h

Page 46: Ejercicios Emu8086

261. xor ax,ax262. mov cx,0FFFFh263. L1: 264. add ax,bx265. loop L1266. 267. mov ax,4C00h ;268. int 21h ;Terminar el programa269.270. START ENDP271.272. CODE ENDS273. END START

8

1. El siguiente programa le pide al usuario la confirmación 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 pulse5. ;la tecla 'N' o 'n'6. ;------------------------------------------------------------------

------------7.8. cr equ 13 ;retorno de carro9. lf equ 10 ;alimentacion de linea10.11. ;-----------------------------------------------------------------

-------------12. ;Definicion del segmento de datos13. ;-----------------------------------------------------------------

-------------14. DATOS SEGMENT15. DeseaContinuar db cr,lf,'Desea continuar? S/N: '16. db'$'17. continuando db ' Continuando...',cr,lf18. db'$'19. LetraErronea db ' La tecla pulsada es incorrecta.',cr,lf20. db'$'21. DATOS ENDS22.23. ;-----------------------------------------------------------------

-------------24. ;Definicion del segmento de pila25. ;-----------------------------------------------------------------

-------------26. PILA SEGMENT STACK "STACK"27. db 40h dup(?)28. PILA ENDS29.

Page 47: Ejercicios Emu8086

30. ;------------------------------------------------------------------------------

31. ;Definicion del segmento de codigo32. ;-----------------------------------------------------------------

-------------33. CODE SEGMENT34. assume CS:code, DS:datos, SS:pila35.36. START: 37. mov ax,datos38. mov ds,ax39. jmp continuar ;Saltamos a la etiqueta

CONTINUAR40.41. INICIO:42. lea dx,continuando ;43. mov ah,9 ;44. int 21h ;Mensaje de que seguimos en el

programa45. jmp continuar ;Salto para preguntar si se

desea continuar46.47. ERROR:48. lea dx,LetraErronea ;49. mov ah,9 ;Mensaje de que la letra

introducida50. int 21h ;no es correcta51.52. CONTINUAR:53. lea dx,DeseaContinuar ;54. mov ah,9 ;55. int 21h ;Mostrar pregunta para ver si

desea continuar56. 57. mov ah,1 ;Esperar a que se pulse una tecla58. int 21h ;y mostrarla por pantalla59. 60. cmp al, 'S' ;61. je inicio ;62. cmp al, 's' ;63. je inicio ;Desea continuar64. 65. cmp al, 'N' ;66. je salir ;67. cmp al, 'n' ;68. je salir ;No desea continuar, terminamos69. 70. jmp error ;La tecla pulsada no es 'S', 's',

'N' ni 'n'71. ;Se va a mostrar un mensaje de

error. Saltamos72. ;a la etiqueta ERROR73. 74. salir: 75. mov ax, 4C00h76. int 21h77.

Page 48: Ejercicios Emu8086

78. CODE ENDS79. END START

80. Este programa cambia el color de fondo de una posición determinada de pantalla. Si se ejecuta varias veces seguidas veremos como cambia de blanco a negro y viceversa:

81.82. PANTALLA equ 0B800h83.84. ;-----------------------------------------------------------------

-------------85. ;Definicion del segmento de pila86. ;-----------------------------------------------------------------

-------------87. PILA SEGMENT STACK "STACK"88. db 40h dup(0)89. PILA ENDS90.91. ;-----------------------------------------------------------------

-------------92. ;Definicion del segmento de codigo93. ;-----------------------------------------------------------------

-------------94. CODE SEGMENT95. assume CS:code, SS:pila96.97. START:98. mov ax,PANTALLA99. mov ds,ax100. mov bx,(80*24+5)*2+1 ;Ultima linea, caracter 5 101. ;Utilizamos el '+1' para acceder102. ;directamente al fondo103.104. cmp byte ptr [bx],07h ;Vemos si el fondo es negro105. jz CambiaFondo106. 107. mov byte ptr [bx],07h ;Si no es negro lo ponemos108. jmp fin109.110. CambiaFondo:111. mov byte ptr [bx],70h ;Ponemos el fondo blanco112.113. fin:114. mov ax,4C00h115. int 21h116.117. CODE ENDS118. 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. PANTALLA equ 0b800h122. ROJO equ 4 123. LETRA_ROJA equ 'V'124. LETRA_AZUL equ 'S'125. AZUL equ 1

Page 49: Ejercicios Emu8086

126.127. ;-----------------------------------------------------------------

-------------128. ;Definicion del segmento de codigo129. ;-----------------------------------------------------------------

-------------130. CODE SEGMENT131. assume CS:code132. org 100h ;Dejar las 100h primeras posiciones para

el PSP133.134. START:135. jmp instalar ;Bifurcar a la rutina de instalacion136.137.138. ;-----------------------------------------------------------------

-------------139. ; letras140. ;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 far149.150. push ax ;151. push es ;152. push di ;Guardamos los registros en la pila153. 154. cli ;Inhabilitar las interrupciones155.156. mov al,0Ch ;157. out 70h,al ;158. in al,71h ;Leer el RTC159.160. mov ax,pantalla161. mov es,ax162. mov di,79*2 ;Esquina superior derecha163. mov ax,es:[di] ;Guardamos en AX lo que hay en la esquina164.165. cmp ah,AZUL ;Si era azul ahora debemos mostrar166. je muestra_v_rojo ;la 'V' de color rojo167.168. mov ah,AZUL169. mov al,LETRA_AZUL170. mov es:[di],ax ;Guardar en ES:[DI] que hemos puesto la

letra171. ;de color azul172. jmp fin ;Terminar el procedimiento173.174. muestra_v_rojo:175. mov ah,ROJO

Page 50: Ejercicios Emu8086

176. mov al,LETRA_ROJA177. mov es:[di],ax ;Guardar en ES:[DI] que hemos puesto la

letra178. ;de color rojo179.180. fin:181. mov al,20h ;182. out 20h,al ;183. out 0A0h,al ;EOI al maestro y al esclavo184.185. sti ;Habilitar las interrupciones186.187. pop di ;188. pop es ;189. pop ax ;Recuperar los registros190.191. iret192. letras endp193.194.195. ;-----------------------------------------------------------------

-------------196. ; instalar197. ;198. ; in:199. ; out:200. ; machaca: ax, dx, es201. ; make: Instala el programa dejandolo residente202. ;203. ;-----------------------------------------------------------------

-------------204. instalar proc205.206. cli ;Inhabilitar las interrupciones207.208. xor ax,ax ;209. mov es,ax ;Poner a 0 ES210. mov es:[70h*4],offset letras ;Guardar el offset211. mov es:[70h*4+2],cs ;y el segmento de la rutina212.213. in al,0A1h ;Leer el PIC esclavo214. and al,11111110b ;215. out 0A1h,al ;Activamos IR0216.217. in al,21h ;Leer el PIC maestro218. and al,11111011b ;219. out 21h,al ;Activado220.221. mov al,0Ah ;Vamos a escribir en el registro A del

RTC222. out 70h,al ;223. mov al,2Fh ;Los simbolos se intercambian cada medio

segundo224. out 71h,al ;Lo indicamos en el registro A del RTC225.226. mov al,0Bh ;Vamos a escribir en el registro B del

RTC

Page 51: Ejercicios Emu8086

227. out 70h,al ;228. in al,71h ;229. or al,01000000b ;230. out 71h,al ;Activamos las interrupciones periodicas231.232. sti ;Habilitar las interrupciones233.234. lea dx,instalar ;235. int 27h ;Dejar residente236.237. instalar endp238.239. CODE ENDS240. END START

241. El siguiente ejercicio de examen nos pide conocer la instrucción scasb. Hallar cuál es el valor de AX tras la instrucción NOP:

242.243. ;-----------------------------------------------------------------

-------------244. ;Definicion del segmento de datos245. ;-----------------------------------------------------------------

-------------246. DATOS SEGMENT247. Cadena1 db 50 dup(0)248. Cadena2 db 50 dup(?)249. DATOS ENDS250.251. ;-----------------------------------------------------------------

-------------252. ;Definicion del segmento de pila253. ;-----------------------------------------------------------------

-------------254. PILA SEGMENT STACK "STACK"255. db 40h DUP(0)256. PILA ENDS257.258. ;-----------------------------------------------------------------

-------------259. ;Definicion del segmento de codigo260. ;-----------------------------------------------------------------

-------------261. CODE SEGMENT262. assume cs:code,ds:datos,ss:pila263.264. START PROC265. ;Inicializamos los registros de segmento266. mov ax,datos267. mov ds,ax268. mov ax,pila269. mov ss,ax270.271. xor ax,ax272. mov cx,10h273. lea si,Cadena1274. lea di,Cadena2275. otro:

Page 52: Ejercicios Emu8086

276. push ds277. inc ax278. pop es279. scasb280. loop otro281. nop ;AX=10h, SI=0, DI=42h282.283. mov ax,4C00h ;284. int 21h ;Terminar el programa285.286. START ENDP287.288. CODE ENDS289. END START

290. Otro ejercicio como el anterior, pero usando la instrucción repne. Recordar que la instrucción LOOP primero decrementa y despues compara CX con 0, así que cuidado con este ejercicio:

291.292. ;-----------------------------------------------------------------

-------------293. ;Definicion del segmento de datos294. ;-----------------------------------------------------------------

-------------295. DATOS SEGMENT296. Cadena1 db 50 dup(0)297. Cadena2 db 50 dup(?)298. DATOS ENDS299.300. ;-----------------------------------------------------------------

-------------301. ;Definicion del segmento de pila302. ;-----------------------------------------------------------------

-------------303. PILA SEGMENT STACK "STACK"304. db 40h DUP(0)305. PILA ENDS306.307. ;-----------------------------------------------------------------

-------------308. ;Definicion del segmento de codigo309. ;-----------------------------------------------------------------

-------------310. CODE SEGMENT311. assume cs:code,ds:datos,ss:pila312.313. START PROC314. ;Inicializamos los registros de segmento315. mov ax,datos316. mov ds,ax317. mov ax,pila318. mov ss,ax319.320. xor ax,ax321. mov cx,10h322. lea si,Cadena1323. lea di,Cadena2

Page 53: Ejercicios Emu8086

324. otro:325. push ds326. inc ax327. pop es328. repne scasb329. loop otro330. nop331.332. mov ax,4C00h ;333. int 21h ;Terminar el programa334.335. START ENDP336.337. CODE ENDS338. END START

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/96343. ;-----------------------------------------------------------------

-------------344.345. ;-----------------------------------------------------------------

-------------346. ;Definicion del segmento de codigo347. ;-----------------------------------------------------------------

-------------348. CODE SEGMENT349. assume CS:code350.351. START:352.353. ;Inicializar354. mov byte ptr ds:[1000h],0355. mov byte ptr ds:[1001h],0356. mov byte ptr ds:[1002h],0357. mov byte ptr ds:[1003h],0358.359. mov si,1000h360. mov cx,4361. l1: 362. add [si],si363. inc si364. loop l1365.366. mov ax,4C00h367. int 21h368.369. CODE ENDS370. END START

371. Hallar el contenido de SI tras la ejecución de los bucles: 372.373. ;-----------------------------------------------------------------

-------------

Page 54: Ejercicios Emu8086

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

-------------376.377. ;-----------------------------------------------------------------

-------------378. ;Definicion del segmento de codigo379. ;-----------------------------------------------------------------

-------------380. CODE SEGMENT381. assume CS:code382.383. START:384.385. mov si,0386. mov cx,4387. L2: push cx388. mov cx,100h389. L1: dec cx390. inc si391. loop l1392. pop cx393. loop l2394. 395. mov ax,4C00h396. int 21h397.398. CODE ENDS399. END START

9

1. Otro problema de examen. Hallar el valor de AX tras la instrucción mov ax,word ptr ds:[3]

2.3. ;------------------------------------------------------------------

------------4. ;Definicion del segmento de datos5. ;------------------------------------------------------------------

------------6. DATOS SEGMENT7. dw 3Ah,7Bh,9Ch8. db 34h,76h,65h9. org 110. db 67h,31h,56h,"SE ACABO"11. DATOS ENDS12.13. ;-----------------------------------------------------------------

-------------14. ;Definicion del segmento de pila15. ;-----------------------------------------------------------------

-------------16. PILA SEGMENT STACK "STACK"17. db 40h DUP(0)

Page 55: Ejercicios Emu8086

18. PILA ENDS19.20. ;-----------------------------------------------------------------

-------------21. ;Definicion del segmento de codigo22. ;-----------------------------------------------------------------

-------------23. CODE SEGMENT24. assume cs:code,ds:datos,ss:pila25.26. START PROC27. ;Inicializamos los registros de segmento28. mov ax,datos29. mov ds,ax30. mov ax,pila31. mov ss,ax32.33. mov ax,word ptr ds:[3]34.35. mov ax,4C00h ;36. int 21h ;Terminar el programa37.38. START ENDP39.40. CODE ENDS41. END START

42. Muy similar al anterior: 43.44. ;-----------------------------------------------------------------

-------------45. ;Definicion del segmento de datos46. ;-----------------------------------------------------------------

-------------47. DATOS SEGMENT48. dw 3Ah,7Bh,9Ch49. db 34h,76h,65h50. org 251. db 67h,31h,56h,"SE ACABO"52. DATOS ENDS53.54. ;-----------------------------------------------------------------

-------------55. ;Definicion del segmento de pila56. ;-----------------------------------------------------------------

-------------57. PILA SEGMENT STACK "STACK"58. db 40h DUP(0)59. PILA ENDS60.61. ;-----------------------------------------------------------------

-------------62. ;Definicion del segmento de codigo63. ;-----------------------------------------------------------------

-------------64. CODE SEGMENT65. assume cs:code,ds:datos,ss:pila66.

Page 56: Ejercicios Emu8086

67. START PROC68. ;Inicializamos los registros de segmento69. mov ax,datos70. mov ds,ax71. mov ax,pila72. mov ss,ax73.74. mov ax,word ptr ds:[3]75.76. mov ax,4C00h ;77. int 21h ;Terminar el programa78.79. START ENDP80.81. CODE ENDS82. END START

83. ¿Cuál es el valor de AX tras la instrucción NOP?: 84.85. ; Ejercicio: examen ETCII - febrero 200286.87. ;-----------------------------------------------------------------

-------------88. ;Definicion del segmento de pila89. ;-----------------------------------------------------------------

-------------90. PILA SEGMENT STACK "STACK"91. db 40h DUP(0)92. PILA ENDS93.94. ;-----------------------------------------------------------------

-------------95. ;Definicion del segmento extra96. ;-----------------------------------------------------------------

-------------97. EXTRA SEGMENT98. RESULT DW 0,099. EXTRA ENDS100.101. ;-----------------------------------------------------------------

-------------102. ;Definicion del segmento de codigo103. ;-----------------------------------------------------------------

-------------104. CODE SEGMENT105. assume CS:code,ES:extra,SS:pila106.107. ;-----------------------------------------------------------------

-------------108. ; Procedimiento inicial109. ;-----------------------------------------------------------------

-------------110. START PROC111.112. mov ax,1Fh113. push ax114. inc sp115. push ax

Page 57: Ejercicios Emu8086

116. dec sp117. pop ax118. pop ax119. nop120.121. mov ax,4C00h ;122. int 21h ;Terminar el programa123.124. START ENDP125.126. CODE ENDS127. END START

128. Muy importantes también son los ejercicios de pila. Hallar el valor de AX tras la instrucción NOP:

129.130. ;-----------------------------------------------------------------

-------------131. ;Definicion del segmento de pila132. ;-----------------------------------------------------------------

-------------133. PILA SEGMENT STACK "STACK"134. db 40h DUP(0)135. PILA ENDS136.137. ;-----------------------------------------------------------------

-------------138. ;Definicion del segmento de codigo139. ;-----------------------------------------------------------------

-------------140. CODE SEGMENT141. assume cs:code,ss:pila142.143. START PROC144. ;Inicializamos los registros de segmento145. mov ax,pila146. mov ss,ax147.148. mov al,5149. mov bx,0FA45h150. push bx151. push ax152. mov bp,sp153. mov al,[bp+3]154. nop155.156. mov ax,4C00h ;157. int 21h ;Terminar el programa158.159. START ENDP160.161. CODE ENDS162. END START

163. Estos ejercicios de pilas suelen tener truco la mayoría de las veces ;) Hallar el valor de AX tras el último POP:

164.

Page 58: Ejercicios Emu8086

165. ;------------------------------------------------------------------------------

166. ;Definicion del segmento de pila167. ;-----------------------------------------------------------------

-------------168. PILA SEGMENT STACK "STACK"169. db 40h DUP(0)170. PILA ENDS171.172. ;-----------------------------------------------------------------

-------------173. ;Definicion del segmento de codigo174. ;-----------------------------------------------------------------

-------------175. CODE SEGMENT176. assume cs:code,ss:pila177.178. START PROC179. ;Inicializamos los registros de segmento180. mov ax,pila181. mov ss,ax182.183. push 0F34h184. push 63h185. pop ax186. inc sp187. pop ax188.189. mov ax,4C00h ;190. int 21h ;Terminar el programa191.192. START ENDP193.194. CODE ENDS195. END START

10

1. Hallar el valor de AX tras la instrucción div bl: 2.3. ;------------------------------------------------------------------

------------4. ;Definicion del segmento de codigo5. ;------------------------------------------------------------------

------------6. CODE SEGMENT7. assume cs:code8.9. START PROC10.11. mov ah,112. mov al,0D7h13. xor bx,bx14. stc

Page 59: Ejercicios Emu8086

15. rcr bx,116. rcr bx,117. div bl 18.19. mov ax,4C00h ;20. int 21h ;Terminar el programa21.22. START ENDP23.24. CODE ENDS25. END START

26. De nuevo un ejercicio sencillito para dejar a un lado los exámenes (por el momento) y relajarnos un poco y ver otra forma de inicializar variables. Este programa muestra dos líneas, una llena de '5' y otra de '@':

27.28. ;-----------------------------------------------------------------

-------------29. ;Definicion del segmento de datos30. ;-----------------------------------------------------------------

-------------31. DATOS SEGMENT32. Cadena1 db 80 dup("5"),"$"33. Cadena2 db 80 dup("@"),"$"34. DATOS ENDS35.36. ;-----------------------------------------------------------------

-------------37. ;Definicion del segmento de pila38. ;-----------------------------------------------------------------

-------------39. PILA SEGMENT STACK "STACK"40. db 40h DUP(0)41. PILA ENDS42.43. ;-----------------------------------------------------------------

-------------44. ;Definicion del segmento de codigo45. ;-----------------------------------------------------------------

-------------46. CODE SEGMENT47. assume cs:code,ds:datos,ss:pila48.49. START PROC50. ;Inicializamos los registros de segmento51. mov ax,datos52. mov ds,ax53. mov ax,pila54. mov ss,ax55.56. mov dx,offset Cadena157. mov ah,958. int 21h59.60. mov dx,offset Cadena261. mov ah,962. int 21h

Page 60: Ejercicios Emu8086

63.64. mov ax,4C00h ;65. int 21h ;Terminar el programa66.67. START ENDP68.69. CODE ENDS70. END START

71. Volvemos con más instrucciones de cadena y otro ejercicio de examen. Hallar el valor de CX tras la instrucción repnz scasb:

72.73. ;-----------------------------------------------------------------

-------------74. ;Definicion del segmento de datos75. ;-----------------------------------------------------------------

-------------76. DATOS SEGMENT77. texto db "Esto es un texto",0,"Y este otro",078. DATOS ENDS79.80. ;-----------------------------------------------------------------

-------------81. ;Definicion del segmento de pila82. ;-----------------------------------------------------------------

-------------83. PILA SEGMENT STACK "STACK"84. db 40h DUP(0)85. PILA ENDS86.87. ;-----------------------------------------------------------------

-------------88. ;Definicion del segmento de codigo89. ;-----------------------------------------------------------------

-------------90. CODE SEGMENT91. assume cs:code,ds:datos,ss:pila92.93. START PROC94. ;Inicializamos los registros de segmento95. mov ax,datos96. mov ds,ax97. mov ax,pila98. mov ss,ax99. 100. push ds101. pop es102. cld103. mov ax,4C00h104. lea di,texto105. mov cx,14h106. repnz scasb107.108. mov ax,4C00h ;109. int 21h ;Terminar el programa110.111.START ENDP

Page 61: Ejercicios Emu8086

112.113.CODE ENDS114. 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 ax,4C00h ; int 21h ;Terminar el programa

START ENDP

CODE ENDS END START

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

Page 62: Ejercicios Emu8086

;------------------------------------------------------------------------------;Definicion del segmento de datos;------------------------------------------------------------------------------DATOS SEGMENT db 10,'A',32,45h,10001101b,16 tabla dw 15,'Dk','27',4F5hDATOS 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 si,si mov ax,[si] sub ax,[si] mov al,byte ptr tabla[si]

mov ax,4C00h ; int 21h ;Terminar el programa

START ENDP

CODE ENDS END START

Instrucción JMP

Propósito: Salto incondicional

Page 63: Ejercicios Emu8086

Sintaxis:

JMP destino

Esta instrucción se utiliza para desviar el flujo de un programa sin tomar en cuenta las condiciones actuales de las banderas ni de los datos.

Instrucción JA (JNBE)

Propósito: Brinco condicional

Sintaxis:

JA Etiqueta

Después de una comparación 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).

Instrucción JAE (JNB)

Propósito: 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.

Instrucción JB (JNAE)

Propósito: salto condicional

Sintaxis:

JB etiqueta

Salta si está abajo o salta si no está arriba o si no es igual.

Page 64: Ejercicios Emu8086

Se efectúa el salto si CF esta activada.

Instrucción JBE (JNA)

Propósito: salto condicional

Sintaxis:

JBE etiqueta

Salta si está abajo o si es igual o salta si no está arriba.

El salto se efectúa si CF está activado o si ZF está activado (que cualquiera sea igual a 1).

Instrucción JE (JZ)

Propósito: salto condicional

Sintaxis:

JE etiqueta

Salta si es igual o salta si es cero.

El salto se realiza si ZF está activada.

Instrucción JNE (JNZ)

Propósito: salto condicional

Sintaxis:

JNE etiqueta

Salta si no es igual o salta si no es cero.

El salto se efectua si ZF está desactivada.

Instrucción JG (JNLE)

Propósito: salto condicional, se toma en cuenta el signo.

Page 65: Ejercicios Emu8086

Sintaxis:

JG etiqueta

Salta si es más grande o salta si no es menor o igual.

El salto ocurre si ZF = 0 u OF = SF.

Instrucción JGE (JNL)

Propósito: salto condicional, se toma en cuenta el signo.

Sintaxis:

JGE etiqueta

Salta si es más grande o igual o salta si no es menor que.

El salto se realiza si SF = OF

Instrucción JL (JNGE)

Propósito: 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 efectúa si SF es diferente a OF.

Instrucción JLE (JNG)

Propósito: salto condicional, se toma en cuenta el signo.

Sintaxis:

JLE etiqueta

Salta si es menor o igual o salta si no es más grande.

El salto se realiza si ZF = 1 o si SF es diferente a OF

Page 66: Ejercicios Emu8086

Instrucción JC

Propósito: salto condicional, se toman en cuenta las banderas.

Sintaxis:

JC etiqueta

Salta si hay acarreo.

El salto se realiza si CF = 1

Instrucción JNC

Propósito: salto condicional, se toma en cuenta el estado de las banderas.

Sintaxis:

JNC etiqueta

Salta si no hay acarreo.

El salto se efectúa si CF = 0.

Instrucción JNO

Propósito: 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.

Instrucción JNP (JPO)

Propósito: salto condicional, toma en cuenta el estado de las banderas.

Sintaxis:

JNP etiqueta

Page 67: Ejercicios Emu8086

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

El salto ocurre si PF = 0.

Instrucción JNS

Propósito: salto condicional, toma en cuenta el estado de las banderas.

Sintaxis:

JNP etiqueta

Salta si el signo esta desactivado.

El salto se efectúa si SF = 0.

Instrucción JO

Propósito: 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.

Instrucción JP (JPE)

Propósito: 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 efectúa si PF = 1.

Instrucción JS

Propósito: salto condicional, toma en cuenta el estado de las banderas.

Page 68: Ejercicios Emu8086

Sintaxis:

JS etiqueta

Salta si el signo está prendido.

El salto se efectúa si SF = 1.

Instrucción LOOP

Propósito: Generar un ciclo en el programa.

Sintaxis:

LOOP etiqueta

La instrucción loop decrementa CX en 1, y transfiere el flujo del programa a la etiqueta dada como operando si CX es diferente a 1.

Instrucción LOOPE

Propósito: Generar un ciclo en el programa considerando el estado de ZF

Sintaxis:

LOOPE etiqueta

Esta instrucción 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.

Instrucción LOOPNE

Propósito: Generar un ciclo en el programa, considerando el estado de ZF

Sintaxis:

LOOPNE etiqueta

Esta instrucción decrementa en uno a CX y transfiere el flujo del programa solo si ZF es diferente a 0.

Instrucción DEC

Page 69: Ejercicios Emu8086

Propósito: Decrementar el operando

Sintaxis:

DEC destino

Esta operación resta 1 al operando destino y almacena el nuevo valor en el mismo oeprando.

Instrucción INC

Propósito: Incrementar el operando.

Sintaxis:

INC destino

La instrucción suma 1 al operando destino y guarda el resultado en el mismo operando destino.

Instrucción CMP

Propósito: Comparar los operandos.

Sintaxis:

CMP destino, fuente

Esta instrucción resta el operando fuente al operando destino pero sin que éste almacene el resultado de la operación, solo se afecta el estado de las banderas.

Instrucción CMPS (CMPSB) (CMPSW)

Propósito: Comparar cadenas de un byte o palabra.

Sintaxis:

CMP destino, fuente

Con esta instrucción 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.

Page 70: Ejercicios Emu8086

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

Instrucción CLC

Propósito: Limpiar bandera de acarreo.

Sintaxis:

CLC

Esta instrucción apaga el bit correspondiente a la bandera de acarreo, o sea, lo pone en cero.

Instrucción CLD

Propósito: Limpiar bandera de dirección

Sintaxis:

CLD

La instrucción CLD pone en cero el bit correspondiente a la bandera de dirección.

Instrucción CLI

Propósito: Limpiar bandera de interrupción

Sintaxis:

CLI

CLI pone en cero la bandera de interrupciones, desabilitando así aquellas interrupciones enmascarables.

Una interrupción enmascarable es aquella cuyas funciones son desactivadas cuando IF = 0.

Instrucción CMC

Propósito: Complementar la bandera de acarreo.

Sintaxis:

Page 71: Ejercicios Emu8086

CMC

Esta instrucción complementa el estado de la bandera CF, si CF = 0 la instrucción la iguala a 1, y si es 1 la instrucción la iguala a 0.

Podemos decir que unicamente "invierte" el valor de la bandera.

Instrucción STC

Propósito: Activar la bandera de acarreo.

Sintaxis:

STC

Esta instrucción pone la bandera CF en 1.

Instrucción STD

Propósito: Activar la bandera de dirección.

Sintaxis:

STD

La instrucción STD pone la bandera DF en 1.

Instrucción STI

Propósito: Acticar la bandera de interrupción.

Sintaxis:

STI

La instrucción activa la bandera IF, esto habilita las interrupciones externas enmascarables (las que funcionan unicamente cuando IF = 1 ).

Page 72: Ejercicios Emu8086

Ejercicio 1: Escribir un código que verifique si dos cadenas son iguales

org 100hcomienzo: mov si, xmov al, msg2[si]cmp msg[si], al ;comparar letra por letra las cadenas, si uno no coincide manda directamente a fin y termina el programajne fin:cmp msg[si], "$" ;si es el final y el programa llega aca, quiere decir que son igualesjz final:inc xloop comienzofinal:mov dx, offset msg3 mov ah, 9int 21hfin:retmsg db "hello world $" msg2 db "hello world $" msg3 db "Son iguales $"x dw 0

Ejercicio 2: Escribir un código 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 100hmov si, 0 ;ponemos si en 0comienzo: mov al, msg2[0] ;copiar la primera letra de la palabra a alcmp msg[si],"$" ;si es el fin de la cadena mandar a finaljz finalcmp msg[si], al ;comparar si encuentra la primera letra de la cadenajne 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

Page 73: Ejercicios Emu8086

seguir: inc si ;para seguir recorriendo la palabraloop comienzo ;bucle principal para recorrer palabraresultado:mov dx, offset msg3 ;copiar msg3 a dxmov ah, 9 ;preparar ah con 9 para la interrupcion 21hint 21h ;mostrar contenido en dxfinal:retmsg db "Hola Mundo$" msg2 db "ola$" msg3 db "Si es subcadena$"

Ejercicio 3: Escribir un código 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 100hmov si, 0 ;ponemos si en 0comienzo:cmp msg[si],"$" ;si es el fin de la cadena mandar a finaljz 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 cadenacmp 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 palabraloop comienzo ;bucle principal para recorrer palabraresultado:mov dx, offset msg3 ;copiar msg3 a dxmov ah, 9 ;preparar ah con 9 para la interrupcion 21hint 21h ;mostrar contenido en dxfinal:retmsg db "cerro$" msg2 db "recanate$" msg3 db "Si se encuentran todos los caracteres$"

Page 74: Ejercicios Emu8086

Ejercicio 4: Escribir una programa que reciba una cadena ingresada por teclado, terminada en ENTER. Luego que elimine todos los caracteres que no son dígitos, sin utilizar una variable auxiliar.

ORG 100Hmov si, 0lectura: 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 fin3cmp al,47 ;si tecla no es mayor a 47 ir a fin3 (tecla <= 47) jng fin3mov 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 10hmov bx[si], "$" mov dx, offset bxmov ah, 9 ;preparar ah con 9 para la interrupcion 21hint 21h ;mostrar contenido en dxret

Ejercicio 5: Escribir un programa que tome una cadena que representa un número decimal y escriba su equivalente octal

org 100h ; inicio de programamov si, 0mov al, 0

cadAnum:cmp cad[si], "$" jz seguir

mov bl, 10 mul blsub cad[si], '0' add al, cad[si]

inc siloop cadAnum

seguir:

Page 75: Ejercicios Emu8086

mov cx, si mov si, 0mov bl, 8pasar: 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 pasarfina:cmp ah, 0jnz finalmov oct[si], alfinal:;mov dx, offset res;mov ah, 9 ;preparar ah con 9 para la interrupcion 21h;int 21h ;mostrar contenido en dxretcad db "64$"oct db 0

Ejercicio 6: Escribir un programa que tome tres cadenas, la primera y la tercera representan un número y la segunda una operación, por ejemplo: “329″, “-”, “21″ e imprima el resultado “308″

org 100h ; inicio de programainclude 'emu8086.inc' ;Incluye funciones de libreria emu8086 ; DEFINE_SCAN_NUM; DEFINE_PRINT_STRING DEFINE_PRINT_NUM DEFINE_PRINT_NUM_UNSmov si, 0mov al, 0;Convertir primera cadena a numero cadAnum:cmp cad1[si], "$" jz seguir

mov bl, 10 mul blsub cad1[si], '0' add al, cad1[si]

inc siloop cadAnum

seguir:mov aux1, al;Convertir segunda cadena a numeromov si, 0mov al, 0cadAnum2:cmp cad3[si], "$" jz seguir2

mov bl, 10

Page 76: Ejercicios Emu8086

mul blsub cad3[si], '0' add al, cad3[si]

inc siloop cadAnum2

seguir2:mov bl, al mov al, aux1;realizar operaciones normalmente teniendo ya los dos numeros decimalescmp cad2, "-"jz resta cmp cad2, "+"jz suma cmp cad2, "*"jz multi cmp cad2, "/"jz diviresta: sub al, bljmp finsuma: add al, bljmp finmulti: mul bljmp findivi: div bljmp fin

fin:mov bx, axmov ah,09 lea dx,msgint 21h mov ax, bxcall PRINT_NUMretcad1 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 msgmov ah, 9int 21h

Page 77: Ejercicios Emu8086

;============================; 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, 0int 16h; print the key:mov ah, 0ehint 10h; press 'esc' to exit:cmp al, 1bhjz exitjmp wait_for_key;============================exit:retmsg 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 1end

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

name "arreglo-mayor"org 100hmov cx, 8 bucle1: mov c, cx

mov bx, cx mov cx, 9

bucle2:

Page 78: Ejercicios Emu8086

mov si, cx mov ah, v[si-1] cmp ah,v[bx-1] jnge seguir ;Si v[8] < v[7] no hacer nada, sino: mov dh, v[bx-1] ;Copiar v[7] en dh mov dl, v[si-1] ;Copiar v[8] en dl mov v[bx-1], dl ;Copiar dl en v[7] mov v[si-1], dh ;Copiar dh en v[8] seguir: loop bucle2

mov cx, c loop bucle1retv db 2,32,64,32,98,12,5,21,91c 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 1bucle: 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 bucle1parte2: ;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

Page 79: Ejercicios Emu8086

cont db 0 ;cont = contador MCM db 0 ;en esta variable se guarda el MCMMCD db 0 ;en esta variable se guarda el MCDnro1 db 48 ;numero1 decimalnro2 db 60 ;numero2 decimal

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

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

bucle1: mov dx, cx mov al, color ;AL = pixel color mov ah, 0ch ;Change color for a single pixel int 10h ;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 = columnfin:retcolor 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

Page 80: Ejercicios Emu8086

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