Está en la página 1de 5

Introducción a la gestión de subrutinas

Una subrutina es un fragmento de código independiente, que normalmente realiza una tarea auxiliar
completa, a la que se puede llamar mediante una instrucción específica, desde cualquier parte de un
programa y que, una vez ha completado su cometido, devuelve el control a la instrucción siguiente a la
que había efectuado la llamada. Es habitual que cuando se llame a una subrutina se le pasen uno o
varios datos, llamados parámetros, para que opere con ellos, para que realice unas acciones u otras,
etcétera. Asimismo, también es frecuente que la subrutina, al terminar, devuelva uno o varios
resultados a la parte del programa que la llamó. Por otro lado, conviene tener en cuenta que,
dependiendo del lenguaje de programación y de sus particularidades, una subrutina puede recibir
cualquiera de los siguientes nombres: rutina, procedimiento, función, método o subprograma.

Esta división de los programas en subrutinas es importante porque permite estructurarlos y desarrollarlos
de forma modular: cada subrutina es un trozo de código independiente que realiza una tarea, y el resto el
programa puede hacerse sabiendo únicamente qué hace la subrutina y cuál es su interfaz, es decir, con qué
parámetros debe comunicarse con ella. No es necesario saber cómo está programado el código de la
subrutina para poder utilizarla en un programa. Por esta misma razón, la mayor parte de depuradores de
código y simuladores —incluyendo QtARMSim—, incluyen la opción de depurar paso a paso pasando
por encima —step over—. Esta opción de depuración, cuando se ncuentra con una llamada a una
subrutina, ejecuta la subrutina como si fuera una única instrucción, en lugar de entrar en su código.
Sabiendo qué pasar a una subrutina y qué valores devuelve, es decir conociendo su interfaz, y habiéndola
probado con anterioridad, es posible centrarse en la depuración del resto del programa de forma
independiente, aprovechando la modularidad comentada anteriormente.

Así pues, la utilización de subrutinas permite reducir tanto el tiempo de desarrollo del código como el de
su depuración. Sin embargo, el uso de subrutinas tiene una ventaja de mayor calado: subproblemas que
aparecen con frecuencia en el desarrollo de ciertos programas pueden ser implementados como subrutinas
y agruparse en bibliotecas (libraries en inglés). Cuando un programador requiere resolver un determinado
problema ya resuelto por otro, le basta con recurrir a una determinada biblioteca y llamar a la subrutina
adecuada. Es decir, gracias a la agrupación de subrutinas en bibliotecas, el mismo código puede ser
reutilizado por muchos programas.

Llamada y retorno de una subrutina

ARM Thumb proporciona las siguientes instrucciones para gestionar la llamada y el retorno de una
subrutina: «bl etiqueta» y «mov pc, lr». 6.1. Llamada y retorno de una subrutina. La instrucción «bl
etiqueta» se utiliza para llamar a una subrutina que comienza en la dirección de memoria indicada por
dicha etiqueta.
Cuando el procesador ejecuta esta instrucción, lleva a cabo las siguientes acciones:
 Almacena la dirección de memoria de la siguiente instrucción a la que contiene la instrucción «bl
etiqueta» en el registro r14 (también llamado LR, por link register, registro enlace).
 Transfiere el control del flujo del programa a la dirección indicada en el campo «etiqueta». Es
decir, se realiza un salto incondicional a la dirección especificada en «etiqueta»
La instrucción «mov pc, lr» se utiliza al final de la subrutina para retornar a la instrucción siguiente a la
que la había llamado. Cuando el procesador ejecuta esta instrucción, actualiza el contador de programa
con el valor del registro LR, lo que a efectos reales implica realizar un salto incondicional a la dirección
contenida en el registro LR.
El siguiente código muestra un programa de ejemplo en ensamblador de ARM que utiliza una subrutina
llamada «suma». Esta subrutina suma los valores almacenados en los registros r0 y r1, y devuelve la
suma de ambos en el registro r0. Como se puede observar, la subrutina se llama desde dos puntos del
programa principal —la primera línea del programa principal es la etiquetada con «main»—.

Paso de parámetros
Se denomina paso de parámetros al mecanismo mediante el cual el programa invocador y la subrutina
intercambian datos. Los parámetros intercambiados entre el programa invocador y la subrutina pueden
ser de tres tipos según la dirección en la que se transmita la información: de entrada, de salida o de
entrada/salida. Los parámetros de entrada proporcionan información del programa invocador a la
subrutina. Los de salida devuelven información de la subrutina al programa invocador. Por último, los de
entrada/salida proporcionan información del programa invocador a la subrutina y devuelven
información de la subrutina al programa invocador. Por otro lado, para realizar el paso de parámetros es
necesario disponer de algún recurso físico donde se pueda almacenar y leer la información que se quiere
transferir. Las dos opciones más comunes son los registros o la memoria.
Para poder utilizar las subrutinas conociendo únicamente su interfaz, pudiendo de esta manera emplear
funciones de bibliotecas, es necesario establecer un convenio acerca de cómo pasar y devolver los
parámetros para que cualquier programa pueda utilizar cualquier subrutina, aunque estén programados
de forma independiente. Este capítulo se va a ocupar únicamente del paso de parámetros por medio de
registros y, en este caso, la arquitectura ARM adopta como convenio el paso mediante los registros r0,
r1, r2 y r3, ya sea para parámetros de entrada, de salida o de entrada/salida. Para aquellos casos en los
que se tengan que pasar más de 4 parámetros, el convenio define cómo pasar el resto de los parámetros
mediante la pila.
El último aspecto a tener en cuenta del paso de parámetros es cómo se transfiere cada uno de los
parámetros. Hay dos formas de hacerlo: por valor o por referencia. Se dice que un parámetro se pasa
por valor cuando lo que se transfiere es el dato en sí. Por otra parte, un parámetro se pasa por
referencia cuando lo que se transfiere es la dirección de memoria en la que se encuentra dicho dato.

Paso de parámetros por valor


Como se ha comentado, un parámetro se pasa por valor cuando únicamente se transfiere su valor. El
paso de parámetros por valor implica la siguiente secuencia de acciones:
1. Antes de realizar la llamada a la subrutina, el programa invocador carga el valor de los
parámetros de entrada en los registros correspondientes.
2. La subrutina, finalizadas las operaciones que deba realizar y antes de devolver el control al
programa invocador, carga el valor de los parámetros de salida en los registros
correspondientes.
3. El programa invocador recoge los parámetros de salida de los registros correspondientes.
Paso de parámetros por referencia
Como ya se ha comentado, el paso de parámetros por referencia consiste en pasar las direcciones de
memoria en las que se encuentran los parámetros. Para pasar los parámetros por referencia se debe
realizar la siguiente secuencia de acciones:
1. Antes de realizar la llamada a la subrutina, el programa invocador carga en los registros
correspondientes, las direcciones de memoria en las que está almacenada la información que se
quiere pasar.
2. La subrutina carga en registros el contenido de las direcciones de memoria indicadas por los
parámetros de entrada y opera con ellos (recuerda que ARM no puede operar directamente con
datos en memoria).
3. La subrutina, una vez ha finalizado y antes de devolver el control al programa principal, almacena
los resultados en las direcciones de memoria proporcionadas por el programa invocador.
Practica: Resolver el ejercicio 6.9 del libro

También podría gustarte