Est-ce une tâche à faire?
Les bits sont des bits. Bit, Byte, mot, double mot, ce sont des termes matériels, quelque chose d'ensembles d'instructions/assembleur va faire référence. hex, décimal, octal, non signé, signé, chaîne, caractère, etc sont des manifestations de langages de programmation. De même .text, .bss, .data, etc sont aussi des manifestations d'outils logiciels, l'ensemble d'instructions ne se soucie pas d'une adresse étant .data et l'autre étant .text, c'est la même instruction de toute façon. Il y a des raisons pour lesquelles toutes ces choses de langage de programmation existent, de très bonnes raisons parfois, mais ne soyez pas confus en essayant de résoudre ce problème. Pour convertir des bits en ascii lisible par l'homme, vous devez d'abord connaître votre table ascii et les opérateurs bit à bit, et, ou, décalage logique, décalage arithmétique, etc. Plus charger et stocker et d'autres choses. Pensez mathématiquement ce qu'il faut pour passer d'un certain nombre dans un registre/mémoire à un hexagone ASCII. Say 0x1234 qui est 0b0001001000110100. Pour qu'un humain puisse le lire, oui vous devez l'insérer dans une chaîne faute de meilleur terme, mais vous n'avez pas nécessairement besoin de stocker quatre caractères plus un zéro dans les emplacements mémoire adjacents pour faire quelque chose avec. Cela dépend de votre fonction de sortie. Normalement, les entités de sortie basées sur des caractères se réduisent à un seul output_char() de quelque sorte appelé plusieurs fois.
Vous pouvez convertir en une chaîne mais c'est plus de travail, pour chaque caractère ASCII que vous calculez, vous appelez une sorte de fonction de sortie basée sur un seul caractère. putchar() est un exemple de fonction de type caractère de sortie octet.
Donc pour les binaires, vous voulez examiner un bit à la fois et créer un 0x30 ou 0x31. Pour octal, 3 bits à la fois et créer 0x30 à 0x37. Hex est basé sur 4 bits à la fois.Hex a le problème que les 16 caractères que nous voulons utiliser ne sont pas trouvés adjacents dans la table ASCII. Donc vous utilisez 0x30 à 0x39 pour 0 à 9 mais 0x41 à 0x46 ou 0x61 à 0x66 pour A à F selon vos préférences ou vos besoins. Donc, pour chaque chiffrement vous pourriez ET avec 0xF, comparer avec 9 et ADD 0x30 ou 0x37 (10 + 0x37 = 0x41, 11 + 0x37 = 0x42, etc).
Conversion de bits dans un registre en une représentation ascii de binaire. Si le bit dans la mémoire était un 1 montrer un 1 (0x31 ascii) du bit était un 0 montrer un 0 (0x30 en ASCII).
void showbin (unsigned char x)
{
unsigned char ra;
for(ra=0x80;ra;ra>>=1)
{
if(ra&x) output_char(0x31); else output_char(0x30);
}
}
Il peut sembler logique d'utiliser unsigned char ci-dessus, mais unsigned int, en fonction du processeur cible, pourrait produire un code beaucoup mieux (nettoyeur/plus rapide). mais qui est un autre sujet
ci-dessus pourrait ressembler pourrait ressembler à ceci en assembleur (intentionnellement pas en utilisant x86)
...
mov r4,r0
mov r5,#0x80
top:
tst r4,r5
moveq r0,#0x30
movne r0,#0x31
bl output_char
mov r5,r5, lsr #1
cmp r5,#0
bne top
...
Déroulé est plus facile d'écrire et va être un peu plus vite, le compromis est plus la mémoire utilisée
...
tst r4, #0x80
moveq r0, #0x30
movne r0, #0x31
bl output_char
tst r4, #0x40
moveq r0, #0x30
movne r0, #0x31
bl output_char
tst r4, #0x20
moveq r0, #0x30
movne r0, #0x31
bl output_char
...
Dites que vous avez eu 9 numéros de bits et je voulais convertir en octal. Prenez trois bits à la fois (rappelez-vous que les humains lisent de gauche à droite, donc commencez avec les bits supérieurs) et ajoutez 0x30 pour obtenir 0x30 à 0x37.
...
mov r4,r0
mov r0,r4,lsr #6
and r0,r0,#0x7
add r0,r0,#0x30
bl output_char
mov r0,r4,lsr #3
and r0,r0,#0x7
add r0,r0,#0x30
bl output_char
and r0,r4,#0x7
add r0,r0,#0x30
bl output_char
...
Un seul octet (8 bits) en hexadécimal pourrait ressembler à:
...
mov r4,r0
mov r0,r4,lsr #4
and r0,r0,#0xF
cmp r0,#9
addhi r0,r0,#0x37
addls r0,r0,#0x30
bl output_character
and r0,r4,#0xF
cmp r0,#9
addhi r0,r0,#0x37
addls r0,r0,#0x30
bl output_character
...
faisant une boucle de 1 à N mémoriser cette valeur dans la mémoire et la lecture de la mémoire (.data), la sortie en mode hexadécimal:
...
mov r4,#1
str r4,my_variable
...
top:
ldr r4,my_variable
mov r0,r4,lsr #4
and r0,r0,#0xF
cmp r0,#9
addhi r0,r0,#0x37
addls r0,r0,#0x30
bl output_character
and r0,r4,#0xF
cmp r0,#9
addhi r0,r0,#0x37
addls r0,r0,#0x30
bl output_character
...
ldr r4,my_variable
add r4,r4,#1
str r4,my_variable
cmp r4,#7 ;say N is 7
bne top
...
my_variable .word 0
L'enregistrement dans le RAM est un gaspillage si vous avez suffisamment de registres. Bien qu'avec x86 vous pouvez opérer directement sur la mémoire et ne pas devoir passer par des registres.
x86 n'est pas la même que l'assembleur ci-dessus (ARM) donc il est laissé comme un exercice du lecteur pour élaborer l'équivalent. Le fait est que c'est le déplacement, l'alignement et l'ajout de cette matière, la décomposer en étapes élémentaires et les instructions tombent naturellement à partir de là.
le code C donné ci-dessus produit "(" quand on lui donne une valeur supérieure à 0x80 (c.-à-d. si donné 0x8F il donne "(F") –
@AdrianZhang: [Ca marche pour moi] (https://ideone.com/GXg0mH) - as-tu changé quelque chose? Pouvez-vous fournir un [mcve] qui montre le problème? –
Peu importe, il semble que le passage d'un 'uint8_t' à un' char' produit un mauvais résultat. C'est drôle comme c'est arrivé. –