Le livre d'Irvine sur le Masm.

Le livre d'Irvine sur le Masm. - ASM - Programmation

Marsh Posté le 09-12-2004 à 06:14:20    

Bonjour.
 
A mes moments perdus, j'étudie le livre de Kip Irvine sur le Masm : Assembleur x86.
A la p. 174, il présente une procédure ReadInt de sa bibliothèque Irvine32.lib, qui lit (après saisie) un entier signé stockable sur 32 bits; si la saisie ne peut pas être stockée de cette façon, la procédure affiche un message d'erreur et, théoriquement, arme le drapeau Overflow.
J'ai l'impression qu'en fait, elle n'arme pas ce drapeau. Cela me semble résulter de l'exécution du programme suivant (solution de l'exercice 3 du chapitre 6, p. 255) :
 
TITLE Evaluation d'un résultat de test.    (MonExamen.asm)
 
; Description : ma solution de l'exercice d'Irvine, ch. 6,
; exerc. 3, p. 255. L'utilisateur introduit un score et le programme affiche la
; cote littérale correspondante.
; Auteur :
; Date de création : 8 décembre 2004.
 
INCLUDE Irvine32.inc
 
.data
zerosigne SDWORD 0         ; pour éviter la comparaison d'un
                           ; registre et de la valeur immédiate
                           ; nulle.
                           ; (Je ne sais pas si cette comparaison
                           ; est permise et, à supposer qu'elle le
                           ; soit, je suppose que les entiers
                           ; comparés sont alors supposés non
                           ; signés, cfr. p. 250 pour la
                           ; comparaison de deux registres.)
cent SDWORD 100            ; idem. (Eviter la comparaison d'un
                           ; registre et d'une valeur immédiate.)
prompt1 BYTE "Saisissez un entier de 0 ", 133, "100 : ", 0
prompt2 BYTE "L'entier que vous saisissez doit aller de 0 ", 133, " 100. Il ne peut pas ", 136, "tre n", 130, "gatif. Recommencez.", 0
prompt3 BYTE "Ce que vous avez saisi n'est pas stockable comme entier sign", 130, " sur 32 bits. Le programme se termine. Dans une version future, il vous permettra peut-", 136, "tre de recommencer.", 0
 
promptA BYTE "A", 0
promptB BYTE "B", 0
promptC BYTE "C", 0
promptD BYTE "D", 0
promptF BYTE "F", 0
 
entierlu SDWORD ?          ; Ceci aussi servira à forcer
                           ; une comparaison entre entiers signés.
.code
 
main PROC
 
  mov edx, OFFSET prompt1
  call WriteString         ; affiche la chaîne stockée à l'adresse
                           ; contenue dans edx. (Bibl. Irvine.inc)
  or eax, 0                ; désarme Overflow, ce qui permettra de
                           ; savoir si l'instruction suivante
                           ; (ReadInt) échoue. (Méthode indiquée
                           ; p. 218.)
  call ReadInt             ; Voir Irvine p. 174.
                           ; Lit un entier signé sur 32 bits
                           ; et le renvoie vers eax. Affiche un
                           ; message d'erreur et arme Overflow si
                           ; la saisie ne peut être stockée comme
                           ; entier signé sur 32 bits.
                           ; EN FAIT, ON DIRAIT QUE, DANS LE CAS
                           ; OU LA SAISIE NE PEUT PAS ETRE STOCKEE
                           ; COMME ENTIER SIGNE SUR 32 BITS,
                           ; READINT N'ARME PAS OVERFLOW. VOIR
                           ; PLUS LOIN.
; Ce qui suit est pour mes essais.
  call DumpRegs            ; Rappel : DumpRegs est une procédure de la
                           ; bibliothèque Irvine32.lib. Elle affiche
                           ; le contenu de certains registres
                           ; (notamment le drapeau Overflow) aux fins
                           ; de débogage (p. 171). Je suppose donc
                           ; qu'elle ne modifie pas les registres.
                           ; Si on fait lire par ReadInt un nombre
                           ; trop grand, elle devrait armer le
                           ; drapeau Overflow (Irvine, p. 174),
                           ; mais ce DumpRegs
                           ; montre qu'elle ne l'arme pas !!!!!!!!
;;;;;;;;;;
 
  jo mauvaisentier         ; saute si ReadInt a armé le drapeau
                           ; Overflow. (Mais comme noté, il me
                           ; semble qu'il y a un bug : elle n'arme
                           ; jamais ce drapeau...)
  .WHILE (eax < zerosigne) || (eax > cent)
    mov edx, OFFSET prompt2
    call WriteString
    or eax, 0              ; Voir plus haut.
    call ReadInt
    jo mauvaisentier       ; Voir plus haut.
  .ENDW
  mov entierlu, eax      ; Pour forcer la comparaison entre
                         ; entiers signés.
  .IF entierlu >= 90
    mov edx, OFFSET promptA
    call WriteString
  .ELSEIF entierlu >= 80
    mov edx, OFFSET promptB
    call WriteString
  .ELSEIF entierlu >= 70
    mov edx, OFFSET promptC
    call WriteString
  .ELSEIF entierlu >= 60
    mov edx, OFFSET promptD
    call WriteString
  .ELSE
    mov edx, OFFSET promptF
    call WriteString
  .ENDIF
  jmp quitter
 
mauvaisentier:
  mov edx, OFFSET prompt3
  call WriteString
 
quitter:
 
  exit  ; Retour au système d'exploitation. (Défini dans
        ; Irvine32.inc.)
 
main ENDP
 
END main
 
Quelqu'un peut-il me dire s'il y a réellement quelque chose qui cloche dans la procédure ReadInt d'Irvine ou si c'est moi qui me trompe ?
Merci d'avance.
 
P.S. Les commentaires du programme montrent que la comparaison d'un registre et d'une valeur immédiate me pose un problème, mais c'est une autre affaire.
 
Panurge.


Message édité par Panurge le 10-12-2004 à 17:43:00
Reply

Marsh Posté le 09-12-2004 à 06:14:20   

Reply

Marsh Posté le 10-12-2004 à 12:48:58    

Je ne connais ni masm ni Irvine cependant
si la procédure readint positionne l'indicateur de retenu OF, il ne sert à rien de le désarmer avant vu qu'il sera modifié de toute façon
je ne sait pas ce que fait la procédure dumpregs, mais il est dangereux de faire un test sur un indicateur après toute une série d'instruction sans avoir au préalable sauvegardé les indicateurs ces derniers étant très volatils.
Quel est ce grand nombre qui devrait faire apparaitre le message ?

Reply

Marsh Posté le 10-12-2004 à 18:01:37    

Bonsoir db_ et merci d'avoir répondu.
 
Vous dites "Si la procédure readint positionne l'indicateur de retenue OF, il ne sert à rien de le désarmer avant, vu qu'il sera modifié de toute façon".
Je ne sais pas s'il est censé être modifié de toute façon : Irvine (p. 174) dit que ReadInt arme le drapeau Overflow en cas de saisie non stockable comme entier signé sur 32 bits, mais ne dit pas que ce drapeau est désarmé si la saisie est correcte. Il me semble donc que si on veut savoir avec certitude si ReadInt arme Overflow, il faut le désarmer au préalable.
J'aurais dû rappeler dans les commentaires du programme (c'est fait maintenant) que DumpRegs est une procédure de la bibliothèque Irvine32.lib qui affiche, aux fins de débogage, le contenu de certains registres, notamment du drapeau Overflow; je suppose donc que cette procédure ne modifie aucun registre.
Notez que j'ai ajouté cet appel de DumpRegs après avoir constaté que le programme s'exécutaitait comme si ReadInt n'armait pas Overflow en cas d'entrée débordante.
Le nombre trop grand était 32323232325 (32 milliards et quelque chose). Il provoquait bel et bien le message de débordement envoyé par la procédure ReadInt, mais la suite du programme se passait comme si l'indicateur de débordement n'avait pas été armé.
 
Encore merci.
 
Panurge.


Message édité par Panurge le 10-12-2004 à 19:52:04
Reply

Marsh Posté le 31-01-2005 à 13:11:27    

salut
j'etudie moi aussi depuis quelque temps le livre de Kip Irvine sur l'assembleur  
1)je suis d'accord avec db_ , ca ne sert a rien d'initialiser
un drapeau dont on utilise pas la valeur initiale puisqu'il sera modifié avant qu'on l'utilise.
2)J'ai remarqué aussi que la procedure readint n'arme pas le drapeau overflow, mais en faisant appel a dumpregs on se rend vite compte qu'en fait c'est le drapeau carry (retenue) qui est armé si le nombre est trop grand pour etre stocké sur 32bits. Je pense qu'il s'agit d'une erreur du livre ou alors la procedure readint ne correspond pasa celle qu'on devrait avoir.
Donc pour controler l'erreur dans ton prog il faut tout simplement remplacer jo par jc.
3) Ca ne pose aucun probleme de comparer un registre et une valeur immediate signée ou pas, je ne vois pas ou est le probleme, enfin c'est très bien expliqué dans le livre p216
 
voici ma source :
 
TITLE chap6ex3
 
INCLUDE Irvine32.inc
 
 
.data
 
 tab byte "ABCDF",0
 prompt byte "entrer un nombre entre 0 et 100 compris (-1 pour quitter)",0
 errmsg byte "erreur recommencez",
 
.code
 
main PROC
 
 mov esi,offset tab
l1:
 call crlf
 mov edx,offset prompt
 call writestring
 call crlf
 call readint
 jc err
 cmp eax,-1
 je quit
 cmp eax,0
 jb err
 cmp eax,59
 ja l2
 mov eax,[esi+4]
 call writechar
 jmp l1
l2:
 cmp eax,69
 ja l3
 mov eax,[esi+3]
 call writechar
 jmp l1
l3:
 cmp eax,79
 ja l4
 mov eax,[esi+2]
 call writechar
 jmp l1
l4:
 cmp eax,89
 ja l5
 mov eax,[esi+1]
 call writechar
 jmp l1
l5:
 cmp eax,100
 ja err
 mov eax,[esi]
 call writechar
 jmp l1
err:
 mov edx,offset errmsg
 call writestring
 jmp l1
quit:
 
 exit
main ENDP
 
 
 
END main

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed