Est-ce que l'accès mémoire non alignés toujours provoquer des erreurs de bus?

StackOverflow https://stackoverflow.com/questions/1496848

  •  19-09-2019
  •  | 
  •  

Question

Selon la page Wikipedia Segmentation fault , une erreur de bus peut être causée par un accès mémoire non alignés. L'article donne un exemple sur la façon de déclencher une erreur de bus. Dans l'exemple, nous devons activer la vérification d'alignement pour voir l'erreur de bus. Que faire si nous désactivons cette vérification d'alignement?

Le programme semble fonctionner correctement. J'ai un programme d'accès mémoire non alignés fréquemment, et il est utilisé par pas mal de gens, mais personne ne signale les erreurs de bus ou d'autres résultats étranges pour moi. Si on désactive la vérification de l'alignement, ce qui est l'effet secondaire de la mémoire non alignée?

Plates-formes: Je travaille sur x86 / x86-64 . J'ai aussi essayé de mon programme en compilant avec « ppc -arch gcc » sur un Mac et fonctionne correctement.

Était-ce utile?

La solution

  1. Il se peut accéder beaucoup plus lente mémoire non alignée (comme dans, plusieurs fois plus lent).

  2. Pas toutes les plates-formes supportent même l'accès non alignés - x86 et x64 font, mais ia64 (Itanium) ne constitue pas, par exemple

  3. .
  4. Un compilateur peut émuler accès non aligné (VC ++ fait que pour les pointeurs déclarés comme __unaligned sur ia64, par exemple) - en insérant des contrôles supplémentaires pour détecter le cas non aligné, et le chargement / parties de stockage de l'objet chevauchant la limite d'alignement séparément. Cela est encore plus lent que l'accès non alignée sur les plates-formes qui supportent nativement, cependant.

Autres conseils

Cela dépend beaucoup de l'architecture de la puce. x86 et PUISSANCE sont très indulgents, Sparc, Itanium et VAX jettent différentes exceptions.

Prenons l'exemple suivant que je viens de tester sur ARM9:

//Addresses       0     1     2    3     4     5     6     7      8    9
U8 u8Temp[10] = {0x11,0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00};

U32 u32Var;

u32Var = *((U32*)(u16Temp+1));  // Let's read four bytes starting from 0x22

// You would expect that here u32Var will have a value of 0x55443322 (assuming we have little endian)
// But in reallity u32Var will be 0x11443322!
// This is because we are accessing address which %4 is not 0.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top