Eu estava inspecionando a saída pré-processada do meu programa C e olhei o arquivo de cabeçalhowordsize.h
Esta localizado em
/usr/include/i386-linux-gnu/bits/wordsize.h
o arquivo contém apenas uma macro
#define __WORDSIZE 32
Minha pergunta é: o tamanho das palavras está sendo decidido pelo compilador que está instalado ou tem algo a ver com o sistema operacional que eu instalei (32 bits ou 64 bits) ou tem algo a ver com a configuração de hardware do meu máquina.
Eu sou novo no desenvolvimento no Linux.
Responder1
Em geralwordsize
é decidido de acordo com a arquitetura de destino durante a compilação. Seu compilador normalmente compilará usando wordsize
o sistema atual.
Usando gcc
(entre outros), você também pode ajustar isso usando vários sinalizadores. Por exemplo, em um host de 64 bits você pode compilar para32 bitsmáquina, ouforçaPalavras de 32 bits.
-m32 # int, long and pointer to 32 bits, generates code for i386.
-m64 # int, long and pointer to 64 bits, generates code for x86-64.
-mx32 # int, long and pointer to 32 bits, generates code for x86-64.
Você também deve observar limits.h
e inttypes.h
ver o uso desta definição.
Para compilação cruzada, confiramultilib(Link de 32 bits no SO) e pesquise na web.
Verifique com quais sinalizadores seu GCC foi construído:
gcc -v
Quanto aos tamanhos, eles geralmente estão intimamente relacionados à unidade central de processamento e relacionados – como tamanho máximo de um endereço de memória, tamanho dos registros da CPU, etc.
Para uma rápida visão, você não precisa entender muito disso, mas dependendoonde você estápode dar algumas dicas:
Se você usar gcc
e compilar com o -S
sinalizador, também poderá consultar oinstruções de montagem. Aqui, um pouco confuso, por exemplo, em uma máquina de 32 bits, uma palavra é de 16 bits e longa é de 32 bits. ( __WORDSIZE
)
Então, por exemplo, movl $123, %eax
significa movimento longo (32 bits - __WORDSIZE
)123
registrareax
e movw
significa mover palavra (16 bits).
Isto são convenções de nomenclatura – e apenas dizer isso WORDSIZE
pode significar mais de uma coisa. Você também pode encontrar códigos onde eles, por exemplo, definem algo como
#define WORD_SIZE 16
pois tudo depende do contexto. Se você ler dados de um arquivo ou fluxo onde a fonte tem tamanho de palavra de 16 bits, isso seria natural. Apenas para ressaltar que nem sempre assuma médias de tamanho de palavra __WORDSIZE
quando lidas em código.
O exemplo com definição do usuário WORD_SIZE
não afetaria o conjunto de instruções no código de máquina gerado. Para o GCC em geral eu recomendariaeste livro.(Infelizmente é um pouco antigo – mas ainda não encontrei um livro semelhante, fácil de ler e mais atualizado. (Não que eu tenha procurado tanto.) É curto, conciso e agradável. E se você apenas tiver em mente que coisas podem ter mudado, como recursos adicionados, etc., mesmo assim é uma boa introdução.)
Ele fornece uma introdução rápida e agradável dos vários aspectos da compilação. Olhe paracapítulo 11para uma boa explicação da cadeia de compilação.
Não conheço nenhuma opção no GCC para compilar 16 bits. Uma maneira de fazer isso seria escrever em assembly usando .code16
para instruir o código que deveria ser de 16 bits.
Exemplo:
.file "hello.s"
.text
.code16 /* Tel GAS to use 16-bit instructions. */
.globl start, _start
start:
_start:
movb $0x48, %al
...
Isto é necessário, por exemplo, para carregadores de inicialização como GRUB e LILO para o código presente em MBR
seu disco rígido.
A razão para isso é que quando o computador inicializa, a CPU está em um modo especial onde não possui instruções de 32 bits, mas no máximo 16 bits, também conhecidas como Modo Real.
Resumindo, o que acontece é que o BIOS faz um teste de hardware, depois carrega os primeiros 512 bytes do seu disco de inicialização na memória e deixa o controle para esse código começando no endereço 0
. Este código, por sua vez, localiza onde reside o próximo estágio dos arquivos, carrega-os na memória e continua a execução, finalmente inserindo
Modo protegidoonde você temnormalModo de 32 bits.
Responder2
Aqui está o que o meu tem:
% cat /usr/include/bits/wordsize.h
/* Determine the wordsize from the preprocessor defines. */
#if defined __x86_64__
# define __WORDSIZE 64
# define __WORDSIZE_COMPAT32 1
#else
# define __WORDSIZE 32
#endif
Portanto, é determinado por wordsize.h
, que vem com o seu compilador. Mas um inteligente selecionará um tamanho apropriado.
Responder3
Você deve ser capaz de escolher o tamanho padrão das palavras no momento da compilação, geralmente usando uma das opções -m32
ou -m64
.
/usr/include/i386-linux-gnu/bits/wordsize.h
foi projetado para ser usado ao compilar aplicativos de 32 bits.
Deve haver um /usr/include/x86_64-linux-gnu/bits/wordsize.h
contendo uma definição de 64 bits __WORDSIZE
.
Esta mudança foi introduzida com o Ubuntu 11.4:https://wiki.ubuntu.com/MultiarchSpec
Se -m64
falhar, você poderá ter uma distribuição de 32 bits. uname -m
vou te contar.
Embora seja possível compilar binários de 64 bits em um sistema de 32 bits, isso seria inconveniente, pois você não terá uma maneira simples de executá-los lá.
Se sua CPU for um modelo de 64 bits (verifique em lscpu
), você pode querer instalar uma distribuição de 64 bits para poder construir facilmente pacotes multiarch.