EXEMPLES SIMPLES DE FICHIERS ÉCRITS AVEC NASM

cs_eRoZion Messages postés 241 Date d'inscription vendredi 23 mai 2003 Statut Membre Dernière intervention 8 octobre 2007 - 13 oct. 2005 à 00:39
cs_Nasman Messages postés 202 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 29 septembre 2008 - 19 juil. 2007 à 09:24
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/34175-exemples-simples-de-fichiers-ecrits-avec-nasm

cs_eRoZion Messages postés 241 Date d'inscription vendredi 23 mai 2003 Statut Membre Dernière intervention 8 octobre 2007 1
13 oct. 2005 à 00:39
J'ai pas le temps de regarder aujourd'hui mais je commence à m'intéresser à l'assembleur et ça a l'air très utile. ;)

Pour les fichier .exe, il faut les renommer sinon ça ne fonctionne pas au téléchargement, en .ex_ par exemple.


eRoZion
roygrizzly Messages postés 17 Date d'inscription mardi 25 janvier 2005 Statut Membre Dernière intervention 11 mai 2006
3 mai 2006 à 09:18
Ce code fonctionne parfaitement!!
J'aimerai savoir comment il faut faire pour afficher le contenu d'un registre, qui est chez moi un entier? Voici ma fonction qui fait comme un printf en C mais dans une fenetre: le paramètre est mis dans la pile avant l'apel à printf

printf:
pop AX
mov dword [Message],AX
push byte 0
push dword Titre
push dword Message
push byte 0
call [MessageBoxA]
ret

et ça marche pas, c'est un problème de type apparament:
a.asm:15: error: mismatch in operand sizes
make: *** [assemble] Error 1

merci
cs_Nasman Messages postés 202 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 29 septembre 2008 3
3 mai 2006 à 09:40
Bonjour ROYGRIZZLY,

Je ne sais pas ce qu'il y a dans AX (type de données) mais ce qui est sur c'est qu'avec ton pop AX tu récupère un word (deux octets - AX est un registre 16 bits).
Le mov dword [Message],AX te génère une erreur car tu demandes d'écrire un dword à partir de l'emplacement Message alors que AX est un word.
Je ne pense pas que ce soit l'instruction à utiliser pour résoudre ton problème mais en ce qui concerne l'erreur "mismatch in operand sizes" elle devrait être résolue avec:
movzx eax,ax ;garde les deux octets de poids faible et remplit les deux autres avec zéro
mov [Message],eax ;écrit 4 octets à partir de l'adresse Message (le dword est implicite)

A+
roygrizzly Messages postés 17 Date d'inscription mardi 25 janvier 2005 Statut Membre Dernière intervention 11 mai 2006
3 mai 2006 à 10:13
dans AX, il y a un entier, ici 3, en faite c'est du code généré par mon compilateur, donc il y a la fonction main et la fonction printf, pour passer 3 en paramètre de la fonction printf [printf(3)] je fais un push 3

extern ExitProcess
import ExitProcess Kernel32.dll
extern MessageBoxA
import MessageBoxA user32.dll

segment code public use32 class=CODE
..start:
call main
push byte 0
call [ExitProcess]
ret
;--------------------------
printf:
pop ax
movzx eax,ax
mov [Message],eax
push byte 0
push dword Titre
push dword Message
push byte 0
call [MessageBoxA]
ret
;--------------------------

main:
push 3
call printf
ret
segment data public use32 class=DATA
Titre db "Affichage des messages :",0
Message db "...",0

Tampon resd 100

ça assemble mais quand je le lance, la fenetre est bizarre, elle n'a pas de bordure ni de titre, et ça affiche 7 et à coté un carré puis quand je fais OK, le programme plante, windows me dit que le prog a rencontré un problème et qu'il l'a fermé

merci
cs_Nasman Messages postés 202 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 29 septembre 2008 3
3 mai 2006 à 11:06
Je crois savoir la raison du plantage.

Sur la pile tu as empilé la valeur 3 (quoique Nasm me génère une erreur car la taille de la données n'est pas indiquée). Il faut mettre push dword 3 (taille d'un integer en C) ou push byte 3 (de toute façon windows t'empilera 4 octets mais push byte 3 prend moins de place en mémoire).
Après la valeur empilée le système empile l'adresse de retour qui suit l'appel du call - c'est cette valeur que tu récupères dans ax !!! - D'où un affichage non prévu.
Après le ret tu place ta valeur 3 dans eip - ce qui n'est pas apprécié du système.

Pour corriger:
1) convertir la valeur numérique 3 en une chaine (pour être affichée par MessageBox - ta routine devrait traiter un dword soit 4 octets soit une chaine de 8 + 1 caractères (0 terminal)
2)tu peux empiler ce que tu veux mais garde à l'esprit qu'après le call esp pointe sur l'adresse de retour et esp+4 sur le dernier push précédent le call.
3)après traitement le ret dépile le sommet de pile dans eip
4)faire le ménage et dépiler les octets mis sur la pile avant le call. Soit avec un pop (ou add esp,xxxx)dans le programme d'appel, soit avec un ret xxxx dans le sous programme;

A+