Soyez le premier à donner votre avis sur cette source.
Snippet vu 14 306 fois - Téléchargée 30 fois
MODEL SMALL STACK 100h DATA SEGMENT Chaine DB 25 DUP ('$') Prompt DB 'Conversion de $' ChHexa DB 'en hexa :0x$' ChDec DB 'en decimal :$' ChBin DB 'en binaire :0b$' ChOct DB 'en octal :0o$' ChNeg DB 'en negatif :$' CRLF DB 13,10,'$' DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA TerminalChar EQU '$' ;inverse une chaine ;================== ;DS:SI : adresse du début de la chaine ;DS:DI : adresse de fin de la chaine (avant le caractère de terminaison de chaine) InverseChaine PROC ;on inverse la chaine puisque l'on a calculé la représentation à l'envers (méthode des divisions successives) boucleInv: ;on échange [DI] <-> [SI] MOV AL,byte ptr [DI] MOV AH,byte ptr [SI] MOV byte ptr [SI],AL MOV byte ptr [DI],AH ;octets suivants DEC DI INC SI ;tant que l'on n'a pas tout inversé (SI < DI) CMP SI,DI JL boucleInv RET InverseChaine ENDP ;convertit un nombre en sa représentation décimale (chaine) ;========================================================== ;DS:SI : adresse où stocker la chaine ;AX : nombre à convertir ;CX=1 : nombre signé, CX=0 : non signé ChaineDec PROC ;sauvegarde des registres PUSH DX PUSH DI PUSH CX PUSH SI PUSH AX ;si le nombre est non signé CMP CX,0 ;on passe à la conversion JE PasSigne ;sinon, on calcule la valeur absolue ;si AX est >= 0 CMP AX,0 JGE PasSigne ;valeur absolue de AX NEG AX ;on ajoute le signe MOV byte ptr [SI],'-' ;on passe au caractère suivant INC SI PasSigne: ;sauvegarde de l'offset de départ de la chaine MOV DI,SI ;mot de poids fort dans le dividende XOR DX,DX ;tant qu'il y a des chiffres à ajouter boucleDec: ;CX=AX pour le calcule du reste de division MOV CX,AX ;division par 10 : algo de Terje Mathisen ;======================================== MOV DX,0CCCDh ;on divise AX par 10 : résultat dans DX MUL DX SHR DX,3 ;======================================== ;on sauvegarde de résultat dans AX MOV AX,DX ;on calcule le reste de la division de CX(=AX avant division) SHL DX,1 ;DX = quotient * 2 SUB CX,DX ;CX = divende - quotient * 2 SHL DX,2 ;DX = quotient * 2 * 4 = quotient * 8 SUB CX,DX ;CX = dividende - quotient * 2 - quotient * 8 = dividende - quotient * 10 = reste ;on ajoute '0'=48 pour convertir le chiffre en code ascii correspondant ADD CX,'0' ;on le copie dans la chaine MOV byte ptr [DI],CL ;on passe au caractère suivant INC DI ;si le quotient est nul, on a fini la conversion CMP AX,0 JA boucleDec ;on met un caractère de fin de chaine MOV byte ptr [DI],TerminalChar ;on se place avant le caractère de la fin de chaine DEC DI ;on inverse la chaine puisque l'on a calculé la représentation à l'envers (méthode des divisions successives) CALL InverseChaine ;récupération des registres POP AX POP SI POP CX POP DI POP DX RET ChaineDec ENDP ;convertit un nombre en sa représentation héxadécimale (chaine) ;============================================================== ;DS:SI : adresse où stocker la chaine ;AX : nombre à convertir ;CX : nombre de digits ChaineHex PROC ;sauvegarde des registres PUSH DX PUSH DI PUSH CX PUSH SI PUSH AX ;sauvegarde de l'offset de départ de la chaine MOV DI,SI ;tant qu'il y a des chiffres à ajouter boucleHexa: ;DX=AX pour le calcul du reste de AX / 16 MOV DX,AX ;DX = reste de la division de AX par 16 AND DX,15 ;DX = AX and 01111b = AX mod 16 ;on divise AX par 16 = 2 ^ 4 SHR AX,4 ;le reste DX est-il entre 0 et 9 CMP DX,9 ;si 9 < DX < 15 JA LettreHexa ;sinon, un chiffre ADD DX,'0' JMP MetChaine ;on doit afficher une lettre Hexadécimale LettreHexa: ADD DX,'A'-10 ;on met le caractère dans la chaine MetChaine: MOV byte ptr [DI],DL ;on passe au caractère suivant INC DI ;un digit affiché en plus DEC CX ;si le quotient est nul, on a fini la conversion CMP AX,0 JA boucleHexa ;s'il n'y a plus de digit '0' à ajouter devant le nombre CMP CX,0 ;on termine la chaine JLE FinChaineHexa ;sinon, on ajoute les '0' manquants boucle0Hexa: ;on met un "0" MOV byte ptr [DI],'0' ;on passe au caractère suivant INC DI ;tant que CX != 0 LOOP boucle0Hexa ;on ajoute le caractère de fin de chaine FinChaineHexa: ;on met un caractère de fin de chaine MOV byte ptr [DI],TerminalChar ;on se place avant le caractère de la fin de chaine DEC DI ;on inverse la chaine puisque l'on a calculé la représentation à l'envers (méthode des divisions successives) CALL InverseChaine ;récupération des registres POP AX POP SI POP CX POP DI POP DX RET ChaineHex ENDP ;convertit un nombre en sa représentation octale (chaine) ;========================================================== ;DS:SI : adresse où stocker la chaine ;AX : nombre à convertir ;CX : nombre de digits ChaineOct PROC ;sauvegarde des registres PUSH DX PUSH DI PUSH CX PUSH SI PUSH AX ;sauvegarde de l'offset de départ de la chaine MOV DI,SI ;tant qu'il y a des chiffres à ajouter boucleOct: ;on divise AX par 8 : quotient dans AX, reste dans DX (DL) ;calcul du reste MOV DL,AL ;DL=AL AND DL,07h ;DL = AL and 0111b = AL mod 8 ;division par 2 ^ 3 = division par 8 SHR AX,3 ;on ajoute '0'=48 pour convertir le chiffre en code ascii correspondant ADD DL,'0' ;on le copie dans la chaine MOV byte ptr [DI],DL ;on passe au caractère suivant INC DI ;on a un digit de plus DEC CX ;si le quotient est nul, on a fini la conversion CMP AX,0 JA boucleOct ;s'il n'y a plus de digit '0' à ajouter devant le nombre CMP CX,0 ;on termine la chaine JLE FinChaineOct ;sinon, on ajoute les '0' manquants boucle0Oct: ;on met un "0" MOV byte ptr [DI],'0' ;on passe au caractère suivant INC DI ;tant que CX != 0 LOOP boucle0Oct ;on ajoute le caractère de fin de chaine FinChaineOct: ;on met un caractère de fin de chaine MOV byte ptr [DI],TerminalChar ;on se place avant le caractère de la fin de chaine DEC DI ;on inverse la chaine puisque l'on a calculé la représentation à l'envers (méthode des divisions successives) CALL InverseChaine ;récupération des registres POP AX POP SI POP CX POP DI POP DX RET ChaineOct ENDP ;convertit un nombre en sa représentation décimale (chaine) ;========================================================== ;DS:SI : adresse où stocker la chaine ;AX : nombre à convertir ChaineBin PROC ;sauvegarde des registres PUSH DX PUSH DI PUSH CX PUSH SI PUSH AX ;sauvegarde de l'offset de départ de la chaine MOV DI,SI ;tant qu'il y a des chiffres à ajouter boucleBin: ;on divise AX par 2 : quotient dans AX, reste dans DX (DL) ;calcul du reste MOV DL,AL ;DL=AL AND DL,1 ;DL=AL and 2 = AL mod 2 ;division par 2 SHR AX,1 ;on ajoute '0'=48 pour convertir le chiffre en code ascii correspondant ADD DL,'0' ;on le copie dans la chaine MOV byte ptr [DI],DL ;on passe au caractère suivant INC DI ;on a un digit de plus DEC CX ;si le quotient est nul, on a fini la conversion CMP AX,0 JA boucleBin ;s'il n'y a plus de digit '0' à ajouter devant le nombre CMP CX,0 ;on termine la chaine JLE FinChaineBin ;sinon, on ajoute les '0' manquants boucle0Bin: ;on met un "0" MOV byte ptr [DI],'0' ;on passe au caractère suivant INC DI ;tant que CX != 0 LOOP boucle0Bin ;on ajoute le caractère de fin de chaine FinChaineBin: ;on met un caractère de fin de chaine MOV byte ptr [DI],TerminalChar ;on se place avant le caractère de la fin de chaine DEC DI ;on inverse la chaine puisque l'on a calculé la représentation à l'envers (méthode des divisions successives) CALL InverseChaine ;récupération des registres POP AX POP SI POP CX POP DI POP DX RET ChaineBin ENDP ;macro pour afficher une chaine à l'écran Printf MACRO Chain PUSH AX MOV AH,09h ;fonction 9 : "puts" LEA DX,Chain ;DS:DX : adresse de la chaine à afficher INT 21h ;interruption DOS POP AX ENDM ;programme principal de test Deb: ;init de DS MOV AX,DATA MOV DS,AX ;DS:SI : adresse de la chaine résultat LEA SI,Chaine ;nombre à afficher MOV AX,0FFF9h ;================ Printf Prompt ;affichage ;pas de signe MOV CX,0 ;conversion CALL ChaineDec Printf Chaine Printf CRLF ;================ Printf ChDec ;affichage ;pas de signe MOV CX,0 ;conversion CALL ChaineDec Printf Chaine Printf CRLF ;================ Printf ChHexa ;affichage ;4 digits MOV CX,4 ;conversion CALL ChaineHex Printf Chaine Printf CRLF ;================ Printf ChOct ;affichage ;conversion CALL ChaineOct Printf Chaine Printf CRLF ;================ Printf ChBin ;affichage ;16 digits MOV CX,16 ;conversion CALL ChaineBin Printf Chaine Printf CRLF ;================ Printf ChNeg ;affichage NEG AX ;un signe MOV CX,1 ;conversion CALL ChaineDec Printf Chaine Printf CRLF MOV AL,0 MOV AH,04Ch INT 21h CODE ENDS END Deb
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.