Afficher une variable

cs_Mick7 Messages postés 54 Date d'inscription samedi 11 septembre 2004 Statut Membre Dernière intervention 18 avril 2007 - 20 avril 2006 à 13:20
cs_Nasman Messages postés 202 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 29 septembre 2008 - 21 avril 2006 à 08:36
Salut,

Si vous avez un bon tutorial asm je suis
prenneur car ça fait un petit moment que je cherche et j'ai rien trouvé de vraiment complet.

Bon voila mon probleme j'aimerai afficher la valeur d'une variable
numerique dans le fentre ms-dos, j'arrive a afficher un texte mais je
ne sais comment faire pour afficher une simple valeur....

Merci.

3 réponses

cs_Nasman Messages postés 202 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 29 septembre 2008 3
20 avril 2006 à 14:19
Bonjour Mick7,

Il te faut au préalable convertir ta variable numérique en une chaine ASCII.

1er cas:
ta valeur est une valeur hexadécimale et tu veux la convertir en une chaine du type "A73B".
Il te faut choisir si tu travaille sur 1 octet (2 caractères), 1 word (4 caractères) ou un dword (8 caractères).
Pour un word par exemple le byte de poids faible est stocké en mémoire avant le byte de poids fort. Par exemple mov [adresse],ax mettra al à adresse et ah à adresse+1.
Il te faudra commencer à convertir l'octet de poids fort (à adresse+1) en deux caractères correspondant aux 4 bits de poids fort puis aux 4 bits de poids faible.
Procéder de même pour l'octet de poids faible (à adresse). Terminer par un $ pour DOS.

Pour convertir:Séparer l'octet en ces deux parties soit avec des shl al,4 et des and al,0xF, soit avec l'instruction aam 16d (si ton compilateur l'accepte). Si le résultat est compris entre 0 et 9 il te faux rajouter 30h pour avoir le caractère ASCII ('0' 30h, '9' 39h)Si le résultat est entre A et F, il te faut ajouter 37h ('A' 41h, 'F' 46h).

2ème cas:
Pour convertir une valeur en une chaine décimale il existe plusieurs méthodes.
La plus évidente est d'effectuer des divisions (quelle horreur) par dix puis rajouter 30h pour avoir les caractères.
Une autre méthode plus performante consiste à multiplier par 1/10. Pour celà on calcule la "représentation" de 1/10 en binaire soit
0,000110011001100110011.....soit
11001100110011001100110011001101
2 puissance 35

Soit encore
CCCCCCCDh
2 puissance 35
Les algorithmes multiplient par CCCCCCCDh puis divisent par 8 (shl 3) et divisent par 2 puissance 32 (en fait on ne retient que le dword supérieur)

3ème cas:
Nombre en virgule flottante. Ceci nécessite de savoir comment s'effectue cette représentation des nombres. Les conversions sont plus délicates mais peuvent utiliser les procédures précédentes.

Tu peux trouver différentes routines dans une de mes sources mais d'autres méthodes sont possibles.

A+
0
cs_Mick7 Messages postés 54 Date d'inscription samedi 11 septembre 2004 Statut Membre Dernière intervention 18 avril 2007
20 avril 2006 à 19:05
Ok je commence a comprendre mais c'est pas encore ça... pourrait-tu
t'expliquer un peu plus sur la convertion d'une valeur en chaine
decimal j'ai pas tout compris, bon il faut convertir les valeurs en
code ASCII mais comment on peut faire si la valeur et superieur a 9,
des petites explication ou peut-etre un code source m'aiderait bien

Merci
0
cs_Nasman Messages postés 202 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 29 septembre 2008 3
21 avril 2006 à 08:36
Bonjour Mick7,

Voici deux routines, la première hexascii convertit un octet en hexa en une chaine de caractères, la deuxième hexadec convertit la valeur hexa en une chaine décimale (entière). Tous les calculs de conversion s'effectuent en hexa, les chiffres isolés (entre 0 et 9) sont convertits en caractères.

hexascii: ;convertit la valeur mise dans al en 2 octets al et ah (al=poids fort, ah=poids faible)


aam 16 ;décompose en deux octets ah (division par 16) et al (reste division)
;peut être remplacé par mov ah,al et shr al,4 si pb (MASM)
cmp al,0x9 ;vérifie si numérique
jna num1 ;si <=9
add al,"A"-"0"-10 ;sinon ajoute 7
num1 xchg ah,al ;lit les 4 bits de poids fort
cmp al,0x9
jna num2
add al,"A"-"0"-10
num2 add ax,"00" ;rajoute "0"-0 à chacun des octets
ret

hexadec: ;effectue la conversion hexa vers chaine décimale
;premier paramètre empilé=pointeur vers une chaine de destination
;deuxième paramètre, un dword (signé) à convertir


push eax ;sauvegarde les registres de travail
push edx
push ecx
push esi
push edi
dec esp ;décrémente le pointeur de pile pour mettre le 0 terminal
xor edx,edx
mov [esp],dl ;met le zéro terminal
mov esi,esp ;pointeur de la chaine temporaire
sub esp,byte 11 ;créé un emplacement supplémentaire de 11 octets (signe+10caractères)
mov ecx,[esp+36] ;lit le dword à convertir
test ecx,ecx
jge convd
neg ecx
convd dec esi
mov eax,0xCCCCCCCD ;=(1/10) *800000000h
mul ecx
shr edx,3 ;prend la partie entière de la division par 100000000h puis par 8
lea eax,[edx+4*edx] ;multiplie par 5
shl eax,1 ;puis par 2 (soit par dix)
sub ecx,eax ;calcule le reste
add cl,"0" ;convertit en ascii (rajoute 30h)
mov [esi],cl ;sauvegarde
mov ecx,edx ;prend le quotient et continue le traitement
test ecx,ecx
jnz convd
mov ecx,esp
add ecx,12
sub ecx,esi ;longueur de la chaine
cmp [esp+39],byte 0 ;le nombre était-il négatif
jns copie
inc ecx ;1 caractère de plus pour le signe
dec esi ;si oui copie le signe au début de la chaine
mov [esi],byte "-"
copie mov edi,[esp+40] ;lit l'emplacement où mettre la chaine
rep movsb ;effectue la copie
add esp,byte 12 ;écrase l'emplacement temporaire de la chaine
pop edi
pop esi ;restaure les registres utilisés
pop ecx
pop edx
pop eax
ret 8 ;retour en vidant la pile des deux paramètres

A titre d'exemple la conversion de 1234ABCDh (305441741) va te donner les restes des divisions par dix dans l'ordre soit 1, 4, 7, 1, 4, 4, 5, 0, 3 et remettre ces chiffres (convertis en caractères) dans le bon ordre soit
33h,30h,35h,34h,34h,31h,37h,34h,31h et terminer par 0 soit encore


"305441741",0 avec éventuellement le signe '-' si négatif

J'espère avoir répondu à ta question
A+
0
Rejoignez-nous