Rechercher : dans
Par :

[C] Rotation de bits sur la gauche (ROL)

Dernière réponse le 3 jui 2006 à 13:14:15 anais, le 30 jun 2006 à 21:51:34 
 Signaler ce message aux modérateurs

Bonsoir !

Je cherche à recoder un programme en assembleur en C : pour le moment tout se passe bien, mais j'ai quelques soucis avec l'instruction rol (rotation de bits vers la gauche).

J'ai un nombre en hexadécimal qui est 65657247, et je veux effectuer un rol de 104 (en décimal) dessus. A la main, a la calculette et avec mon programme en assembleur j'obtiens : 65724765 (en hexa).

Je cherche donc à obtenir la même chose en C : d'après ce post : c rol j'ai un code qui ressemble à ça (sous dev c++) :

#include <stdio.h>
#define ROL(x,b) (((x) >> (b)) | ((x) << (32 - (b))))

int main(int argc, char * argv[])
{
int a = 0x65657247;

printf("%8.8x\n",  ROL(a,104));
system ("pause");

return 0;
}


A la compilation, j'obtiens : warning: right shift count >= width of type et warning: left shift count is negative
Je vois pas du tout d'ou vient le problème... qui pourrait m'aider à trouver le résultat attendu ?

Merci d'avance !

Meilleures réponses pour « [C] Rotation de bits sur la gauche (ROL) » dans :
Langage C - Les opérateurs Voir Qu'est-ce qu'un opérateur ? Les opérateurs sont des symboles qui permettent de manipuler des variables, c'est-à-dire effectuer des opérations, les évaluer, etc. On distingue plusieurs types d'opérateurs : les opérateurs de calcul les opérateurs...
Manipuler des entiers en 64 bits VoirManipuler des entiers en 64 bits En C, un entier traditionnel non signé sur 32 bits ne peut pas dépasser la valeur de 4 294 967 295. Il se peut que vous soyiez amenés à manipuler des nombres plus grands et pour celà vous aurez besoin des entiers...
Pourquoi Windows ne voit pas les 4 Go de RAM installés ? VoirWindows XP ou Vista en édition 32 bits ne peuvent pas utiliser 4 Go, il n'y a rien à faire, c'est une limitation mathématique. En 32 bits, le système ne peut adresser que : 2 puissance 32 = 4,3 Milliards d'adresses différentes , correspondant...
Autoexec.NT - Sous-système Windows 16 bits VoirEn voulant installer un programme 16 bits sous Windows, le message d'erreur suivant apparaît : Sous-système Windows 16 bits C:\WINDOWS\SYSTEM32\AUTOEXEC.NT. Le fichier système ne convient pas à l'exécution des applications MS-DOS ou Microsoft...
Télécharger Visual C++ Express VoirVisual C++ Express est une version "gratuite" et allégée de Visual Studio ; l'utilisation requiert l'inscription sur le site de Microsoft. Cet environnement de développement permet de créer des application Win32 ou du .NET C.
Télécharger Drivers Realtek AC'97 Audio pour Vista/7 VoirLe pilote Realtek AC 97 Audio Codec pour Windows Vista (et Windows 7) fonctionne sur les systèmes Windows Vista 32 et 64 bits. Les chipsets audio supportées sont : Realtek ALC100 Realtek ALC101 Realtek ALC200 Realtek ALC201A Realtek...
Les structures en langage C VoirDifférence entre une structure et un tableau Un tableau permet de regrouper des éléments de même type, c'est-à-dire codés sur le même nombre de bits et de la même façon. Toutefois, il est généralement utile de pouvoir rassembler des éléments de...
Langage C - Les types de données VoirLes types de données Les données manipulées en langage C sont typées, c'est-à-dire que pour chaque donnée que l'on utilise (dans les variables par exemple) il faut préciser le type de donnée, ce qui permet de connaître l'occupation mémoire (le...
Langage C++ - Les opérateurs VoirQu'est-ce qu'un opérateur ? Les opérateurs sont des symboles qui permettent de manipuler des variables, c'est-à-dire effectuer des opérations, les évaluer, etc. On distingue plusieurs types d'opérateurs : les opérateurs de calcul les opérateurs...

1

mamiemando, le 1 jui 2006 à 11:01:31
  • +1

Vu ce qui est dit là :
http://www.squalenet.net/fr/ti/tutorial_c/8-operateurs-arith­metiques-et-bits-a-bi...

je dirais que c'est simplement :

#include <stdio.h>
#include <stdlib.h>

int main(){
  unsigned int x = 0x65657247;
  x << 104;
  printf("hex = %x\n",x);
  printf("dec = %d\n",x);
  getchar();
  return 0;
}

PS : evite d'utiliser les commande via system() qui vont faire que ton programme va dépendre de l'OS (windows ou linux), alors que getchar() fait pareil et marche avec tout le monde...

Bonne chance

Répondre à mamiemando

2

anais, le 1 jui 2006 à 18:31:44

Merci pour ta réponse, cependant, je crois que ton code ne fait qu'un décalage de bits vers la gauche (shl en asm), et non une rotation !

Répondre à anais

3

mamiemando, le 3 jui 2006 à 00:38:05

Ok je viens de capter ce que tu faisais. Comme b = 104
1) ((x) >> (b)) entraine un décalage de 104 bits alors que l'entier est codé sur moins de bits (32 je suppose vu ce que tu as écris).
2) ((x) << (32 - (b))) à un décalage de 32-104 <= 0 bits

D'où les messages d'erreurs du compilateur. Il faudrait que tu utilises pour (1) un décalage de moins de 32 bits (en utilisant un opérateur modulo (% en C) ?), et pour deux une valeur absolue (par exemple à l'aide d'une autre macro) ?

Bonne chance

Répondre à mamiemando

4

 kilian, le 3 jui 2006 à 13:14:15
  • +1

Salut,

Ta macro ROL fait en fait un equivalent de ror en assembleur (rotation des bits vers la droite).

Si tu ne mets pas de constante dans b pour ta macro, le compilateur ne te mettra aucune alerte. D'ailleurs avec ta macro (si tu la corriges en un vrai rol), la rotation se fait très bien même avec de gros nombres (par contre on dirait qu'un rol en assembleur ne peut supporter d'opérande de plus de 255 pour la rotation, tandis que ta macro supportera plus.

Si tu as quand même des soucis, tu peux utiliser une fonction qui découpe la rotation en plusieurs rotations distinctes de moins de 32 bits. Un exemple:

#include <stdio.h>
// Ta rotation ror corrigée en rol
#define ROL32(x,b) (((x) << (b)) | ((x) >> (32 - (b))))

//La rotation en assembleur
unsigned int test_asm()
{
	__asm__("movl $100, %eax\n\t"
	        "roll  $255, %eax"
	        );
}

// La rotation découpée en plusieurs rotations distinctes
unsigned int rol(unsigned int nb, unsigned int r)
{
	for (; r>31; r-=31)
	{
		nb = ROL32(nb, 31);
	}
	nb = ROL32(nb, r);
	return nb;
}

int main(int argc, char **argv)
{
	unsigned int a=100;
	unsigned int r=255;
        //Affichage de la rotation en assembleur
	printf("%u\n", test_asm() );
        //Affichage de la rotation en C
        //Marche aussi, chez moi, avec printf("%u\n", ROL32(a,r) );
	printf("%u\n", rol(a,r) );
	return 0;
}

Répondre à kilian
Collection CommentÇaMarche.net