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.
eRoZion
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_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 à 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 à 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;
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
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
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 à 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 à 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+