13.01.2015 Views

Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO

Pensar en C++ (Volumen 1) - Grupo ARCO

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

✐<br />

✐<br />

✐<br />

“Volum<strong>en</strong>1” — 2012/1/12 — 13:52 — page 313 — #351<br />

✐<br />

11.3. El constructor de copia<br />

función es colocar los argum<strong>en</strong>tos <strong>en</strong> la pila. Sin embargo, <strong>en</strong> el código <strong>en</strong>samblador<br />

de PassingBigStructures.cpp se ve una acción adicional: la dirección de B2<br />

se coloca <strong>en</strong> la pila antes de hacer la llamada a la función aunque, obviam<strong>en</strong>te, no<br />

sea un argum<strong>en</strong>to. Para <strong>en</strong>t<strong>en</strong>der qué pasa, necesita <strong>en</strong>t<strong>en</strong>der las restricciones del<br />

compilador cuando llama a una función.<br />

Marco de pila para llamadas a función<br />

Cuando el compilador g<strong>en</strong>era código para llamar a una función, primero coloca<br />

<strong>en</strong> la pila todos los argum<strong>en</strong>tos y luego hace la llamada. D<strong>en</strong>tro de la función se<br />

g<strong>en</strong>era código para mover el puntero de pila hacia abajo, y así proporciona memoria<br />

para las variables locales d<strong>en</strong>tro de la función. («hacia abajo» es relativo, la máquina<br />

puede increm<strong>en</strong>tar o decrem<strong>en</strong>tar el puntero de pila al colocar un argum<strong>en</strong>to). Pero<br />

cuando se hace el CALL de <strong>en</strong>samblador para llamar a la función, la CPU coloca<br />

la dirección desde la que se realiza la llamada, y <strong>en</strong> el RETURN de <strong>en</strong>samblador se<br />

utiliza esa dirección para volver al punto desde donde se realizó la llamada. Esta<br />

dirección es sagrada, porque sin ella el programa se perdería por completo. He aquí<br />

es aspecto del marco de pila después de ejecutar CALL y poner las variables locales<br />

de la función:<br />

Argum<strong>en</strong>tos de la función<br />

Dirección de retorno<br />

Variables locales<br />

Figura 11.1: Llamada a una función<br />

El código g<strong>en</strong>erado por el resto de la función espera que la memoria t<strong>en</strong>ga esta<br />

disposición para que pueda utilizar los argum<strong>en</strong>tos y las variables locales sin tocar<br />

la dirección de retorno. Llámese a este bloque de memoria, que es todo lo que una<br />

función necesita cuando se la llama, el marco de la función (function frame).<br />

Podría parecer razonable retornar valores mediante la utilización de la pila. El<br />

compilador simplem<strong>en</strong>te los colocaría allí y la función devolvería un desplazami<strong>en</strong>to<br />

que indicara dónde empieza el valor de retorno.<br />

Re-<strong>en</strong>trada<br />

Este problema ocurre porque las funciones <strong>en</strong> C y <strong>C++</strong> pued<strong>en</strong> sufrir interrupciones;<br />

esto es, los l<strong>en</strong>guajes han de ser (y de hecho son) re-<strong>en</strong>trantes. También permit<strong>en</strong><br />

llamadas a funciones recursivas. Esto quiere decir que <strong>en</strong> cualquier punto de ejecución<br />

de un programa puede sufrir una interrupción sin que el programa se vea<br />

afectado por ello. Obviam<strong>en</strong>te la persona que escribe la rutina de servicio de interrupciones<br />

(ISR) es responsable de guardar y restaurar todos los registros que se<br />

utilic<strong>en</strong> <strong>en</strong> la ISR. Pero si la ISR necesita utilizar la pila, ha de hacerlo con seguridad.<br />

(Pi<strong>en</strong>se que una ISR es como una función normal sin argum<strong>en</strong>tos y con valor de retorno<br />

void que guarda y restaura el estado de la CPU. La ejecución de una ISR suele<br />

313<br />

✐<br />

✐<br />

✐<br />

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!