Professional Documents
Culture Documents
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
pantalla
4.
5. ;------------------------------------------------------------------
------------
6. ;Definición del segmento de codigo
7. ;------------------------------------------------------------------
------------
8. CODE SEGMENT
9. assume cs:code
10.
11. START PROC
12. mov ax,pantalla ;Cargar la dirección de la
coordenada 0,0 de la
13. mov ds,ax ;pantalla
14. xor bx,bx ;Ponemos bx a 0
15.
16. pinta_caracter:
17. mov ds:[bx],byte ptr "V" ;Escribir el carácter en
su coordenada
18. inc bx ;En lugar de sumar 2, se
incrementa 2 veces porque
19. ;consume menos ciclos de
reloj del procesador
20. inc bx ;Cada posicion de la
pantalla son 2 bytes,
21. cmp bx,2000*2 ;por eso bx va a llegar
hasta 4000
22. jl pinta_caracter ;Si bx<4000 volvemos a
pintar otro carácter
23.
24. mov ax,4C00h ;
25. int 21h ;Terminar el programa
26.
27. START ENDP
28.
29. CODE ENDS
30. END START
31. Hacer un programa que coja el 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 0B800h
34.
35. ;-----------------------------------------------------------------
-------------
36. ;Definición del segmento de codigo
37. ;-----------------------------------------------------------------
-------------
38. CODE SEGMENT
39. assume cs:code
40.
41. START PROC
42. mov ax,pantalla ;Cargar la dirección de la
coordenada 0,0 de la
43. mov ds,ax ;pantalla
44. xor bx,bx
45. mov dx,ds:[bx] ;Obtener el carácter de la
coordenada 0,0
46.
47. pinta_caracter:
48. inc bx
49. inc bx
50. mov ds:[bx],dx ;Copiar el carácter
obtenido por toda la pantalla
51. cmp bx,1995*2 ;Dejamos los ultimos 4
caracteres sin rellenar
52. jl pinta_caracter
53.
54. mov ds:[1996*2],byte ptr "E" ;En los ultimos 4
caracteres escribimos
55. mov ds:[1997*2],byte ptr "T" ;nuestro mensaje
56. mov ds:[1998*2],byte ptr "S" ;
57. mov ds:[1999*2],byte ptr "I" ;
58.
59. mov ax,4C00h ;
60. int 21h ;Terminar el programa
61.
62. START ENDP
63.
64. CODE ENDS
65. END START
66. Nos vemos en la necesidad ya de empezar a manejar el Turbo Debugger. No
todos los programas que hagamos tienen por qué mostrar algo por la pantalla.
Veremos ahora un programa que realiza la suma de los 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
principio puede parecernos un poco raro y no saber muy bien a que equivale,
pero poco a poco iremos aprendiendo a pensar en hexadecimal y binario :D.
Antes de nada les voy a mostrar los archivos .bat que he venido utilizando
durante mi aprendizaje del ensamblador: - Para debuggear un programa puede
utilizarse únicamente el programa deb.bat:
67.
68. :-----------------------------------------------------------------
------
69. :
70. : Fichero: deb.bat
71. :
72. : Descripcion:
73. : Ensamblar modulo fuente principal de un programa, crear modulo
74. : objeto y debuggearlo.
75. :
76. :-----------------------------------------------------------------
------
77. :
78. echo off
79. if z%1 == z goto error
80. goto check
81. :error
82. echo *** error: falta nombre del modulo fuente ***
83. goto fin
84. :check
85. if exist %1.asm goto ensam
86. echo *** error: fichero %1.asm no existe ***
87. goto fin
88. :ensam
89. tasm /zi %1;
90. if exist %1.obj goto mensa
91. echo *** error en programa fuente ***
92. goto fin
93. :mensa
94. tlink /v %1
95. echo ... creado fichero %1.obj
96.
97. td %1
98.
99. :fin
;------------------------------------------------------------------
------------
;Definición del segmento de codigo
;------------------------------------------------------------------
------------
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
100. Realizar un programa que limpie la pantalla dejando el fondo azul y los
caracteres rojos:
101.
102. pantalla EQU 0B800h
103.
104. ;-----------------------------------------------------------------
-------------
105. ;Definición del segmento de pila
106. ;-----------------------------------------------------------------
-------------
107. PILA SEGMENT STACK "STACK"
108. db 40h dup(0)
109. PILA ENDS
110.
111. ;-----------------------------------------------------------------
-------------
112. ;Definición del segmento extra
113. ;-----------------------------------------------------------------
-------------
114. EXTRA SEGMENT
115. result dw 0,0
116. EXTRA ENDS
117.
118. ;-----------------------------------------------------------------
-------------
119. ;Definición del segmento de codigo
120. ;-----------------------------------------------------------------
-------------
121. CODE SEGMENT
122. assume cs:code,es:extra,ss:pila
123.
124. START PROC
125.
126. cld ;DF=0 (incrementar DI)
127. mov ax,pantalla
128. mov es,ax
129. xor di,di
130. mov ax,1C00h ;Fondo azul, caracteres rojos con
intensidad
131. ;Equivalente a: mov
ax,0001110000000000b
132. mov cx,2000
133. rep stosw ;Repetirlo las 2000 veces
134.
135. mov ax,4C00h ;
136. int 21h ;Terminar el programa
137.
138. START ENDP
139.
140. CODE ENDS
141. 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:
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
4
Vamos 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.
5
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, despues
5. ;rellena toda la pantalla con '*' y por ultimo vuelve a dejar la
pantalla como
6. ;estaba
7. ;------------------------------------------------------------------
------------
8.
9. PANTALLA equ 0B800h
10.
11. ;-----------------------------------------------------------------
-------------
12. ;Definicion del segmento de datos
13. ;-----------------------------------------------------------------
-------------
14. DATOS SEGMENT
15.
16. pantalla_bak db 80*25*2 DUP(?) ;Reservar una variable para
guardar toda la
17. ;informacion de la pantalla
18. DATOS ENDS
19.
20. ;-----------------------------------------------------------------
-------------
21. ;Definicion del segmento de pila
22. ;-----------------------------------------------------------------
-------------
23. PILA SEGMENT STACK "STACK"
24. db 40h dup(0)
25. PILA ENDS
26.
27. ;-----------------------------------------------------------------
-------------
28. ;Definicion del segmento extra
29. ;-----------------------------------------------------------------
-------------
30. EXTRA SEGMENT
31. RESULT DW 0,0
32. EXTRA ENDS
33.
34. ;-----------------------------------------------------------------
-------------
35. ;Definicion del segmento de codigo
36. ;-----------------------------------------------------------------
-------------
37. CODE SEGMENT
38. assume DS:datos, CS:code, SS:pila
39.
40. START:
41. mov ax,PANTALLA
42. mov ds,ax
43.
44. xor si,si
45. mov ax,datos
46. mov es,ax
47. lea di,pantalla_bak ;Apuntar a la variable
48.
49. mov cx,80*25*2 ;Numero de bytes que tenemos que
copiar
50. cld ;Direccion para incrementar DI y SI
51.
52. backup:
53. movsb ;Mover el contenido de la direccion de
memoria apuntada
54. ;por SI a la apuntada por DI, en este
caso la variable
55. ;pantalla_bak
56. loop backup
57.
58. mov cx,80*25 ;
59. xor bx,bx ;
60. mov al,'*' ;
61. mov ah,70h ;Llenar la pantalla de '*'
62.
63. llena:
64. mov [bx],ax
65. inc bx
66. inc bx
67. loop llena
68.
69. push ds ;
70. push es ;
71. pop ds ;
72. pop es ;Intercambiar DS y ES
73.
74. xor di,di
75. lea si,pantalla_bak
76.
77. xor ah,ah ;
78. int 16h ;Esperar a que se pulse una tecla
79.
80. mov cx,4000 ;Los 4000 bytes de la pantalla
81.
82. restaura: ;
83. movsb ;
84. loop restaura ;Volver a dejar la pantalla como al
principio
85.
86. mov ax,4C00h
87. int 21h
88.
89. CODE ENDS
90. END START
91. Realizar un programa que devuelva la primera posición en que se ha
encontrado un carácter dado:
92.
93. ;-----------------------------------------------------------------
-------------
94. ;Devuelve la primera posicion en que se ha encontrado el caracter
a buscar
95. ;-----------------------------------------------------------------
-------------
96.
97. CARACTER equ 'v'
98.
99. ;-----------------------------------------------------------------
-------------
100. ;Definicion del segmento de datos
101. ;-----------------------------------------------------------------
-------------
102. DATOS SEGMENT
103. mensaje db "www.victorsanchez2.net"
104. msg_caracter db "El caracter: "
105. msg_posicion db "Se encuentra en la posicion: "
106. DATOS ENDS
107.
108. ;-----------------------------------------------------------------
-------------
109. ;Definicion del segmento de pila
110. ;-----------------------------------------------------------------
-------------
111. PILA SEGMENT STACK "STACK"
112. db 40h DUP(0)
113. PILA ENDS
114.
115. ;-----------------------------------------------------------------
-------------
116. ;Definicion del segmento extra
117. ;-----------------------------------------------------------------
-------------
118. EXTRA SEGMENT
119. RESULT DW 0,0
120. EXTRA ENDS
121.
122. ;-----------------------------------------------------------------
-------------
123. ;Definicion del segmento de codigo
124. ;-----------------------------------------------------------------
-------------
125. CODE SEGMENT
126. assume cs:code,ds:datos,es:extra,ss:pila
127.
128. START PROC
129. ;Inicializamos los registros de segmento
130. mov ax,datos
131. mov ds,ax
132. mov ax,pila
133. mov ss,ax
134. mov ax,extra
135. mov es,ax
136.
137. ;Limpiamos la pantalla
138. mov ax,0B800h ;En esta direccion comienza la memoria de
video
139. mov es,ax ;Lo cargamos en el segmento extra
140. xor di,di ;Ponemos DI=0
141. mov cx,80*25 ;80 lineas x 25 columnas
142. xor al,al ;0=" " Rellenar la pantalla con blancos
143. mov ah,0Fh ;Fondo negro, letras blancas
144. rep stosw
145.
146. lea si,mensaje ;Cargar el mensaje donde buscaremos
147. mov al,CARACTER ;Cargar el caracter a buscar
148. mov cx,22 ;Longitud maxima para buscar (longitud de
'mensaje')
149.
150. call busca_fin ;Buscar la posicion en que se encuentra
el CARACTER
151.
152. mov ax,0B800h ;
153. mov es,ax ;Colocarnos al inicio de la memoria de
video
154. add cl,30h ;Preparar CL para mostrar el caracter por
pantalla
155. push cx ;Guardarlo para recuperarlo despues
156.
157. mov di,(80*2)*2 ;Colocarnos en la segunda fila
158. lea si,mensaje ;Colocar el offset de mensaje en si
159. mov cx,22 ;Total de caracteres de mensaje
160. call pinta ;Mostrarlo por pantalla
161.
162. mov di,(80*4)*2 ;Nos colocamos en la cuarta fila
163. lea si,msg_caracter ;Cargar el offset
164. mov cx,13 ;Total de caracteres de mensaje
165. call pinta ;Mostrarlo por pantalla
166.
167. mov di,(80*4+13)*2 ;Colocarnos al final del
msg_caracter
168. mov byte ptr es:[di],CARACTER ;Mostrar el CARACTER por
pantalla
169.
170. mov di,(80*5)*2 ;Ponernos en la quinta fila
171. lea si,msg_posicion ;Cargar el offset
172. mov cx,29 ;Total de caracteres de mensaje
173. call pinta ;Mostrarlo por pantalla
174.
175. mov di,(80*5+29)*2 ;Colocarnos al final del msg_posicion
176. pop cx ;Recuperar la posicion en que se
encontraba CARACTER
177. mov es:[di],cl
178.
179. mov ax,4C00h ;
180. int 21h ;Terminar el programa
181.
182. START ENDP
183.
184. ;-----------------------------------------------------------------
-------------
185. ; busca_fin
186. ;
187. ; in: AL contiene el caracter que debemos buscar
188. ; SI contiene la cadena que debemos buscar
189. ; out: En CX se guarda la posicion donde se ha encontrado el
caracter
190. ; machaca: CX
191. ; make: Devuelve en CX la primera posicion donde se ha encontrado
el caracter
192. ; dado en AL
193. ;-----------------------------------------------------------------
-------------
194.
195. busca_fin proc near
196.
197. push di
198. push dx
199. push es
200. push si
201. push ax
202.
203. mov ax,ds ;
204. mov es,ax ;
205. mov di,si ;Copiar DS:SI en ES:DI
206.
207. mov dx,cx ;Copiar el limite en otro registro
208. cld ;Direccion incremental
209. pop ax ;Recuperar el caracter que nos han pedido
210. push ax ;Guardarlo en la pila para no perderlo
211. repnz scasb ;Buscar el caracter pedido
212. sub dx,cx ;Calcular la longitud
213. mov cx,dx ;Guardar la longitud en CX
214.
215. pop ax
216. pop si
217. pop es
218. pop dx
219. pop di
220. ret
221.
222. busca_fin endp
223.
224. ;-----------------------------------------------------------------
-------------
225. ; pinta
226. ;
227. ; in: SI contiene el offset del mensaje a mostrar
228. ; DI contiene la direccion donde se ira mostrando el mensaje
229. ; CX contiene el numero de iteraciones a realizar
230. ; out:
231. ; machaca: CX
232. ; make: Muestra por pantalla el mensaje dado
233. ;-----------------------------------------------------------------
-------------
234. pinta proc near
235.
236. push ax
237. push si
238. push di
239.
240. mov ah,0Fh ;Fondo negro y letras blancas
241.
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 pantalla
249.
250. pop di
251. pop si
252. pop ax
253. ret
254.
255. pinta endp
256.
257. CODE ENDS
258. 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 archivo
C:\>tlink /t archivo
C:\>archivo
;------------------------------------------------------------------
------------
;Programa que muestra la sucesion de codigos ASCII en la esquina
superior
;derecha de la pantalla, intercambiando los caracteres cada medio
segundo
;------------------------------------------------------------------
------------
PANTALLA equ 0b800h
;------------------------------------------------------------------
------------
;Definicion del segmento de codigo
;------------------------------------------------------------------
------------
CODE SEGMENT
assume CS:code
org 100h ;Dejar las 100h primeras posiciones para
el PSP
START:
jmp instalar ;Bifurcar a la rutina de instalacion
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
pop di ;
pop es ;
pop ax ;Recuperar los registros
iret
letras endp
lea dx,instalar
int 27h
instalar endp
CODE ENDS
END START
;------------------------------------------------------------------
------------
;Desactiva las interrupciones periodicas del RTC y elimina el
programa anterior
;de la memoria.
;------------------------------------------------------------------
------------
;------------------------------------------------------------------
------------
;Definicion del segmento de pila
;------------------------------------------------------------------
------------
PILA SEGMENT STACK "STACK"
DB 40h dup(0)
PILA ENDS
;------------------------------------------------------------------
------------
;Definicion del segmento extra
;------------------------------------------------------------------
------------
EXTRA SEGMENT
RESULT DW 0,0
EXTRA ENDS
;------------------------------------------------------------------
------------
;Definicion del segmento de codigo
;------------------------------------------------------------------
------------
CODE SEGMENT
ASSUME CS:CODE,SS:pila
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 ax
push es
push ds
FIN: pop ds
pop es
pop 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.
7 Las soluciones y archivos fuente de todos los ejercicios podéis obtenerlos escribiéndome
un e-mail para pedírmelos.
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 pulse
5. ;la tecla 'N' o 'n'
6. ;------------------------------------------------------------------
------------
7.
8. cr equ 13 ;retorno de carro
9. lf equ 10 ;alimentacion de linea
10.
11. ;-----------------------------------------------------------------
-------------
12. ;Definicion del segmento de datos
13. ;-----------------------------------------------------------------
-------------
14. DATOS SEGMENT
15. DeseaContinuar db cr,lf,'Desea continuar? S/N: '
16. db'$'
17. continuando db ' Continuando...',cr,lf
18. db'$'
19. LetraErronea db ' La tecla pulsada es incorrecta.',cr,lf
20. db'$'
21. DATOS ENDS
22.
23. ;-----------------------------------------------------------------
-------------
24. ;Definicion del segmento de pila
25. ;-----------------------------------------------------------------
-------------
26. PILA SEGMENT STACK "STACK"
27. db 40h dup(?)
28. PILA ENDS
29.
30. ;-----------------------------------------------------------------
-------------
31. ;Definicion del segmento de codigo
32. ;-----------------------------------------------------------------
-------------
33. CODE SEGMENT
34. assume CS:code, DS:datos, SS:pila
35.
36. START:
37. mov ax,datos
38. mov ds,ax
39. jmp continuar ;Saltamos a la etiqueta
CONTINUAR
40.
41. INICIO:
42. lea dx,continuando ;
43. mov ah,9 ;
44. int 21h ;Mensaje de que seguimos en el
programa
45. jmp continuar ;Salto para preguntar si se
desea continuar
46.
47. ERROR:
48. lea dx,LetraErronea ;
49. mov ah,9 ;Mensaje de que la letra
introducida
50. int 21h ;no es correcta
51.
52. CONTINUAR:
53. lea dx,DeseaContinuar ;
54. mov ah,9 ;
55. int 21h ;Mostrar pregunta para ver si
desea continuar
56.
57. mov ah,1 ;Esperar a que se pulse una tecla
58. int 21h ;y mostrarla por pantalla
59.
60. cmp al, 'S' ;
61. je inicio ;
62. cmp al, 's' ;
63. je inicio ;Desea continuar
64.
65. cmp al, 'N' ;
66. je salir ;
67. cmp al, 'n' ;
68. je salir ;No desea continuar, terminamos
69.
70. jmp error ;La tecla pulsada no es 'S', 's',
'N' ni 'n'
71. ;Se va a mostrar un mensaje de
error. Saltamos
72. ;a la etiqueta ERROR
73.
74. salir:
75. mov ax, 4C00h
76. int 21h
77.
78. CODE ENDS
79. END START
80. Este programa cambia el color de fondo de una posición determinada de
pantalla. Si se ejecuta varias veces seguidas veremos como cambia de blanco a
negro y viceversa:
81.
82. PANTALLA equ 0B800h
83.
84. ;-----------------------------------------------------------------
-------------
85. ;Definicion del segmento de pila
86. ;-----------------------------------------------------------------
-------------
87. PILA SEGMENT STACK "STACK"
88. db 40h dup(0)
89. PILA ENDS
90.
91. ;-----------------------------------------------------------------
-------------
92. ;Definicion del segmento de codigo
93. ;-----------------------------------------------------------------
-------------
94. CODE SEGMENT
95. assume CS:code, SS:pila
96.
97. START:
98. mov ax,PANTALLA
99. mov ds,ax
100. mov bx,(80*24+5)*2+1 ;Ultima linea, caracter 5
101. ;Utilizamos el '+1' para acceder
102. ;directamente al fondo
103.
104. cmp byte ptr [bx],07h ;Vemos si el fondo es negro
105. jz CambiaFondo
106.
107. mov byte ptr [bx],07h ;Si no es negro lo ponemos
108. jmp fin
109.
110. CambiaFondo:
111. mov byte ptr [bx],70h ;Ponemos el fondo blanco
112.
113. fin:
114. mov ax,4C00h
115. int 21h
116.
117. CODE ENDS
118. END START
119. Otro programa .COM (no os olvideis de compilar con las banderas
antes mencionadas). En este caso se trata de mostrar las letras V y S con un
intervalo de medio segundo, siendo una letra roja y la otra azul:
120.
121. PANTALLA equ 0b800h
122. ROJO equ 4
123. LETRA_ROJA equ 'V'
124. LETRA_AZUL equ 'S'
125. AZUL equ 1
126.
127. ;-----------------------------------------------------------------
-------------
128. ;Definicion del segmento de codigo
129. ;-----------------------------------------------------------------
-------------
130. CODE SEGMENT
131. assume CS:code
132. org 100h ;Dejar las 100h primeras posiciones para
el PSP
133.
134. START:
135. jmp instalar ;Bifurcar a la rutina de instalacion
136.
137.
138. ;-----------------------------------------------------------------
-------------
139. ; letras
140. ;
141. ; in:
142. ; out:
143. ; machaca:
144. ; make: Hace que se intercambien las letras V y S cada medio
segundo en
145. ; colores diferentes.
146. ;
147. ;-----------------------------------------------------------------
-------------
148. letras proc far
149.
150. push ax ;
151. push es ;
152. push di ;Guardamos los registros en la pila
153.
154. cli ;Inhabilitar las interrupciones
155.
156. mov al,0Ch ;
157. out 70h,al ;
158. in al,71h ;Leer el RTC
159.
160. mov ax,pantalla
161. mov es,ax
162. mov di,79*2 ;Esquina superior derecha
163. mov ax,es:[di] ;Guardamos en AX lo que hay en la esquina
164.
165. cmp ah,AZUL ;Si era azul ahora debemos mostrar
166. je muestra_v_rojo ;la 'V' de color rojo
167.
168. mov ah,AZUL
169. mov al,LETRA_AZUL
170. mov es:[di],ax ;Guardar en ES:[DI] que hemos puesto la
letra
171. ;de color azul
172. jmp fin ;Terminar el procedimiento
173.
174. muestra_v_rojo:
175. mov ah,ROJO
176. mov al,LETRA_ROJA
177. mov es:[di],ax ;Guardar en ES:[DI] que hemos puesto la
letra
178. ;de color rojo
179.
180. fin:
181. mov al,20h ;
182. out 20h,al ;
183. out 0A0h,al ;EOI al maestro y al esclavo
184.
185. sti ;Habilitar las interrupciones
186.
187. pop di ;
188. pop es ;
189. pop ax ;Recuperar los registros
190.
191. iret
192. letras endp
193.
194.
195. ;-----------------------------------------------------------------
-------------
196. ; instalar
197. ;
198. ; in:
199. ; out:
200. ; machaca: ax, dx, es
201. ; make: Instala el programa dejandolo residente
202. ;
203. ;-----------------------------------------------------------------
-------------
204. instalar proc
205.
206. cli ;Inhabilitar las interrupciones
207.
208. xor ax,ax ;
209. mov es,ax ;Poner a 0 ES
210. mov es:[70h*4],offset letras ;Guardar el offset
211. mov es:[70h*4+2],cs ;y el segmento de la rutina
212.
213. in al,0A1h ;Leer el PIC esclavo
214. and al,11111110b ;
215. out 0A1h,al ;Activamos IR0
216.
217. in al,21h ;Leer el PIC maestro
218. and al,11111011b ;
219. out 21h,al ;Activado
220.
221. mov al,0Ah ;Vamos a escribir en el registro A del
RTC
222. out 70h,al ;
223. mov al,2Fh ;Los simbolos se intercambian cada medio
segundo
224. out 71h,al ;Lo indicamos en el registro A del RTC
225.
226. mov al,0Bh ;Vamos a escribir en el registro B del
RTC
227. out 70h,al ;
228. in al,71h ;
229. or al,01000000b ;
230. out 71h,al ;Activamos las interrupciones periodicas
231.
232. sti ;Habilitar las interrupciones
233.
234. lea dx,instalar ;
235. int 27h ;Dejar residente
236.
237. instalar endp
238.
239. CODE ENDS
240. 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 datos
245. ;-----------------------------------------------------------------
-------------
246. DATOS SEGMENT
247. Cadena1 db 50 dup(0)
248. Cadena2 db 50 dup(?)
249. DATOS ENDS
250.
251. ;-----------------------------------------------------------------
-------------
252. ;Definicion del segmento de pila
253. ;-----------------------------------------------------------------
-------------
254. PILA SEGMENT STACK "STACK"
255. db 40h DUP(0)
256. PILA ENDS
257.
258. ;-----------------------------------------------------------------
-------------
259. ;Definicion del segmento de codigo
260. ;-----------------------------------------------------------------
-------------
261. CODE SEGMENT
262. assume cs:code,ds:datos,ss:pila
263.
264. START PROC
265. ;Inicializamos los registros de segmento
266. mov ax,datos
267. mov ds,ax
268. mov ax,pila
269. mov ss,ax
270.
271. xor ax,ax
272. mov cx,10h
273. lea si,Cadena1
274. lea di,Cadena2
275. otro:
276. push ds
277. inc ax
278. pop es
279. scasb
280. loop otro
281. nop ;AX=10h, SI=0, DI=42h
282.
283. mov ax,4C00h ;
284. int 21h ;Terminar el programa
285.
286. START ENDP
287.
288. CODE ENDS
289. 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 datos
294. ;-----------------------------------------------------------------
-------------
295. DATOS SEGMENT
296. Cadena1 db 50 dup(0)
297. Cadena2 db 50 dup(?)
298. DATOS ENDS
299.
300. ;-----------------------------------------------------------------
-------------
301. ;Definicion del segmento de pila
302. ;-----------------------------------------------------------------
-------------
303. PILA SEGMENT STACK "STACK"
304. db 40h DUP(0)
305. PILA ENDS
306.
307. ;-----------------------------------------------------------------
-------------
308. ;Definicion del segmento de codigo
309. ;-----------------------------------------------------------------
-------------
310. CODE SEGMENT
311. assume cs:code,ds:datos,ss:pila
312.
313. START PROC
314. ;Inicializamos los registros de segmento
315. mov ax,datos
316. mov ds,ax
317. mov ax,pila
318. mov ss,ax
319.
320. xor ax,ax
321. mov cx,10h
322. lea si,Cadena1
323. lea di,Cadena2
324. otro:
325. push ds
326. inc ax
327. pop es
328. repne scasb
329. loop otro
330. nop
331.
332. mov ax,4C00h ;
333. int 21h ;Terminar el programa
334.
335. START ENDP
336.
337. CODE ENDS
338. 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/96
343. ;-----------------------------------------------------------------
-------------
344.
345. ;-----------------------------------------------------------------
-------------
346. ;Definicion del segmento de codigo
347. ;-----------------------------------------------------------------
-------------
348. CODE SEGMENT
349. assume CS:code
350.
351. START:
352.
353. ;Inicializar
354. mov byte ptr ds:[1000h],0
355. mov byte ptr ds:[1001h],0
356. mov byte ptr ds:[1002h],0
357. mov byte ptr ds:[1003h],0
358.
359. mov si,1000h
360. mov cx,4
361. l1:
362. add [si],si
363. inc si
364. loop l1
365.
366. mov ax,4C00h
367. int 21h
368.
369. CODE ENDS
370. END START
371. Hallar el contenido de SI tras la ejecución de los bucles:
372.
373. ;-----------------------------------------------------------------
-------------
374. ; Ejercicio: examen ETCII - 12/02/96
375. ;-----------------------------------------------------------------
-------------
376.
377. ;-----------------------------------------------------------------
-------------
378. ;Definicion del segmento de codigo
379. ;-----------------------------------------------------------------
-------------
380. CODE SEGMENT
381. assume CS:code
382.
383. START:
384.
385. mov si,0
386. mov cx,4
387. L2: push cx
388. mov cx,100h
389. L1: dec cx
390. inc si
391. loop l1
392. pop cx
393. loop l2
394.
395. mov ax,4C00h
396. int 21h
397.
398. CODE ENDS
399. END START
9
1. Otro problema de examen. Hallar el valor de AX tras la instrucción mov
ax,word ptr ds:[3]
2.
3. ;------------------------------------------------------------------
------------
4. ;Definicion del segmento de datos
5. ;------------------------------------------------------------------
------------
6. DATOS SEGMENT
7. dw 3Ah,7Bh,9Ch
8. db 34h,76h,65h
9. org 1
10. db 67h,31h,56h,"SE ACABO"
11. DATOS ENDS
12.
13. ;-----------------------------------------------------------------
-------------
14. ;Definicion del segmento de pila
15. ;-----------------------------------------------------------------
-------------
16. PILA SEGMENT STACK "STACK"
17. db 40h DUP(0)
18. PILA ENDS
19.
20. ;-----------------------------------------------------------------
-------------
21. ;Definicion del segmento de codigo
22. ;-----------------------------------------------------------------
-------------
23. CODE SEGMENT
24. assume cs:code,ds:datos,ss:pila
25.
26. START PROC
27. ;Inicializamos los registros de segmento
28. mov ax,datos
29. mov ds,ax
30. mov ax,pila
31. mov ss,ax
32.
33. mov ax,word ptr ds:[3]
34.
35. mov ax,4C00h ;
36. int 21h ;Terminar el programa
37.
38. START ENDP
39.
40. CODE ENDS
41. END START
42. Muy similar al anterior:
43.
44. ;-----------------------------------------------------------------
-------------
45. ;Definicion del segmento de datos
46. ;-----------------------------------------------------------------
-------------
47. DATOS SEGMENT
48. dw 3Ah,7Bh,9Ch
49. db 34h,76h,65h
50. org 2
51. db 67h,31h,56h,"SE ACABO"
52. DATOS ENDS
53.
54. ;-----------------------------------------------------------------
-------------
55. ;Definicion del segmento de pila
56. ;-----------------------------------------------------------------
-------------
57. PILA SEGMENT STACK "STACK"
58. db 40h DUP(0)
59. PILA ENDS
60.
61. ;-----------------------------------------------------------------
-------------
62. ;Definicion del segmento de codigo
63. ;-----------------------------------------------------------------
-------------
64. CODE SEGMENT
65. assume cs:code,ds:datos,ss:pila
66.
67. START PROC
68. ;Inicializamos los registros de segmento
69. mov ax,datos
70. mov ds,ax
71. mov ax,pila
72. mov ss,ax
73.
74. mov ax,word ptr ds:[3]
75.
76. mov ax,4C00h ;
77. int 21h ;Terminar el programa
78.
79. START ENDP
80.
81. CODE ENDS
82. END START
83. ¿Cuál es el valor de AX tras la instrucción NOP?:
84.
85. ; Ejercicio: examen ETCII - febrero 2002
86.
87. ;-----------------------------------------------------------------
-------------
88. ;Definicion del segmento de pila
89. ;-----------------------------------------------------------------
-------------
90. PILA SEGMENT STACK "STACK"
91. db 40h DUP(0)
92. PILA ENDS
93.
94. ;-----------------------------------------------------------------
-------------
95. ;Definicion del segmento extra
96. ;-----------------------------------------------------------------
-------------
97. EXTRA SEGMENT
98. RESULT DW 0,0
99. EXTRA ENDS
100.
101. ;-----------------------------------------------------------------
-------------
102. ;Definicion del segmento de codigo
103. ;-----------------------------------------------------------------
-------------
104. CODE SEGMENT
105. assume CS:code,ES:extra,SS:pila
106.
107. ;-----------------------------------------------------------------
-------------
108. ; Procedimiento inicial
109. ;-----------------------------------------------------------------
-------------
110. START PROC
111.
112. mov ax,1Fh
113. push ax
114. inc sp
115. push ax
116. dec sp
117. pop ax
118. pop ax
119. nop
120.
121. mov ax,4C00h ;
122. int 21h ;Terminar el programa
123.
124. START ENDP
125.
126. CODE ENDS
127. 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 pila
132. ;-----------------------------------------------------------------
-------------
133. PILA SEGMENT STACK "STACK"
134. db 40h DUP(0)
135. PILA ENDS
136.
137. ;-----------------------------------------------------------------
-------------
138. ;Definicion del segmento de codigo
139. ;-----------------------------------------------------------------
-------------
140. CODE SEGMENT
141. assume cs:code,ss:pila
142.
143. START PROC
144. ;Inicializamos los registros de segmento
145. mov ax,pila
146. mov ss,ax
147.
148. mov al,5
149. mov bx,0FA45h
150. push bx
151. push ax
152. mov bp,sp
153. mov al,[bp+3]
154. nop
155.
156. mov ax,4C00h ;
157. int 21h ;Terminar el programa
158.
159. START ENDP
160.
161. CODE ENDS
162. END START
163. Estos ejercicios de pilas suelen tener truco la mayoría de las veces ;)
Hallar el valor de AX tras el último POP:
164.
165. ;-----------------------------------------------------------------
-------------
166. ;Definicion del segmento de pila
167. ;-----------------------------------------------------------------
-------------
168. PILA SEGMENT STACK "STACK"
169. db 40h DUP(0)
170. PILA ENDS
171.
172. ;-----------------------------------------------------------------
-------------
173. ;Definicion del segmento de codigo
174. ;-----------------------------------------------------------------
-------------
175. CODE SEGMENT
176. assume cs:code,ss:pila
177.
178. START PROC
179. ;Inicializamos los registros de segmento
180. mov ax,pila
181. mov ss,ax
182.
183. push 0F34h
184. push 63h
185. pop ax
186. inc sp
187. pop ax
188.
189. mov ax,4C00h ;
190. int 21h ;Terminar el programa
191.
192. START ENDP
193.
194. CODE ENDS
195. END START
10
1. Hallar el valor de AX tras la instrucción div bl:
2.
3. ;------------------------------------------------------------------
------------
4. ;Definicion del segmento de codigo
5. ;------------------------------------------------------------------
------------
6. CODE SEGMENT
7. assume cs:code
8.
9. START PROC
10.
11. mov ah,1
12. mov al,0D7h
13. xor bx,bx
14. stc
15. rcr bx,1
16. rcr bx,1
17. div bl
18.
19. mov ax,4C00h ;
20. int 21h ;Terminar el programa
21.
22. START ENDP
23.
24. CODE ENDS
25. 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 datos
30. ;-----------------------------------------------------------------
-------------
31. DATOS SEGMENT
32. Cadena1 db 80 dup("5"),"$"
33. Cadena2 db 80 dup("@"),"$"
34. DATOS ENDS
35.
36. ;-----------------------------------------------------------------
-------------
37. ;Definicion del segmento de pila
38. ;-----------------------------------------------------------------
-------------
39. PILA SEGMENT STACK "STACK"
40. db 40h DUP(0)
41. PILA ENDS
42.
43. ;-----------------------------------------------------------------
-------------
44. ;Definicion del segmento de codigo
45. ;-----------------------------------------------------------------
-------------
46. CODE SEGMENT
47. assume cs:code,ds:datos,ss:pila
48.
49. START PROC
50. ;Inicializamos los registros de segmento
51. mov ax,datos
52. mov ds,ax
53. mov ax,pila
54. mov ss,ax
55.
56. mov dx,offset Cadena1
57. mov ah,9
58. int 21h
59.
60. mov dx,offset Cadena2
61. mov ah,9
62. int 21h
63.
64. mov ax,4C00h ;
65. int 21h ;Terminar el programa
66.
67. START ENDP
68.
69. CODE ENDS
70. 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 datos
75. ;-----------------------------------------------------------------
-------------
76. DATOS SEGMENT
77. texto db "Esto es un texto",0,"Y este otro",0
78. DATOS ENDS
79.
80. ;-----------------------------------------------------------------
-------------
81. ;Definicion del segmento de pila
82. ;-----------------------------------------------------------------
-------------
83. PILA SEGMENT STACK "STACK"
84. db 40h DUP(0)
85. PILA ENDS
86.
87. ;-----------------------------------------------------------------
-------------
88. ;Definicion del segmento de codigo
89. ;-----------------------------------------------------------------
-------------
90. CODE SEGMENT
91. assume cs:code,ds:datos,ss:pila
92.
93. START PROC
94. ;Inicializamos los registros de segmento
95. mov ax,datos
96. mov ds,ax
97. mov ax,pila
98. mov ss,ax
99.
100. push ds
101. pop es
102. cld
103. mov ax,4C00h
104. lea di,texto
105. mov cx,14h
106. repnz scasb
107.
108. mov ax,4C00h ;
109. int 21h ;Terminar el programa
110.
111. START ENDP
112.
113. CODE ENDS
114. END START
115. ¿Que es lo que encuentra el programa? "to" de la palabra "Esto" "ot"
de la palabra "otra"
116.
117. ;-----------------------------------------------------------------
-------------
;Definicion del segmento de datos
;---------------------------------------------------------------------
---------
DATOS SEGMENT
cadena db "Esto es otra cadena"
DATOS ENDS
;---------------------------------------------------------------------
---------
;Definicion del segmento de pila
;---------------------------------------------------------------------
---------
PILA SEGMENT STACK "STACK"
db 40h DUP(0)
PILA ENDS
;---------------------------------------------------------------------
---------
;Definicion del segmento de codigo
;---------------------------------------------------------------------
---------
CODE SEGMENT
assume cs:code,ds:datos,ss:pila
START PROC
;Inicializamos los registros de segmento
mov ax,datos
mov ds,ax
cld
mov ax,datos
mov es,ax
mov cx,100h
mov ax,"ot"
lea di,cadena
repnz scasw
mov ax,4C00h ;
int 21h ;Terminar el programa
START ENDP
CODE ENDS
END START
;---------------------------------------------------------------------
---------
;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
JMP destino
Instrucción JA (JNBE)
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.
Sintaxis:
JAE etiqueta
Instrucción JB (JNAE)
Sintaxis:
JB etiqueta
Sintaxis:
JBE etiqueta
Instrucción JE (JZ)
Sintaxis:
JE etiqueta
Sintaxis:
JNE etiqueta
Instrucción JG (JNLE)
JG etiqueta
Sintaxis:
JGE etiqueta
El salto se realiza si SF = OF
Instrucción JL (JNGE)
Sintaxis:
JL etiqueta
Sintaxis:
JLE etiqueta
Sintaxis:
JC etiqueta
El salto se realiza si CF = 1
Instrucción JNC
Sintaxis:
JNC etiqueta
El salto se efectúa si CF = 0.
Instrucción JNO
Sintaxis:
JNO etiqueta
El salto se efectua si OF = 0.
Sintaxis:
JNP etiqueta
Salta si no hay paridad o salta si la paridad es non.
El salto ocurre si PF = 0.
Instrucción JNS
Sintaxis:
JNP etiqueta
El salto se efectúa si SF = 0.
Instrucción JO
Sintaxis:
JO etiqueta
El salto se realiza si OF = 1.
Instrucción JP (JPE)
Sintaxis:
JP etiqueta
El salto se efectúa si PF = 1.
Instrucción JS
JS etiqueta
El salto se efectúa si SF = 1.
Instrucción LOOP
Sintaxis:
LOOP etiqueta
Instrucción LOOPE
Sintaxis:
LOOPE etiqueta
Instrucción LOOPNE
Sintaxis:
LOOPNE etiqueta
Instrucción DEC
Propósito: Decrementar el operando
Sintaxis:
DEC destino
Instrucción INC
Sintaxis:
INC destino
Instrucción CMP
Sintaxis:
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.
Sintaxis:
Instrucción CLC
Sintaxis:
CLC
Instrucción CLD
Sintaxis:
CLD
Instrucción CLI
Sintaxis:
CLI
Instrucción CMC
Sintaxis:
CMC
Instrucción STC
Sintaxis:
STC
Instrucción STD
Sintaxis:
STD
Instrucción STI
Sintaxis:
STI
org 100h
comienzo:
mov si, x
mov al, msg2[si]
cmp msg[si], al ;comparar letra por letra las cadenas, si uno no coincide
manda directamente a fin y termina el programa
jne fin:
cmp msg[si], "$" ;si es el final y el programa llega aca, quiere decir
que son iguales
jz final:
inc x
loop comienzo
final:
mov dx, offset msg3
mov ah, 9
int 21h
fin:
ret
msg db "hello world $"
msg2 db "hello world $"
msg3 db "Son iguales $"
x dw 0
org 100h
mov si, 0 ;ponemos si en 0
comienzo:
mov al, msg2[0] ;copiar la primera letra de la palabra a al
cmp msg[si],"$" ;si es el fin de la cadena mandar a final
jz final
cmp msg[si], al ;comparar si encuentra la primera letra de la cadena
jne seguir
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 100h
mov si, 0 ;ponemos si en 0
comienzo:
cmp msg[si],"$" ;si es el fin de la cadena mandar a final
jz resultado
seguir:
inc si ;para seguir recorriendo la palabra
loop comienzo ;bucle principal para recorrer palabra
resultado:
mov dx, offset msg3 ;copiar msg3 a dx
mov ah, 9 ;preparar ah con 9 para la interrupcion 21h
int 21h ;mostrar contenido en dx
final:
ret
msg db "cerro$"
msg2 db "recanate$"
msg3 db "Si se encuentran todos los caracteres$"
Ejercicio 4: Escribir una programa que reciba una cadena ingresada por teclado, terminada
en ENTER. Luego que elimine todos los caracteres que no son dígitos, sin utilizar una
variable auxiliar.
ORG 100H
mov si, 0
lectura:
mov ah,1
int 21h
cmp al,13
jz resultado:
cmp al, 57 ;si tecla es mayor a 57 entonces ir a fin3 (tecla > 57)
ja fin3
cmp al,47 ;si tecla no es mayor a 47 ir a fin3 (tecla <= 47)
jng fin3
mov bx[si], al ;si es un digito entonces guardo en bx
inc si ;incrementa si
fin3:
jmp lectura
resultado:
mov ah,00h ;limpia la pantalla
mov al,03h
int 10h
mov bx[si], "$"
mov dx, offset bx
mov ah, 9 ;preparar ah con 9 para la interrupcion 21h
int 21h ;mostrar contenido en dx
ret
Ejercicio 5: Escribir un programa que tome una cadena que representa un número decimal
y escriba su equivalente octal
cadAnum:
cmp cad[si], "$"
jz seguir
mov bl, 10
mul bl
sub cad[si], '0'
add al, cad[si]
inc si
loop cadAnum
seguir:
mov cx, si
mov si, 0
mov bl, 8
pasar:
div bl ;dividir al con bl
mov oct[si], ah ;copiar a la cadena oct el resultado sobrante de la
division
inc si ;incrementar si
loop pasar
fina:
cmp ah, 0
jnz final
mov oct[si], al
final:
;mov dx, offset res
;mov ah, 9 ;preparar ah con 9 para la interrupcion 21h
;int 21h ;mostrar contenido en dx
ret
cad db "64$"
oct db 0
mov bl, 10
mul bl
sub cad1[si], '0'
add al, cad1[si]
inc si
loop cadAnum
seguir:
mov aux1, al
;Convertir segunda cadena a numero
mov si, 0
mov al, 0
cadAnum2:
cmp cad3[si], "$"
jz seguir2
mov bl, 10
mul bl
sub cad3[si], '0'
add al, cad3[si]
inc si
loop cadAnum2
seguir2:
mov bl, al
mov al, aux1
;realizar operaciones normalmente teniendo ya los dos numeros decimales
cmp cad2, "-"
jz resta
cmp cad2, "+"
jz suma
cmp cad2, "*"
jz multi
cmp cad2, "/"
jz divi
resta:
sub al, bl
jmp fin
suma:
add al, bl
jmp fin
multi:
mul bl
jmp fin
divi:
div bl
jmp fin
fin:
mov bx, ax
mov ah,09
lea dx,msg
int 21h
mov ax, bx
call PRINT_NUM
ret
cad1 db "10$"
cad2 db "-"
cad3 db "2$"
aux1 db ?
aux2 dw ?
msg dw "El resultado es: $"
name "keybrd"
org 100h
; print a welcome message:
mov dx, offset msg
mov ah, 9
int 21h
;============================
; eternal loop to get
; and print keys:
wait_for_key:
; check for keystroke in
; keyboard buffer:
mov dh, pos
mov dl, pos
mov bh, 0
mov ah, 2
int 10h ;Movemos el cursor
mov al,'X'
mov bh,0
mov bl,1
mov cx,1
mov ah,09h
inc pos ;Imprimimos una x
int 10h
mov ah, 1
int 16h
jz wait_for_key
; get keystroke from keyboard:
; (remove from the buffer)
mov ah, 0
int 16h
; print the key:
mov ah, 0eh
int 10h
; press 'esc' to exit:
cmp al, 1bh
jz exit
jmp wait_for_key
;============================
exit:
ret
msg db "Type anything...", 0Dh,0Ah
db "[Enter] - carriage return.", 0Dh,0Ah
db "[Ctrl]+[Enter] - line feed.", 0Dh,0Ah
db "You may hear a beep", 0Dh,0Ah
db " when buffer is overflown.", 0Dh,0Ah
db "Press Esc to exit.", 0Dh,0Ah, "$"
pos db 1
end
name "arreglo-mayor"
org 100h
mov cx, 8
bucle1:
mov c, cx
mov bx, cx
mov cx, 9
bucle2:
mov si, cx
mov ah, v[si-1]
cmp ah,v[bx-1]
jnge seguir ;Si 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 bucle1
ret
v db 2,32,64,32,98,12,5,21,91
c dw 0
parte3: ;una vez que tengamos el MCM primero multiplicar nro1 * nro 2
mov al, nro1 ;con ese resultado, dividir por el MCM de nro1 y nro2 y
tenemos el MCD
mov bl, nro2
mul bl
mov bl, MCM
div bl
mov MCD, al
ret ;fin del programa
cont db 0 ;cont = contador
MCM db 0 ;en esta variable se guarda el MCM
MCD db 0 ;en esta variable se guarda el MCD
nro1 db 48 ;numero1 decimal
nro2 db 60 ;numero2 decimal
mov cx,1
mov 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
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
error:
; ....
;leer archivo
leer:
mov bx, handle
mov cx, 1
mov dx, offset leido
mov ah, 3fh
int 21h
cmp ax, 0 ;ax queda en 0 cuando llega a EOF
jz FIN ;si es 0 entonces va a fin para cerrar archivo
mostrar:
cmp aux, "a" ;compara si el anterior es a
jnz abajo
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