Affichage d'un registre dans la console.

Voir le sujet précédent Voir le sujet suivant Aller en bas

Affichage d'un registre dans la console.

Message par Admin le Sam 3 Déc - 15:04

Dans ce tutoriel, je vous montrerais simplement le vidage d'un seul registre. Pour les autres vidages, je vous laisse le soin de les écrire en vous inspirant de procédures déjà écrites pour le 32 bits ou celles faisant appel à la bibliothèque du C.
Pour éviter toute incidence, les procédures de vidages utiliseront des paramètres passés par push et devront sauvegarder les registres utilisés.
Code:

;---programme 64 bits
; affichage dans la console d'un registre

%include "../windowsinc64.inc"

;=======================================
; segment des données initialisées
;=======================================
segment .data

szMessFin  db 10,13,"Fin du programme.",0
szRetourLigne db 10,13,0
szMessRegistre db "Ligne %d Valeur du registre = %p ",10,13,0

;=======================================
; segment des données non initialisées
;=======================================
segment .bss
hMain  resq 1
szResult  resb 100

;=======================================
; segment de code
;=======================================
segment .text
    global Main
   extern afferreur,saisieClavier

Main:
    sub rsp, 8h    ; alignement de la pile avant tout appel de procédure
   sub rsp,20h
    ;recup handle de l'instance du programme
   mov  rcx,NULL
   call GetModuleHandleA
   mov r9,__LINE__ - 1
   cmp  eax,NULL
   je  .gestionerreurs
    push __LINE__
   push rax
    call vidregistre
   
   mov rax,0
   jmp .main_fin
.gestionerreurs:
   call afferreur
   mov  rax,1
   jmp .fin
.main_fin:   
    push szMessFin
   call affconsole
   call saisieClavier
.fin:   
   mov  rcx,rax          ; code retour
   call ExitProcess  ; fin du programme
;=================================================
;vidage d'un registre
;=================================================
;parametre 1 contient le N° de ligne et parametre 2 le registre
vidregistre:   
    enter 0,0
   sub rsp,20h
    mov rcx,szResult
   mov rdx,szMessRegistre
   mov r8,[rbp+24]  ; contient le N° de ligne
   mov r9,[rbp+16]  ; contient la valeur du registrre
   call wsprintfA    ; formatage du message
   mov r9,__LINE__ - 1
   cmp  eax,NULL
   je  .erreur
    push szResult    ; passage du résultat à la procèdure d'affichage
    call affconsole
   jmp .fin
.erreur:
   call afferreur
.fin:
    add rsp,20h
    leave
   ret 16
;=================================================
;affichage console
;=================================================
affconsole:
    enter 16,0          ; reservation de 16 octets pour les variables locales
    sub rsp,20h
   mov rcx,STD_OUTPUT_HANDLE  ; code pour la sortie standard
    call    GetStdHandle      ; acquisition du handle de la sortie standard
   mov r9,__LINE__ - 1
   cmp    eax,NULL
   je       .erreur
    mov    [rbp-8], rax    ; stockage dans une zone reservée par le enter

   ;calcul de la longueur du message
   mov rcx,[rbp+16] ; recup de l'adresse du message à  afficher
   cmp byte [rcx],0 ; verification que la chaine ne soit pas vide
   jne .calcullg    ; car la fonction lstrlen n'aime pas cela !!!!
   xor rax,rax
   jmp .suite
.calcullg:   
   call  lstrlen    ;calcul de la longueur du message
   mov r9,__LINE__ - 1
   cmp    eax,NULL
   je       .erreur
.suite:   
   add rsp,20h  ; on rend la place des parametres précédent
   sub rsp, 8h  ; donc on enleve déjà 8 octets pour preparer la pile
   push    0    ; avant le push du parametre qui enleve 8 octets sur la pile
   sub rsp, 20h  ; puis on enleve les 32 octets pour la place des 4 parametres
   
   mov    rcx,[rbp-8]  ;handle console
   mov    rdx,[rbp+16]  ;message a afficher   
   mov    r8,rax  ; longueur calculee avant   par lstrlen
   mov    r9,NULL
    call    WriteConsoleA
   add  rsp, 10h ; dépile le paramètre et son alignement
   mov r9,__LINE__ - 2
   cmp    rax,NULL
   jne    .fin
.erreur:
   call afferreur
.fin:
    add rsp,20h
    leave
   ret 8  ; un seul parametre à dépiler

Dans la segment .data, nous definissons le message à afficher après le formatage par la fonction wsprintfA. Vous remarquerez que nous utilisons le code %d pour éditer le N° de ligne en décimal et le code %p pour éditer la valeur du registre au format d'un pointeur hexadécimal.
Ensuite dans le code, nous allons rechercher le handle de l'instance de notre programme (attribuée par windows à tout programme) par la fonction GetStdHandle et afficher sa valeur par appel à vidregistre. Dans vidregistre, nous nous contentons d'appeler la fonction wsprintfA avec la chaine de formatage, la zone résultats et les 2 paramètres N° de ligne et valeur du registre passés par push. Nous passons le résultat à la sous procèdure affconsole qui va effectue l'affichage comme nous l'avons vu des les programmes précédents. Remarque : à titre d'exemple nous nous servons d'une zone de 8 octets réservée par l'instruction enter (Rappel précédent , nous réservons 2 fois 8 octets pour éviter un désalignement de la pile).
Nous avons écrits 2 procédures distinctes pour les déplacer par la suite dans notre fichier de routines internes.
Maintenant à vous de travailler pour écrire les routines de vidage de tous les registres Smile
avatar
Admin
Admin

Messages : 38
Date d'inscription : 28/11/2016

Voir le profil de l'utilisateur http://assembleur64.forumactif.com

Revenir en haut Aller en bas

Voir le sujet précédent Voir le sujet suivant Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum