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_Nasman Messages postés 202 Date d'inscription mardi 17 mai 2005 Statut Membre Dernière intervention 29 septembre 2008 3
19 juil. 2007 à 09:24
Bonjour GOKUDO,

Tu peux trouver des informations complémentaires sur les modes de compilations dans la source suivante
http://www.asmfr.com/codes/CREATION-DIFFERENTS-EXECUTABLES-AVEC-NASM-ALINK_37036.aspx

A+
gokudo Messages postés 22 Date d'inscription jeudi 14 juin 2007 Statut Membre Dernière intervention 18 août 2009
19 juil. 2007 à 09:07
j'ai rien compris mais ça a l'air interessant. je vai apprendre un pe et venir vous embeter avec mes questions ^_^. merci beaucoup nasman pour c tuto.
roygrizzly Messages postés 17 Date d'inscription mardi 25 janvier 2005 Statut Membre Dernière intervention 11 mai 2006
3 mai 2006 à 14:28
je viens de comprendre ton code, en faisant :
push dword 0x00000031
push dword 0x39393939
j'obtient 99991 !!

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 à 13:45
Tu n'est pas obligé de stocker ta chaine a une adresse précise, tu peux la mettre sur la pile et indiquer son adresse pour la MessageBox

printf: ;esp pointe sur l'adresse de retour (le ret qui suit le call printf)
lea eax,[esp+4] ;eax vaut esp+4
push byte 0
push dword Titre ;le titre est dans les data
push eax ;la chaine à afficher est dans la pile
push byte 0
call [MessageBoxA]
ret 8 ;dépile les données après le retour à main (deux dword)
;--------------------------

main:
push dword 0x0072756F ;chaine "our",0
push dword "Bonj"
; met Bonjour dans la pile, on peut aussi le faire avec des
; sub esp,8 ;reserve 8 octets
; mov [esp],dword "Bonj"
; mov [esp+4],dword 0x0072756F
call printf
ret
segment data public use32 class=DATA
Titre db "Affichage des messages :",0

A+
roygrizzly Messages postés 17 Date d'inscription mardi 25 janvier 2005 Statut Membre Dernière intervention 11 mai 2006
3 mai 2006 à 13:26
cool, ça marche, merci beaucoup, pour afficher un 0 j'ai juste à faire :
push dword 0x00000030
pour 10:
push dword 0x00003031
pour les négatifs:
push dword 0x0000312D
avec ce système on peut aficher un chiffre entre -999 et 9999
il faudrais concaténer plusieurs dword si le chiffre est grand (ou petit si négatif)
je vais essayer de programmer ça en C vu que c'est le boulot du compilateur

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 à 13:00
J'ai repris ton code pour lui faire afficher un message. Pour convertir en chaine on verra après...

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: ;esp pointe sur l'adresse de retour (le ret qui suit le call printf)
mov eax,[esp+4] ;esp+4 pointe sur les données empilées
mov [Message],eax
push byte 0
push dword Titre
push dword Message
push byte 0
call [MessageBoxA]
ret 4 ;dépile les données après le retour à main (un dword)
;--------------------------

main:
push dword 0x00434241 ;chaine "ABC",0
call printf
ret
segment data public use32 class=DATA
Titre db "Affichage des messages :",0
Message db "...",0

Tampon resd 100

A+
roygrizzly Messages postés 17 Date d'inscription mardi 25 janvier 2005 Statut Membre Dernière intervention 11 mai 2006
3 mai 2006 à 12:52
désolé j'ai fait une faute : il faut lire
sub esp,4
et non
ret esp,4
roygrizzly Messages postés 17 Date d'inscription mardi 25 janvier 2005 Statut Membre Dernière intervention 11 mai 2006
3 mai 2006 à 12:49
1)la conversion c'est trop compliqué pour moi!!! les codes que j'ai trouvé sont trop longs et je comprends pas tout, y'a t il moyen de mettreune chaine de caractères dans la pile?
2)si je comprends bien, pour accèder à mon paramètre, dans le sus programme, il faut que je fasse:

mov bx, esp ;sauvegarde de esp
add esp,4
pop ax ;récupération du parmètre
mov esp, bx ;restauration de esp

ou bien:

add esp,4
pop ax,
ret esp,4
?

3)eip prends la valeur du sommet de pile si je comprends bien? il doit y avoir quoi dans le sommet de pile?
4)je ne peux pas dépiler toute la pile avant d'apeller le sous programme vu que j'ai besoin du ou des paramètres

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+
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 à 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 à 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_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
Rejoignez-nous