Então, eu sei quais são os seguintes registros e seus usos:
CS = Segmento de Código (usado para IP)
DS = segmento de dados (usado para MOV)
ES = Segmento de Destino (usado para MOVS, etc.)
SS = segmento de pilha (usado para SP)
Mas para que os seguintes registros devem ser usados?
FS = "Segmento de arquivo"?
GS = ???
Nota: Eu estou não perguntando sobre qualquer sistema operacional particular - Estou perguntando sobre o que eles tinham a intenção de ser usado pelo CPU, se alguma coisa.
assembly
x86
cpu-architecture
cpu-registers
memory-segmentation
user541686
fonte
fonte
Respostas:
É para isso que foram concebidos e para que são utilizados pelo Windows e Linux.
A intenção original por trás dos registradores de segmento era permitir que um programa acesse muitos segmentos diferentes (grandes) de memória que deveriam ser independentes e parte de um armazenamento virtual persistente. A ideia foi tirada do sistema operacional Multics de 1966 , que tratava os arquivos simplesmente como segmentos de memória endereçáveis. Não BS "Abrir arquivo, gravar registro, fechar arquivo", apenas "Armazenar este valor naquele segmento de dados virtual" com limpeza de página suja.
Nossos sistemas operacionais atuais de 2010 são um grande retrocesso, e é por isso que são chamados de "Eunucos". Você só pode endereçar o único segmento do seu espaço de processo, dando um assim chamado "espaço de endereçamento plano (IMHO opaco)". Os registradores de segmento na máquina x86-32 ainda podem ser usados para registradores de segmentos reais, mas ninguém se importou (Andy Grove, ex-presidente da Intel, teve um famoso ataque público no século passado quando descobriu depois que todos aqueles engenheiros da Intel gastaram energia e seu dinheiro para implementar esse recurso, que ninguém iria usá-lo. Vá, Andy!)
A AMD ao ir para 64 bits decidiu que não se importava se eliminasse o Multics como uma escolha (essa é a interpretação caridosa; a não caridosa é que eles não tinham ideia sobre o Multics) e então desabilitou a capacidade geral de registradores de segmento no modo de 64 bits. Ainda havia a necessidade de threads acessarem o armazenamento local de threads, e cada thread precisava de um ponteiro ... em algum lugar no estado de thread imediatamente acessível (por exemplo, nos registradores) ... para armazenar o armazenamento local de threads. Como o Windows e o Linux usaram FS e GS (obrigado Nick pelo esclarecimento) para este propósito na versão de 32 bits, a AMD decidiu permitir que os registradores de segmento de 64 bits (GS e FS) fossem usados essencialmente apenas para este propósito (acho que você pode faça com que eles apontem para qualquer lugar em seu espaço de processo; não sei se o código do aplicativo pode carregá-los ou não).
Teria sido mais bonito do ponto de vista arquitetônico do IMHO fazer com que o mapa de memória de cada thread tivesse um endereço virtual absoluto (por exemplo, 0-FFF digamos) que fosse seu armazenamento local do thread (nenhum ponteiro de registro [segmento] necessário!); Eu fiz isso em um sistema operacional de 8 bits na década de 1970 e foi extremamente útil, como ter outra grande pilha de registros para trabalhar.
Então, os registradores de segmento agora são como seu apêndice. Eles servem a um propósito residual. Para nossa perda coletiva.
Aqueles que não conhecem a história não estão condenados a repeti-la; eles estão condenados a fazer algo mais estúpido.
fonte
Os registradores
FS
eGS
são registradores de segmento. Eles não têm um propósito definido pelo processador, mas, em vez disso, são determinados pelo SO que os executa. No Windows de 64 bits, oGS
registro é usado para apontar para estruturas definidas pelo sistema operacional.FS
eGS
são comumente usados por kernels do sistema operacional para acessar a memória específica de thread. No Windows, oGS
registro é usado para gerenciar a memória específica do segmento. O kernel do Linux usaGS
para acessar a memória específica da CPU.fonte
*dest++ = lookup[*src++];
que, de outra forma, seria um tanto estranho se dest, lookup e src estivessem em três locais não relacionados.FS é usado para apontar para o bloco de informações de thread (TIB) nos processos do Windows.
um exemplo típico é ( SEH ), que armazena um ponteiro para uma função de retorno de chamada em
FS:[0x00]
.GS é comumente usado como um ponteiro para um armazenamento local de thread (TLS). e um exemplo que você pode ter visto antes é a proteção canário de pilha (stackguard), no gcc você pode ver algo assim:
fonte
De acordo com o Manual da Intel, no modo de 64 bits, esses registros devem ser usados como registros básicos adicionais em alguns cálculos de endereço linear. Retirei isso da seção 3.7.4.1 (pág. 86 no conjunto de 4 volumes). Normalmente, quando a CPU está neste modo, o endereço linear é o mesmo que o endereço efetivo, porque a segmentação geralmente não é usada neste modo.
Portanto, neste espaço de endereço plano, FS e GS desempenham um papel no endereçamento não apenas de dados locais, mas de certas estruturas de dados do sistema operacional (página 2793, seção 3.2.4), portanto, esses registros foram destinados a serem usados pelo sistema operacional, no entanto, esses designers específicos determinar.
Há alguns truques interessantes ao usar substituições nos modos de 32 e 64 bits, mas isso envolve software privilegiado.
Do ponto de vista das "intenções originais", é difícil dizer, a não ser que sejam apenas registros extras. Quando a CPU está no modo de endereço real , é como se o processador estivesse funcionando como um 8086 de alta velocidade e esses registros precisassem ser acessados explicitamente por um programa. Para a verdadeira emulação do 8086, você executaria a CPU no modo virtual-8086 e esses registros não seriam usados.
fonte
TL; DR;
Simplesmente para acessar dados além do segmento de dados padrão (DS). Exatamente como o ES.
A longa leitura:
Bem, quase, mas o DS não é 'algum' segmento de dados, mas o padrão. Todas as operações ocorreram por padrão (* 1). É onde todas as variáveis padrão estão localizadas - essencialmente
data
ebss
. De certa forma, é parte da razão pela qual o código x86 é bastante compacto. Todos os dados essenciais, que são os acessados com mais frequência, (mais o código e a pilha) estão a uma distância abreviada de 16 bits.O ES é usado para acessar todo o resto (* 2), tudo além dos 64 KiB do DS. Como o texto de um processador de texto, as células de uma planilha ou os dados de imagem de um programa gráfico e assim por diante. Ao contrário do que costumamos presumir, esses dados não são tão acessados, portanto, precisar de um prefixo dói menos do que usar campos de endereço mais longos.
Da mesma forma, é apenas um pequeno aborrecimento que o DS e o ES tenham que ser carregados (e recarregados) ao fazer operações de string - isso pelo menos é compensado por um dos melhores conjuntos de instruções de tratamento de caracteres de seu tempo.
O que realmente dói é quando os dados do usuário excedem 64 KiB e as operações precisam ser iniciadas. Enquanto algumas operações são feitas simplesmente em um único item de dados por vez (pense
A=A*2
), a maioria requer dois (A=A*B
) ou três itens de dados (A=B*C
). Se esses itens residirem em segmentos diferentes, o ES será recarregado várias vezes por operação, adicionando alguma sobrecarga.No início, com pequenos programas do mundo de 8 bits (* 3) e conjuntos de dados igualmente pequenos, não era grande coisa, mas logo se tornou um grande gargalo de desempenho - e mais ainda um verdadeiro pé no saco para programadores (e compiladores). Com o 386, a Intel finalmente proporcionou alívio ao adicionar mais dois segmentos, de forma que qualquer operação unária , binária ou ternária em série , com elementos espalhados na memória, poderia ocorrer sem recarregar o ES o tempo todo.
Para programação (pelo menos em montagem) e design do compilador, isso foi um ganho e tanto. Claro, poderia ter havido ainda mais, mas com três o gargalo basicamente havia sumido, então não há necessidade de exagerar.
Em termos de nomenclatura, as letras F / G são simplesmente continuações alfabéticas após E. Pelo menos do ponto de vista do design da CPU, nada está associado.
* 1 - O uso de ES para destino de string é uma exceção, pois são necessários simplesmente dois registradores de segmento. Sem eles não seriam muito úteis - ou sempre precisando de um prefixo de segmento. O que poderia matar um dos recursos surpreendentes, o uso de instruções de string (não repetitivas), resultando em desempenho extremo devido à codificação de byte único.
* 2 - Então, em retrospectiva, 'segmento de tudo o resto' teria sido uma nomenclatura muito melhor do que 'segmento extra'.
* 3 - É sempre importante ter em mente que o 8086 foi criado apenas como uma medida provisória até que o 8800 fosse concluído e destinado principalmente ao mundo embarcado para manter os clientes do 8080/85 a bordo.
fonte