AMD64
Révision datée du 17 juin 2008 à 16:38 par imported>SylvainBeucler
- Détecter un processeur 64bit: cherche le flag
lm
:
cat /proc/cpuinfo | grep --color -w lm
- Compiler en 32bit sous AMD64:
aptitude install lib32gcc1 libc6-dev-i386 cat <<EOF | gcc -xc -o test32 - -m32 #include <stdio.h> int main() { printf("sizeof(int) = %d, sizeof(void*) = %d\n", sizeof(int), sizeof(void*)); } EOF
- Détecter un exécutable 32 ou 64:
$ file test32 test32: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, dynamically linked (uses shared libs), for GNU/Linux 2.6.0, not stripped $ file test64 test64: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.6.0, dynamically linked (uses shared libs), for GNU/Linux 2.6.0, not stripped
- Exécuter en 32bit sous AMD64: aucune manipulation particulière, mais il faut avoir les dépendances 32bit installées:
$ ./test32 sizeof(int) = 4, sizeof(void*) = 4 $ ./test64 sizeof(int) = 4, sizeof(void*) = 8
- Détecter un noyau (pas un processeur) 64bit:
$ uname -m x86_64
- Simuler un noyau 32bit:
$ aptitude install linux32 $ linux32 uname -m i686 # mais ça ne fait rien d'autre que ça
- Lancer un VServer installé en 32bit sous 64bit: aucune manipulation.
- Créer un VServer 32bit sous 64bit: http://linux-vserver.org/Installing_32-bit_Fedora_on_64-bit_Debian (essentiellement:
export ARCH=i386
)
Test GCC plus poussé
#include <stdio.h> struct test_alignment { int a, b, c; }; struct test_alignment2 { int a; int *p; }; struct test_alignment3 { int a; double d; }; int main(void) { struct test_alignment s[3]; struct test_alignment2 s2[3]; struct test_alignment3 s3[3]; printf("sizeof(int) = %d\n", sizeof(int)); printf("sizeof(void*) = %d\n", sizeof(void*)); printf("sizeof(long) = %d\n", sizeof(long)); printf("sizeof(long long) = %d\n", sizeof(long long)); printf("sizeof(double) = %d\n", sizeof(double)); printf("sizeof(struct test_alignment[0]) = %d\n", sizeof(s[0])); printf("sizeof(struct test_alignment*3) = %d\n", sizeof(s)); printf("sizeof(struct test_alignment2[0]) = %d\n", sizeof(s2[0])); printf("sizeof(struct test_alignment2*3) = %d\n", sizeof(s2)); printf("sizeof(struct test_alignment3[0]) = %d\n", sizeof(s3[0])); printf("sizeof(struct test_alignment3*3) = %d\n", sizeof(s3)); return 0; }
# ./test32 sizeof(int) = 4 sizeof(void*) = 4 sizeof(long) = 4 sizeof(long long) = 8 sizeof(double) = 8 sizeof(struct test_alignment[0]) = 12 sizeof(struct test_alignment*3) = 36 sizeof(struct test_alignment2[0]) = 8 sizeof(struct test_alignment2*3) = 24 sizeof(struct test_alignment3[0]) = 12 sizeof(struct test_alignment3*3) = 36 # ./test64 sizeof(int) = 4 sizeof(void*) = 8 sizeof(long) = 8 sizeof(long long) = 8 sizeof(double) = 8 sizeof(struct test_alignment[0]) = 12 sizeof(struct test_alignment*3) = 36 sizeof(struct test_alignment2[0]) = 16 sizeof(struct test_alignment2*3) = 48 sizeof(struct test_alignment3[0]) = 16 sizeof(struct test_alignment3*3) = 48
On remarque donc que:
int
garde la même taillevoid*
double naturellement (plus grand adressage mémoire), mais aussilong
long long
etdouble
ne bougent pas- le compilateur continue d'aligner des blocs de 4 octets sur des multiples de 4 octets
- le compilateur aligne en revanche des blocs de 8 octets sur des multiples de 8 octets en 64bit, et non plus de 4 octets comme en 32bit
Conclusion: sur du code très courant, l'alignement ne changera pas, mais des changements surviennent tout de même facilement.