Blogia
Las Pequeñas Paranoyas de Motagirl

Punteros y modelos de memoria

Hace un par de días sufrí en propias carnes algo que nadie jamás me había explicado hasta ese momento: La diferencia entre los punteros near y los punteros far.  Resulta que un puntero far ocupa cuatro bytes porque guarda el segmento  (2bytes) y el offset (otros 2bytes), mientras que un puntero near sólo ocupa dos bytes porque sólo guarda el offset.¿Qué significa esto? Que con un puntero near NO puedes acceder a otro segmento distinto al que estás usando. Curioso...

(Para los que no sepan de qué hablo: un puntero es mas o menos como una variable, pero en vez de guardar un valor (’2’, ’3’, "patata") guarda otra dirección de memoria (04E6,0000 por ejemplo)).

Otra cosa importante es el modelo de memoria  elegido. Esto representa el modelo de "cómo" accederá a memoria el compilador. En TurboC podemos elegir entre Tiny, Small, Medium, Compact, Large y Huge. Estos se diferencian en los tamaños de los segmentos de código, datos y pila, y en el  tipo de los punteros. Podría explicarlo en modo  texto pero se ve más claro en una tabla:

SEGMENTOSPUNTEROS
MODELOCODIGO        |  DATOS   | PILACODIGO  | DATOS
Tiny64Kbnear
Small64Kb64Kbnear
Medium1Mb64Kbfarnear
Compact64Kb1Mbnearfar
Large1Mb1Mbfar
Huge1Mb

1Mb
(bloques > 64Kb)

far

Por ejemplo, el modelo Medium se utiliza para programas  pequeños que utilizan pocos datos, al contrario  que el Compact, que es usado para programas pequeños que utilizan gran cantidad de datos.

Como  ejemplo de lo "importante" (pasad por alto la trivialidad del programa de  ejemplo xD) que puede llegar a ser esto (habérmelo leído antes me hubiera ahorrado una tarde de programas con comportamientos erráticos), os expongo el ejemplo que me trajo de cabeza a mí. Resulta que el compilador que usamos para esta asignatura, Borland TurboC (sí,  algo actual  y todo eso) sobre MS-DOS (idem) viene por defecto con el model Small. Y claro, para esto necesitabamos como mínimo Compact (aunque vamos de sobraos y lo recomendado era Huge)

El programa en cuestión consiste en acceder a la memoria de video y escribir directamente en ella para crear un rectángulo con  un carácter y todas las variantes de color de carácter y color de fondo. El acceso a la memoria se realiza mediante un puntero, tal que así:

char *p = MK_FP(0xB800, 0x000)

donde MK_FP indica  que queremos un puntero far (FP,Far Pointer) y 0xB800, 0x0000 indica el inicio del segmento 0xB800, que es el de video.

Así que,  nos  ponemos manos a la obra y compilamos/enlazamos/ejecutamos con varios  modelos de memoria (esto se puede cambiar desde Options/Compiler/Model en el TurboC)

-Tiny, Small y Medium:

Los "efectos" son variados, desde  un warning al compilar ("Conversión sospechosa de puntero"), warning al enlazar ("No hay pila"), error al ejecutar ("Instrucción no permitida") hasta autoabortos:

Small

Bueno, al menos no me salta el antivirus como hace un par de años xD

 

-Compact, Large y Huge:

Ahora sí que se está accediendo al segmento "bueno" por ser un puntero far, y el resultado es justo el que esperábamos:

Huge

¿A que es mono? Pues casi lagrimeo un poco cuando  descubrí que mi código  era bonito y maravilloso pero que el error estaba en el modelo de memoria elegido. Ahora seguro que ya no se me vuelve a olvidar :D

 

 

8 comentarios

Mariella -

Soy una perra hasta el pincho tu BLOG ALA FIRME ,SOY DE LA USMP.

Oscar -

oh... ahora entiendo... bien me dijo mi madre... -no hagas superposiciones antes de conocer :p

Te agradezco lo del código, realmente ando aprendiendo C++ (principiante) y tenía una duda con apuntadores y llegué aquí... y bueno siempre es bueno ver códigos.
Saludos

motagirl2 -

Hola Oscar, me alegro de que te gustara :)
Lo de los canibalizadores es porque el cacho de código en cuestión era una práctica de la universidad, y no da gusto que tras pegarte el curro alguien llegue y presente el mismo código pero con su nombre...
Te lo envío al correo si quieres.

Oscar Rovira -

Me agradó tu forma de explicar incluso más que la explicación en si.
hubiera sido bueno tener el código.
Saludos.

p.d. no estoy muy de acuerdo con lo de los "canibalizadores" de código.
realmente hablas de un pequeño código y no de un programa y aún así y para irnos lejos y no hacer tan grande la p.d... Basta con ver linux GNU... un buen open source no?..
saludos

motagirl2 -

Te lo mando por private, que los canibalizadores de código están en todas partes xD

Tú -

genialtástico post, no tenía ni puta idea de que existieran diferentes tipos de punteros.

Voy a revisar mis programillas con punteros, porque yo también programaba con el TurboC de borland, y no entiendo por qué no me petó nunca ninguno si por defecto te viene small.

P.D. Compact para mostrar el cuadro de coloreh? se pué ver el código fuente?

ajota -

Con post como este voy a dejar de tomar notas en las prácticas de periferals :P

effervescente -

Ey! Pues a mi me estaba pasando lo mismo! así que me ha servido. Muchas gracias por la explicación, deberías hacerlo más a menudo ¿eh?.
Nos vemos :*