Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

chenillard ?

6 réponses
Avatar
Jomanix
bonjour
j'ai réaliser un petit chenillard en assembleur qui me fait une rotation sur
une valeur codée sur 8 bits.

Je voulais savoir si en c il y avait ue instruction qui me permettait la mem
chose.

A la rigueur je divise ou je multiplie ma valeur par 2 selon le sens que je
souhaite. ok
mais je les entiers sont tous codé sur 16 - 32 bits et non sur 8.
est ce qu'il existe un type binaire sur 8 bits?

merci d'avance.

6 réponses

Avatar
Richard Delorme
j'ai réaliser un petit chenillard en assembleur qui me fait une rotation sur
une valeur codée sur 8 bits.

Je voulais savoir si en c il y avait ue instruction qui me permettait la mem
chose.
A la rigueur je divise ou je multiplie ma valeur par 2 selon le sens que je
souhaite. ok


Il y a << et >> qui sont des opérateurs de décalage, et non de rotation.

mais je les entiers sont tous codé sur 16 - 32 bits et non sur 8.
est ce qu'il existe un type binaire sur 8 bits?


Le C ne garantit pas la taille exacte des types entiers, uniquement des
tailles minimales. Ceci précisé, en général, le type char (et ses
acolytes signed et unsigned) est codé sur 8 bits. On peut éventuellement
le vérifier avec la macro CHAR_BIT définie dans <limits.h>.
Dans tout les cas, on peut masquer le résultat avec un et-binaire pour
s'assurer de ne conserver que 8 bits.

--
Richard

Avatar
Pierre Maurette
bonjour
j'ai réaliser un petit chenillard en assembleur qui me fait une rotation sur
une valeur codée sur 8 bits.

Je voulais savoir si en c il y avait ue instruction qui me permettait la mem
chose.
(lire d'abord la dernière réponse, sur les types, plus bas)

Tout d'abord, en fonction de vos contraintes de portabilité, vous
pouvez faire tout simplement:
asm{/* le code qui allait bien en assembleur */};
asm peut être _asm ou __asm. L'avantage de cette solution n'est pas la
vitesse, mais la simplicité. Pour les décalages vers la droite par
exemple, en assembleur, il existe certainement deux instructions, une
signée et une non signée, alors qu'en C le comportement de >> va
dépendre du type des opérandes. Vous risquez donc moins l'erreur bête
avec l'assembleur. Le cas est flagrant si vous vopulez décaler
physiquement une mémoire déclarée signed pour d'autres raisons. C'est
faisable, mais à grand renfort de cast.

La rotation n'existe pas en C. Vous disposez des décalages de bits <<
et >>.

A la rigueur je divise ou je multiplie ma valeur par 2 selon le sens que je
souhaite. ok
Les compilateurs traduisent d'eux même les multiplications et divisions

d'entiers par des *constantes* puissances de 2 par des décalages. Ce
n'est pas une obligation de la norme mais la réalité.

mais je les entiers sont tous codé sur 16 - 32 bits et non sur 8.
est ce qu'il existe un type binaire sur 8 bits?
char est en C le type entier le plus petit. Il fait "souvent" 8 bits de

largeur. Il a la déplorarable particulartité de ne pas être
obligatoirement signed par défaut. Donc, première précaution:
typedef signed char sBYTE;
typedef unsigned char uBYTE;
Noms exact à déterminer pour la meilleure lisibilité sans collision.
BYTE est par exemple défini par Windows.
Ensuite vous pouvez vérifier que vous avez bien le type que vous
attendez (l'octet de l'assembleur, en fait) avec les macros de
limits.h:
CHAR_BIT devrait faire 8
UCHAR_MIN devrait faire 0
UCHAR_MAX devrait faire 255
SCHAR_MIN devrait faire -128 (parfois -127)
SCHAR_MAX devrait faire 127
UCHAR_MIN et UCHAR_MAX dépendent du type (signed ou unsigned) de char.

Le mieux aujourd'hui est peut-être d'utiliser uint8_t et int8_t (quitte
à le typedef-er en sint8_t). Ces deux types décrits dans la norme C99
sont loin d'être implémentés sur tous les compilateurs même parmi les
plus courants. S'ils le sont, c'est dans stdint.h. Ils peuvent être
partiellement définis (uint8_t mais pas int8_t), bien que je n'ai
jamais vu le cas sur des machines x86.
Si vous n'en disposez pas, vous pouvez éventuellement les définir comme
vu plus haut.
Notez que s'il est défini les types signed comme int8_t garantissent le
codage des entiers négatifs en complément à 2.

--
Pour répondre directement: enlever une lettre sur deux
wwaannaaddoooo -> wanadoo

Pierre Maurette

Avatar
Pierre Maurette
J'ai envoyé trop tôt (erreur de bouton, faudrait pas que je travaille
sur machine-outil ou sous-marin lanceur d'engins).
Faire les rotations en C en supposant CHAR_BIT à 8 :

#include<stdio.h>

typedef signed char sBYTE;
typedef unsigned char uBYTE;

int main(void)
{
uBYTE a = 0xAA;/* 10101010 */
int dummy;
dummy = (a & 0x80) >> 7;
a = (a << 1) | dummy ;
printf("%2Xn", a);

/* a == 0x55, 01010101 */
dummy = (a & 0x01) << 7;
a = (a >> 1) | dummy ;
printf("%2Xn", a);
return 0;
}


Si on ne suppose pas CHAR_BIT à 8 :
(je simule grossièrement un CHAR_BIT à 32, code à jeter)

#include<stdio.h>

typedef signed int sBYTE;
typedef unsigned int uBYTE;

#define CHAR_BIT 32

int main(void)
{
uBYTE a = 0xAAAAAAAA;
uBYTE dummy;
dummy = (a & (0x01 << (CHAR_BIT - 1))) >> (CHAR_BIT - 1);
a = (a << 1) | dummy ;
printf("%8Xn", a);

dummy = (a & 0x01) << (CHAR_BIT - 1);
a = (a >> 1) | dummy ;
printf("%8Xn", a);
return 0;
}

--
Pour répondre directement: enlever une lettre sur deux
wwaannaaddoooo -> wanadoo

Pierre Maurette
Avatar
Pierre Maurette
Autre possibilité: en fonction des E/S et du câblage de la sortie, il
peut être utile de faire un rotate sur NB_LEDS bits au sein d'un mot
plus grand. Remarque: NB_LEDS pourrait très bien ne pas être une
constante définie à la compilation.

#include<stdio.h>
#include<limits.h>
#include<assert.h>

typedef unsigned int uTRUC;
#define NB_LEDS 4

int main(void)
{
uTRUC a = 0xF000000A;
uTRUC dummy;
const int shift = NB_LEDS - 1;
assert( (NB_LEDS > 0) && (NB_LEDS <= (sizeof(uTRUC) * CHAR_BIT)));
dummy = (a & (0x01 << shift)) >> shift;
a = (a << 1) | dummy ;
printf("%8Xn", a);

dummy = (a & 0x01) << shift;
a = (a >> 1) | dummy ;
printf("%8Xn", a);
return 0;
}

--
Pour répondre directement: enlever une lettre sur deux
wwaannaaddoooo -> wanadoo

Pierre Maurette
Avatar
Emmanuel Delahaye
Jomanix wrote on 27/05/05 :
j'ai réaliser un petit chenillard en assembleur qui me fait une rotation sur
une valeur codée sur 8 bits.

Je voulais savoir si en c il y avait ue instruction qui me permettait la mem
chose.


Non. Il faut utiliser >> ou << (SHR, SHL) sur un entier non signé et
sauvegarder l'état du bit qui va 'sortir' avant de le réinjecter...

mais je les entiers sont tous codé sur 16 - 32 bits et non sur 8.
est ce qu'il existe un type binaire sur 8 bits?


Le nombre de bits des entiers dépend de l'implémentation. Sur beucoup,
un unsigned char fait 8 bits. Mais pour ce que tu veux faire, ça n'a
pas d'importance.

Il suffit d'extraire les 8 bits significatifs avec & 0xFF.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"

Avatar
Jomanix
Merci beaucoup pour ces précisions et ces détails trés précis.

A l'origine je veux programmer un microcontroleur via le compilateur C de
MPLAB.

Au final je m'en sort en créant un tableau de huit colonne. Ou chaque
colonnne represente un bit donc je me sers seulement du BLMS.
C'est une méthode un peu bourrin. Mais c'est a rendre demain et c'est déjà
programmer.






"Pierre Maurette" a écrit
dans le message de news:
Autre possibilité: en fonction des E/S et du câblage de la sortie, il peut
être utile de faire un rotate sur NB_LEDS bits au sein d'un mot plus
grand. Remarque: NB_LEDS pourrait très bien ne pas être une constante
définie à la compilation.

#include<stdio.h>
#include<limits.h>
#include<assert.h>

typedef unsigned int uTRUC;
#define NB_LEDS 4

int main(void)
{
uTRUC a = 0xF000000A;
uTRUC dummy;
const int shift = NB_LEDS - 1;
assert( (NB_LEDS > 0) && (NB_LEDS <= (sizeof(uTRUC) * CHAR_BIT)));
dummy = (a & (0x01 << shift)) >> shift;
a = (a << 1) | dummy ;
printf("%8Xn", a);

dummy = (a & 0x01) << shift;
a = (a >> 1) | dummy ;
printf("%8Xn", a);
return 0;
}

--
Pour répondre directement: enlever une lettre sur deux
wwaannaaddoooo -> wanadoo

Pierre Maurette