¿Alguien puede explicarme estos punteros con un ejemplo adecuado … y cuando estos punteros se utilizan?

  • huele a la tarea
  • en particular, para los muy teen-age «any1»
  • Recuerdo aquellos en Turbo-C, hace años…
  • sólo son relevantes en 16-bits en plataformas de intel, que son obsoletos. Me compadezco de usted si usted necesita para mantener el código o escribir código nuevo en esta plataforma.
  • «Lo que está cerca, lejos, y [ha] punteros de grandes?» Eso es un difícil acertijo, yo diría 😉
  • amolbagde.110mb.com/cracktheinterview/pages/6_16.html
  • Si esta es una tarea de toda duda, que la escuela realmente necesita para conseguir que los nuevos equipos para su CS aula.
  • «son sólo relevantes en 16-bit intel plataformas de’ erm, ¿qué acerca de las plataformas integradas, Dsp, etc? No puedo creer que aquí todo el mundo está diciendo que esto es viejo y obsoleto, por favor, hacer un poco de investigación primero

InformationsquelleAutor | 2010-08-26

6 Comentarios

  1. 13

    En los viejos tiempos, de acuerdo con el Turbo C manual, cerca de un puntero era meramente de 16 bits cuando la totalidad de su código y los datos de ajuste en el segmento. Un puntero lejos estaba compuesto de un segmento, así como un desplazamiento, pero no a la normalización se realizó. Y un enorme puntero automáticamente normalizado. Dos punteros far podría apuntar a la misma ubicación en la memoria, pero serán diferentes, mientras que la normalizado enorme punteros apuntando a la misma ubicación de memoria será siempre igual.

    • gracias .. bt u puede decirme ejemplo .. por lo que se usble en el presente también .
    • No, realmente no son utilizables para el nuevo código. Ellos eran sólo para los 16 bits de las plataformas de Intel, los cuales fueron declarados obsoletos hace mucho tiempo (creo que el Intel 386 fue el primer chip de apoyo para la 32 bits de memoria plana modelo de eficacia). Si estás escribiendo código que tiene que preocuparse acerca de esto, usted está escribiendo el código de la herencia.
    • gracias PP y Billy.. yo tengo nw .
  2. 29

    El ejemplo principal es la arquitectura Intel X86.

    El Intel 8086 era, internamente, una de 16 bits procesador: todos sus registros de 16 bits de ancho. Sin embargo, el autobús de dirección de 20 bits de ancho (1 MiB). Esto significaba que no podía sostener una dirección completa en un registro, que limita a los primeros 64 kiB.

    De Intel solución fue la creación de 16-bit «registros de segmento», cuyo contenido sería desplazado a la izquierda cuatro bits y se añade a la dirección. Por ejemplo:

    DS ("Data Segment") register:  1234 h
    DX ("D eXtended") register:   + 5678h
                                  ------
    Actual address read:           179B8h

    Esto creó el concepto de 64 kiB segmento. Por lo tanto una «cerca» puntero sería el contenido del registro DX (5678h), y podría ser válido a menos que el registro de DS ya estaba configurado correctamente, mientras que un «ahora» puntero de 32 bits (12345678h, DS seguido por DX) y siempre (pero fue más lento ya que tenía que cargar los dos registros y, a continuación, restaurar el registro de DS cuando se hace).

    (Como supercat las notas de abajo, un desplazamiento a DX que se desbordó sería «roll over» antes de ser añadido a la DS para obtener la dirección final. Esto permitió a los desplazamientos de 16 bits para acceder a cualquier dirección en el 64 kiB segmento, no sólo de la parte que fue de ± 32 kiB de donde DX señalado, como se hace en otras arquitecturas de 16 bits desplazamiento relativo de direccionamiento en algunas instrucciones.)

    Sin embargo, tenga en cuenta que usted podría tener dos «lejos» de los punteros que son diferentes los valores, sino que apuntan a la misma dirección. Por ejemplo, el puntero lejos 100079B8h puntos en el mismo lugar, como 12345678h. Por lo tanto, puntero de la comparación de punteros far fue una operación no válida: los indicadores pueden diferir, pero todavía apuntan al mismo lugar.

    Esto fue lo que me decidió que los Macs (con procesadores Motorola 68000 en el tiempo) no eran tan malos después de todo, así que me lo perdí en gran punteros. Si mal no recuerdo, sólo estaban lejos de los punteros que garantiza que toda la superposición de los bits en los registros de segmento fueron de 0, como en el segundo ejemplo.

    Motorola no tiene este problema con sus 6800 series de procesadores, ya que se limita a 64 kiB, Cuando se creó el 68000 de la arquitectura, que se fue directamente a la 32 bits de los registros, y por lo tanto nunca tuvo necesidad de cerca, lejos, o punteros de grandes. (Lugar, su problema era que sólo la parte inferior de 24 bits de la dirección que realmente importaba, por lo que algunos programadores (notoriamente Apple) usaría el alta de 8 bits como «puntero banderas», causando problemas cuando los buses de direcciones ampliado a 32 bits (4 Gb).)

    Linus Torvalds acaba de celebrar hasta el 80386, que ofrece un «modo protegido», donde las direcciones son de 32 bits, y los registros de segmento fueron la mitad alta de la dirección, y no era necesario añadir, y escribió Linux desde el principio para uso sólo en modo protegido, no extraña segmento de cosas, y es por eso que no tienes cerca y de lejos puntero soporte en Linux (y por qué no de la empresa el diseño de una nueva arquitectura, que jamás va a volver a ellos si quieren el soporte de Linux). Y comieron de Robin juglares, y hubo gran regocijo. (Yay…)

    • Curiosamente, muchos 68000 programas basados terminó con 32K limitaciones en los lugares donde 8088 software tendría 64 KB limitaciones. Dado que la memoria era a menudo escasos, y que el 8088 de 16 bits cantidades en lugares donde el 68000 se necesitaría el uso de las cantidades de 32 bits o la aceptación de 32K límites, el 8088 era en realidad una muy práctico diseño.
    • El «32k límite» para el 68k fue cuando se utiliza un 16 bits desplazamiento relativo de las ramas y de los saltos. Si no hacemos el intento de ordenar las funciones en el segmento de código para tratar de mantener las cosas juntas, que acababa de dar y dar una palmada a un límite de 32 kb, sobre todo cuando usted podría haber tenido un límite de 64 kb. Es todavía menos de un desastre que el sistema Intel donde los diferentes valores de los punteros en realidad podría ser igual. De nuevo, la historia, e incluso sistemas embebidos tienen ningún problema en hacer el direccionamiento de 32 bits a la derecha en estos días.
    • En el Macintosh classic, muchas de las estructuras de datos se limita a 32K porque el OS optado por utilizar 16 bits tipos para muchos fines en lugar de 32 bits tipos; yo esperaría que el mismo sería cierto con una gran cantidad de memoria limitada de software para el 68000 de la plataforma (especialmente la de los 16 bits de bus de variantes). El 68000 del addr+disp16 instrucciones de todo signo-extender el desplazamiento para permitir que tanto los positivos y negativos de desplazamiento. El 8088, sin embargo, puede permitir que un 16 bits de desplazamiento para llegar a +/-65535 bytes dentro de un único objeto, en lugar de +/-32767 bytes, si el desplazamiento se ajusta dentro de un segmento.
    • El clásico Mac límites se remontan a la locura lo que hicieron para empacar las cosas en 128K RAM total, tales como el uso de las (entonces no utilizados) de 8 bits superiores en el sistema de propiedad de los punteros como banderas, y el hecho de que integer en Pascal fue de 2 bytes. (Por otro lado, las cadenas Pascal le dio a usted O(1) la longitud de la cadena en el cálculo, la capacidad de tener valores nulos en las cadenas, y una casi total ausencia de errores de desbordamiento de búfer.) 86 de la serie vamos a compensaciones «envolvente» en un segmento, pero a costa de quedarse con registros de segmento y de cerca y de lejos de los punteros.
    • La memoria no es libre, y aún hoy en día una gran cantidad de aplicaciones se ejecuten más rápido cuando compilado para 32-bit x86 que cuando se compila para x64, a pesar del hecho de que el modo de 64 bits tiene un mayor conjunto de registro. La única significativa del rendimiento pega que puedo ver por el modo de 64 bits es que la versión de 64 bits de las referencias de objeto engullir dos veces como mucho caché de 32 bits queridos. El 8086 realmente necesita un par de registros de segmento, pero aún así, yo diría que lo hace un mejor trabajo de abordar 1MiB de espacio de direcciones de cualquier otra arquitectura de 16 bits antes o después (el M68K es una arquitectura de 32 bits).
    • «donde las direcciones son de 32 bits, y los registros de segmento fueron la mitad alta de la dirección,» Esto es incorrecto. De 32 bits se utilizan direcciones de 32-bit compensaciones que se celebró en registros de 32 bits. Estos son técnicamente «cerca de» punteros debido a que el selector se utiliza todavía, sólo apunta a un piso de 4 GiB descriptor normalmente. El selector de registros no se sostienen «la mitad alta de la dirección».

  3. 21

    Diferencia entre la medida y la enorme punteros:

    Como sabemos por defecto, los punteros son near por ejemplo: int *p es un near puntero. Tamaño de near puntero es de 2 bytes en el caso de 16 bits compilador. Y ya sabemos muy bien el tamaño varía el compilador, sólo almacenar el desplazamiento de la dirección del puntero de referencia. Una dirección que consta de sólo un desplazamiento tiene un rango de 0 – 64K bytes.

    Far y huge punteros:

    Far y huge punteros tienen un tamaño de 4 bytes. Almacenan tanto en el segmento y el desplazamiento de la dirección del puntero de referencia. Entonces, ¿cuál es la diferencia entre ellos?

    Limitación de puntero lejos:

    No podemos cambiar o modificar la dirección de segmento dado mucho la dirección de la aplicación de cualquier operación aritmética sobre ella. Que es mediante el operador aritmético no se puede saltar de un segmento a otro segmento.

    Si que se incrementará la dirección de extremo más allá del valor máximo de su desplazamiento de direcciones en lugar de incrementar dirección de segmento se volverá a repetir su desplazamiento de direcciones en un orden cíclico. Esto también se llama la envoltura, es decir, si el desplazamiento es 0xffff y añadimos 1 entonces es 0x0000 y del mismo modo, si se disminuye 0x0000 por 1 a continuación, se 0xffff y recuerda que no hay cambio en el segmento.

    Ahora voy a comparar enorme y muy lejos de los punteros :

    1.Cuando mucho, un puntero se incrementa o decrementa SÓLO el desplazamiento del puntero es en realidad incrementa o disminuye, pero en caso de gran puntero tanto en el segmento y offset valor de cambio.

    Considere el siguiente Ejemplo, tomado de AQUÍ :

     int main()
        {
        char far* f=(char far*)0x0000ffff;
        printf("%Fp",f+0x1);
        return 0;
      }

    entonces la salida es:

    0000:0000

    No hay ningún cambio en el valor de segmento.

    Y en caso de gran Punteros :

    int main()
    {
    char huge* h=(char huge*)0x0000000f;
    printf("%Fp",h+0x1);
    return 0;
    }

    La Salida es:

    0001:0000

    Esto es debido a la operación de incremento no sólo el valor de desplazamiento pero segmento de valor de cambio.Eso significa que el segmento no va a cambiar en caso de far punteros, pero en caso de huge puntero, se puede pasar de un segmento a otro .

    2.Cuando los operadores relacionales se utilizan en la medida de punteros sólo los desplazamientos de la comparación.En otras palabras operadores relacionales sólo funcionará en la medida de punteros si el segmento de los valores de los indicadores que se comparan son los mismos. Y en el caso de grandes esto no va a suceder, en realidad, la comparación de direcciones absolutas se lleva a cabo.Vamos a entender con la ayuda de un ejemplo de far puntero :

    int main()
    {
    char far * p=(char far*)0x12340001;
    char far* p1=(char far*)0x12300041;
    if(p==p1)
    printf("same");
    else
    printf("different");
    return 0;
    }

    De salida:

    different

    En huge puntero :

    int main()
    {
    char huge * p=(char huge*)0x12340001;
    char huge* p1=(char huge*)0x12300041;
    if(p==p1)
    printf("same");
    else
    printf("different");
    return 0;
    }

    De salida:

    same

    Explicación: Como podemos ver la dirección absoluta para ambos p y p1 es 12341 (1234*10+1 o 1230*10+41) pero no son considerados iguales en el 1er caso, ya que en caso de far punteros sólo desplazamientos son, en comparación, es decir que se va a comprobar si 0001==0041. Lo cual es falso.

    Y en caso de gran punteros, la comparación se realiza la operación en direcciones absolutas que son iguales.

    1. Un puntero lejos nunca es normalizada pero un huge puntero está normalizado . Una normalizado puntero es el que tiene tanto de la dirección como sea posible en el segmento, lo que significa que el desplazamiento nunca es mayor que 15.

      supongo que si tenemos 0x1234:1234, a continuación, la forma normalizada de es 0x1357:0004(dirección absoluta es 13574).
      Un enorme puntero se normaliza sólo cuando alguna operación aritmética que se realiza en ella, y no se normalizan durante la asignación.

       int main()
       {
        char huge* h=(char huge*)0x12341234;
        char huge* h1=(char huge*)0x12341234;
        printf("h=%Fp\nh1=%Fp",h,h1+0x1);
        return 0;
       }

      De salida:

      h=1234:1234
      
      h1=1357:0005

      Explicación:huge puntero no se encuentra normalizado en el caso de la cesión.Pero si una operación aritmética que se realiza en él, va a ser normalizado.Así, h es 1234:1234 y h1 es 1357:0005que está normalizado.

      4.El desplazamiento de enormes puntero está a menos de 16 porque de normalización y no así en el caso de los punteros far.

      veamos un ejemplo para entender lo que quiero decir :

       int main()
        {
        char far* f=(char far*)0x0000000f;
        printf("%Fp",f+0x1);
        return 0;
        }

    De salida:

        0000:0010

    En caso de huge puntero :

          int main()
          {
          char huge* h=(char huge*)0x0000000f;
            printf("%Fp",h+0x1);
            return 0;
            }
    
            Output:
            0001:0000

    Explicación:a medida que incrementamos el puntero lejos por 1 será 0000:0010.Y como hemos incremento enorme puntero por 1 entonces será 0001:0000 porque es de desplazamiento no puede ser mayor que 15 en otras palabras, se puede normalizar.

    • +1 por el contenido.Asegúrese de formatear tu respuesta correctamente la próxima vez.
    • Finalmente entiendo las diferencias. Gracias.
    • Esto es la falta de una mención de los HMA y cómo interactúa con el puntero enorme normalización. (NB no sé cómo compiladores de tratar esto, sólo sé que cuando la normalización de un puntero que desee punto en el HMA, debe permitir los desplazamientos de más de 15.)
  4. 3

    Todas las cosas en esta respuesta sólo es pertinente para la edad 8086 y 80286 memoria segmentada modelo.

    cerca de: un 16 bits puntero que puede abordar cualquier byte de un segmento de 64 kb

    el momento: una de 32 bits puntero que contiene un segmento y un desplazamiento. Tenga en cuenta que debido a que los segmentos se pueden solapar, dos diferentes lejos de los punteros pueden apuntar a la misma dirección.

    enorme: una de 32 bits puntero en la que el segmento está «normalizada» de modo que no hay dos punteros apuntan a la misma dirección a menos que tengan el mismo valor.

    tee: una bebida con pan y mermelada.

    Que nos traerá de regreso a la doh oh, oh, oh

    y cuando estos punteros se utilizan?

    en la década de 1980 y 90′ hasta 32 bits de Windows se convirtió en omnipresente,

    • ^ ^ al fin tenemos algo en breve !
  5. 2

    Esta terminología fue utilizada en 16 bits arquitecturas.

    De 16 bits de los sistemas, los datos se dividen en segmentos de 64 kb. Cada módulo cargable (programa de archivo, biblioteca cargada dinámicamente etc) tenía asociado un segmento de datos – que se podría almacenar hasta 64 kb de datos.

    Un puntero CERCANO fue un puntero con 16 bits de almacenamiento, y se refirió a los datos (sólo) en los módulos actuales segmento de datos.

    16bit programas que tenían más de 64 kb de datos como un requisito de acceso especial asignadores de que iba a devolver un puntero LEJOS – que era un segmento de datos de identificación en la parte superior de 16 bits, y un puntero a ese segmento de datos, en los 16 bits más bajos.

    Aún más grande de los programas de querer lidiar con más de 64 kb de datos contiguos. Un ENORME puntero se ve exactamente como un puntero far – tiene 32 bits de almacenamiento – pero el asignador ha tenido el cuidado de organizar una amplia gama de segmentos de datos, con el consecutivo IDs, por lo que simplemente incrementar el segmento de datos selector de la siguiente fragmento de 64 kb de datos puede ser alcanzado.

    El subyacente de C y C++ lenguaje de las normas nunca realmente reconocido estos conceptos oficialmente en sus modelos de memoria – todos los punteros en C o C++ programa que se supone son del mismo tamaño. Así que la CERCA, LEJOS y ENORMES atributos fueron extensiones proporcionados por los distintos proveedores de compiladores.

  6. 2

    En algunas arquitecturas, un puntero que puede apuntar a cada objeto en el sistema será más grande y más lento para trabajar con más de uno, que puede apuntar a un subconjunto útil de las cosas. Muchas personas se han dado respuestas relacionadas con los 16 bits de la arquitectura x86. Varios tipos de punteros eran comunes en sistemas de 16 bits, aunque cerca de/del miedo distinciones podría reaparecer en sistemas de 64 bits, dependiendo de cómo están implementadas (no me sorprendería si muchos de los sistemas de desarrollo ir a punteros de 64 bits para todo, a pesar del hecho de que en muchos de los casos que va a ser muy inútil).

    En muchos programas, es bastante fácil para subdividir el uso de la memoria en dos categorías: las pequeñas cosas que suman un total de hasta una cantidad bastante pequeña de material (64 KB o 4 gb), pero se accede con frecuencia, y más cosas que puedan total mucho mayor en cantidad, pero que no necesita ser accedido tan a menudo. Cuando una aplicación necesita para trabajar con la parte de un objeto en las «cosas grandes» de la zona, se copia a la parte a «las pequeñas cosas» de la zona, trabaja con ella, y si es necesario, escribe de nuevo.

    Algunos programadores se queja de tener que distinguir entre «cerca» y «lejos» de la memoria, pero en muchos casos, haciendo que tales distinciones pueden permitir que los compiladores de producir mucho mejor código.

    (nota: Incluso en muchos sistemas de 32 bits, en ciertas áreas de memoria que se puede acceder directamente sin instrucciones adicionales, mientras que otras zonas no. Si, por ejemplo, en un 68000 o un BRAZO, uno se mantiene un registro que apunta a la variable global de almacenamiento, será posible cargar cualquier variable dentro de la primera 32K (68000) o 2K (BRAZO) del registro. Obtención de una variable almacenada en otro lugar se requiere una instrucción adicional para calcular la dirección. La colocación más frecuente variables utilizadas en el preferido de las regiones y dejar que el compilador sabe permitiría más eficiente la generación de código.

    • ¿Qué significa que el puntero enorme automáticamente normalizado, mientras que el puntero lejos ¿no ? ¿Qué significa la palabra «normalizar» significa aquí?
    • Cada puntero en el 8086 tiene dos de 16 bits partes–un segmento que es difícil de manipular, y un desplazamiento que puede ser manipulado de forma mucho más cómoda. Direcciones de Hardware son tomadas por multiplicar el segmento de 16 y añadir el desplazamiento. Objetos de hasta 65536 bytes, los cuales están alineados en límites de 16 bytes pueden ser fácilmente manipulados por establecer el segmento de modo que identifica el inicio del objeto y, a continuación, mediante el desplazamiento a los lugares de acceso dentro de ella, pero el hecho de que cada lugar puede ser identificado 4096 diferentes maneras a veces puede ser problemático.
    • La normalización de un puntero significa reemplazar con un puntero que identifica a la misma ubicación física, pero tiene un desplazamiento en el rango de 0 a 15 años. Para algunos patrones de uso, los operadores relacionales y aritmética de apuntadores que ignoran el segmento en total va a cumplir con el Estándar de C y el trabajo, pero implicaría que uno puede tener dos diferentes punteros cuya diferencia es cero, y ninguno de los cuales es mayor que el otro, pero que no obstante son desiguales y que el acceso a diferentes cosas. Tener operadores relacionales tratar punteros como valores de 32 bits (con el segmento como la parte superior de la palabra)…
    • …de trabajo para muchos de los patrones de uso, pero aún así pueden viaje hasta en algunos de los escenarios que se trate de prueba para el puntero se superponen. Me gustaría que la Norma se definen las características intrínsecas para probar si dos punteros «podría» se superponen, o si definitivamente se superponen, ya que el primero puede ser determinado de forma más barata que la segunda, pero en muchos casos sería igual de útil.

Dejar respuesta

Please enter your comment!
Please enter your name here