2009-11-29 22 views
5

En C, J'ai un mot de 32 bits représentant une adresse (et je l'ai stocké dans un long non signé, j'espère que ça va). Maintenant, d'après ce que je comprends, une partie d'une adresse contient le numéro de page et l'autre partie contient le décalage. Je me demandais comment je pouvais extraire juste les bits qui me donnent le numéro de page. J'ai déjà travaillé sur les 22 premiers bits les plus significatifs sont le numéro de page et les 10 autres bits sont le décalage de la page. Comment puis-je saisir uniquement les bits correspondant au numéro de page? Je pense que je peux le faire avec quelques opérations au niveau du bit, mais je ne sais pas comment.Extraction des bits

+0

Bonne question - Je dois le faire pour un désassembleur que j'écris aussi. – new123456

Répondre

11

Utilisez les opérateurs bitshift pour extraire les bits dont vous avez besoin.

pageNumber = x >> 10; 
offset = x & ((1 << 10) - 1); 

Pour le numéro de page, l'opérateur >> déplace les bits vers le bas, de sorte que vous perdez les bits signifcatifs. Pour le décalage, ((1 < < 10) - 1) crée un masque de bits composé de 10 uns qui est utilisé pour sélectionner seulement les 10 bits les moins significatifs et ignorer les bits les plus significatifs.

+1

Ce code peut être une bonne idée pour masquer les bits après les avoir décalés, dans le cas où votre matériel effectue un décalage vers l'arithmétique (prolongation de signe) vers la droite. pagenumber = (x >> 10) & ((1 << 22) - 1); –

2

Je suis un grand fan de la méthode d'extraction de terrain «deux équipes». Cela fonctionne à la fois signé et non signé. Pour extraire un champ de largeur w avec bit le moins significatif lsb de word:

#define BITSIN(W) (8*sizeof(W)) 
return (word << (BITSIN(word) - (lsb+width))) >> (BITSIN(word) - width); 

Dans ce cas, BITSIN(word) == 32 et lsb+width == 32, donc tant que le mot en question est non signée, vous pouvez simplement passer à droite 10 sans masquage.

Une mise en garde: Méfiez-vous des changements de 32 bits sur les types 32 bits! Le standard C permet au compilateur de faire n'importe quoi, et ce que font les puces Intel courantes n'est pas utile: x << y déplace x laissé par y % 32 bits (à condition que x ait un type entier de 32 bits). Cela signifie que si vous essayez de déplacer un entier 32 bits vers la gauche ou vers la droite de 32 bits, le résultat est identique à un non-op. Il existe un problème similaire avec les décalages 64 bits des types 64 bits.

+0

"ce que font les puces Intel courantes n'est pas utile" - que font-ils? – AShelly

+0

@ASHelly: bonne question; J'ai édité la réponse. Qui sait, il pourrait me obtenir une upvote :-) –