gokudo
Messages postés22Date d'inscriptionjeudi 14 juin 2007StatutMembreDernière intervention18 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és17Date d'inscriptionmardi 25 janvier 2005StatutMembreDernière intervention11 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és202Date d'inscriptionmardi 17 mai 2005StatutMembreDernière intervention29 septembre 20083 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és17Date d'inscriptionmardi 25 janvier 2005StatutMembreDernière intervention11 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és202Date d'inscriptionmardi 17 mai 2005StatutMembreDernière intervention29 septembre 20083 3 mai 2006 à 13:00
J'ai repris ton code pour lui faire afficher un message. Pour convertir en chaine on verra après...
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és17Date d'inscriptionmardi 25 janvier 2005StatutMembreDernière intervention11 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és17Date d'inscriptionmardi 25 janvier 2005StatutMembreDernière intervention11 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és202Date d'inscriptionmardi 17 mai 2005StatutMembreDernière intervention29 septembre 20083 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és17Date d'inscriptionmardi 25 janvier 2005StatutMembreDernière intervention11 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
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és202Date d'inscriptionmardi 17 mai 2005StatutMembreDernière intervention29 septembre 20083 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és17Date d'inscriptionmardi 25 janvier 2005StatutMembreDernière intervention11 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és241Date d'inscriptionvendredi 23 mai 2003StatutMembreDernière intervention 8 octobre 20071 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.
19 juil. 2007 à 09:24
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+
19 juil. 2007 à 09:07
3 mai 2006 à 14:28
push dword 0x00000031
push dword 0x39393939
j'obtient 99991 !!
merci
3 mai 2006 à 13:45
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+
3 mai 2006 à 13:26
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
3 mai 2006 à 13:00
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+
3 mai 2006 à 12:52
sub esp,4
et non
ret esp,4
3 mai 2006 à 12:49
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
3 mai 2006 à 11:06
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+
3 mai 2006 à 10:13
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
3 mai 2006 à 09:40
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+
3 mai 2006 à 09:18
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
13 oct. 2005 à 00:39
Pour les fichier .exe, il faut les renommer sinon ça ne fonctionne pas au téléchargement, en .ex_ par exemple.
eRoZion