Inserire in 2 Vettori le coordinate di un quadrato

di il
15 risposte

Inserire in 2 Vettori le coordinate di un quadrato

Salve a tutti,
sto cercando di fare un programma in assembly che mi stampi a video un certo numero di quadrati, in modo casuale, in modo tale che tutti partano dalla prima riga e scendano fino ad arrivare nella parte bassa della schermata.La modalità video che ho utilizzato è quella VGA grafica 300x200 13H.
Per creare i quadrati ho utilizzato la seguente procedura,dove non riesco a capire perché non mi memorizza le coordinate nei rispettivi vettori, e mi si panta quando la eseguo.

CREA PROC NEAR
PUSH AX
PUSH SI
PUSH DI

MOV AX,LUNG ;Genera un numero casuale tra 0 e 20
CALL Random
LEA SI,StarVY ;Vettore dove sono memorizzate le righe
LEA DI,starVX ;Vettore dove sono memorizzate le colonne
PUSH AX
SHL AX,1 ;Moltiplico per 2 AX perchè il Vettore è DW
ADD SI,AX ;Sposto SI e DI in modo tale che puntano sulle coordinate
ADD DI,AX ;del quadrato memorizzate nei due Vettori
POP AX
CMP StarVY[SI],0 ;Confronto se il quadrato è gia stato creato
JNZ Esci ;se si ,esce
MOV BX,15
MUL BX ;moltiplico il numero casuale per 15
INC AX
MOV StarVX[DI],AX ;salvo la coordinata delle colonne del nuovo quadrato
MOV Column,AX
MOV AX,StarVY[SI]
ADD AX,1 ;incremento la coordinata delle righe
MOV Row,AX
MOV StarVY[SI],AX ;salvo la coordinata delle righe del nuovo quadrato
M_Brick Column,Row,COLStar ;Macro che mi Visualizza il quadrato appena creato

Esci: POP DI
POP SI
POP AX
RET
CREA ENDP


Vi ringrazio anticipatamente a chiunque mi possa dare una mano

15 Risposte

  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Ciao
    allora hai commesso alcuni errori
    vedrò di farteli capire.
    iniziamo ad analizzare
    PUSH AX
    PUSH SI
    PUSH DI
    MOV AX,LUNG ;Genera un numero casuale tra 0 e 20
    CALL Random
    
    qui in teoria non hai commesso errori ma mi sembra strano che la routine Random usi anche i registri si e di.
    se hai fatto le tre push iniziali per salvaguardare i registri hai sprecato solo del codice perchè sono i programmi e non le subroutine a dover gestire questo compito.
    perchè i registri normalmente servono per passare i dati tra subroutine e programma.
    comunque in ottica didattica ci può stare.
    LEA SI,StarVY ;Vettore dove sono memorizzate le righe
    LEA DI,starVX ;Vettore dove sono memorizzate le colonne
    PUSH AX
    qui hai fatto bene peccato però che saranno fonte di guai nelle righe successive.
    SHL AX,1 ;Moltiplico per 2 AX perchè il Vettore è DW
    questa riga non serve a nulla in quanto ax è gia di per se una word.
    ADD SI,AX ;Sposto SI e DI in modo tale che puntano sulle coordinate
    ADD DI,AX ;del quadrato memorizzate nei due Vettori
    POP AX
    qui c'è la prima nota dolente
    in quanto di e si contengono gli indirizzi dei vettori mentre ax è un numero casuale quindi ammeno che tu non hai definito 2 vettori talmente grandi da poter contenere tutti i possibili numeri generati,levando la shl perchè altrimenti sarebbero il doppio!, ciò costituisce un errore perchè andresti a sovrascrivere locazioni di memoria che non hanno nulla a che vedere con i vettori.
    CMP StarVY[SI],0 ;Confronto se il quadrato è gia stato creato
    JNZ Esci ;se si ,esce
    gravissimo errore
    perchè usi si come un indice di vettore ma si contiene l'indirizzo del vettore e probbabilmente il vettore non è cosi grande quindi vai ad indirizzare locazioni di memoria che non hanno nulla a che vedere con i vettori.
    la forma corretta è
    cmp word ptr [si],0
    MOV BX,15
    MUL BX ;moltiplico il numero casuale per 15
    INC AX
    questa parte va bene
    MOV StarVX[DI],AX ;salvo la coordinata delle colonne del nuovo quadrato
    gravissimo errore vedi spiegazione della cmp
    la forma corretta è mov word ptr [di],ax
    MOV Column,AX
    va bene
    MOV AX,StarVY[SI]
    ADD AX,1 ;incremento la coordinata delle righe
    qui c' è errore perchè si contiene sempre l'indirizzo del vettore.
    forma corretta : mov ax,word ptr [si]
    MOV Row,AX
    MOV StarVY[SI],AX ;salvo la coordinata delle righe del nuovo quadrato
    gravissimo errore vedi spiegazione della cmp
    M_Brick Column,Row,COLStar ;Macro che mi Visualizza il quadrato appena creato
    qui e corretto
    Esci: POP DI
    POP SI
    POP AX
    RET
    vedi discorso delle push iniziali.
    per gli indirizzamenti
    ricordati che se usi la lea devi usare la forma "[registro]" e poi il registro deve essere incrementato 1 x i byte
    2 x le word
    4 X le dword
    esempio mov word ptr [di],5
    mentre se non vuoi usare la lea la forma corretta e nomevariabile[registro] dove registro deve avere un valore <= alla dimensione del registro -1.
    perchè i vettori in assembler cominciano da 0.

    se non hai capito come modificare il programma ti darò una mano.
    spero di esserti stato d'aiuto
  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Smalldragon ... mi sa che ci sono parecchie imprecisioni in quello che hai scritto ... ma chissà se il nostro amico è ancora interessato ...
  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Scusatemi il ritardo, ma in questi giorni ero a letto con la febbre alta.
    Ti ringrazio tantissimo per avermi risposto e corretto e commentato gli errori, sei stato veramente gentile.
    Ora mi metto a correggere il programma e ti farò sapere.
    Buona giornata
  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Sì ma come dicevo prima, non tutti i suggerimenti sono corretti. Ad esempio, per
    
    SHL AX,1 ;Moltiplico per 2 AX perchè il Vettore è DW
    
    quello che ha scritto smalldragon
    questa riga non serve a nulla in quanto ax è gia di per se una word.
    non ha senso e dovresti usarla.

    Comunque, quando hai un codice da mostrarci, completo delle dichiarazioni dei dati, ti faccio sapere se ci sono problemi.
  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Questo programma è un gioco, in cui ho una navicella(che è un quadrato rosso) che si trova nel basso dello schermo, che devo manovrarla con le frecce dx e sx , in modo tale da evitare le meteoriti(che sono anch'essi dei quadrati gialli) che scendono dall'alto dello schermo.
    Per fare questo ho scritto il seguente codice:


    ;MACRO UTILIZZATE
    INCLUDE c:\ALE.MAC

    ;DICHIARAZIONE LIBRERIA
    INCLUDELIB c:\ALE.LIB

    ;DICHIARAZIONI PROCEDURE ESTERNE
    EXTRN BIOSchr:NEAR
    EXTRN SET_cur:NEAR
    EXTRN BIOSmsg:NEAR
    EXTRN VIA_cur:NEAR
    EXTRN RIP_cur:NEAR
    EXTRN KEY:NEAR
    EXTRN SCRN3:NEAR
    EXTRN PRT_pxl:NEAR
    EXTRN Mattone:NEAR
    EXTRN Lato:NEAR
    EXTRN Random:NEAR
    EXTRN Linea:NEAR
    EXTRN Delay:NEAR



    ;DICHIARAZIONE VARIABILI PER PROCEDURE ESTERNE
    PUBLIC ATTRIB


    DATISEGMENT

    ESC_ EQU 1BH ;Codice Ascii tasto <ESC>
    RIGHT EQU 4DH ;Bytes Scan Code
    LEFT EQU 4BH ;
    UP EQU 48H ;
    DOWN EQU 50H ;

    ATTRIB DB 0EH
    titolo DB "*********** ******** *** *********** *********** "
    DB "*********** ********** ***** *********** *********** "
    DB "*** **** *** ******** *** *** "
    DB "*** **** *** *********** *** *** "
    DB "*** **** *** *** *** *** *** "
    DB "*********** ************ *** *** *** *********** "
    DB "*********** ********** *********** *** *********** "
    DB " *** *** *********** *** *** "
    DB " *** *** *** *** *** *** "
    DB "*********** *** *** *** *********** *********** "
    DB "*********** *** *** *** *********** *********** ",'$'
    Testo01 DB "[P]lay Game",'$'
    Testo02 DB "[Q]uit",'$'
    Testo03 DB "CIAO CIAO",'$'

    ColNAve EQU 0CH
    ColStar EQU 0EH
    Black EQU 00H
    LUNG EQU 21

    Riga DW 180
    Colonna DW 150

    Row DW 0
    Column DW 0

    NavX DW 0
    NavY DW 0

    StarVX DW LUNG DUP(0)
    StarVY DW LUNG DUP(0)


    DATI ENDS

    CODICE SEGMENT BYTE PUBLIC 'CODE'
    ASSUME CS:CODICE,DS:DATI


    ;AREA DESTINATA ALLE PROCEDURE DI PROGRAMMA

    DESKTOP PROC NEAR
    CALL SCRN3 ;Modalità testo VGA 720x400, 16 colori

    M_msg titolo,0,10,0EH
    M_msg Testo01,15,35,0CH
    M_msg Testo02,18,35,0CH

    M_Chr 'P',15,36,0EH
    M_Chr 'Q',18,36,0EH
    CALL VIA_cur
    RET
    DESKTOP ENDP

    ;--------------------------------------------------------------------------------------------------------------------------------------------
    ; Procedura che mi crea un quadrato e memorizza nei vettori le coordinate del primo pixel in alto a sinistra
    ;
    ;--------------------------------------------------------------------------------------------------------------------------------------------

    CREA PROC NEAR

    MOV AX,LUNG ;genera un numero intero casuale da 0 a 20
    CALL Random
    LEA SI,StarVY ;Vettore dove vengono memorizzate le coordinate della prima colonna di ogni quadrato
    LEA DI,starVX ;Vettore dove vengono memorizzate le coordinate della prima riga di ogni quadrato
    PUSH AX
    SHL AX,1 ;moltiplico per 2 AX perchè il vettore è DW
    ADD SI,AX ;Sposto SI e DI in modo tale che puntano sulle coordinate
    ADD DI,AX ;del quadrato scelto in base al numero generato
    POP AX
    CMP word ptr [SI],0 ;confronto la coordinata della riga puntata da SI, se è zero devo creare un quadrato
    JNZ Esci ;altrimenti esce

    MOV BX,15 ;moltiplico per 15 il num casuale perchè la risoluzione dello schermo è di 320 pixel in orizzontale
    MUL BX ;ed ogni quadrato è formato da 15 pixel in orizzontale
    INC AX
    MOV word ptr[DI],AX ;salvo la coordinata della prima colonna del quadrato
    MOV Column,AX
    MOV AX,word ptr[SI]
    ADD AX,1 ;incremento la cordinata della riga del quadrato
    MOV Row,AX
    MOV word ptr[SI],AX ;la salvo nel vettore
    M_Brick Column,Row,COLStar ;Macro che mi visualizza il quadrato

    Esci: RET

    CREA ENDP

    ;--------------------------------------------------------------------------------------------------------------------------------------------
    ; Procedura che mi fa scendere i quadrati creati
    ;
    ;--------------------------------------------------------------------------------------------------------------------------------------------

    Giu PROC NEAR
    LEA SI,StarVY
    LEA DI,StarVX
    MOV CX,LUNG

    XXX0: PUSH CX ;Ciclo che che mi fa scorrere i vettori
    CMP word ptr[SI],0 ;Confronta se il quadrato è stato creato
    JZ XXX1 ;se non è stato creato passa al successivo elemento del vettore
    MOV AX,word ptr[SI]
    MOV Row,AX
    MOV AX,word ptr[DI]
    MOV Column,AX

    M_Riga Column,Row,Black ;macro che mi colora di nero la prima riga del quadrato, in modo da eliminarla
    INC Row
    MOV AX,Row
    PUSH Row
    MOV word ptr[SI],AX ;salvo la nuova coordinata delle righe nel vettore
    ADD Row,14 ;aggiungo 14 per creare la nuova riga che si trova sotto al quadrato
    M_Riga Column,Row,ColStar ;macro che mi colora di giallo la nuova riga della parte bassa del quadrato
    POP Row
    CMP Row,185 ;verifico se il quadrato è arrivato in basso
    JNZ XXX1 ;se non è arrivato in basso passo al sucessivo quadrato
    MOV word ptr[SI],0 ;altrimenti azzero le coordinate del del quadrato
    MOV word ptr[DI],0
    XXX1: POP CX
    ADD SI,2
    ADD DI,2
    LOOP XXX0

    RET

    Giu ENDP

    ;---------------------------------------------------------------------------------------

    MAIN PROC NEAR
    MOV AX,DATI ; Inizializzazione del registro di segmento dati
    MOV DS,AX
    CALL DESKTOP

    Scelta: CALL KEY
    AND AL,11011111B
    CMP AL,'P'
    JZ Start
    CMP AL,'Q'
    JZ fine
    JMP Scelta

    fine: JMP _OUT

    Start: MOV AH,00H ;modalità Video grafica VGA 320x200
    MOV AL,13H
    INT 10H

    M_Brick Colonna,Riga,ColNave ;Crea la navicella (che è un quadrato)

    Sposta: CALL CREA ;procedura che mi crea i meteoriti(sono dei quadrati)
    CALL Giu ;fa scendere i meteoriti


    MOV CX,2 ;ritardo di 110 ms
    CALL Delay

    MOV AH,01H ;Preleva un carattere dal buffer e scrive
    INT 16H ;il codice ascii in AL,lo SCANCODE in AH
    JZ Direzione ;Se il buffer della tastiera ha un carattere ZF=0,perciò salta a direzione
    MOV AH,10H ;svuota il buffer della tastiera
    INT 16H
    CMP AL,ESC_ ;confronta il contenuto di AL con il tasto ESC
    JE _OUT ;Se è uguale esce dal gioco

    Direzione: ;Confronta se il tasto premuto è la freccia destra o sinistra
    CMP AH,RIGHT
    JE Destra
    CMP AH,LEFT
    JE Sinist
    JMP SHORT Sposta


    Destra: ;Muovo verso destra la navicella
    M_Colon Colonna,Riga,Black
    INC Colonna
    MOV AX,Colonna
    MOV NavX,AX
    PUSH Colonna
    ADD Colonna,14
    M_Colon Colonna,Riga,ColNave
    POP Colonna
    JMP Sposta



    Sinist: PUSH Colonna ;muovo verso sinistra la navicella
    ADD Colonna,14
    M_Colon Colonna,Riga,Black
    POP Colonna
    DEC Colonna
    MOV AX,Colonna
    MOV NavX,AX
    M_Colon Colonna,Riga,ColNave
    JMP Sposta


    _OUT: CALL SCRN3 ;Modalità testo VGA 720x400, 16 colori

    M_msg Testo03,18,35,0CH

    PUSH AX
    CALL RIP_cur
    MOV DH,23
    MOV DL,0
    CALL SET_cur
    POP AX
    MOV AH,4CH
    INT 21H

    MAIN ENDP
    CODICE ENDS
    END MAIN
  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Scusami l'ho inviato per sbaglio,stavo cercando di formattare il testo del programma.
    Dati Segment è staccato.
    Se vuoi ti formatto di nuovo il testo del programma.

    Se vuoi ti mando anche le procedure esterne.

    Grazie per l'aiuto che mi stai dando
  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Il problema che mi si presenta è che alcuni quadrati si fermano mentre vengono giu e poi la schermata nel frattempo si riempie di linee gialle da 15 pixel ciascuna come quelle dei quadrati.

    Invece il quadrato rosso riesco a muoverlo e funziona perfettamente.
  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Fai una cosa migliore ... crea uno zip con il progetto completo e fallo scaricare.

    In quale ambiente e con quale compilatore operi?
  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Sto usando windows 7 a 64 bit, e utilizzo l'emulatore DosBox 0.74. Il compilatore che utilizzo è il masm5,devo usare questa versione per scopi didattici.

    Non riesco ad inviarti la cartella zippata perché quando allego il file mi dice che "l'estensione zip non è permessa".Ho provato anche ad inviarti ogni singolo file, nemmeno in questo modo mi da la possibilità. Non so se c'è un altro modo...oppure te lo invio via mail.
  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Usa un qualsiasi sito di filesharing ... o dropbox ...
  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Ti invio il link del mio programma

    https://www.dropbox.com/s/c0680m04zynjuug/Space.zi
  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Scaricato e compilato (anche se non ha senso includere file indicando c:\ altrimenti sei costretto a piazzare i file nella root di C).

    Adesso parliamo del problema ... quale e in quale file?
  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Secondo me il problema sta nel file Space.asm nella procedura Crea e Giu, dove vengono gestite le coordinate dei quadrati.
    Le procedure esterne dovrebbero funzionare perché quando ho iniziato a scrivere il programma riuscivo a far scendere un quadrato dall' alto e contemporaneamente spostare il quadrato rosso con le frecce dx e sx. Da quando ho cercato di creare più quadrati e di memorizzare le coordinate di ogni quadrato nei due vettori, non riesco a coordinare la discesa dei quadrati e non capisco dove sto sbagliando...

    Space.jpg
    Space.jpg

    Grazie mille
  • Re: Inserire in 2 Vettori le coordinate di un quadrato

    Mi sono accorto che,se modifico MOV CX,LUNG nella procedura Giu con MOV CX,1, il primo quadrato mi viene giu e gli altri giustamente vengono creati e rimangono fermi, e dunque funziona per il primo quadrato.Ma se però modifico MOV CX,... da 2 in poi non funziona come dovrebbe
Devi accedere o registrarti per scrivere nel forum
15 risposte