error: db 'error open',10
errorLen: equ $-error
segment .bss
buf: resb 254
read: resb 254
lerr: resb 128
segment .text ; équivalent de main() mais c'est pas une fonction
global _start
mov eax,1 ;syscall 1 => exit
mov ebx,0 ;error code => 0
int 80h ;execute
ret ;end
readf: ;si on a ouvert le fichier
mov ebx,eax ; move file descriptor in ebx
mov eax,3 ;syscall 3 => read
mov ecx,read ;put in read
mov edx,readlen ;length
int 80h ;execute
mov eax,4 ;syscall 4 => write
mov ebx,1 ;where? STDOUT
int 80h ;execute
;ecx , edx already defined
mov eax,1 ;syscall 1 => exit
mov ebx,0 ;error code
int 80h ;execute
ret ;exit
_start: ; programme en lui même
mov eax,3 ;syscall 3 => read
mov ebx,0 ; Where? STDIN
mov ecx,buf ;save in buf
mov edx,buflen ;length of buf
int 80h ;execute
mov eax,5 ;syscall 5 => open
mov ebx,buf ;open what ?buf
mov ecx,0 ;flag => read only
int 80h ;execute
test eax,-1 ; an error ?
je errorf ;yes jump to error
jne readf ;no read file
Je n'ai aucune sortie comme quoi le fichier n'existe pas (qu'il existe ou pas d'ailleurs).
Enfin bref je ne sais pas où est mon erreur.
Pouvez-vous m'aider ou me mettre sur la voie ?
Merci
++
"n'est pas mort ce qui semble a jamais dormir et en d'etrange temps meme la mort peut mourrir"
cs_Nasman
Messages postés202Date d'inscriptionmardi 17 mai 2005StatutMembreDernière intervention29 septembre 20083 18 juil. 2006 à 10:03
Bonjour,
Je ne connais pas les fonctions système de linux, aussi juste une question.
Quels sont les registres modifiés par l'appel de la fonction système 3. En clair es tu sur que les registres ecx et edx contiennent toujours les bonnes valeur lors de l'appel à la fonction syscall 4.
Autre chose : utilisant Nasm pour windows je ne sais pas quelle est la déclaration pour linux pour indiquer le point d'entrée du programme. Est-ce que nasm reconnait _start: comme point d'entrée ?
sheorogath
Messages postés2448Date d'inscriptionsamedi 21 février 2004StatutModérateurDernière intervention29 janvier 201017 18 juil. 2006 à 13:43
pour le point d'entree il n'y a pas de probleme
sinon pour les registre en fait quand je passe sur open eax a toujours la meme valeur 0xFFFFFFFe que le fichier existe ou pas dailleur et je ne vois pas pourquoi
"n'est pas mort ce qui semble a jamais dormir et en d'etrange temps meme la mort peut mourrir"
_dune2_
Messages postés141Date d'inscriptionmercredi 19 juillet 2006StatutMembreDernière intervention20 avril 2011 27 juil. 2006 à 14:32
Bon, aprés quelques essais, j'ai trouvé quelques points interessants :
1) lors du "open", 2 problèmes sont à signaler :
1: le mode d'ouverture doit inclure O_CREAT en plus de O_RDWR
pour créer le fichier s'il n'existe pas ce qui fait qu'il faut mettre
102 dans ECX (O_CREAT=100 | O_RDWR=2)
2: en cas de création du fichier, il faut bien entendu spécifier
les droits du fichier dans EDX, dans notre cas je suggère 0666
-rw-rw-rw- (attention à la notation Octal : 0666 et non 666).
2) lors de la saisie du nom de fichier, il faut retirer le "\n" ajouté
au clavier lors de la saisie, sinon celui-ci fera parti du nom du
fichier (ajout de "?" à la fin du nom du fichier, gênant pour toutes
manipulations).
3) L'utilisation de "cmp" est destructif sur EAX, et le CPU crée un
EAX_ORIG (registre temporaire pour sa sauvegarde) ce qui fait qu'on ne
teste pas le registre EAX comme on s'y attend. Il faut donc utiliser
l'instruction "test" non destructif, et se servir du flag "sign" pour
detecter une valeur négative. ("test eax,eax ; js _failure").
4) Penser à faire un syscall à "close" pour bien terminer ;)
Voici le code (en asm AT&T) incorporant ces modifications et fonctionnel :
// compile with as :
// as readAndWrite.s -o readAndWrite.o ( add -g for debug)
L'ajout des labels à chaque opération m'ont permis de pouvoir mettre
des breakpoints à chaque étape importante lors du débugage avec gdb et
même Eclipse (qui supporte au passage la coloration syntaxique de
AT&T ;) ).
NB: juste une petite explication sur les principales différences entre asm Intel et AT&T pour une meilleure compréhension:
- les opérandes sont inversées : la destination est toujours la dernière opérande en AT&T
- les registres sont toujours précédés par '%'
- les variables qui commencent par '$' sont des valeurs immédiates, sinon, ce sont des adresses qui pointent sur la valeur.
- les valeurs immédiates sont toujours précédés de '$' et la notation
numérique est celle du C : $0x45 (hexa) $45 (decimal) $045 (octal)
Voilà .. je pense que ce doit être suffisent pour comprendre le source ...
mov fdfile,%ebx;
// get fdfile
in EBX
mov
$buffer,%ecx;
// @buffer
mov $(fdfile-buffer),%edx; // strlen ( buffer )
int
$0x80;
// syscall
En effet, lorsqu'on écrit dans le fichier, on écrit une taille $(fdfile-buffer)
qui correspond à la taille du buffer. Quand on fait un 'cat
fichier.txt' on ne s'en rend pas compte car le caractère null termine
la chaine, mais la taille du fichier trahit cette anomalie de taille
d'écriture.
Pour résoudre cette anomalie, on peut utiliser le retour de "_readstdin:"
qui renvoie le nombre d'octets lus, et permettre une écriture dans le
fichier de la partie saisie au clavier uniquement. Le code de retour
étant dans EAX, il s'agira donc de copier EAX dans EDX avant d'écraser
EAX par le syscall 4 :
_writeinfile:
// write buf
in file
mov
%eax,%edx;
// copy the character count of read(STDIN) in size of write(FILE)
mov
$4,%eax;
// syscall 4 = write
mov
fdfile,%ebx;
// get fdfile in EBX
mov $buffer,%ecx; // @buffer
int $0x80;
// syscall
Ainsi, on crée un fichier ayant la taille de ce qui a été pris sur STDIN et non la taille du buffer.