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 445 — #483<br />

✐<br />

15.5. Cómo implem<strong>en</strong>ta <strong>C++</strong> la ligadura dinámica<br />

y el objeto se figura que debe hacer con él.<br />

15.5.3. Detrás del telón<br />

Puede ser útil ver el código <strong>en</strong>samblador que se g<strong>en</strong>era con la llamada a una<br />

función virtual, para poder ver como funciona la ligadura dinámica. Aquí está la<br />

salida de un compilador a la llamada<br />

i.adjust(1);<br />

d<strong>en</strong>tro de la función f(Instrum<strong>en</strong>t& i):<br />

push 1<br />

push si<br />

mov bx, word ptr [si]<br />

call word ptr [bx+4]<br />

add sp, 4<br />

Los argum<strong>en</strong>tos de una llamada a una función <strong>C++</strong>, como los de a una función C,<br />

son colocados <strong>en</strong> la pila de derecha a izquierda (este ord<strong>en</strong> es necesario para poder<br />

soportar las listas de argum<strong>en</strong>tos variables de C), por lo que el argum<strong>en</strong>to 1 se pone<br />

al principio <strong>en</strong> la pila. En este punto <strong>en</strong> la función, el registro si (que es parte de<br />

la arquitectura del procesador Intel X86) conti<strong>en</strong>e la dirección de i. También se<br />

introduce <strong>en</strong> la pila porque es la dirección de comi<strong>en</strong>zo del objeto de interés. Hay<br />

que recordar que la dirección del comi<strong>en</strong>zo del objeto corresponde al valor de this,<br />

y this es introducido <strong>en</strong> la pila de manera oculta antes de cualquier llamada<br />

a función, por lo que la función miembro sabe sobre qué objeto <strong>en</strong> concreto está<br />

trabajando. Debido a esto se verá siempre uno más que el número de argum<strong>en</strong>tos<br />

introducidos <strong>en</strong> la pila antes de una llamada a una función miembro (excepto para<br />

las funciones miembro static, que no ti<strong>en</strong><strong>en</strong> this).<br />

Ahora se puede ejecutar la llamada a la función virtual. Primero hay que producir<br />

el VPTR para poder <strong>en</strong>contrar la VTABLE. Para el compilador el VPTR se inserta al<br />

principio del objeto, por lo que el cont<strong>en</strong>ido de this corresponde al VPTR. La línea<br />

mov bx, word ptr [si]<br />

busca la dirección (word) a la que apunta si, que es el VPTR y la coloca d<strong>en</strong>tro<br />

del registro bx.<br />

El VPTR cont<strong>en</strong>ido <strong>en</strong> bx apunta a la dirección inicial de la VTABLE, pero el puntero<br />

de la función a llamar no se <strong>en</strong>cu<strong>en</strong>tra <strong>en</strong> la posición cero de la VTABLE, si no<br />

<strong>en</strong> la segunda posición (debido a que es la tercera función <strong>en</strong> la lista). Debido al modelo<br />

de memoria cada puntero a función ocupa dos bytes, por lo que el compilador<br />

suma cuatro al VPTR para calcular donde está la dirección de la función apropiada.<br />

Hay que hacer notar que este es un valor constante establecido <strong>en</strong> tiempo de compilación,<br />

por lo que lo único que ocurre es que el puntero a función que está <strong>en</strong> la<br />

posición dos apunta a adjust(). Afortunadam<strong>en</strong>te, el compilador se <strong>en</strong>carga de<br />

todo y se asegura de que todos los punteros a funciones <strong>en</strong> todas las VTABLEs de<br />

una jerarquía particular se cre<strong>en</strong> con el mismo ord<strong>en</strong>, a pesar del ord<strong>en</strong> <strong>en</strong> que se<br />

hayan sobreescrito las funciones <strong>en</strong> las clases derivadas.<br />

Una vez se ha calculado <strong>en</strong> la VTABLE la dirección del puntero apropiado, se<br />

llama a la función a la que apunta el puntero. Esto es, se busca la dirección y se llama<br />

445<br />

✐<br />

✐<br />

✐<br />

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

Saved successfully!

Ooh no, something went wrong!