Les exemples de tracés de courbes ne sont pas très fréquents en assembleur, aussi peut être que ce code pourra aider les débutants. La création de la dialogbox a été reprise d'une source de Bombela (et d'autres), j'y ai rajouté quelques fonctions graphiques à commencer par la création d'un hdc.
Les fonctions incluses comprennent:
-création du hdc
-création de brosses, de traits
-création de rectangles
-création d'axes, de courbes
-affichage d'une légende
Le programme utilise quelques instructions en virgule flottante (ce qui était nouveau pour moi)dont des conversions
Source / Exemple :
;nasmw -fobj courbe.asm pour compiler avec Nasm
;alink -oPE courbe.obj pour linker avec alink (pas de lib necessaire ici)
;déclaration des api à importer
EXTERN ExitProcess
import ExitProcess kernel32.dll
EXTERN CreateWindowExA
import CreateWindowExA user32.dll
extern GetModuleHandleA
import GetModuleHandleA kernel32.dll
extern GetCommandLineA
import GetCommandLineA kernel32.dll
EXTERN RegisterClassExA
import RegisterClassExA user32.dll
EXTERN ShowWindow
import ShowWindow user32.dll
EXTERN LoadIconA
import LoadIconA user32.dll
EXTERN LoadCursorA
import LoadCursorA user32.dll
EXTERN DefWindowProcA
import DefWindowProcA user32.dll
EXTERN PostQuitMessage
import PostQuitMessage user32.dll
EXTERN TranslateMessage
import TranslateMessage user32.dll
EXTERN DispatchMessageA
import DispatchMessageA user32.dll
EXTERN GetMessageA
import GetMessageA user32.dll
EXTERN PostMessageA
import PostMessageA user32.dll
EXTERN BeginPaint
import BeginPaint user32.dll
EXTERN CreateFontIndirectA
import CreateFontIndirectA gdi32.dll
EXTERN DeleteObject
import DeleteObject gdi32.dll
EXTERN Rectangle
import Rectangle gdi32.dll
EXTERN SetPixel
import SetPixel gdi32.dll
EXTERN CreateSolidBrush
import CreateSolidBrush gdi32.dll
EXTERN CreatePen
import CreatePen gdi32.dll
EXTERN SelectObject
import SelectObject gdi32.dll
EXTERN DeleteObject
import DeleteObject gdi32.dll
EXTERN MoveToEx
import MoveToEx gdi32.dll
EXTERN LineTo
import LineTo gdi32.dll
EXTERN SetTextColor
import SetTextColor gdi32.dll
EXTERN TextOutA
import TextOutA gdi32.dll
;définition des constantes utilisées
%define NULL 0
%define SW_SHOW 5
%define CS_HREDRAW 2
%define CS_VREDRAW 1
%define IDC_ARROW 0x00007F00
%define COLOR_BTNFACE 0x0000000F
%define WS_TILEDWINDOW 0x00CF0000
%define WS_EX_LEFT 0
%define WM_CREATE 0x00000001
%define WM_DESTROY 0x00000002
%define TRUE 0x00000001
%define WM_SETFONT 0x00000030
%define WM_QUIT 0x00000012
%define WM_SETFONT 0x00000030
%define WM_SETFONT 0x00000030
%define BS_SOLID 0
%define PS_SOLID 0
%define WM_PAINT 0x0000000F
%define IDI_WINLOGO 0x00007F05
%define IDC_HAND 0x00007F89
%define COLOR_ACTIVECAPTION 0x00000002
;définition des structures
struc WNDCLASSEX
.cbSize resd 1
.style resd 1
.lpfnWndProc resd 1
.cbClsExtra resd 1
.cbWndExtra resd 1
.hInstance resd 1
.hIcon resd 1
.hCursor resd 1
.hbrBackground resd 1
.lpszMenuName resd 1
.lpszClassName resd 1
.hIconSm resd 1
ENDSTRUC
struc MSG
.hwnd resd 1
.message resd 1
.wParam resd 1
.lParam resd 1
.time resd 1
.pt resd 1
ENDSTRUC
struc PAINTSTRUCT
.hdc resd 1
.fErase resd 1
.rcPaint.left resd 1
.rcPaint.top resd 1
.rcPaint.right resd 1
.rcPaint.bottom resd 1
.fRestore resd 1
.fIncUpdate resd 1
.rgbReserved resb 32
ENDSTRUC
struc POINT
.x resd 1
.y resd 1
ENDSTRUC
;il est possible de s'affranchir de ces déclarations en incluant les librairies ad-hoc
SECTION CODE USE32 CLASS=CODE
..start:
push dword NULL
call [GetModuleHandleA]
mov dword [Instance], eax
Call [GetCommandLineA]
mov dword [CommandLine], eax
push dword SW_SHOW
push dword eax
push dword NULL
push dword [Instance]
call WinMain
push dword eax
call [ExitProcess]
;************************************************
;* winMain *
;************************************************
%define hInstance ebp+8
%define hPrevInstance ebp+12
%define lpCmdLine ebp+16
%define nCmdShow ebp+20
WinMain:
enter 48,0 ;reserve 48 octets pour la structure WNDCLASSEX
mov [ebp-48],byte 48 ;cbsize
mov [ebp-44],dword CS_HREDRAW | CS_VREDRAW ;style
mov [ebp-40],dword WinProc ;Winproc
mov [ebp-36],byte 0 ;cbClsExtra
mov [ebp-32],byte 0 ;cbWndExtra
mov eax,dword [Instance] ;hInstance
mov [ebp-28],eax
push dword IDI_WINLOGO
push dword NULL
call [LoadIconA]
mov [ebp-24],eax ;hIcon
mov [ebp-4],eax ;hIconSm
push dword IDC_HAND
push dword NULL
call [LoadCursorA]
mov [ebp-20],eax ;hCursor
mov [ebp-16],dword COLOR_ACTIVECAPTION ;hbrBackground
mov [ebp-12],dword NULL ;lpszMenuName
mov [ebp-8],dword ClassName ;lpszClassName
push esp ;pointeur sur la structure WNDCLASSEX (dans la pile)
call [RegisterClassExA]
cmp eax,0
jne .RegisterOk
mov eax, 1
jmp Fin
.RegisterOk
mov dword [Atom], eax
push dword NULL
mov eax, dword [hInstance]
push dword eax
push dword NULL
push dword NULL
push dword 768 ; Hauteur fenêtre
push dword 1024 ; Largeur fenêtre
push dword 0 ; Haut
push dword 0 ; Gauche
push dword WS_TILEDWINDOW
push dword WindowName
push dword ClassName
push dword WS_EX_LEFT
call [CreateWindowExA]
cmp eax , 0
jne .CreateWindowOk
mov eax, 2
jmp Fin
.CreateWindowOk
mov dword [WindowHandle], eax
push dword SW_SHOW
push dword [WindowHandle]
call [ShowWindow]
.BoucleMessages
push dword 0
push dword 0
push dword [WindowHandle]
push dword Msg
call [GetMessageA]
cmp eax, WM_QUIT
je .FinBoucle
cmp eax, -1
jne .GetMEssageOk
mov eax, 3
jmp Fin
.GetMEssageOk
push dword Msg
call [TranslateMessage]
push dword Msg
call [DispatchMessageA]
jmp .BoucleMessages
.FinBoucle
mov eax, dword [Msg+MSG.wParam]
Fin:
leave
ret 16
;*********************************************
;* WindowProc *
;*********************************************
%define hwnd ebp+8
%define uMsg ebp+12
%define wParam ebp+16
%define lParam ebp+20
WinProc:
enter 0,0
mov eax,[uMsg]
cmp eax,WM_CREATE
je near .Create
cmp eax,WM_DESTROY
je near .Destroy
cmp eax,WM_PAINT
je .Paint
.Defaut
push dword [lParam]
push dword [wParam]
push dword [uMsg]]
push dword [hwnd]
call [DefWindowProcA]
.Fin
leave
ret 16
.Create ;**************************************
push dword FontStandard
call [CreateFontIndirectA]
mov dword [hFontStandard], eax
jmp .Fin
.Destroy ;*************************************
push dword [hFontStandard]
call [DeleteObject]
jmp .Fin
.Paint ;début de la partie graphique______________________________________________________________________________________
push dword mystruc
push dword [WindowHandle]
call [BeginPaint] ;créé un handle de contexte (hdc)
mov [mystruc+PAINTSTRUCT.hdc],eax
push dword [couleurbrosse] ;définit la nouvelle couleur de la brosse
call [CreateSolidBrush]
mov [hbrosse],eax ;sauvegarde le handle correspondant
push eax
push dword [mystruc+PAINTSTRUCT.hdc]
call [SelectObject] ;selectionne la nouvelle brosse, retourne le handle de l'ancienne
mov [hbrosseanc],eax
push dword 684
push dword 812
push dword 84
push dword 100
push dword [mystruc+PAINTSTRUCT.hdc]
call [Rectangle] ;dessine un rectangle avec la couleur de remplissage de la brosse (rouge)
push dword[hbrosseanc]
push dword[mystruc+PAINTSTRUCT.hdc]
call [SelectObject] ;revient à l'ancienne brosse
push dword[hbrosse]
call [DeleteObject] ;suprime la brosse devenue inutile
push dword 128
push dword 150
push dword 640
push dword 756
push dword [mystruc+PAINTSTRUCT.hdc]
call [Rectangle] ;dessine un autre rectangle (couleur par défaut - blanc)
push dword 0
push dword 3
push dword PS_SOLID
call [CreatePen] ;définit un nouveau trait (pour les axes)
mov [hpen],eax
push eax
push dword [mystruc+PAINTSTRUCT.hdc]
call [SelectObject] ;sélectionne ce dernier, retourne le handle de l'ancien
mov [hpenanc],eax
; axe des abscisses
push dword NULL
push dword 384
push dword 150
push dword[mystruc+PAINTSTRUCT.hdc]
call [MoveToEx] ;définit le point de départ de la ligne à tracer
push dword 384
push dword 756
push dword[mystruc+PAINTSTRUCT.hdc] ;définit le point d'arrivée de la ligne
call [LineTo]
; axe des ordonnées
push dword NULL
push dword 640
push dword 200
push dword[mystruc+PAINTSTRUCT.hdc]
call [MoveToEx] ;définit le point de départ de la ligne à tracer
push dword 128
push dword 200
push dword[mystruc+PAINTSTRUCT.hdc] ;définit le point d'arrivée de la ligne
call [LineTo]
push dword [couleurpen]
push dword [largeurpen]
push dword PS_SOLID
call [CreatePen] ;définit un nouveau trait (bleu)
mov [hpen],eax
push eax
push dword [mystruc+PAINTSTRUCT.hdc]
call [SelectObject] ;sélectionne ce dernier, retourne le handle de l'ancien
mov [hpenanc],eax
; tracé de la courbe
push dword NULL
mov eax,384
mov [y],eax
push eax
mov eax,200
mov [x],eax
push eax
push dword[mystruc+PAINTSTRUCT.hdc]
call [MoveToEx] ;définit le point de départ de la ligne à tracer
mov ecx,512
boucle push ecx ;à sauvegarder car utilisé par windows
inc dword [x]
fild dword[x] ;convertit la valeur entière en flottant
fsub dword[xo] ;calcule à partir de l'origine (soustraction flottante)
fmul dword [pi]
fdiv dword[f]
fsin
fmul dword[g] ;fonction=g*sin(pi*(x-xo)/f)
fchs
fadd dword [yo] ;inverse le sens et décale (origine écran en haut)
fistp dword[y] ;reconvertit en entier (et vide la pile)
push dword [y]
push dword [x]
push dword[mystruc+PAINTSTRUCT.hdc]
call [LineTo] ;définit le point d'arrivée de la ligne
pop ecx
loop boucle
; légende
push dword 0x00808000
push dword[mystruc+PAINTSTRUCT.hdc]
call [SetTextColor] ;définit la couleur du texte
push dword 8 ;nombre de caractères du texte
push dword texte
push dword 200
push dword 600
push dword[mystruc+PAINTSTRUCT.hdc]
call [TextOutA] ;affiche le texte en x=600 y=200
leave
ret 16
;fin de la partie graphique_____________________________________________________
; Procedures et fonctions secondaires
;_______________________________________________
;Procedure qui assigne une font standard à un contrôle
; Param : Handle du contrôle dans eax
SetFontStandard:
push dword TRUE
push dword [hFontStandard]
push dword WM_SETFONT
push dword eax
call [PostMessageA]
ret
;_______________________________________________
SECTION DATA USE32 CLASS=DATA
Atom resd 1
WindowHandle resd 1
Msg resd 6
Instance resd 1
CommandLine resd 1
FontStandard dd 10
resd 6
db "MS sans Serif",0
hFontStandard resd 1
ClassName db "WindowClass01",0
WindowName db "Exemple de graphisme", 0
mystruc resd 16
couleurbrosse dd 0x000000ff ;rouge
hbrosse resd 1
hbrosseanc resd 1
couleurpen dd 0x00ff0000 ;bleu
largeurpen dd 1
hpen resd 1
hpenanc resd 1
pi dd 3.1415926535 ;nota il est possible d'utiliser l'instruction fldpi qui charge cette constante
f dd 256. ;le point signifie virgule flottante
g dd 200.
x resd 1
y resd 1
texte db "y=sin(x)"
var resd 1
xo dd 200.
yo dd 384.
Conclusion :
Ce type de code pourra être étoffé pour intégrer les possibilités de la DialogBox (saisies au clavier etc).
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.