Modelo de memória Intel - Intel Memory Model

Na computação , o Intel Memory Model se refere a um conjunto de seis modelos de memória diferentes da CPU x86 operando em modo real que controlam como os registros de segmento são usados ​​e o tamanho padrão dos ponteiros.

Segmentação de memória

Quatro registradores são usados ​​para se referir a quatro segmentos na arquitetura de memória segmentada x86 de 16 bits. DS ( segmento de dados ), CS ( segmento de código ), SS ( segmento de pilha ) e ES (segmento extra). Outro registro de 16 bits pode atuar como um deslocamento em um determinado segmento e, portanto, um endereço lógico nesta plataforma é escrito como segmento : deslocamento , normalmente em notação hexadecimal . No modo real, para calcular o endereço físico de um byte de memória, o hardware desloca o conteúdo do registrador de segmento apropriado 4 bits para a esquerda (efetivamente multiplicando por 16) e, em seguida, adiciona o deslocamento.

Por exemplo, o endereço lógico 7522: F139 produz o endereço físico de 20 bits:

  75220
+ F139
  84359

Observe que esse processo leva ao aliasing da memória, de forma que qualquer endereço físico dado tenha até 4096 endereços lógicos correspondentes. Isso complica a comparação de ponteiros para segmentos diferentes.

Tamanhos de ponteiro

Os formatos de ponteiro são conhecidos como próximo , distante ou enorme .

  • Os ponteiros próximos são deslocamentos de 16 bits dentro do segmento de referência, ou seja, DS para dados e CS para código. Eles são os indicadores mais rápidos, mas estão limitados a apontar para 64 KB de memória (para o segmento associado do tipo de dados). Os ponteiros próximos podem ser mantidos em registradores (normalmente SI e DI).
    mov bx, word [reg]
    mov ax, word [bx]
    mov dx, word [bx+2]
  • Far ponteiros são ponteiros de 32 bits que contêm um segmento e um deslocamento. Para usá-los, o registrador de segmento ES é usado usando a instrução les [reg]|[mem],dword [mem]|[reg] . Eles podem fazer referência a até 1024  KiB de memória. Observe que a aritmética do ponteiro (adição e subtração) não modifica a parte do segmento do ponteiro, apenas seu deslocamento. As operações que excedem os limites de zero ou 65535 (0xFFFF) serão submetidas à operação do módulo 64K exatamente como qualquer operação normal de 16 bits. Por exemplo, se o registro do segmento for definido como 0x5000 e o deslocamento estiver sendo incrementado, no momento em que o deslocamento do contador se tornar (0x10000), o endereço absoluto resultante será transferido para 0x5000: 0000.
    les bx,dword [reg]
    mov ax,word [es:bx]
    mov dx,word [es:bx+2]
  • Ponteiros enormes são essencialmente ponteiros distantes, mas são (principalmente) normalizados toda vez que são modificados para que tenham o maior segmento possível para aquele endereço. Isso é muito lento, mas permite que o ponteiro aponte para vários segmentos e permite comparações precisas de ponteiros, como se a plataforma fosse um modelo de memória plana : proíbe o aliasing de memória conforme descrito acima, portanto, dois ponteiros enormes que fazem referência à mesma memória localização são sempre iguais.
    les bx,dword [reg]
    mov ax,word [es:bx]
    add bx,2
    test bx,0xfff0
    jz lbl
    sub bx,0x10
    mov dx,es
    inc dx
    mov es,dx
 lbl:
    mov dx,word [es:bx]

Modelos de memória

Os modelos de memória são:

Modelo Dados Código Definição
Pequeno* aproximar CS = DS = SS
Pequeno aproximar** aproximar DS = SS
Médio aproximar** distante DS = SS, vários segmentos de código
Compactar distante aproximar segmento de código único, vários segmentos de dados
Grande distante distante múltiplos códigos e segmentos de dados
Enorme enorme distante código múltiplo e segmentos de dados; matriz única pode ser> 64 KB

Outras plataformas

No modo protegido, um segmento não pode ser gravável e executável. Portanto, ao implementar o modelo de memória Tiny, o registrador de segmento de código deve apontar para o mesmo endereço físico e ter o mesmo limite que o registrador de segmento de dados. Isso derrotou um dos recursos do 80286 , que garante que os segmentos de dados nunca sejam executáveis ​​e os segmentos de código nunca sejam graváveis ​​(o que significa que o código de automodificação nunca é permitido). No entanto, no 80386, com sua unidade de gerenciamento de memória paginada , é possível proteger páginas de memória individuais contra gravação.

Os modelos de memória não estão limitados a programas de 16 bits. É possível usar a segmentação no modo protegido de 32 bits também (resultando em ponteiros de 48 bits) e existem compiladores de linguagem C que suportam isso. No entanto, a segmentação no modo de 32 bits não permite acessar um espaço de endereço maior do que o que um único segmento cobriria, a menos que alguns segmentos não estejam sempre presentes na memória e o espaço de endereço linear seja usado apenas como um cache sobre um espaço virtual segmentado maior . Ele permite melhor proteção para acesso a vários objetos (áreas de até 1 MB de comprimento podem se beneficiar de uma granularidade de proteção de acesso de um byte, em comparação com a granularidade grosseira de 4 KiB oferecida pelo paging único) e, portanto, só é usado em aplicações especializadas, como telecomunicações Programas. Tecnicamente, o espaço de endereço "plano" de 32 bits é um modelo de memória "minúsculo" para o espaço de endereço segmentado. Em ambos os reinados, todos os quatro registradores de segmento contêm um e o mesmo valor.

x86-64

Na plataforma x86-64 , existe um total de sete modelos de memória, já que a maioria das referências de símbolo tem apenas 32 bits de largura e se os endereços são conhecidos no momento do link (em oposição ao código independente de posição ). Isso não afeta os ponteiros usados, que são sempre ponteiros planos de 64 bits, mas apenas como os valores que devem ser acessados ​​por meio de símbolos podem ser colocados.

Veja também

Bibliografia

  • Guia do usuário do Turbo C ++ Versão 3.0 . Borland International, Copyright 1992.

Referências