Fecha de publicación: May 02, 2013 10:21:0 PM
Una subrutina es un programa separado del programa principal que es llamado para realizar una función específica.
En programacion se utiliza un concepto denominado "Divide y Venceras", este concepto se refiere a que dada un problema GRANDE dificil de resolver, es mejor para su resolucion dividirlo en pequeños problemas mas simples para resolverlos individualmente, de tal manera que al resolver esos pequeños problemas uno a uno se termina solucionando todo el problema denominado GRANDE.
Un ejemplo simple que nos sirve para propositos de comprencion del concepto de subrutina sera el siguiente:
Se requiere de un programa que divida y multiplique dos numeros dados. en el acumulador a y b, los resultados guardelos en las memorias 20 y 21 para la multiplicacion y 24 y 25 para la division
Para dicho programa utilizaremos subrutinas dividiendo el problema de la siguiente manera:
Un programa que divida a / b y guarde el resultado.
Otro programa multiplique a * b y guarde el resultado.
Las llamadas a subrutina se hacen con la siguiente instruccion:
"CALL" que significa llamada.
las instrucciones son CALL simplemente o ACALL que es para un llamado de 11 bits en un tamaño de memoria de 2k y LCALL un llamado de 16 Bits para un tamaño de memoria mayor de 65k.
para nuestro problema propuesto, tendremos dos llamados a subrutina
del siguiente codigo
; - - - Curso de microcontroladores 8051 - - -
; Leccion #10: subrutinas
; Autor: Raul Alejandro QL
org 0000h
inicio:
mov a,#15h
mov b,#05h
acall multiplicar
acall dividir
ajmp $
multiplicar:
mul ab
mov 20,a
mov 21,b
ret
dividir:
div ab
mov 24,a
mov 25,b
ret
end
tenemos el listado o codigo LST donde se muestran la direccion de memoria de los codigos a ejecutarse y los una columna con la letra N ademas de los codigos en lenguaje maquina formato hexadecimal y los codigos que conocemos, de estos podemos determinar los llamados a subrutina y los retornos al programa principal. con coleres resaltados del resto del codigo
Ejemplo:
1: ; - Curso de microcontroladores 8051 - - -
2: ; Leccion #10: subrutinas
3: ; Autor: Raul Alejandro QL
4:
5: N 0000 org 0000h
6: 0000 inicio:
7: 0000 74 15 mov a,#15h
8: 0002 75 F0 05 mov b,#05h
9: 0005 11 0B acall multiplicar
10: 0007 11 12 acall dividir
11: 0009 01 09 ajmp $
12: 000B multiplicar:
13: 000B A4 mul ab
14: 000C F5 14 mov 20,a
15: 000E 85 F0 15 mov 21,b
16: 0011 22 ret
17: 0012 dividir:
18: 0012 84 div ab
19: 0013 F5 18 mov 24,a
20: 0015 85 F0 19 mov 25,b
21: 0018 22 ret
22: end
En este programa el llamado y retorno a subrutina se ejecutan sin problema, pero existe un detalle en el codigo y es que la division no se ejecuta, como se debe por que los datos en el acumulador a y b han sido modificados por el subprograma multiplicar, para solucionar este problema se utilza los siguientes comandos push y pop que veremos mas adelante.
Bueno para entender como funciona una subrutina tenemos que comprender que son y para que sirven el PC y el SP.
PC Program Counter: presisamente cuenta el codigo en ejecucion del programa cada instruccion que es apuntada por el PC es ejecutada al ser ejecutada el program counter PC se incrementa para ejecutar la siguiete instruccion y asi sucesibamente por todo el codigo fuente.
El SP stack pila, es el que nos permite realizar los CALL, las subrutinas es una memoria muy parecida a un vaso, donde guardas muchas pelotitas, la primera pelotita que entra es la ultima q sale y la que entre ultima es la primera que sale. por la forma de vaso de la memoria.
Ya en el programa, cuando se ejecuta la instruccion call, el PC contador de programa esta en la direccion de memoria 0005, al ejecutar CALL al PC se le suma +2 y ese resultado que apunta a la siguiente instruccion se guarda en el SP stack pointer o puntero de pila, de esta manera el programa tiene guardado en el sp la direccion de regreso al programa que le a convocado. se ejecuta por lo tanto el programa multiplicar y en la direccion 0011 la instruccion RET hace que el valor de el SP (direccion de retorno) pase a PC con lo que el programa retorna al programa principal el cual lo ha convocado a la direccion 0007 que para este caso es otro call.
Como en el caso de nuestro programa donde tenemos 2 call, multiplicar y dividir, cada uno de estos subprogramas utiliza para su ejecucion los mismos datos acumuladores "a" y "b", al ejecutar primiero el subprograma multiplicar se destruyen los datos para el segundo programa, el cual corre con los datos equivocados, no los iniciales, para q esto no ocurra se utiliza las instrucciones push y pop que nos permiten guardar en el SP Stack Pila los datos para que no se afecten y puedan ser usados por otro programa.
Aqui el mismo programa algo modificado para que los acumuladores tambien se guarden en el SP
; - - - Curso de microcontroladores 8051 - - -
; Leccion #10: subrutinas
; Autor: Raul Alejandro QL
org 0000h
inicio:
mov a,#20h
mov b,#05h
acall multiplicar
acall dividir
ajmp $
multiplicar:
push acc
push b
mul ab
mov 20h,a
mov 21h,b
pop b
pop acc
ret
dividir:
push acc
push b
div ab
mov 24h,a
mov 25h,b
pop b
pop acc
ret
end