TL; DR
São posições de memória dentro do processador com nomes específicos, é como se fossem variáveis.
São endereços que armazenam dados por um curto período (poderia ser longo, só não faz sentido) para que o processador possa manipular esse dado ou usá-lo para manipular algum outro. Inclusive alguns servem para controle fundamental do funcionamento do processador ou da execução do seu código, em geral coisas que você nem sabe se existe.
Nada no sentido abstrato que você lida. Tudo concretamente. É só neles que há real execução e eles são muito mais rápidos que a memória onde você acha que seus dados estão na execução.
Eles são um tipo de memória de curto prazo. A única relação com a RAM é que eles se conversam o tempo todo. Em relação aos registradores dados vem e vão de e para a RAM. DetalhandoBasicamente é isso que está na definição :P Memória você sabe? E variável? MemóriaMemória é composta por vários slots de dados e podemos dizer que sempre um slot tem 1 byte de tamanho. O acesso a cada slot é feito por um número, até porque tem uma quantidade grande deles. Pensa na memória como um enorme array de bytes. Alguns desses slots podem ser acessados juntos e é possível dar um nome para acessar alguns deles em específico durante a criação do código, mas de fato o acesso é feito pelo número, mesmo que você não veja isto nele. RegistradoresOs registradores não deixam de ser uma memória, mas com características especiais e em baixíssimo número, até porque a distância que o sinal elétrico precisa percorrer precisa ser bem pequeno para acontecer muito rápido. Se tivessem muitos registradores boa parte deles ficariam longe e o tempo de acesso seria maior. Ao contrário da memória normal, cada slot nessa memória dentro do núcleo do processador tem um tamanho um pouco maior, geralmente chamamos isso de palavra. Então em processadores 32 bits esse tamanho é 4 bytes e um de 64 bits o tamanho é 8 bytes. Mas existem registrados especiais com tamanhos diferentes, alguns são de 1 bit porque não precisa mais que aquilo, e outros pode ter vários bytes para processar ações especiais em vetores, criptografia, etc. Não deixa de ser um local onde bits ficam armazenados por um tempo, em geral bem pouco tempo, em até 1 ou poucos ciclos. Como eles são poucos podem ter um nome. Mas como tudo em Assembly não deram nomes tão fáceis. E como não é uma tarefa específica como o ocorre em um código normal de uma aplicação os nomes são bem genéricos. Mas podemos dizer que eles são as variáveis de baixo nível de qualquer código. Mantendo a analogia que fiz com a memória entenda eles como um grande objeto com vários membros nomeados, seria definido como uma classe ou uma estrutura. OperaçõesTodas operações que o processador consegue realizar é em cima dos registradores. Não é possível manipular a memória RAM diretamente, você tem que mover a informação para o registrador manipular e depois pode mover o resultado para a RAM novamente, se for o que deseja. As portas lógicas que executam algo pegando os bits presentes em um ou dois registradores (tem instruções especiais que podem pegar mais dados, são chamadas de SIMD) e transformando em outro(s) bit(s) que devem entrar em algum(ns) registrador(es). PerformanceO acesso a um registrador em um processador x86 tem custo na casa do picossegundos. É possível fazer 3 ou 4 bilhões de acessos por segundo. Um ARM não fica muito atrás disso. O acesso à RAM custa quase 100 nanossegundos (tem baixado um pouco), portanto uns 10 milhões de acessos por segundo. É uma diferença brutal. Por isso é importante manter os dados no registrador. E por isso no passado escrever Assembly ajudava muito. Hoje os compiladores tendem a fazer escolhas melhores que humanos em muitos casos e coloca o que é mais importante no registrador. Note que o tempo de acesso não é o mesmo de uma operação de manipulação. Uma divisão por exemplo pode custar vários nanossegundos até mesmo acessando apenas o registrador. AbstraçãoTudo o que você escreve em linguagem de alto nível que toca em um dado passará por um registrador. Esse código Assembly é um pouco alto nível porque as variáveis X e Y não existem no contexto do Assembly, aí iria endereços puros de memória (no caso da stack). LimitaçãoDeve estar imaginando que por serem poucos registradores (16 principais nos casos mais comuns) o que fazer quando você está trabalhando com muita variáveis (mesmo que conceitualmente falando). Você vai mandando para a memória o que não cabe no processador naquele momento. Na prática isso ocorre naturalmente porque você põe alguns dados nos principais registradores, executa algo e pega o resultado mandando para a memória. CacheO processador tem uma abstração legal que ele pode manter certos dados muito acessados em cache, os famosos L1, L2, L3 e finado L4 que por serem pequenos ficam mais perto do processador e tem tempos de acesso bem melhores que a RAM. E a distância é o motivo de ter vários níveis. Em certo ponto de vista o registrador é uma espécie de cache também, onde a memória seria como o arquivo de swap dos sistema operacional, está lá para garantir que tudo funciona com grandes volumes, mas é melhor evitar o seu uso. Eu poderia até falar nas novas memórias não voláteis que farão a RAM persistirem dados, ou poderia falar do cache line onde os dados são sempre transferidos em bloco, por isso acessar 1 byte ou 64 (tipicamente) tem custo quase igual, mas isso foge um pouco do foco. Registradores existentesExistem 4 registradores principais em um processador Intel x86 que são chamados EAX, EBX, ECX, EDX. Em 64 bits os nomes são RAX, RBX, RCX, RCX e obviamente os tamanhos são maiores. Como curiosidade em 16 bits eles se chamam AX, BX, CX, DX, e eles podem ser acessados em cada byte individual na sua parte baixa ou alta, então tem o AL e AH, BL e BH, e assim por diante. Lembre-se esses são apenas nomes como se fossem variáveis, não tem muito segredo. E podemos dizer que eles tem um tipo só, que é a palavra. Quase tudo é feito nesses registradores. O mais comum, mas só por convenção é que sejam:
Outros registradores bem importantes usados o tempo todo em toda aplicação que são considerados de uso geral mas que quase sempre são usados para algo bem específico são:
Lembrando que em 64 bits eles começam com R. Depois temos registradores especiais de segmento que não há uso prático hoje em dia com o advento da memória virtual. Um dos mais importantes registradores é o EIP ou Instruction Pointer. É ele que sabe onde do código está executando. Cada instrução que termina sua execução incrementa para o próximo endereço de execução que o código deve realizar, que é variável nos processadores Intel-like, mas tem tamanho fixo em processadores RISC como é o ARM. Um Em 64 bits temos os R8 ao R15 que são registradores complementares e funcionam como os primeiros, mas sem nada mais convencional para uso e são usados como otimizações, em operações simples costumam ficar vazios (conceitualmente já que sempre terá dado que estava lá). Não falei de registradores especiais usados por instruções MMX, SSEx, etc. porque não os entendo bem e acho que não é caso da maioria dos usos. Finalmente chegamos nos registradores de bit (flags) que recebem certos resultados de controle e são consultados em certas instruções para decidir o que fazer. Já deve imaginar que role em muitas instruções de comparação, mas não só, até em aritmética pode rolar bastante. Esses registradores são atualizados em boa parte das operações, portanto você só tem o último estado, se precisa dessa informação para alguma operação posterior (geralmente não precisa) então deve armazenar em algum lugar, seja um registrador geral ou na memória. Não vou listar todos, mas os principais são (endereços dos bits):
Seu código:
Tipicamente isso pode demorar uns cento e tantos nanossegundos para executar. E apenas pouco mais de 2 ou 3 nanossegundo é o cálculo em si. Por isso que eu falo que otimizar é não acessar memória, não é economizar processamento em si. Fazer tudo o que precisa estar no processador e operar nele e conseguir evitar que registradores sejam usados de forma sobreposta em uma linha de processamento fazem absurdamente mais pela performance que economizar instruções de processamento ou usar instruções com menos ciclos de custo. Porque toda vez que precisa usar o EAX por exemplo, e ele está ocupado, você tem que jogar para a memória o que tem ali (empilhar) para poder usá-lo sem problemas e depois que terminar essa nova operação tem que voltar o valor salvo antes na pilha para o registrador para ele continuar o que estava fazendo. Mesmo que o empilhamento ocorra no cache L1 custa bem mais caro não só porque é uma operação extra só de controle, mas também porque ela custa caro. Um dos motivos que tenta-se fazer inline de funçãoé porque há muita cópia de dados do registrador para memória e vice-versa em chamadas de função. Ao contrário do que as pessoas pensam, Assembly não é tão difícil assim, é chato, é esquisito, tem que ter muito cuidado, mas tem baixa complexidade e pouca abstração que dificulta o entendimento. Na verdade se adotassem uma sintaxe um pouco melhor assustaria menos. Mas claro, assim como em C o acesso ao heap ou uso de ponteiros já assusta porque é fácil cometer erros e melar a memória, em Assembly qualquer acesso assusta geral. Pode interessar:
Coloquei no GitHub para referência futura. Onde ficam armazenadas as informações que o processador usa?A memória RAM é onde são armazenados dados temporários para que o processador possa acessar informações importantes de maneira mais rápida.
Onde se armazena dados?Barato e criado de forma simples; os dados são armazenados em arquivos e pastas. É normalmente encontrado em unidades de disco rígido e significa que os arquivos são exatamente iguais tanto para o disco rígido como para o usuário.
O que fica armazenado no processador?Ela tem o objetivo de guardar dados, informações e processos temporários acessados com frequência e assim agilizar o processo de uso no momento em que são requisitados pelo usuário. Desse modo, a memória cache pode ser considerada um pequeno componente que consta dentro do processador.
Onde os dados são processados dentro de uma CPU?Componentes da CPU
A UC também é responsável pelo controle de entrada e saída de dados da CPU. Unidade lógica e aritmética (ULA): é a parte da CPU responsável pelos cálculos (operações lógicas e aritméticas). É na ULA que os dados são processados no interior da CPU.
|