Utilitaire qui effectue les opérations élémentaires courantes entre deus nombres hexadécimaux (+,-,and,or,xor) sur 64 bits et donne le résultat en hexadécimal et en décimal.Il peut traiter les nombres négatifs et positif.
Source / Exemple :
; #########################################################################
.386
.model flat, stdcall
option casemap :none ; casse sensible
; #########################################################################
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\masm32.lib
; #########################################################################
;=============
; Local macros
;=============
szText MACRO Name, Text:VARARG
LOCAL lbl
jmp lbl
Name db Text,0
lbl:
ENDM
;=================
; Local prototypes
;=================
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
Ed1Proc PROTO :DWORD,:DWORD,:DWORD,:DWORD
Controle PROTO :DWORD
Convert PROTO :DWORD
dqtoa PROTO :QWORD, :DWORD, :DWORD
.data
dlgname db "TESTWIN",0
M0 db "Dépasement de capacité : 65 bits!",13,10,10
db " Pour avoir le résultat exact : ",13,10
db " HEXA : placer devant, le 65° bit : chiffre 1",13,10
db " DECI : ajouter 18 446 744 073 709 551 616 ",13,10
db " au résutat affiché.",13,10,10
db " calculatrice Windows de rigueur",0
M1 db " ATTENTION !!!!",0
Txt1 db 9 dup (0); Recueuille l'entrée basse 1
Txt2 db 9 dup (0); " " " 2
Txt3 db 9 dup (0); Recueuille l'entrée haute 1
Txt4 db 9 dup (0); " " " 2
buff db 19 dup (0); " le résultat en Hexa
;==============================================================
; le tampon suivant est utilisé par dqtoa et doit avoir une
; longueur de 30 octets minimun
;=============================================================
StringDec db 31 dup (0); " le résultat en décimal
Reste dq 0
nbch dd 0
Cpt dd 0
Cpt1 dd 0
signe dd 0
.data?
hEdit1 dd ?
hEdit2 dd ?
hEdit3 dd ?
hEdit4 dd ?
hEdit5 dd ?
hEdit6 dd ?
hButn1 dd ?
hButn2 dd ?
hButn3 dd ?
hButn4 dd ?
hButn5 dd ?
hButn6 dd ?
hInstance dd ?
hIcon dd ?
hText dd ?
Nega dd ?
Drapo dd ?
lpfnEd1Proc dd ?
Nb1 dd ? ; chaîne 1 > 64 bits Low
Nb2 dd ? ; chaine 2 > 64 bits Low
Nb3 dd ? ; chaîne 1 > 64 bits High
Nb4 dd ? ; chaîne 2 > 64 bits High
Nb5 dd ? ; Résultat Low
Nb6 dd ? ; Résultat High
Nb10 dq ?
; #########################################################################
.code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
; -----------------------------------------------------
; Appel de dialog box stockée dans le fichier ressource
; -----------------------------------------------------
invoke DialogBoxParam,hInstance,ADDR dlgname,0,ADDR WndProc,0
invoke ExitProcess,eax
; #########################################################################
WndProc proc hWin :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD
LOCAL Ps :PAINTSTRUCT
.if uMsg == WM_INITDIALOG
szText dlgTitle," Calculs avec des nombres hexadécimaux "
invoke SendMessage,hWin,WM_SETTEXT,0,ADDR dlgTitle
invoke LoadIcon,hInstance,200
mov hIcon, eax
invoke SendMessage,hWin,WM_SETICON,1,hIcon
;==================================================
;Recherche des handles correspondants aux controles
;de la boite de dialogue (Edits et boutons)
;==================================================
invoke GetDlgItem,hWin,100
mov hEdit1, eax
invoke GetDlgItem,hWin,101
mov hEdit2, eax
invoke GetDlgItem,hWin,102
mov hEdit3, eax
invoke GetDlgItem,hWin,103
mov hEdit4, eax
invoke GetDlgItem,hWin,104
mov hEdit5, eax
invoke GetDlgItem,hWin,105
mov hEdit6, eax
invoke GetDlgItem,hWin,50
mov hText, eax
invoke GetDlgItem,hWin,1000
mov hButn1, eax
invoke GetDlgItem,hWin,1001
mov hButn2, eax
invoke GetDlgItem,hWin,1002
mov hButn3, eax
invoke GetDlgItem,hWin,1003
mov hButn4, eax
invoke GetDlgItem,hWin,1004
mov hButn5, eax
invoke GetDlgItem,hWin,1005
mov hButn6, eax
invoke SetFocus,hEdit1 ; Curseur dans Edit1
;==============================================
; la proc Ed1Proc va gérer les entrées de Edit1
; et de Edit2, controler l'entrée des Nb hexa et
; du retour arrière (Del) uniquement.
; L'adresse de l'ancienne procédure (WndProc)
; est sauvegardée dans lpfnEd1Proc.
;==============================================
invoke SetWindowLong,hEdit1,GWL_WNDPROC,Ed1Proc
mov lpfnEd1Proc, eax
invoke SetWindowLong,hEdit2,GWL_WNDPROC,Ed1Proc
mov lpfnEd1Proc, eax
invoke SetWindowLong,hEdit3,GWL_WNDPROC,Ed1Proc
mov lpfnEd1Proc, eax
invoke SetWindowLong,hEdit4,GWL_WNDPROC,Ed1Proc
mov lpfnEd1Proc, eax
xor eax, eax
ret
.elseif uMsg == WM_COMMAND
.if wParam == 1000 ; Ajouter
mov Nega,0
invoke Controle,hWin
.if Drapo == 1
mov Drapo,0
ret
.endif
mov eax,Nb1 ; ajouter les 32 bits
mov ebx,Nb2 ; de poids faible
add eax,ebx
mov Nb2,eax
mov ecx,Nb3 ; ajout des 32 bits
mov edx,Nb4 ; de poids forts etde
adc ecx,edx ; la retenue si elle existe.
mov Nb1,ecx
jnc @F ; si carry : il y a dépassement
mov Drapo,1 ; le signaler par le flag
@@:
;======================================
; résultat > chaîne hexa puis affichage
;======================================
push ecx
invoke dw2hex,eax,addr buff+10
pop ecx
invoke dw2hex,ecx,addr buff+1
invoke SetDlgItemText,hWin,105,addr buff+10
invoke SetDlgItemText,hWin,104,addr buff+1
invoke Convert,hWin
.if Drapo == 1
;============================================
; prévenir que le résutat affiché est faux :
; en réalité incomplet.
;============================================
mov Drapo,0
invoke MessageBox,hWin,addr M0,addr M1,MB_OK
.endif
.elseif wParam == 1001 ; Soustraire
invoke Controle,hWin
mov Nega,0
mov eax,Nb1
mov ebx,Nb2
sub eax,ebx
mov Nb2,eax
mov edx,Nb4
mov ecx,Nb3
adc edx,0
sub ecx,edx
mov Nb1,ecx
jnc @F ; si carry : résultat négatif
mov Nega,1
@@:
xor esi,esi
.if Nega==1
;=========================================
; négatif, faire précéder le résultat
; décimal du signe moins.
;=========================================
lea esi,buff
mov byte ptr[esi],2Dh
.else
lea esi,buff
mov byte ptr[esi],2Bh
.endif
push ecx
;=============================================
; placer les 2 chaines hexa au bon endroit
; dans le buffer et les afficher dans les
; edits correspondants.
;=============================================
invoke dw2hex,eax,addr buff+10
pop ecx
invoke dw2hex,ecx,addr buff+1
invoke SetDlgItemText,hWin,105,addr buff+10
invoke SetDlgItemText,hWin,104,addr buff
;==============================================
; appeler la procédure chargée de convertir
; un QWORD en chaine décimale et de l'afficher.
;==============================================
invoke Convert,hWin
.elseif wParam == 1002 ; effacer
invoke SendMessage,hEdit1,WM_SETTEXT,0,NULL
invoke SendMessage,hEdit2,WM_SETTEXT,0,NULL
invoke SendMessage,hEdit3,WM_SETTEXT,0,NULL
invoke SendMessage,hEdit4,WM_SETTEXT,0,NULL
invoke SendMessage,hEdit5,WM_SETTEXT,0,NULL
invoke SendMessage,hEdit6,WM_SETTEXT,0,NULL
.elseif wParam == 1003 ; and
invoke Controle,hWin
mov eax,Nb1
mov ebx,Nb2
and eax,ebx
mov Nb2,eax
invoke dw2hex,eax,addr buff+10
invoke SetDlgItemText,hWin,105,addr buff+10
mov eax,Nb3
mov ebx,Nb4
and eax,ebx
mov Nb1,eax
invoke dw2hex,eax,addr buff+1
invoke SetDlgItemText,hWin,104,addr buff+1
invoke Convert,hWin
.elseif wParam == 1004 ; or
invoke Controle,hWin
mov eax,Nb1
mov ebx,Nb2
or eax,ebx
mov Nb2,eax
invoke dw2hex,eax,addr buff+10
invoke SetDlgItemText,hWin,105,addr buff+10
mov eax,Nb3
mov ebx,Nb4
or eax,ebx
mov Nb1,eax
invoke dw2hex,eax,addr buff+1
invoke SetDlgItemText,hWin,104,addr buff+1
invoke Convert,hWin
.elseif wParam == 1005 ; xor
invoke Controle,hWin
mov eax,Nb1
mov ebx,Nb2
xor eax,ebx
mov Nb2,eax
invoke dw2hex,eax,addr buff+10
invoke SetDlgItemText,hWin,105,addr buff+10
mov eax,Nb3
mov ebx,Nb4
xor eax,ebx
mov Nb1,eax
invoke dw2hex,eax,addr buff+1
invoke SetDlgItemText,hWin,104,addr buff+1
invoke Convert,hWin
.endif
.elseif uMsg == WM_CLOSE
invoke EndDialog,hWin,0
.elseif uMsg == WM_PAINT
invoke BeginPaint,hWin,ADDR Ps
; --------------------------------------------
; Les fonctions suivantes sont dans MASM32.LIB
; Elles tracent les cadres autour des controles
; --------------------------------------------
invoke FrameGrp,hButn1,hButn3,6,1,0
invoke FrameGrp,hButn4,hButn6,6,1,0
invoke FrameWindow,hWin,0,1,1
invoke FrameWindow,hWin,1,1,0
invoke EndPaint,hWin,ADDR Ps
xor eax, eax
ret
.endif
xor eax, eax
ret
WndProc endp
; ########################################################################
Ed1Proc proc hCtl: DWORD,
uMsg1: DWORD,
wParam1: DWORD,
lParam1: DWORD
.if uMsg1 == WM_CHAR
.if wParam1 == 8 ; touche Suppr
jmp accept
.endif
.if wParam1 < "0"
.if wParam1 == 02Dh ; touche moins
jmp accept
.else
xor eax,eax
ret
.endif
.endif
.if wParam1 > "9"
.if wParam1 >= 'A' && wParam1 <= 'F'
jmp accept
.endif
.if wParam1 >= 'a' && wParam1 <= 'f'
jmp accept
.endif
xor eax,eax
ret
.endif
.endif
accept: ; Rend le contrôle à la procédure normale.
invoke CallWindowProc, lpfnEd1Proc, hCtl, uMsg1,wParam1,lParam1
ret
Ed1Proc endp
; #########################################################################
Controle proc hCtrl:DWORD
;====================================
; Remise à zéro des buffers de sortie
;====================================
lea edi,buff
mov ecx,19
mov al,0
rep stosb
mov Nb1,0
mov Nb2,0
;=====================================
; Récupération des textes hexa entrés.
; 9 caractères maximum (8 hexa + 0)
;=====================================
invoke GetDlgItemText,hCtrl,101,addr Txt1,9
invoke GetDlgItemText,hCtrl,103,addr Txt2,9
invoke GetDlgItemText,hCtrl,100,addr Txt3,9
invoke GetDlgItemText,hCtrl,102,addr Txt4,9
;================================
; Controle si une entrée est vide
;================================
lea esi,Txt3
lea edi,Txt1
szText t1,"1er nombre nul? ..bizarre !!"
.if (byte ptr[esi] == 0) && (byte ptr[edi] == 0)
invoke MessageBox,0,addr t1,0,0
mov Drapo,1
ret
.endif
lea esi,Txt4
lea edi,Txt2
szText t2,"Il faut 2 nombres pour opérer !!"
.if (byte ptr [esi]==0) && (byte ptr[edi] == 0)
invoke MessageBox,0,addr t2,0,0
mov Drapo,1
ret
.endif
;=================================
; 4 Chaînes hexa > 4 nombres DWORD
;=================================
lea esi,Txt3
lea edi,Txt4
.if byte ptr[esi]==0
mov Nb3,0
.else
invoke htodw,addr Txt3
mov Nb3,eax
.endif
.if byte ptr[edi]==0
mov Nb4,0
.else
invoke htodw,addr Txt4
mov Nb4,eax
.endif
lea esi,Txt1
lea edi,Txt2
.if byte ptr[esi] == 0
mov Nb1,0
.else
invoke htodw,addr Txt1
mov Nb1,eax
.endif
.if byte ptr[edi] == 0
mov Nb2,0
.else
invoke htodw,addr Txt2
mov Nb2,eax
.endif
ret
Controle endp
; #########################################################################
Convert Proc Hwin :DWORD
;=======================================================
; récupération de 2 DWORD et transformation en 1 QWORD
;======================================================
mov eax,Nb1
mov edx,Nb2
mov esi,offset Nb10
mov [esi],edx
add esi,4
mov [esi],eax
cmp Nega,1
jne Positif
invoke dqtoa,Nb10,addr StringDec,1
mov Nega,0
jmp @F
Positif:
invoke dqtoa,Nb10,addr StringDec,0
@@:
invoke SetDlgItemText,Hwin,106,addr StringDec
ret
Convert endp
;=============================================================
; la proc suivante (que j'utilise dans plusieurs utilitaires)
; est normalement intégrée dans ma bibliothèque masm32.lib
;=============================================================
dqtoa proc Nombre:QWORD,buffer:DWORD,sens:DWORD
pushad
mov eax,sens
mov signe,eax
lea esi,Nombre
lea edi,Reste
xor eax,eax
mov [edi],eax
mov [edi+4],eax
mov ecx,64
mov Cpt1,63
mov eax,[esi]
mov ebx,[esi+4]
cmp signe,1
jne @F
not eax
not ebx
add eax,1
adc ebx,0
@@:
push ecx
mov ecx,[edi]
mov edx,[edi+4]
shl ebx,1
adc ecx,0
shl eax,1
adc ebx,0
mov [esi],eax
mov [esi+4],ebx
mov [edi],ecx
push eax
push ebx
mov eax,540BE400h
mov ebx,00000002h
cmp edx,ebx
ja @0
jb @1
cmp ecx,eax
jb @1
@0:
sub ecx,eax
sbb edx,ebx
mov [edi],ecx
mov [edi+4],edx
mov Cpt,1
jmp stop
@1:
mov Cpt,0
stop:
pop ebx
pop eax
dec Cpt1
js yapu
shl edx,1
clc
shl ecx,1
adc edx,0
mov [edi],ecx
mov [edi+4],edx
yapu:
add eax,Cpt
mov [esi],eax
pop ecx
loop @B
mov eax,[edi]
mov edx,[edi+4]
mov ecx,10
mov edi,buffer
add edi,29
@@:
div ecx
add dl,30h
mov byte ptr[edi],dl
dec edi
xor dl,dl
inc nbch
cmp eax,0
je @F
jmp @B
@@:
mov eax,[esi]
mov edx,[esi+4]
cmp eax,0 ; eax nul : voir edx
jne @2 ; non nul : traiter
cmp edx,0 ; edx également nul
je @F ; passer au formatage.
@2:
; si la division par 10 000 000 000 tombe sur
; un ou des zéro, ils n'apparaissent pas,
; il faut donc les restituer mais
; uniquement si il ya qq. chose à placer devant
cmp nbch,10
je @3
mov byte ptr[edi],30h
dec edi
inc nbch
jmp @2
@3:
div ecx
add dl,30h
mov byte ptr[edi],dl
dec edi
xor dl,dl
inc nbch
cmp eax,0
je @F
jmp @3
@@:
inc edi
mov esi,edi
@@:
cmp byte ptr[esi],30h
jne @F
inc esi
jmp @B
@@:
mov edi,buffer
cmp signe,1
jne @F
mov byte ptr[edi],2Dh
inc edi
mov byte ptr[edi],20h
inc edi
@@:
mov eax,nbch
mov ecx,3
div ecx
cmp edx,0
je ici
mov ecx,edx
@@:
cmp byte ptr [esi],0
je stp
movsb
loop @B
mov byte ptr [edi],20h
inc edi
ici:
mov ecx,3
@@:
cmp byte ptr [esi],0
je stp
movsb
loop @B
mov byte ptr [edi],20h
inc edi
jmp ici
stp:
mov byte ptr [edi],0
mov nbch,0
popad
ret
dqtoa endp
;####################################################
end start ; Fin du programme
;########################################
#include "\masm32\include\resource.h"
TESTWIN DIALOGEX MOVEABLE IMPURE LOADONCALL DISCARDABLE 200, 40, 241, 134, 0
STYLE 0x0004 | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_POPUP
CAPTION "Dialog"
FONT 8, "Ms Serif", 700, 0 /*FALSE*/
BEGIN
EDITTEXT 100, 56,13,49,13, ES_AUTOHSCROLL | ES_LEFT, , 0
EDITTEXT 101, 106,13,49,13, ES_AUTOHSCROLL | ES_LEFT, , 0
EDITTEXT 102, 56,32,49,13, ES_AUTOHSCROLL | ES_LEFT, , 0
EDITTEXT 103, 106,32,49,13, ES_AUTOHSCROLL | ES_LEFT, , 0
EDITTEXT 104, 56,50,49,14, ES_AUTOHSCROLL | ES_LEFT, , 0
EDITTEXT 105, 106,50,49,13, ES_AUTOHSCROLL | ES_LEFT, , 0
EDITTEXT 106, 56,69,98,13, ES_AUTOHSCROLL | ES_LEFT, , 0
PUSHBUTTON "Ajouter", 1000, 180,12,40,16, 0, , 0
PUSHBUTTON "Soustraire", 1001, 180,32,40,16, 0, , 0
PUSHBUTTON "Effacer", 1002, 180,52,40,16, 0, , 0
PUSHBUTTON "AND", 1003, 56,98,31,16, ,0
PUSHBUTTON "OR", 1004, 90,98,30,16, ,0
PUSHBUTTON "XOR", 1005, 125,98,30,16, ,0
CTEXT "High 64 bits",50,60, 2,30,9,SS_LEFT, , 0
CTEXT "Low 64 bits", 60,109 2,30,9,SS_LEFT, , 0
CTEXT "Entrée 1", 20, 11,14,35,10,SS_LEFT, , 0
CTEXT "Entrée 2", 30, 11,34,35,8, SS_LEFT, , 0
CTEXT "Résultat", 40, 11,49,35,8, SS_LEFT, , 0
CTEXT " Hexa", 40, 11,57,35,8, SS_LEFT, , 0
CTEXT "Résultat", 40, 11,68,35,8, SS_LEFT, , 0
CTEXT " Déci", 40, 11,76,35,8, SS_LEFT, , 0
END
200 ICON MOVEABLE PURE LOADONCALL DISCARDABLE "ICON1.ICO"
Conclusion :
petit utilitaire sans prétention mais qui, je l'espère, pourra intéresser quelques uns.
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.