IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

x86 16-bits Assembleur Discussion :

Programmation évènementielle et problème de tableau


Sujet :

x86 16-bits Assembleur

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 30
    Points : 11
    Points
    11
    Par défaut Programmation évènementielle et problème de tableau
    Bonjour,
    je dois réaliser un Space Invaders en assembleur mais je rencontre deux difficulté. Tout d'abord, le space invaders doit être en temps réel. Si on ne bouge pas le vaisseau, les aliens doivent bouger. Or, nous devons utiliser une variable compteur qui décompte à chaque tour de la boucle principale. Pour le reconnaissance des touches, j'utilise l'interruption 16h.0 qui possède un défaut dans ce cas. Elle attend que j'appuie sur une touche pour faire avancer le programme. Existe-t-il une interruption qui réalise la même action sans arrêter le programme ? Ou doit-on ruser (dans ce cas, je ne vois pas)?
    Autre point, les données sont enregistrées sous forme de tableau
    (exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tab dw 0,0,0,0,0,0,0,0
         dw 1,1,1,1,1,1,1,1
         dw 0,0,0,0,0,0,0,0
    )
    Ma fonction pour afficher les aliens fonctionne mais n'affiche pas les bons aliens. Grâce au code debug de la console, j'ai pu m'apercevoir qu'en fait, je ne naviguait pas dans le tableau, je reste à la case 1 ? Pourtant, je pense avoir tout bien ecrit. Voilà en gros ma parcelle de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    affichage_aliens: ;routine d'affichage des aliens
    	mov cx, 6
    	;mov bx, tab_alien
    	;mov [add1],bx
    	mov dx, [ya1]
    	mov word [yall], dx
    	mov bx, tab_alienb_cte
    	colonne_tab:
    		push cx
    		mov cx,11
    		mov dx, [xa1]
    		mov word [xall], dx
    		ligne_tab:
    			push cx
    			mov dx, [yall]
    			mov word [y], dx
    			mov dx, [xall]
    			mov word [x], dx
    			mov dx, [ha1]
    			mov word [h], dx
    			mov dx, [la1]
    			mov word [l], dx
    			call compare
    			inc bx
    			push bx
    			call affiche_sprite
    			pop bx
    			mov dx, [la1]
    			add word [xall], dx
    			pop cx
    		loop ligne_tab
    		pop cx
    		mov dx, [ha1]
    		add [yall], dx
    	loop colonne_tab
    	ret
     
    compare: ;probleme de selection de l'addresse
     
    	mov bl, [bx]
    	cmp bl, 0
    	je aff_mort
    	cmp bl, 5
    	je aff_alien1
    	cmp bl, 1
    	je aff_alien2
    	cmp bl, 3
    	je aff_alien3
    	ret
    	aff_mort:
    		cmp word [allure], 1
    		je mort1
    		jmp mort2
    		mort1:
    		mov word[add_sprite], mort
    	ret
    		mort2:
    		mov word[add_sprite], alien1b
    	ret
    	aff_alien1:
    		cmp word [allure], 1
    		je mort1a
    		jmp mort2a
    		mort1a:
    		mov word[add_sprite], alien1
    	ret
    		mort2a:
    		mov word[add_sprite], alien1b
    	ret
    	aff_alien2:
    		cmp word [allure], 1
    		je mort1b
    		jmp mort2b
    		mort1b:
    		mov word[add_sprite], alien2
    	ret
    		mort2b:
    		mov word[add_sprite], alien2b
    	ret
    	aff_alien3:
    		cmp word [allure], 1
    		je mort1c
    		jmp mort2c
    		mort1c:
    		mov word[add_sprite], alien3
    	ret
    		mort2c:
    		mov word[add_sprite], alien3b
    	ret

    Merci d'avance de vos éclaircissements...

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 59
    Points : 88
    Points
    88
    Par défaut
    Pour éviter que le service 0 de l'int 16h attende l'arrivée d'un caractère, on teste au préalable si le tampon clavier n'est pas vide à l'aide du service 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Test_tampon_clavier:
            mov     ah,1
            int     16h
            jnz     Lit_caractere
     
           (...)
     
    Lit_caractere:
            xor     ah,ah
            int     16h
    Je donne quelques explications dans le sujet situé au lien suivant :
    http://www.developpez.net/forums/d10...-informatique/


    Quant au problème de parcours dans un tableau, une possibilité serait d'utiliser l'adressage basé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            mov     dx,tableau [bx]
            ; équivalent à
            mov     dx,[bx+tableau]

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 30
    Points : 11
    Points
    11
    Par défaut
    Merci pour cette réponse rapide. Je viens d'essayer et ca marche. Fallait y penser (j'ai pas encore ce genre de réflexes).
    Par contre, pour le tableau, nasm me renvoie "invalid effective adress". Pourtant, je récupère bien l'adresse du tableau, j'y ajoute bx, je met le tout dans dx et puis je place la valeur pointé par dx dans dl. Et je compare. Je ne vois pas ce qui ne va pas...

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 59
    Points : 88
    Points
    88
    Par défaut
    je place la valeur pointée par dx dans dl
    Cela signifie une instruction inexistante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            mov     dl,[dx]         ; usage impossible de DX
    ; au lieu de
            mov     dl,[bx]         ; usant du registre de base BX

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 30
    Points : 11
    Points
    11
    Par défaut
    Merci MIG86. Le jeu marche bien maintenant. Par contre j'ai un dernier problème.
    Je dois afficher le score et pour cela, je dois bien sûr décomposer la variable en chiffres indépendant. Il est écrit que je dois diviser par 10 mais si je divise 1234 par 10, j'obtiens 123.4 et le 3 n'est pas isolé. Ou alors il y a une chose qui m’échappe dans le DIV ?

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 59
    Points : 88
    Points
    88
    Par défaut
    Pour éviter tout débordement, on utilisera un diviseur 16 bits. Le dividende sera donc représenté sur 32 bits par DX:AX. Une fois la division effectuée, DX sera le reste et AX le quotient.
    Pour afficher un nombre décimal inférieur à 65.536, la méthode est très simple. Tout d'abord, on met la valeur à sortir dans AX, le diviseur dix dans BX (par ex.) et le compteur CX à zéro. Ensuite, on procède ainsi :
    - incrémenter CX ;
    - annuler DX ;
    - effectuer la division par BX ;
    - empiler le reste DX ;
    - si le quotient AX n'est pas nul, recommencer les étapes précédentes ;
    - afficher les chiffres à dépiler grâce à une boucle.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
            ; Valeur à afficher en décimal dans AX
            mov     bx,10
            xor     cx,cx           ; Compteur à 0
    Division:
            inc     cx
            xor     dx,dx           ; DX = 0
            idiv    bx              ; Divise DX:AX par 10
            push    dx              ; Empile le reste
            or      ax,ax           ; Nouveau dividende nul ?
            jnz     Division        ; Sinon, recommence
            mov     ah,2            ; Fct DOS affichage car.
    Affiche:
            pop     dx              ; Dépile chiffre
            add     dl,48           ; Représentation ASCII
            int     21h             ; Appel DOS
            loop    Affiche         ; Recommence tant que CX <> 0

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 30
    Points : 11
    Points
    11
    Par défaut
    Oki, je comprend mieux. Par contre, j'ai une question sur le loop. Modifie-t-il la valeur contenue dans cx ? Par exemple, je loop sur cx = 5. Est-ce que cx sera décrémenter a chaque passage sur le loop ?

  8. #8
    Membre émérite
    Avatar de Eric2a
    Homme Profil pro
    Technicien
    Inscrit en
    Septembre 2005
    Messages
    1 225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Corse (Corse)

    Informations professionnelles :
    Activité : Technicien

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 225
    Points : 2 411
    Points
    2 411
    Par défaut
    Salut,

    Oui.

    LOOP label permet de répéter plusieurs fois la même séquence d'instructions.

    A chaque execution de cette instruction, le registre CX est décrémenté (n'affecte pas les indicateurs) et, tant que CX est différent de 0, le programme saute à l'adresse spécifiée par label.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 30
    Points : 11
    Points
    11
    Par défaut
    j'ai un probleme lorsque je veut afficher le score. Lorsque j'appelle la fonction, j'ai le message d'erreur suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    E:\Cours\ASR2\nasm\SpIn.com
    Le processeur NTVDM a rencontré une instruction non autorisé.
    CS:0f00 IP:000f OP:63 6f 6d 6d 61 ...
    Voici le code de mon programme qui correspond a l'affichage:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    affichage_score: ;;routine d'affichage du score
    	mov ax, [score]
    	mov bx, 10
    	xor cx, cx
    	divide:
    		inc cx
    		xor dx, dx
    		idiv bx
    		push dx
    		or ax,ax
    		jne divide
    	loop_score:
    		mov word [y], 5
    		mov bx, [xs]
    		mov word [x], bx
    		mov word [h], 5
    		mov word [l], 5
    		pop dx
    		call test_chiffre
    		mov word [add_sprite], bx
    		push cx
    		push dx
    		call affiche_sprite
    		pop cx
    		pop dx
    		inc word [xs]
    		inc word [xs]
    		inc word [xs]
    		inc word [xs]
    		inc word [xs]
    		inc word [xs]
    		inc word [xs]
    	loop loop_score
    	mov word [xs], 50
    ret
     
     
    test_chiffre: ;routine de test des chiffres du score
        cmp dx,0
    	je chiffre_0
    	cmp dx,1
    	je chiffre_1
    	cmp dx,2
    	je chiffre_2
    	cmp dx,3
    	je chiffre_3
    	cmp dx,4
    	je chiffre_4
    	cmp dx,5
    	je chiffre_5
    	cmp dx,6
    	je chiffre_6
    	cmp dx,7
    	je chiffre_7
    	cmp dx,8
    	je chiffre_8
    	cmp dx,9
    	je chiffre_9
    	chiffre_0:
    		mov bx,zero
    		ret
    	chiffre_1:
    		mov bx,un
    		ret
    	chiffre_2:
    		mov bx,deux
    		ret
    	chiffre_3:
    		mov bx,trois
    		ret
    	chiffre_4:
    		mov bx,quatre
    		ret
    	chiffre_5:
    		mov bx,cinq
    		ret
    	chiffre_6:
    		mov bx,six
    		ret
    	chiffre_7:
    		mov bx,sept
    		ret
    	chiffre_8:
    		mov bx,huit
    		ret
    	chiffre_9:
    		mov bx,neuf
    		ret

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 59
    Points : 88
    Points
    88
    Par défaut
    OP:63 6f 6d 6d 61 ...
    Cela correspond à :
    comma ...

    L'exécution du programme s'est sans doute poursuivie dans une zone de données.

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 30
    Points : 11
    Points
    11
    Par défaut
    Comma ? C'est quoi ?

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    59
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2010
    Messages : 59
    Points : 88
    Points
    88
    Par défaut
    Les nombres hexadécimaux affichés par le message d'erreur représentent les valeurs ASCII d'un mot commençant par « comma ».
    Le programme s'est peut-être branché sur un message à cause d'un saut mal calculé (JMP étiquette+valeur). A moins qu'une instruction RET a été oubliée et que le processeur a pris les données suivantes pour des instructions.

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 30
    Points : 11
    Points
    11
    Par défaut
    Finalement sa marche. C'est juste qu'il aime pas que je l'appelle avec un call mais plutot avec un jmp. Par contre, si m'a variable vaut 534, il m'affiche 534000000001. Pourquoi donc ?

    EDIT: C'est bon, j'ai fais une erreur de pile. Je me ferais avoir a chaque fois
    Merci MIG86, merci beaucoup.

Discussions similaires

  1. [XHTML] problème de tableau
    Par virgul dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 28/04/2005, 07h18
  2. Problème de tableau
    Par tom06440 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 26/04/2005, 20h30
  3. Problème de tableau
    Par krfa1 dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 08/02/2005, 11h09
  4. [Programmation en C][Probléme d'affichage]
    Par ronan99999 dans le forum Windows
    Réponses: 7
    Dernier message: 01/09/2004, 11h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo