_dune2_
Messages postés141Date d'inscriptionmercredi 19 juillet 2006StatutMembreDernière intervention20 avril 2011 27 juil. 2006 à 14:44
salut,
merci pour cette précision.
En fait j'ai oublié de mettre les indicateurs de segment, c'est pourquoi les data se trouve en début du segment de code (et c'est pas beau du tout !! :) surtout si on gère le bit de protection d'écriture et execution des zones mémoires !!!).
Mais je garde l'astuce de mettre les variables en fin de code, pour des embryons de test.
dune2.
cs_patatalo
Messages postés1466Date d'inscriptionvendredi 2 janvier 2004StatutModérateurDernière intervention14 février 20142 27 juil. 2006 à 14:26
salut,
le probleme est que tu dois specifier l'offset de debut de desassemblage avec ndisasm car sinon, il commence a 0x00000080 au lieu de 0x00000084.
etant donné que tu a un dword data a 0x00000080, ndisasm le prends comme faisant partie du code si non spécifié et tu te retrouve avec:
00000080 000000 add truc,bidule
00000083 00BA80800408 add [edx+0x8048080],bh
00000089 8B1580800408 mov edx,[0x8048080]
ce code serait correctement désassemblé par ndisasm:
_start:
mov edx,monadresse
mov edx,[monadresse]
mov edx,monadresse
mov edx,[edx]
mov eax,1
mov ebx,0
int 80h
monadresse: dd 0
je me rappelle plus l'option pour specifier l'offset ou commencer le desassemblage, "ndisasm" tout court dans une console doit te l'afficher.
@++
_dune2_
Messages postés141Date d'inscriptionmercredi 19 juillet 2006StatutMembreDernière intervention20 avril 2011 27 juil. 2006 à 13:55
re :)
Aprés plusieurs essais, ... je reste perplexe :)
Je ne sais plus vraiement où se cache la vérité ....
Je m'explique :
- Code d'exemple :
Mais à priori une subtilité dans la notation porte à confusion, l'absence de '$' devant une adresse semble indiquer la présence d'un pointeur vers la valeur ....
Ceci explique ma confusion ... et donc confirme que l'utilisation de "mov edx,[buflen] est tout à fait correct, et j'en prend note ;)
Merci pour cette mise au point ;)
cs_patatalo
Messages postés1466Date d'inscriptionvendredi 2 janvier 2004StatutModérateurDernière intervention14 février 20142 27 juil. 2006 à 00:22
re,
c'est bien de nasm que l'on parle ?
mov edx,buflen -> edx = adresse de la variable buflen
mov edx,[buflen] -> edx = valeur dword a l'adresse buflen
si tu obtient la meme chose au desassemblage, verifie que tu n'ai pas compilé deux fois la meme chose.
tiré de la doc de nasm (Writing 32bits code):
At the other end of the process, to call a C function from your assembly code, you would do something like this:
extern _printf
; and then, further down...
push dword [myint] ; one of my integer variables
push dword mystring ; pointer into my data segment
call _printf
add esp,byte 8 ; `byte' saves space
; then those data items...
segment _DATA
myint dd 1234
mystring db 'This number -> %d <- should be 1234',10,0
@++
sheorogath
Messages postés2448Date d'inscriptionsamedi 21 février 2004StatutModérateurDernière intervention29 janvier 201017 26 juil. 2006 à 20:57
woaw merci a tous !!!
je vais tout reprendre alors :s
merci encore
bonne soiree
_dune2_
Messages postés141Date d'inscriptionmercredi 19 juillet 2006StatutMembreDernière intervention20 avril 2011 26 juil. 2006 à 16:57
salut,
les arguments à passer en parametres sont :
eax: N° du syscall (4 pour le write)
ebx: N° du filedescriptor (1 pour stdout)
ecx: Pointeur vers le buffer de la chaine
edx: taille de la chaine à afficher
Donc, Patalo confirme bien la nécessité d'utiliser "mov edx,[buflen]" si buflen est déclaré en "dd",
ou alors "movzx edx,byte[buflen]" dans le cas où buflen est déclaré "db".
Suite à des essais de compilations suivi de désassemblage, j'ai constaté la chose suivante :
l'utilisation de label pour réaliser un adressage indirect ne fonctionne pas.
Je m'explique :
"mov edx,[buflen]" donne le même résultat que "mov edx,buflen", or ce n'est pas ce que l'on souhaite !
Dans notre cas, c'est le contenu de l'adresse buflen que nous voulons mettre dans edx, il faut donc proceder
en 2 étape :
"mov edx,buflen"
"mov edx,[edx]"
Ainsi, aprés désassemblage, le résultat est correct :)
et pour le cas de buflen en "db"
"mov edx,buflen"
"movzx edx,byte[edx]"
Ce qui change quelque peu le source original :) Mais, me dira-t-on, pourquoi alors ça fonctionnait ???
Tout simplement car à la place de la taille, nous avions une adresse qui est largement plus grand que la taille de la chaine, mais que la fonction write s'arrête aussi au 1er caractere null de fin de chain, donc bien avant notre taille de chaine éronée.
dune2.
cs_patatalo
Messages postés1466Date d'inscriptionvendredi 2 janvier 2004StatutModérateurDernière intervention14 février 20142 26 juil. 2006 à 15:49
salut,
un dd est obligatoire dans le code de sheorogath étant donné qu'apparement, edx est un pointeur vers la taille.
si c'est la taille qui doit etre dans edx, il faut faire
mov edx,[buflen] ou comme precedement mov edx,buflen-buff avec le code donné par _DUNE2_
faudrait dejà connaitre les paramètres à passer a la fonction systeme eax=4, ensuite, faut voir...
@++
_dune2_
Messages postés141Date d'inscriptionmercredi 19 juillet 2006StatutMembreDernière intervention20 avril 2011 25 juil. 2006 à 23:23
Ooops :)
Y-a un warning à la compilation du à la ligne :
; global _start
Il faut retirer le point-virgule de commentaire ... bon ceci dit, y-a qu'un seul _start et le compilo s'en sort plutot bien tout seul :)
dune2
PS: je tiens à exprimer quand même un doute, si quelqu'un peut confirmer, sur la ligne "mov edx,buflen" du code original. En effet, pour moi, ceci aurait pour effet de charger l'adresse "buflen" et non contenu 1024. Pour charger la valeur "1024", j'écrirais plutot : "mov edx,[buflen]" pour charger le contenu de l'adresse buflen (avec les apports de commentaires concernant l'utilisation de movzx bien entendu).
_dune2_
Messages postés141Date d'inscriptionmercredi 19 juillet 2006StatutMembreDernière intervention20 avril 2011 25 juil. 2006 à 23:08
bonjour,
je confirme le raisonnement de Patalo ainsi que de Necromagik.
Je souhaite juste apporter une précision au message de Necromagik :
edx est un registre 32bits. Pour cette raison, l'utilisation de "dd" pour reserver la variable semble plus adapté. Mais l'utilisation de "dw" reste possible, à la différence que c'est une reservation d'un mot 16bits et qu'il faudra utiliser l'intruction "movzx" comme le mentionnait Patalo pour 'étendre' (movzx = mov with zero extension) ta variable 16bits en 32bits dans le registre "edx" en complétant avec des zéro.
une autre solution à ton exemple pour se passer du stockage de la longueur est d'utiliser la soustraction de 2 pointeurs pour calculer la taille de celui-ci dans ton code au moment de la compilation :
; Instruction de compilation :
; NASM -f elf hello_world.asm
; ld -o hello_world hello_world.o
;segment .data ; ; variables initialisées constantes
; buflen: db 1024 ; taille du buffer
segment .bss
buf: resb 1024 ; buffer
buflen:
; on utilisera la soustraction des 2 pointeurs buf et buflen pour calculer
; la taille de buf au moment de la compilation, ce qui évite tout risque
; de modification inattendu de buflen en mémoire
segment .text ; équivalent de main() mais c'est pas une fonction
; global _start
_start: ; programme en lui même
mov eax,3 ;syscall 3 => read
mov ebx,0 ; 0 => lit le clavier
mov ecx,buf ;dans quoi on stock
mov edx,buflen-buf ;taille du buffer calculé à la compilation
int 80h ;on execute en appelant la syscall
mov eax,4 ;syscall 4 => write
mov ebx,1 ;1 => STDOUT
mov ecx,buf ; ecrire quoi ? buf
mov edx,buflen-buf ;taille du buffer calculé à la compilation
int 80h ;appel de syscall
mov eax,1 ; 1 => exit
mov ebx,0 ; 0 code de sortie
int 80h ;fin
dune2.
sheorogath
Messages postés2448Date d'inscriptionsamedi 21 février 2004StatutModérateurDernière intervention29 janvier 201017 25 juil. 2006 à 19:45
ok merci de ton aide ^^
actuellement je bosse pendant mon temps libre sur une autre source linux qui seras poster mais je galere
je prendrais en compte tes conseil
merci
cs_necromagik
Messages postés3Date d'inscriptiondimanche 20 juin 2004StatutMembreDernière intervention25 juillet 2006 25 juil. 2006 à 12:18
Salut
Pas forcément un dd, un dw peut aller.
Voilà les correspondances (je te met aussi l'équivalent en C..)
(unsigned char) - db: 1 octet - 256 valeurs
(unsigned short int) - dw: 2 octets - 65535 valeurs
(unsigned int) - dd: 4 octets - 4 milliards et quelques
sheorogath
Messages postés2448Date d'inscriptionsamedi 21 février 2004StatutModérateurDernière intervention29 janvier 201017 17 juil. 2006 à 11:52
re, ^^
si j'ai bien compris (ne pouvant tester de suite :() il faut que je remplace mon db par dd ?
sheorogath
Messages postés2448Date d'inscriptionsamedi 21 février 2004StatutModérateurDernière intervention29 janvier 201017 17 juil. 2006 à 10:20
merci je regarde le tout merci bcp
ca va peut etre m'aider pour le probleme sur mon nouveau prog
asm :p
allez merci je regarde
++
cs_patatalo
Messages postés1466Date d'inscriptionvendredi 2 janvier 2004StatutModérateurDernière intervention14 février 20142 17 juil. 2006 à 10:16
re,
je ne devais pas etre réveillé hier soir, un db avec une valeure de 1024 c'est impossible (0..255). Ce code ne doit pas se compiler sans generation d'une erreur.
@++
cs_patatalo
Messages postés1466Date d'inscriptionvendredi 2 janvier 2004StatutModérateurDernière intervention14 février 20142 17 juil. 2006 à 01:30
re,
a moins que la valeur a mettre dans edx ne soit un pointeur vers la taille mais je pense que la valeur devrait etre en dword et pas en byte à ce moment, c'est corrigé grace a l'alignement mais si tu met une autre déclaration dans le segment data, ça ne marche plus.
@++
cs_patatalo
Messages postés1466Date d'inscriptionvendredi 2 janvier 2004StatutModérateurDernière intervention14 février 20142 17 juil. 2006 à 01:21
salut,
c'est de l'asm 32, et en plus, il y a peu de code linux, c'est donc toujours interessant ne serait-ce que pour les débutants.
une petite erreur qui doit je pense se corriger toute seule grace a l'alignement DWORD:
mov edx,buflen -> movzx edx,byte buflen (tu déclare un db et pas un dd)
@++
sheorogath
Messages postés2448Date d'inscriptionsamedi 21 février 2004StatutModérateurDernière intervention29 janvier 201017 16 juil. 2006 à 20:34
je suis ouvert a tout commentaire/blame/eloge/question
si vous voulez la liste des interruption linux j'ai un pdf (envoyez moi un mp avec votre mail)
je sais que le code est simple mais impossible de trouver un equivalent sur le net donc voila ^^
27 juil. 2006 à 14:44
merci pour cette précision.
En fait j'ai oublié de mettre les indicateurs de segment, c'est pourquoi les data se trouve en début du segment de code (et c'est pas beau du tout !! :) surtout si on gère le bit de protection d'écriture et execution des zones mémoires !!!).
Mais je garde l'astuce de mettre les variables en fin de code, pour des embryons de test.
dune2.
27 juil. 2006 à 14:26
le probleme est que tu dois specifier l'offset de debut de desassemblage avec ndisasm car sinon, il commence a 0x00000080 au lieu de 0x00000084.
etant donné que tu a un dword data a 0x00000080, ndisasm le prends comme faisant partie du code si non spécifié et tu te retrouve avec:
00000080 000000 add truc,bidule
00000083 00BA80800408 add [edx+0x8048080],bh
00000089 8B1580800408 mov edx,[0x8048080]
ce code serait correctement désassemblé par ndisasm:
_start:
mov edx,monadresse
mov edx,[monadresse]
mov edx,monadresse
mov edx,[edx]
mov eax,1
mov ebx,0
int 80h
monadresse: dd 0
je me rappelle plus l'option pour specifier l'offset ou commencer le desassemblage, "ndisasm" tout court dans une console doit te l'afficher.
@++
27 juil. 2006 à 13:55
Aprés plusieurs essais, ... je reste perplexe :)
Je ne sais plus vraiement où se cache la vérité ....
Je m'explique :
- Code d'exemple :
monadresse: dd 0
_start:
mov edx,monadresse
mov edx,[monadresse]
mov edx,monadresse
mov edx,[edx]
mov eax,1
mov ebx,0
int 80h
Et voilà le désassemblage de nasm (ndisasm -b32) :
00000083 00BA80800408 add [edx+0x8048080],bh <- décalage de 1 byte ....
démarrage @00000084 = "mov edx,0x8048080"
00000089 8B1580800408 mov edx,[0x8048080]
0000008F BA80800408 mov edx,0x8048080
00000094 8B12 mov edx,[edx]
00000096 B801000000 mov eax,0x1
0000009B BB00000000 mov ebx,0x0
000000A0 CD80 int 0x80
Ce qui semble tout à fait exact.
Maintenant avec objdump :
8048084: ba 80 80 04 08 mov $0x8048080,%edx <- @ de départ correct
8048089: 8b 15 80 80 04 08 mov 0x8048080,%edx
804808f: ba 80 80 04 08 mov $0x8048080,%edx
8048094: 8b 12 mov (%edx),%edx
8048096: b8 01 00 00 00 mov $0x1,%eax
804809b: bb 00 00 00 00 mov $0x0,%ebx
80480a0: cd 80 int $0x80
Mais à priori une subtilité dans la notation porte à confusion, l'absence de '$' devant une adresse semble indiquer la présence d'un pointeur vers la valeur ....
Ceci explique ma confusion ... et donc confirme que l'utilisation de "mov edx,[buflen] est tout à fait correct, et j'en prend note ;)
Merci pour cette mise au point ;)
27 juil. 2006 à 00:22
c'est bien de nasm que l'on parle ?
mov edx,buflen -> edx = adresse de la variable buflen
mov edx,[buflen] -> edx = valeur dword a l'adresse buflen
si tu obtient la meme chose au desassemblage, verifie que tu n'ai pas compilé deux fois la meme chose.
tiré de la doc de nasm (Writing 32bits code):
At the other end of the process, to call a C function from your assembly code, you would do something like this:
extern _printf
; and then, further down...
push dword [myint] ; one of my integer variables
push dword mystring ; pointer into my data segment
call _printf
add esp,byte 8 ; `byte' saves space
; then those data items...
segment _DATA
myint dd 1234
mystring db 'This number -> %d <- should be 1234',10,0
@++
26 juil. 2006 à 20:57
je vais tout reprendre alors :s
merci encore
bonne soiree
26 juil. 2006 à 16:57
les arguments à passer en parametres sont :
eax: N° du syscall (4 pour le write)
ebx: N° du filedescriptor (1 pour stdout)
ecx: Pointeur vers le buffer de la chaine
edx: taille de la chaine à afficher
Donc, Patalo confirme bien la nécessité d'utiliser "mov edx,[buflen]" si buflen est déclaré en "dd",
ou alors "movzx edx,byte[buflen]" dans le cas où buflen est déclaré "db".
Suite à des essais de compilations suivi de désassemblage, j'ai constaté la chose suivante :
l'utilisation de label pour réaliser un adressage indirect ne fonctionne pas.
Je m'explique :
"mov edx,[buflen]" donne le même résultat que "mov edx,buflen", or ce n'est pas ce que l'on souhaite !
Dans notre cas, c'est le contenu de l'adresse buflen que nous voulons mettre dans edx, il faut donc proceder
en 2 étape :
"mov edx,buflen"
"mov edx,[edx]"
Ainsi, aprés désassemblage, le résultat est correct :)
et pour le cas de buflen en "db"
"mov edx,buflen"
"movzx edx,byte[edx]"
Ce qui change quelque peu le source original :) Mais, me dira-t-on, pourquoi alors ça fonctionnait ???
Tout simplement car à la place de la taille, nous avions une adresse qui est largement plus grand que la taille de la chaine, mais que la fonction write s'arrête aussi au 1er caractere null de fin de chain, donc bien avant notre taille de chaine éronée.
dune2.
26 juil. 2006 à 15:49
un dd est obligatoire dans le code de sheorogath étant donné qu'apparement, edx est un pointeur vers la taille.
si c'est la taille qui doit etre dans edx, il faut faire
mov edx,[buflen] ou comme precedement mov edx,buflen-buff avec le code donné par _DUNE2_
faudrait dejà connaitre les paramètres à passer a la fonction systeme eax=4, ensuite, faut voir...
@++
25 juil. 2006 à 23:23
Y-a un warning à la compilation du à la ligne :
; global _start
Il faut retirer le point-virgule de commentaire ... bon ceci dit, y-a qu'un seul _start et le compilo s'en sort plutot bien tout seul :)
dune2
PS: je tiens à exprimer quand même un doute, si quelqu'un peut confirmer, sur la ligne "mov edx,buflen" du code original. En effet, pour moi, ceci aurait pour effet de charger l'adresse "buflen" et non contenu 1024. Pour charger la valeur "1024", j'écrirais plutot : "mov edx,[buflen]" pour charger le contenu de l'adresse buflen (avec les apports de commentaires concernant l'utilisation de movzx bien entendu).
25 juil. 2006 à 23:08
je confirme le raisonnement de Patalo ainsi que de Necromagik.
Je souhaite juste apporter une précision au message de Necromagik :
edx est un registre 32bits. Pour cette raison, l'utilisation de "dd" pour reserver la variable semble plus adapté. Mais l'utilisation de "dw" reste possible, à la différence que c'est une reservation d'un mot 16bits et qu'il faudra utiliser l'intruction "movzx" comme le mentionnait Patalo pour 'étendre' (movzx = mov with zero extension) ta variable 16bits en 32bits dans le registre "edx" en complétant avec des zéro.
une autre solution à ton exemple pour se passer du stockage de la longueur est d'utiliser la soustraction de 2 pointeurs pour calculer la taille de celui-ci dans ton code au moment de la compilation :
; Instruction de compilation :
; NASM -f elf hello_world.asm
; ld -o hello_world hello_world.o
;segment .data ; ; variables initialisées constantes
; buflen: db 1024 ; taille du buffer
segment .bss
buf: resb 1024 ; buffer
buflen:
; on utilisera la soustraction des 2 pointeurs buf et buflen pour calculer
; la taille de buf au moment de la compilation, ce qui évite tout risque
; de modification inattendu de buflen en mémoire
segment .text ; équivalent de main() mais c'est pas une fonction
; global _start
_start: ; programme en lui même
mov eax,3 ;syscall 3 => read
mov ebx,0 ; 0 => lit le clavier
mov ecx,buf ;dans quoi on stock
mov edx,buflen-buf ;taille du buffer calculé à la compilation
int 80h ;on execute en appelant la syscall
mov eax,4 ;syscall 4 => write
mov ebx,1 ;1 => STDOUT
mov ecx,buf ; ecrire quoi ? buf
mov edx,buflen-buf ;taille du buffer calculé à la compilation
int 80h ;appel de syscall
mov eax,1 ; 1 => exit
mov ebx,0 ; 0 code de sortie
int 80h ;fin
dune2.
25 juil. 2006 à 19:45
actuellement je bosse pendant mon temps libre sur une autre source linux qui seras poster mais je galere
je prendrais en compte tes conseil
merci
25 juil. 2006 à 12:18
Pas forcément un dd, un dw peut aller.
Voilà les correspondances (je te met aussi l'équivalent en C..)
(unsigned char) - db: 1 octet - 256 valeurs
(unsigned short int) - dw: 2 octets - 65535 valeurs
(unsigned int) - dd: 4 octets - 4 milliards et quelques
17 juil. 2006 à 11:52
si j'ai bien compris (ne pouvant tester de suite :() il faut que je remplace mon db par dd ?
17 juil. 2006 à 10:20
ca va peut etre m'aider pour le probleme sur mon nouveau prog
asm :p
allez merci je regarde
++
17 juil. 2006 à 10:16
je ne devais pas etre réveillé hier soir, un db avec une valeure de 1024 c'est impossible (0..255). Ce code ne doit pas se compiler sans generation d'une erreur.
@++
17 juil. 2006 à 01:30
a moins que la valeur a mettre dans edx ne soit un pointeur vers la taille mais je pense que la valeur devrait etre en dword et pas en byte à ce moment, c'est corrigé grace a l'alignement mais si tu met une autre déclaration dans le segment data, ça ne marche plus.
@++
17 juil. 2006 à 01:21
c'est de l'asm 32, et en plus, il y a peu de code linux, c'est donc toujours interessant ne serait-ce que pour les débutants.
une petite erreur qui doit je pense se corriger toute seule grace a l'alignement DWORD:
mov edx,buflen -> movzx edx,byte buflen (tu déclare un db et pas un dd)
@++
16 juil. 2006 à 20:34
si vous voulez la liste des interruption linux j'ai un pdf (envoyez moi un mp avec votre mail)
je sais que le code est simple mais impossible de trouver un equivalent sur le net donc voila ^^