Pergunta

C memória do modelo, com uso de ponteiro de aritmética e de todos, parece modelo de espaço de endereço simples.Computadores de 16 bits usado segmentada de acesso de memória.Como de 16 bits compiladores C lidar com este problema e simular uma televisão de espaço de endereço a partir da perspectiva do programador de C?Por exemplo, que cerca de linguagem de montagem instruções seria o seguinte código para compilar em um 8086?

long arr[65536];  // Assume 32 bit longs.
long i;
for(i = 0; i < 65536; i++) {
    arr[i] = i;
}
Foi útil?

Solução

Como os compiladores C de 16 bits lidaram com esse problema e simularam um espaço de endereço plano da perspectiva do programador C?

Eles não. Em vez disso, eles tornaram a segmentação visível ao programador C, estendendo o idioma tendo vários tipos de indicadores: near, far, e huge. UMA near Ponteiro era apenas um compensado, enquanto far e huge Os ponteiros eram um segmento combinado e deslocamento. Havia uma opção de compilador para definir o Modelo de memória, que determinou se o tipo de ponteiro padrão estava próximo ou longe.

No código do Windows, ainda hoje, você costuma ver typedefs como LPCSTR (por const char*). O "LP" é uma reserva dos dias de 16 bits; significa "Ponteiro Longo (Far)".

Outras dicas

C O modelo de memória não implica de forma alguma um espaço de endereço plano. Nunca fez. De fato, a especificação do idioma c foi projetada especificamente para permitir espaços de endereço não flat.

Na implementação mais trivial com o espaço de endereço segmentado, o tamanho do maior objeto contínuo seria limitado pelo tamanho do segmento (65536 bytes em uma plataforma de 16 bits). Isso significa que size_t Nessa implementação, seria de 16 bits e que seu código simplesmente não compilaria, pois você está tentando declarar um objeto com tamanho maior que o máximo permitido.

Uma implementação mais complexa apoiaria o chamado enorme Modelo de memória. Veja bem, realmente não há problema em abordar blocos de memória contínuos de algum Tamanho em um modelo de memória segmentada, ele requer apenas alguns esforços extras na aritmética do ponteiro. Portanto, dentro do enorme modelo de memória, a implementação faria esses esforços extras, o que tornaria o código um pouco mais lento, mas ao mesmo tempo permitiria abordar objetos de praticamente qualquer tamanho. Portanto, seu código compilaria perfeitamente bem.

Os verdadeiros ambientes de 16 bits usam ponteiros de 16 bits que atingem qualquer endereço. Os exemplos incluem a família PDP-11, 6800 (6802, 6809, 68HC11) e o 8085. Este é um ambiente limpo e eficiente, assim como uma simples arquitetura de 32 bits.

A família 80x86 forçou a nós um espaço de endereço híbrido de 16 bits/20 bits no chamado "modo real"-o espaço de endereçamento 8086 nativo. O mecanismo usual para lidar com isso foi melhorar os tipos de indicadores em dois tipos básicos, near (Ponteiro de 16 bits) e far (Ponteiro de 32 bits). O padrão para os ponteiros de código e dados pode ser definido a granel por um "modelo de memória": tiny, small, compact, medium, far, e huge (Alguns compiladores não suportam todos os modelos).

o tiny O modelo de memória é útil para pequenos programas nos quais todo o espaço (código + dados + pilha) é menor que 64k. Todos os indicadores são (por padrão) 16 bits ou near; Um ponteiro está implicitamente associado a um valor de segmento para todo o programa.

o small O modelo assume que a pilha de dados + é menor que 64k e no mesmo segmento; O segmento de código contém apenas código, portanto, também pode ter até 64k, para uma pegada máxima de memória de 128K. Os ponteiros de código são near e implicitamente associado ao CS (o segmento de código). Os ponteiros de dados também são near e associado ao DS (o segmento de dados).

o medium O modelo possui até 64k de dados + pilha (como pequena), mas pode ter qualquer quantidade de código. Os ponteiros de dados são 16 bits e estão implicitamente ligados ao segmento de dados. Os ponteiros de código são de 32 bits far Ponteiros e têm um valor de segmento, dependendo de como o vinculador configurou os grupos de código (um incômodo de contabilidade nojento).

o compact O modelo é o complemento do meio: menos de 64k de código, mas qualquer quantidade de dados. Os ponteiros de dados são far e os ponteiros de código são near.

Dentro large ou huge Modelo, o subtipo padrão de ponteiros é de 32 bits ou far. A principal diferença é que os enormes indicadores são sempre normalmente normalizados, para que incrementá -los evite problemas com 64k em torno. Ver isto.

No ms-DOS de 16 bits, eu não me lembro de ter sido capaz de fazer isso.Você poderia ter várias coisas que foram cada um de 64 k (bytes)(porque o segmento pode ser ajustada e o desvio de zero), mas não lembro se você pudesse atravessar a fronteira com uma única matriz.O plano de espaço de memória onde você pode willy quer queira quer não atribuir tudo o que você queria e alcance tão profundo como você gostava de uma matriz não aconteceu até poderíamos compilar 32 bits DOS programas (em processadores 386 ou 486).Talvez outros sistemas operacionais e compiladores que a microsoft e borland, o que poderia gerar televisão matrizes maior do que 64kbytes.Win16, eu não me lembro de que a liberdade até win32 bater, talvez a minha memória está ficando enferrujado...Você foi o sortudo ou rico para ter um megabyte de memória de qualquer maneira, um 256kbyte ou 512kbyte máquina não era inédito.Sua unidade de disquete tinha uma fração de meg para 1.44 meg, eventualmente, e o seu disco rígido se qualquer um tivesse uma dúzia ou poucos meg, então você apenas não calcular coisa que grande que, muitas vezes.

Lembro-me do desafio, eu tinha de aprender sobre DNS quando você pode baixar todo o banco de dados do DNS de todos os nomes de domínio registrado no planeta, na verdade, você tinha de colocar o seu próprio servidor de dns que era quase obrigatório na hora de ter um web site.Esse arquivo foi 35megabytes, e o meu disco rígido foi de 100 mb, além de dos e windows mastigando alguns dos que isso.Provavelmente tinha 1 ou 2 mb de memória, poderia ter sido capaz de fazer de 32 bits dos programas no momento.Se ele estava me querendo para analisar o arquivo ascii que eu fiz em várias passagens, mas a cada passagem que a saída tinha que ir para outro arquivo, e eu tive que excluir o antes arquivo de ter espaço em disco para o próximo arquivo.Dois controladores de disco em um padrão de placa-mãe, um para o disco rígido e a outra para a unidade de cd-rom, aqui, novamente, este material não era barato, não havia uma grande quantidade de reposição slots isa, se você pode pagar um outro disco rígido e placa de controlador de disco.

Havia ainda o problema da leitura 64kbytes com C você passou fread o número de bytes que você queria ler em um de 16 bits, int, o que significava 0 a 65535 não 65536 bytes, e o desempenho caiu drasticamente se você não ler, mesmo em sectores de tamanho, de modo que você acabou de ler 32kbytes de cada vez para maximizar o desempenho, 64 k vem até o dos32 dias, quando foram finalmente convencido de que o valor passado para fread era agora um número de 32 bits e o compilador não vai demorar para cortar a parte superior de 16 bits e usar apenas o menor de 16 bits (o que aconteceu, muitas vezes, se você usou o suficiente compiladores/versões).Estamos actualmente a sofrer problemas semelhantes na versão de 32 bits para 64 transição, como fizemos com a de 16 para 32 bits de transição.O que é mais interessante é o código da gente como eu, que aprendeu que vai de 16 a 32 bits, int tamanho alterado, mas unsigned char unsigned long não, então você adaptado e usado raramente int para que seus programas de compilar e trabalhar para 16 e 32 bits.(O código de pessoas da geração de que tipo de stands para outras pessoas que também viveram por ele e usado o mesmo truque).Mas para o de 32 a 64 de transição é a outra maneira ao redor e o código não refatorado para usar o tipo de uint32 declarações estão sofrendo.

Leitura wallyk a resposta que acabou de chegar, o ponteiro grande coisa que enrolado faz um sino, também nem sempre ser capaz de compilar enorme.pequeno foi o modelo de memória plana de que estamos confortáveis com a de hoje, e como hoje foi fácil porque você não tem que preocupar-se sobre segmentos.Então foi um desejável para compilar para pequenas quando podia.Você ainda não tem um monte de memória, disco ou disquete espaço para que você apenas não se normalmente lidam com dados tão grande.

E concordando com outra resposta, o segmento de deslocamento coisa foi 8088/8086 intel.Todo o mundo ainda não estava dominado pela intel, assim, havia outras plataformas que só tinha uma televisão de espaço de memória, ou usado de outros truques, talvez em hardware (fora do processador) para resolver o problema.Porque do segmento offset/intel foi capaz de andar a 16 bits coisa mais do que ele provavelmente deve ter.Segmento/offset tinha alguns legal e coisas interessantes que você poderia fazer com ele, mas era uma dor como qualquer outra coisa.Você simplificado a sua vida e viveu em um apartamento de memória ou espaço em você constantemente preocupado com os limites do segmento.

Realmente fixando o tamanho do endereço no antigo X86 é meio complicado. Você poderia dizer que é de 16 bits, porque a aritmética que você pode executar em um endereço deve caber em um registro de 16 bits. Você também pode dizer que são 32 bits, porque os endereços reais são calculados em um registro de um objetivo geral de 16 bits e o registro de segmento de 16 bits (todos os 32 bits são significativos). Você também pode apenas dizer que são 20 bits, porque os registros do segmento são deslocados de 4 bits à esquerda e adicionados aos registros GP para endereçamento de hardware.

Na verdade, não importa muito o que você escolheu, porque todos são aproximadamente as aproximações da máquina abstrata C. Alguns compiladores permitem escolher um modelo de memória que você estava usando por compilação, enquanto outros apenas assumem endereços de 32 bits e, em seguida, verifique cuidadosamente se as operações que podem transbordar de 16 bits emitem instruções que lidam com esse caso corretamente.

Verificação de saída isto Entrada da Wikipedia. Sobre ponteiros distantes. Basicamente, é possível indicar um segmento e um deslocamento, possibilitando pular para outro segmento.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top