Page 1 sur 1
Champs de bits / Variables de taille n bits
Publié : dim. 29/avr./2018 15:45
par Naheulf
Bonjour à tous et à toutes,
Est-ce que quelqu’un(e) sait comment déclarer une structure avec des champs qui ne sont pas des multiples d’un octet ?
Je voudrais arriver à faire l’équivalent du code C suivant :
Code : Tout sélectionner
struct CompressedChunkHeader{
unsigned size:12;
unsigned signature:3;
unsigned flag:1;
unsigned reserved:16:
};
L'idéal serait bien évidement de pouvoir accéder aux valeurs avec un simple
Code : Tout sélectionner
Structure CompressedChunkHeader [Align 0.125]
size.???
signature.???
flag.???
reserved.w
EndStructure
maStructure.CompressedChunkHeader
maStructure\size = 9
;some code
If maStructure\signature <> sommeDeControle
; erreur
EndIf
D'après ce que j'ai vu il faut nécessairement passer par les opérateurs binaires. "&", "|", "<<" et ">>".
Re: Champs de bits / Variables de taille n bits
Publié : dim. 29/avr./2018 16:57
par nico
Oui, il faut passer par les opérateurs binaires. Il est possible aussi de le faire en passant par des chaines de caractères.
Tiens, je te fais un exemple ici:
Dans cet exemple, je prend les valeurs en commençant par le bit de poids fort vers le bit de poids faible, on peut faire l'inverse mais c'est pas forcément nécessaire et utile de rajouter du code en plus dans notre cas.
[Edit] modification du code, travaille avec 8, 16, 32 ou 64 bit
Code : Tout sélectionner
Structure CompressedChunkHeader
; la valeur ChunkHeader qui nous intéresse qui sera répartie dans les variables qui suivent après traitement.
ChunkHeader.l
size.l
signature.l
flag.l
reserved.l
EndStructure
Procedure.q bit(Valeur.q, PositionDepart.l, Longueur.l, nbBit.l)
Protected Valeur$
Valeur$ = Bin(Valeur, #PB_Quad)
Valeur$ = RSet(Valeur$, nbBit, "0")
Debug Valeur$
Valeur$ = Mid(Valeur$, PositionDepart, Longueur)
Debug Valeur$
Valeur = Val("%" + Valeur$)
ProcedureReturn Valeur
EndProcedure
test.CompressedChunkHeader\ChunkHeader = %00101111000011110101111100001111
test\size = bit(test\ChunkHeader, 1, 12, 32)
Debug test\size
test\signature = bit(test\ChunkHeader, 13, 3, 32)
Debug test\signature
test\flag = bit(test\ChunkHeader, 16, 1, 32)
Debug test\flag
test\reserved = bit(test\ChunkHeader, 17, 16, 32)
Debug test\reserved
Re: Champs de bits / Variables de taille n bits
Publié : dim. 29/avr./2018 16:59
par Fig
A ma connaissance, en Pb il est nativement impossible d'accéder à des bits, encore moins d'utiliser une structure non multiple de l'octet.
Il faut utiliser les opérateurs binaires et cela complique légèrement le code.
Re: Champs de bits / Variables de taille n bits
Publié : dim. 29/avr./2018 17:11
par GallyHC
Bonjour,
Je penses juste que pour la signature, on peut faire "signature.s{3}", après j'avoue que je ne sais pas.
Cordialement,
GallyHC
Re: Champs de bits / Variables de taille n bits
Publié : dim. 29/avr./2018 17:12
par nico
Mais pourquoi intervenir pour simplement répéter ce qui est déjà écrit précédemment?
Re: Champs de bits / Variables de taille n bits
Publié : dim. 29/avr./2018 17:17
par GallyHC
Bonjour,
nico a écrit :Mais pourquoi intervenir pour simplement répéter ce qui est déjà écrit précédemment?
C'est pour qui cette phrase?
GallyHC
Re: Champs de bits / Variables de taille n bits
Publié : dim. 29/avr./2018 17:18
par Fig
nico a écrit :Mais pourquoi intervenir pour simplement répéter ce qui est déjà écrit précédemment?
Si ça me concerne, tu as posté alors que j'écrivais moi aussi, tout simplement.
Re: Champs de bits / Variables de taille n bits
Publié : dim. 29/avr./2018 17:22
par nico
Ok, déolé.
Re: Champs de bits / Variables de taille n bits
Publié : dim. 29/avr./2018 17:33
par Ollivier
Moi, j'ai une technique de psychopathe : chaque bit est un entier signé de 64 bits de type quad. Tu extrais l'info, tu lis et modifies l'info, puis tu la recomprime en bits.
Code : Tout sélectionner
Structure Psychostruc
Size.I[12]
Signature.I[3]
Flag.I
Reserved.I[16]
EndStructure
Une fois que c'est modifié, plié... Hop, recompression
ICI
Re: Champs de bits / Variables de taille n bits
Publié : dim. 29/avr./2018 22:14
par G-Rom
ton code en C correspond a cela en PB :
Il faut que tu joue avec les bits pour accéder aux éléments, attention a la capacité des champs, 12 bits , c'est moins qu'un word, environ +/- 2047
soit en gros :
Code : Tout sélectionner
Structure CompressedChunkHeader
reserved.l
EndStructure
Macro setSize(struct, size)
struct\reserved = struct\reserved &FFF | (size<<19)
EndMacro
Macro getSize(struct)
struct\reserved >> 19 & $FFF
EndMacro
Macro setSignature(struct, size)
struct\reserved = struct\reserved | (size<<15)
EndMacro
Macro getSignature(struct)
struct\reserved >> 15 & $F
EndMacro
Macro setFlag(struct, bit)
If bit=1
struct\reserved | (1<<14)
Else
struct\reserved & (254 << 14)
EndIf
EndMacro
Macro getFlag(struct)
Struct\reserved >> 14 & $1
EndMacro
A.CompressedChunkHeader
A\reserved = 0
setSize(A,245)
setSignature(A,15)
setFlag(A,1)
Debug RSet(Bin(A\reserved),32,"0")
Debug getSize(A)
Debug getSignature(A)
Debug getFlag(A)
Re: Champs de bits / Variables de taille n bits
Publié : lun. 30/avr./2018 19:04
par Ollivier
Tiens, ça m'étonne que ce soit en little endian les champs de bits en C.
Si c'est le cas, mon code de compression de quads booléens en bits est à mettre au placard !
Re: Champs de bits / Variables de taille n bits
Publié : lun. 30/avr./2018 19:35
par G-Rom
J'ai pas pris en compte l'endianess, tu peu changer mon code pour changé les bits dans l'ordre qui t'arrange.
Re: Champs de bits / Variables de taille n bits
Publié : jeu. 03/mai/2018 8:29
par Ollivier
J'ai essayé de trouver une soluce à la fois proche de la syntaxe actuelle (structure+lecture+écriture) en maintenant la performance : impossible.
La syntaxe bloque. Et la structuration (créer une structure avec des champs variable en fonction des arguments d'une macro) bloque aussi.
Le seul petit truc que j'ai "réussi" à pondre, c'est le masque d'un champ :
Code : Tout sélectionner
Macro BitMask(BitStart, BitLength)
(((1 << BitLength) - 1) << BitStart)
EndMacro
C'est en big endian à base 0 pour BitStart et en bits pour BitLength.
Le problème, c'est que c'est quasiment impossible d'obtenir les deux arguments BitStart et BitLength sous forme de constante pré-calculée à partir d'une liste de directive de type
J'arrive à obtenir des suites polynomiales avec les macros. Par exemple
qui donne
mais je n'arrive pas à faire un calcul de type "oignon" avec les macros.
De ce type:
sachant que si toutes ces valeurs sont des constantes ou des arguments de macros, elles peuvent être stockées dans des constantes et donc être précalculées.
Re: Champs de bits / Variables de taille n bits
Publié : sam. 05/mai/2018 19:50
par Naheulf
Merci pour toutes vos réponses.
Au moins c'est clair : Il n'y a plus qu'à se faire sa propre tambouille pour accéder aux bits.
Merci à tous