República Bolivariana de Venezuela
Ministerio Del Poder Popular Para La Defensa
Universidad Nacional Experimental Politécn...
Apuntadores
Un puntero o apuntador es una variable que da referencia a una región
de memoria. Es decir, es una variable la...
*Se genera código compacto y eficiente.
*Es una herramienta muy poderosa.
- C usa apuntadores explícitamente con:
*Es la ú...
Otro ejemplo en C++: Se presenta una función que no devuelve ningún
valor, esta función llamada "swap" tiene como parámetr...
x = 10;
y = 20;
printf("x=%dty=%dn",x,y);
swap(&x, &y);
printf("x=%dty=%dn",x,y);
}
void swap(int *px, int *py)
{
int temp...
*Un arreglo No Es una variable. Hacer a = ap y a++ Es Ilegal
Los arreglos son pasados a las funciones, cuando un arreglo e...
¿Cómo se puede hacer lo anterior?
1. Guardar todas las líneas en un arreglo de tipo char grande. Observando
que n marca el...
a[n][m] , nos indica que los elementos del arreglo están guardados renglón por
renglón.
Cuando se pasa un arreglo bidimens...
Si cada apuntador en nomb indica un arreglo de 20 elementos entonces
y solamente entonces 200 chars estarán disponibles (1...
Recordando que con el especificador de almacenamiento de clase static
se reserva en forma permanente memoria el arreglo, m...
Fallas comunes con apuntadores
A continuación se muestran dos errores comunes que se hacen con los
apuntadores.
--No asign...
Un buen programa en C debe revisar lo anterior, por lo que el código
Anterior puede ser reescrito como:
p = (char *) mallo...
2-Realizar un programa que me permita cargar y mostrar un vector de
10 enteros utilizando punteros. Se debe mostrar tambié...
permite especificar a la CPU
distintas.

= 4.294.967.296 direcciones de memoria

Debido a la estructura de 32 bits de un p...
Si hablamos de la asignación lógica encontraremos que existen las
siguientes:
*La asignación dinámica.
*La asignación está...
*Registro de almacenamiento: usado únicamente para el
almacenamiento temporal de la información binaria, la cual no puede ...
Las dos señales de control aplicadas a la unidad de memoria se llaman
lectura y escritura, cada una es referenciada por la...
Métodos de direccionamiento
Generalmente una instrucción consta de una parte de operación y una
de dirección.
La parte de ...
En los lenguajes de programación, se puede acceder a las direcciones
de memoria utilizando punteros. Si bien algunos siste...
Próxima SlideShare
Cargando en…5
×

Trabajo programacion 1 jose silva

227 visualizaciones

Publicado el

trabajo referente a punteros y direccionamiento de memoria, unefa 7mo semestre ing de sistemas

Publicado en: Educación
0 comentarios
0 recomendaciones
Estadísticas
Notas
  • Sé el primero en comentar

  • Sé el primero en recomendar esto

Sin descargas
Visualizaciones
Visualizaciones totales
227
En SlideShare
0
De insertados
0
Número de insertados
2
Acciones
Compartido
0
Descargas
4
Comentarios
0
Recomendaciones
0
Insertados 0
No insertados

No hay notas en la diapositiva.

Trabajo programacion 1 jose silva

  1. 1. República Bolivariana de Venezuela Ministerio Del Poder Popular Para La Defensa Universidad Nacional Experimental Politécnica De La Fuerza Armada UNEFA – Yaracuy Nirgua Apuntadores y Direcciones de Memoria Alumno: José A. Silva Clisanchez CI. 22317008 Ing. De Sistemas 7mo Semestre Octubre 2013
  2. 2. Apuntadores Un puntero o apuntador es una variable que da referencia a una región de memoria. Es decir, es una variable la cual su valor es una dirección de memoria, si se tiene una variable ' p ' de tipo puntero que contiene una dirección de memoria en la que se encuentra almacenado un valor ' v ' se dice que ' p ' apunta a ' v '. El programador utilizará punteros para guardar datos en memoria en muchas ocasiones, de la forma que se describe a continuación. [Memoria] | . | | . | | . | ----- |--------| | p |-->| v | ----- |--------| | . | | . | | . | Algunos lenguajes restringen el uso de apuntadores para que hagan referencia exclusivamente a objetos en el heap (un montículo, es una estructura de Árbol con información perteneciente a un conjunto ordenado. Los montículos tienen la característica de que cada nodo padre tiene un valor mayor que el de todos sus nodos hijos). Los punteros son de amplia utilización en programación y muchos lenguajes permiten la manipulación directa o indirecta de los mismos. La principal razón de ser de los punteros es la de manejar datos alojados en la zona de memoria dinámica o heap (aunque también se pueden manipular objetos en la zona estática), bien sean datos elementales, estructuras (struct en C) u objetos pertenecientes a una clase (en lenguajes Orientados a Objetos). Gracias a esta propiedad, los punteros permiten modelar un grafo, en donde los elementos de éste son los datos residentes en memoria y las relaciones entre los elementos son los propios apuntadores. Los apuntadores son una parte fundamental de C. Si usted no puede usar los apuntadores apropiadamente entonces está perdiendo la potencia y la flexibilidad que C ofrece básicamente. El secreto para C esta en el uso de apuntadores. - C usa los apuntadores en forma extensiva. ¿Por qué? *Es la única forma de expresar algunos cálculos.
  3. 3. *Se genera código compacto y eficiente. *Es una herramienta muy poderosa. - C usa apuntadores explícitamente con: *Es la única forma de expresar algunos cálculos. *Se genera código compacto y eficiente. *Es una herramienta muy poderosa. - C usa apuntadores explícitamente con: *Arreglos, *Estructuras *Funciones -Ejemplo de uso de punteros en una estructura en C El ejemplo que sigue es propio del lenguaje C/C++ y no es de aplicación en otros lenguajes de programación. struct Elemento // Ejemplo de un nodo de lista doble enlazada { int dato; struct Elemento *siguiente; // El '*' es el operador de indirección, y es el usado para declarar punteros struct Elemento *anterior; }; Para acceder a los atributos como punteros de una estructura que va a ser tratada como tal, se debe desreferenciar el puntero y acceder a sus miembros como se haría con una variable normal, o usar directamente el operador: ->. De tal modo que: Elemento *elem; Elemento sig1 = (*elem).siguiente; Elemento sig2 = elem->siguiente; /* Se cumple que: sig1==sig2 */ Los paréntesis en este ejemplo son necesarios, pues el operador '*' es el que menor prioridad de operaciones tiene asignada (por lo que se haría *(elem.siguiente), lo que es incorrecto, pues trataría acceder a un campo de una dirección de memoria, y no de una estructura. Esto es un error sintáctico, en tiempo de compilación).
  4. 4. Otro ejemplo en C++: Se presenta una función que no devuelve ningún valor, esta función llamada "swap" tiene como parámetros dos punteros del tipo int. Así, cuando sea llamada desde alguna parte del programa, recibirá las direcciones de dos variables; luego accederá a dichas variables gracias al operador de indirección (* precediendo al identificador del puntero) y podrá intercambiar sus valores residentes. void swap(int *x, int *y) { int temp; temp = *x; // copia el valor apuntado por x a temp *x = *y; // copia el valor apuntado por y en la ubicación del puntero x *y = temp; // copia el valor de temp en la ubicación apuntada por y } Ejemplo en C# //Suma de dos números enteros private unsafe int Suma(int* a, int* b) { return *a + *b; } // Su uso (El método llamador también debe tener la palabra clave 'unsafe'): // int x, y; // int *ptr1 = &x; // int *ptr2 = &y; // Suma (ptr1, ptr2); Apuntadores y Funciones Cuando C pasa argumentos a funciones, los pasa por valor, es decir, si el parámetro es modificado dentro de la función, una vez que termina la función el valor pasado de la variable permanece inalterado. Hay muchos casos que se quiere alterar el argumento pasado a la función y recibir el nuevo valor una vez que la función ha terminado. Para hacer lo anterior se debe usar una llamada por referencia, en C se puede simular pasando un puntero al argumento. Con esto se provoca que la computadora pase la dirección del argumento a la función. Para entender mejor lo anterior consideremos la función swap() que intercambia el valor de dos argumentos enteros: void swap(int *px, int *py); main() { int x, y;
  5. 5. x = 10; y = 20; printf("x=%dty=%dn",x,y); swap(&x, &y); printf("x=%dty=%dn",x,y); } void swap(int *px, int *py) { int temp; temp = *px; /* guarda el valor de la direccion x */ *px = *py; /* pone y en x */ *py = temp; /* pone x en y */ } Apuntadores y Arreglos Existe una relación estrecha entre los punteros y los arreglos. En C, un nombre de un arreglo es un índice a la dirección de comienzo del arreglo. En esencia, el nombre de un arreglo es un puntero al arreglo. Considerar lo siguiente: int a[10], x; int *ap; ap = &a[0]; /* ap apunta a la dirección de a[0] */ x = *ap; /* A x se le asigna el contenido de ap (a[0] en este caso) */ *(ap + 1) = 100; /* Se asigna al segundo elemento de 'a' el valor 100 usando ap*/ Como se puede observar en el ejemplo la sentencia a[t] es idéntica a ap+t. Se debe tener cuidado ya que C no hace una revisión de los límites del arreglo, por lo que se puede ir fácilmente más allá del arreglo en memoria y sobrescribir otras cosas. C sin embargo es mucho más sutil en su relación entre arreglos y apuntadores. Por ejemplo se puede teclear solamente: ap = a; en vez de ap = &a[0]; y también *(a + i) en vez de a[i], esto es, &a[i] es equivalente con a+i. Y como se ve en el ejemplo, el direccionamiento de apuntadores se puede expresar como: a[i] que es equivalente a *(ap + i) Sin embargo los apuntadores y los arreglos son diferentes: *Un apuntador es una variable. Se puede hacer ap = a y ap++.
  6. 6. *Un arreglo No Es una variable. Hacer a = ap y a++ Es Ilegal Los arreglos son pasados a las funciones, cuando un arreglo es pasado a una función lo que en realidad se le está pasando es la localidad de su elemento inicial en memoria. Por lo tanto: strlen(s) es equivalente a strlen(&s[0]) Esta es la razón por la cual se declara la función como: int strlen(char s[]); y una declaración equivalente es int strlen(char *s); Ya que char s[] es igual que char *s. La función strlen() es una función de la biblioteca estándar que regresa la longitud de una cadena. Se muestra enseguida la versión de esta función que podría escribirse: int strlen(char *s) { char *p = s; while ( *p != '0' ) p++; return p - s; } Se muestra enseguida una función para copiar una cadena en otra. Al igual que en el ejercicio anterior existe en la biblioteca estándar una función que hace lo mismo. void strcpy(char *s, char *t) { while ( (*s++ = *t++) != '0' ); } En los dos últimos ejemplos se emplean apuntadores y asignación por valor. Se emplea el uso del carácter nulo con la sentencia while para encontrar el fin de la cadena. Arreglos de Apuntadores En C se pueden tener arreglos de apuntadores ya que los apuntadores son variables. Un ejemplo de su uso puede ser: ordenar las líneas de un texto de diferente longitud. Los arreglos de apuntadores son una representación de datos que se manejan de una forma eficiente y conveniente líneas de texto de longitud variable.
  7. 7. ¿Cómo se puede hacer lo anterior? 1. Guardar todas las líneas en un arreglo de tipo char grande. Observando que n marca el fin de cada línea como se muestra a continuación en la figura8.1 2. Guardar los apuntadores en un arreglo diferente donde cada apuntador apunta al primer carácter de cada línea. 3. Comparar dos líneas usando la función de la biblioteca estándar strcmp(). 4. Si dos líneas están desacomodadas -- intercambiar (swap) los apuntadores (no el texto). Figura 8.1: Arreglos de apuntadores (Ejemplo de ordenamiento de cadenas). Con lo anterior se elimina: *El manejo complicado del almacenamiento. *Alta sobrecarga por el movimiento de líneas. Arreglos multidimensionales y apuntadores Un arreglo multidimensional puede ser visto en varias formas en C, por ejemplo: Un arreglo de dos dimensiones es un arreglo de una dimensión, donde cada uno de los elementos es en sí mismo un arreglo. Por lo tanto, la notación
  8. 8. a[n][m] , nos indica que los elementos del arreglo están guardados renglón por renglón. Cuando se pasa un arreglo bidimensional a una función se debe especificar el número de columnas, el número de renglones es irrelevante. La razón de lo anterior, es nuevamente los apuntadores. C requiere conocer cuantas son las columnas para que pueda brincar de renglón en renglón en la memoria. Considerando que una función deba recibir int a[5][35], se puede declarar el argumento de la función como: f( int a[][35] ) { ..... } o aún f( int (*a)[35] ) { ..... } En el último ejemplo se requieren los paréntesis (*a) ya que [ ] tiene una precedencia más alta que *. Por lo tanto: int (*a)[35]; declara un apuntador a un arreglo de 35 enteros, y por ejemplo si hacemos la siguiente referencia a+2, nos estaremos refiriendo a la dirección del primer elemento que se encuentran en el tercer renglón de la matriz supuesta, mientras que int *a[35]; declara un arreglo de 35 apuntadores a enteros. Ahora veamos la diferencia (sutil) entre apuntadores y arreglos. El manejo de cadenas es una aplicación común de esto. Considera: char *nomb[10]; char anomb[10][20]; En donde es válido hacer nomb[3][4] y anomb[3][4] en C. Sin embargo: anomb es un arreglo verdadero de 200 elementos de dos dimensiones tipo char. El acceso de los elementos anomb en memoria se hace bajo la siguiente fórmula 20*renglon + columna + dirección_base En cambio nomb tiene 10 apuntadores a elementos.
  9. 9. Si cada apuntador en nomb indica un arreglo de 20 elementos entonces y solamente entonces 200 chars estarán disponibles (10 elementos). Con el primer tipo de declaración se tiene la ventaja de que cada apuntador puede apuntar a arreglos de diferente longitud. Considerar: char *nomb[] = { "No mes", "Ene", "Feb", "Mar", .... }; char anomb[][15] = { "No mes", "Ene", "Feb", "Mar", ... }; Lo cual gráficamente se muestra en la figura 8.2. Se puede indicar que se hace un manejo más eficiente del espacio haciendo uso de un arreglo de apuntadores y usando un arreglo bidimensional. Figura 8.2: Arreglo de 2 dimensiones VS. Arreglo de apuntadores. Inicialización estática de arreglos de apuntadores La inicialización de arreglos de apuntadores es una aplicación ideal para un arreglo estático interno, por ejemplo: func_cualquiera() { static char *nomb[] = { "No mes", "Ene", "Feb", "Mar", .... }; }
  10. 10. Recordando que con el especificador de almacenamiento de clase static se reserva en forma permanente memoria el arreglo, mientras el código se está ejecutando. Apuntadores y Estructuras Los apuntadores a estructuras se definen fácilmente y en una forma directa. Considerar lo siguiente: main() { struct COORD { float x,y,z; } punto; struct COORD *ap_punto; punto.x = punto.y = punto.z = 1; ap_punto = &punto; /* Se asigna punto al apuntador */ ap_punto->x++; ap_punto->y+=2; ap_punto->z=3; /* Con el operador -> se accesan los miembros */ /* de la estructura apuntados por ap_punto */ } Otro ejemplo son las listas ligadas: typedef struct { int valor; struct ELEMENTO *sig; } ELEMENTO; ELEMENTO n1, n2; n1.sig = &n2; La asignación que se hace corresponde a la figura 8.3 Figura 8.3: Esquema de una lista ligada con 2 elementos. Solamente se puede declarar sig como un apuntador tipo ELEMENTO. No se puede tener un elemento del tipo variable ya que esto generaría una definición recursiva la cual no está permitida. Se permite poner una referencia a un apuntador ya que los bytes se dejan de lado para cualquier apuntador.
  11. 11. Fallas comunes con apuntadores A continuación se muestran dos errores comunes que se hacen con los apuntadores. --No asignar un apuntador a una dirección de memoria antes de usarlo int *x *x = 100; Lo adecuado será, tener primeramente una localidad física de memoria, digamos int y; int *x, y; x = &y; *x = 100; --Indirección no válida Supongamos que se tiene una función llamada malloc() la cual trata de asignar memoria dinámicamente (en tiempo de ejecución), la cual regresa un apuntador al bloque de memoria requerida si se pudo o un apuntador a nulo en otro caso. char *malloc() -- una función de la biblioteca estándar que se verá más adelante. Supongamos que se tiene un apuntador char *p Considerar: *p = (char *) malloc(100): /* pide 100 bytes de la memoria */ *p = 'y'; Existe un error en el código anterior. ¿Cuál es? El * en la primera línea ya que malloc regresa un apuntador y *p no apunta a ninguna dirección. El código correcto deberá ser: p = (char *) malloc(100); Ahora si malloc no puede regresar un bloque de memoria, entonces p es nulo, y por lo tanto no se podrá hacer: *p = 'y';
  12. 12. Un buen programa en C debe revisar lo anterior, por lo que el código Anterior puede ser reescrito como: p = (char *) malloc(100): /* pide 100 bytes de la memoria */ if ( p == NULL ) { printf("Error: fuera de memorian"); exit(1); } *p = 'y'; Ejercicios 1-Dado un vector de 10 elementos ={1, 2, 3, 4, 4, 7, 8, 9, 5, 4}, escribir un programa en C (haciendo uso de puntero) que muestre las direcciones de memoria de cada elemento del vector. #include "stdio.h" #include <conio.h> int main(){ int *p, i; int mat[10] ={1, 2, 3, 4, 4, 7, 8, 9, 5, 4}; p=mat; for(i=0; i<=3; i++) { printf("n mat[%d] = %d ",i, *p); printf("tDirecci¢n: %x",p); p++; } getch(); }
  13. 13. 2-Realizar un programa que me permita cargar y mostrar un vector de 10 enteros utilizando punteros. Se debe mostrar también la dirección de memoria de cada elemento del vector. */ #include <stdio.h> #include <conio.h> void main() { clrscr(); int *vdir[10],vect[10]; for(int i=0;i<10;i++) { printf("nInsertar un numero: "); scanf("%d",&vect[i]); vdir[i] = &vect[i]; } for(i=0;i<10;i++) printf("nDireccion de memoria ocupada %d, Valor %d ",vdir[i],vect[i]); getch(); } Direccionamiento De Memoria El direccionamiento de la memoria puede considerarse desde dos puntos de vista: Físico y lógico. El primero se refiere a los medios electrónicos utilizados en el ordenador para acceder a las diversas posiciones de memoria. El segundo a la forma en que se expresan y guardan las direcciones. En este epígrafe nos referiremos exclusivamente a la forma en que son tratadas las direcciones de memoria de la PC. En informática, una dirección de memoria es un identificador para una localización de memoria con la cual un programa informático o un dispositivo de hardware puede almacenar un dato para su posterior reutilización. Una forma común de describir la memoria principal de un ordenador es como una colección de celdas que almacenan datos e instrucciones. Cada celda está identificada unívocamente por un número o dirección de memoria. Para poder acceder a una ubicación específica de la memoria, la CPU genera señales en el bus de dirección que habitualmente tiene un tamaño de 32 bits en la mayoría de máquinas actuales. Un bus de dirección de 32 bits
  14. 14. permite especificar a la CPU distintas. = 4.294.967.296 direcciones de memoria Debido a la estructura de 32 bits de un procesador común como los de Intel, las direcciones de memoria se expresan a menudo en hexadecimal. Por ejemplo. Para no tener que escribir 111111010100000000000010101100 podemos escribir 3F5000AC en hexadecimal. En el bus de direcciones que tiene 20 bits, las posibilidades son 1.048.576 (Rango 00000-FFFFFh). Si tratamos con las direcciones de 16 bits, tenemos acceso a 65.536 posiciones (Rango 0000-FFFFh). Hablando de un bus de direcciones de 8 bits, tiene acceso a 256 posiciones (Rango 00-FFh). EL funcionamiento de la memoria es similar al método utilizado para ordenar la correspondencia en una oficina postal, a cada bit de datos se le asigna una dirección y cada dirección corresponde a una ubicación en la memoria. Cada vez que utilizamos nuestro equipo de computo hacemos uso de la memoria, pero en realidad no nos damos cuenta de cómo es que cada instrucción, operación o movimiento que realizamos se queda registrado en la memoria, listo en todo momento para ser utilizado nuevamente. El proceso para almacenar la información en la memoria se da de la siguiente forma: El procesador envía la dirección para los datos, El controlador de la memoria encuentra la ubicación adecuada y por último, el procesador envía los datos a escribir. La lectura de la información pasa por un proceso semejante: El procesador envía la dirección de los datos solicitados, el controlador de la memoria encuentra los bits de información contenidos en dicha dirección, posteriormente los envía al bus de datos del procesador. Asignación Lógica De Memoria
  15. 15. Si hablamos de la asignación lógica encontraremos que existen las siguientes: *La asignación dinámica. *La asignación estática. Por ejemplo, cuando trabajamos en un lenguaje de programación requerimos de la asignación de memoria y se hace de la siguiente forma; donde por lo general comienza con algunas de las siguientes literales que son parte una parte de la memoria: CS, SS, DS y ES. Asignación Física De Memoria Dentro del Físico podemos acceder a las distintas posiciones de memoria a través de los medios electrónicos. Los registros pueden ser clasificados en 2 tipos: *Circuito operacional: capaz de acumular información binaria en sus flipflop y tiene compuertas capaces de realizar tareas de procesamiento de datos.
  16. 16. *Registro de almacenamiento: usado únicamente para el almacenamiento temporal de la información binaria, la cual no puede ser alterada cuando se transfiere ya sea hacia dentro o fuera del registro. Donde una unidad de memoria es una colección de registros de almacenamiento conjuntamente con los circuitos asociados necesarios para la transferencia de información, los cuales se llaman registros de memoria; esta almacena la información en grupos llamados palabras y cada una de ellas se almacenan en un registro de memoria. La información transferida a los elementos de salida se toma de los registros en la unidad de memoria, se manda a los registros operacionales y el resultado de esto se devuelve a los registros de memoria. Propiedades básicas que debe tener el componente que forma las celdas binarias en la unidad de memoria. 1-Propiedad dependiente de dos estados para la representación binaria. 2-Ser pequeño en tamaño. 3-Bajo costo por bit de almacenamiento. 4-Tiempo de acceso eficaz. Por ejemplo: Núcleos magnéticos, CI semiconductores y superficies magnéticas de cintas, tambores y discos. Una palabra es una entidad de x bits que se mueven hacia dentro y fuera del almacenamiento como una unidad, puede representar un operando, una instrucción, o un grupo de caracteres alfanuméricos o cualquier información codificada binariamente. La comunicación entre una unidad de memoria y lo que la rodea se logra por medio de dos señales: *Las señales de control: especifican la dirección de la trasferencia requerida, cuando una palabra debe ser acumulada en un registro de memoria o cuando una palabra almacenada previamente debe ser transferida hacia afuera del registro de memoria. *Registros externos: Uno especifica el registro de memoria escogido entre los miles disponibles y otro especifica la configuración en bits de dicha palabra. El registro de direcciones de memoria especifica la palabra de memoria seleccionada. A cada una se le asigna un número de identificación comenzando desde 0 hasta el número máximo de palabras disponible, posteriormente el número de localización o dirección se transfiere al registro de direcciones.
  17. 17. Las dos señales de control aplicadas a la unidad de memoria se llaman lectura y escritura, cada una es referenciada por la unidad de memoria. Los circuitos internos de la memoria aceptan esta dirección del registro y abren caminos necesarios para seleccionar la palabra. Después de aceptar una de las señales, los circuitos de control interno dentro de la unidad de memoria suministran la función deseada. La información primaria se destruye cuando se escribe la nueva. La secuencia del control interno en una memoria de lectura destructible debe proveer señales de control que puedan causar que la palabra sea restaurada en sus celdas binarias. La información transferida hacia dentro y fuera de los registros en la memoria y al ambiente externo, se comunica a través de un registro llamado registro separador de memoria (buffer register). Cuando la unidad de memoria recibe una señal de control de escritura, el control interno interpreta el contenido del registro separador como la configuración de bits de la palabra que se va a almacenar en un registro de memoria. Con una señal de control de lectura, el control interno envía la palabra del registro de memoria al registro separador. La secuencia de operaciones necesarias para comunicarse con la unidad de memoria para transferir una palabra hacia afuera dirigida al BR es: 1-Transferir los bits de dirección de la palabra seleccionada al AR. 2-Activar la entrada de control de lectura. La secuencia de operaciones necesarias par a almacenar una nueva: 1-Transferir los bits de direcci6n de la palabra seleccionada al MAR. 2-Transferir los bits de datos de la palabra al MBR. 3-Activar la entrada de control de escritura. Propiedades De La Unidad De Memoria: Construidas con CI semiconductores, retienen la información en el registro de memoria durante el proceso de lectura de manera que no ocurre pérdida. Núcleo magnético, pierde la información binaria almacenada durante el proceso de lectura, debido a esto debe tener funciones de control adicionales para reponer la palabra al registro de memoria.
  18. 18. Métodos de direccionamiento Generalmente una instrucción consta de una parte de operación y una de dirección. La parte de dirección contiene la dirección de un operando utilizado en la ejecución de la instrucción o la dirección donde se encuentra la dirección del operando. En el primer caso la dirección es dirección directa, el segundo es operación indirecta. *Directo: La instrucción contiene la dirección de la posición de memoria donde se encuentra el operando. *Indirecto: Contiene la dirección donde se encuentra la dirección del operando. Relativo: Contiene el número N. En memoria la dirección del operando se encuentra sumando el numero N al número del contador del programa. Indexado: Contiene un número N que puede ser positivo o negativo. *Inmediato: Contiene el mismo operando. Aplicación de direccionamiento de memoria en informática En aplicaciones informáticas las direcciones son asignadas por el sistema operativo a cada programa en ejecución, asegurándose éste, comúnmente por medio de un Daemon, que las direcciones utilizadas por un ejecutable u otro proceso no se solapen o se escriba en posiciones protegidas de memoria, por ejemplo, en el sector de arranque. Los sistemas operativos actuales son comúnmente diferenciados según el ancho de palabra soportado por sus registros, es decir 32 y 64 bits. Estas cifras se refieren a la máxima capacidad que dichos sistemas operativos pueden direccionar, así un sistema de 32 bits podría acceder y direccionar, sin utilizar memoria virtual, un máximo de 232 posiciones de memoria, usualmente designadas por un código hexadecimal. Debido a esto, el rango de valores naturales que pueden ser almacenados en 32 bits es de 0 hasta 4.294.967.295 (0h - FFFFFFFFh), que vienen a ser los famosos 4 gigabytes de capacidad límite de los sistemas operativos de 32 bits. Para los sistemas de 64 bits, siguiendo el razonamiento anterior, obtendríamos 264 posibilidades, lo que se traduce en un rango de valores desde 0 hasta 18.446.744.073.709.551.615 (0h- FFFFFFFFFFFFFFFFh), 18,4 exabytes o 18.400.000.000.000 de gigabytes direccionables.
  19. 19. En los lenguajes de programación, se puede acceder a las direcciones de memoria utilizando punteros. Si bien algunos sistemas operativos y lenguajes actuales no permiten acceder a determinadas direcciones de memoria (o incluso, lenguajes como Java que no implementan punteros), esto no significa que dichas direcciones no existan o no sean correctas. Por ejemplo: La posición de memoria 0h es una posición válida y correcta y es normal que se trabaje sobre ella por ejemplo cuando se modifica la tabla descriptora de interrupciones. Pero cuando se trabaja en modo protegido, los programas ejecutándose como aplicaciones de usuario no tienen acceso a algunas posiciones (entre ellas la 0h), pero en el sistema operativo DOS que trabaja en modo real, se puede acceder a toda la memoria disponible con un simple programa de usuario. Aplicación de direccionamiento de memoria en electrónica En aplicaciones electrónicas una dirección es el identificador único de cada dispositivo conectado a un bus de datos, así el dispositivo maestro dispondrá de un código para seleccionar uno, y solo uno, de los dispositivos esclavos conectados a él.

×