Dobrando de tamanho…

Confesso para vocês que minha experiência em assembly estava confinada ao tamanho máximo da palavra em 32 bits. Recentemnte tive a curiosidade de instalar, em meu notebook, o Ubuntu 11.04 x86-64. Copiei o Projeto Virtual Worlds para ele, compilei e tive uma pequena surpresa que, afinal de contas, faz todo sentido.

Nesse modo de operação os registradores de segmento não têm serventia. Essa não foi a surpresa, porque mesmo no modo 32 bits o código gerado por compiladores também não usam os registradores de segmento. Estes já são inicializados pelo sistema operacional pra você. Outra coisa que não é surpreendente, mas é interessante, é que o compilador, em modo 64 bits, evita o uso da pilha para passagem de parâmetros para as funções. Ele tenta usar. sempre que possível, os registradores RSI e RDI para esse fim… O que me supreendeu mesmo foram as rotinas em ponto-flutuante:

No modo 16 e 32 bits o compilador tende a gerar código preparatório para uso da pilha do co-processador matemático. No caso do modo 64 bits, o compilador naturalmente tende a usar SSE! Faz todo sentido porque todos os processadores (Intel ou não) que suportam o modo x86-64 implementam também SSE… As vantagens do modo x86-64:

  1. Pouquíssima copia de blocos de 32 ou 64 bits (floats e doubles, por exemplo) de um lado pro outro é feita;
  2. Existem 16 registradores XMM# (de XMM0 até XMM15), 8 a mais do que na arquitetura x86.
  3. Existem 15 registradores de uso geral (RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, R8, R9, R10, R11, R12, R13, R14, R15 – onde, é claro, RSP tem um “uso” especial), 8 a mais do que na arquitetura x86 (e todos eles com 64 bits de tamanho).

Os “co-processadores” matemáticos, embutidos nos modernos processadores, possuem pilha de 8 posições. Daí, ter 16 registradores XMM# e usá-los, por padrão, é uma vantagem muito grande… E ter 8 registradores de “uso geral” adicionais também dá pra fazer uma festa!

No modelo dos 64 bits as variáveis inteiras podem dobrar de tamanho sem que dois registradores sejam usados e que aritmética de múltipla precisão seja usada (usando o bit de Carry). Mas essa também não surpreende. Só causa alguma confusão: Algumas pessoas acham que o tipo int, por exemplo, é automaticamente acrescido de 32 bits, ficando grandão… Isso não acontece. O tipo int continua tendo 32 bits de tamanho. O que altera no modo 64 bits é o tamanho dos ponteiros (de 32 para 64 bits) e o tipo long (este sim fica grandão: com 64 bits de tamanho, no Linux, pelo menos). Existem quatro modelos de tipos integrais:

I32LP64 (ou LP64) – Onde o tipo long é de 64 bits (este é usado pelo Linux, HP-UX, AIX, z/OS, FreeBSD e OS/X);
IL32P64 (ou LLP64) 
– Onde o tipo long é 32 bts (este é usado pelo Windows);
ILP64 – Onde os tipos int e long são de 64 bits (usado no SPARC);
SILP64 – Onde short, int e long são de 64 bits (usado pela Cray).

Os modelos ILP64 e SILP64 são pouco usados e, na minha opinião, a Microsoft cometeu o equivoco de deixar um tipo chamado “longo” com o mesmo tamanho do inteiro normal. Pra mim o modelo I32LP64 faz muito mais sentido, com char (8 bits), short (16 bits), int (32 bits) e long (64 bits). O tipo long long continua com 64 bits de tamanho (e em todos os modelos), mas sempre me soou como um tipo esquisito (“longo longo”? Um tipo de 128 bits seria “long long long”? E um de 256 bits, seria “long long long long”?).

Para não confundir ninguém o padrão C99 da linguagem C contém o header padrão stdint.h que define os tipos int8_t, int16_t, int32_t e int64_t (e seus derivados “unsigned”, colocando um “u” na frente). Use-o.

Anúncios

Um comentário sobre “Dobrando de tamanho…

  1. O bacana disso tudo, é que depois de estudar *um pouquinho* eu tinha visto estes types em asm/types.h e asm-generic/types.h, ou seja, to começando entender estes posts… ;) #living and learning

Deixe um comentário

Faça o login usando um destes métodos para comentar:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s