Visualizzazione dei risultati da 1 a 4 su 4
  1. #1

    [Assembler] programmino

    Salve ragazzi,
    So che può essere insolito leggere problemi che come soggetto abbiano il linguaggio di programmazione assembler ma ultimamente mi e' capitato di dover aiutare mio nipote alle superiori.
    L'ho studiato anche io (circa 14 anni fa XD) quindi tra trapassato, memoria e passaggi poco chiari qualcosa proprio non mi torna... in particolare su questo programma per l'8086 dove si utilizzano soltanto le istruzioni di MOV ed i vari JUMP

    il problema è il seguente, si hanno 20 numeri (Byte) a partire dal registro 0200
    e di questi 20 numeri si vogliono sapere quanti sono 0 e quanti <> 0 il risultati vanno posti nei registri 0300 e 0301.
    Nel registro BX inseriremo proprio 0200 e nei DL e CH i risultati che andranno in 0300 e 0301
    In CL inseriamo il numero di confronti da effettuare (abbiamo detto 20 numeri quindi 14 in esadecimale)

    l'idea sarebbe quella di valutare il primo elemento se 0 incrementare DL altrimenti incrementare CH, Decrementare CL e ripetere la cosa finché CL non diventa 0

    fin qui tutt'ok ma il codice in alcune parti proprio non mi è chiaro e ve lo riporto:

    1 Mov BX, 0200
    2 Mov CL, 14
    3 Mov DL, 0
    4 Mov CH, 0 ;fino a qui tutto chiaro azzeriamo i due registri e mettiamo 0200 e 14 (20in decimale in CL
    5 Mov AL, [BX] ; mettiamo in AL il contenuto del registro BX (AL in teoria è 8 bit mentre il contenuto di BX non dovrebbe essere a 16 bit?)
    6 Mov AL, 00 ; che senso ha se si e' appena inserito il contenuto di BX?
    7 JE5 ;Salta se operatore1 = operatore2 (questo salto non mi e' chiaro)
    8 INC DL
    9 INC BX
    10 DEC CL
    11 JNE 5 ; Salta se l'operatore1 <> operatore2 (se flag zero è 0)
    12 MOV [0301], DL
    13 MOV [0300], CH ; mette i risultati nei rispettivi registri
    14 INT 20 ;e in questo caso finirebbe il programma
    15 INC CH ; altrimenti incrementa CH (dovrebbe essere)
    16 JMP 9
    17 INC BX
    18 DEC CL ; passiamo al numero successivo e decrementiamo i numeri da confrontare
    19 JNE 5
    20 MOV [0300], CH
    21 INT 20

    se qualcuno mi chiarisse le idee (mi rinfrescherebbe alla grande la memoria XD) ne sarei veramente grato

  2. #2

    Re: [Assembler] programmino

    Originariamente inviato da Vincent81
    il problema è il seguente, si hanno 20 numeri (Byte) a partire dal registro 0200
    Quel 0200 non è un registro, ma sicuramente è inteso come indirizzo di memoria. Quindi alla locazione di memoria 0200 parte l'array di byte (se li vuoi di un byte non puoi superare 255 altrimenti devi farli di 2 byte).

    Intanto perchè usa i valori numerici come indirizzi di memoria?
    Credo che all'inizio del codice allochi delle variabili, facendo tipo

    codice:
    array_numeri db 1,3,56,15,48,15,48,98,15 ;,ecc... questo è un array di byte (8 bit), se volessi allocare un array di interi (per numeri maggiori di 255) devi usare dw al posto di db). E' l'indirizzo 0200 (non usare cmq l'indirizzo ma usa la label array_numeri e poi ci pensa il compilatore a convertirli in indirizzi
    diversi_da_zero db 0 ;dovrebbe essere il tuo indirizzo 0300 - ovviamente array_numeri non può contenere piu' di 255 numeri altrimenti il contatore non basta piu'
    uguali_a_zero db 0 ;dovrebbe essere il tuo indirizzo 0301 - ovviamente array_numeri non può contenere piu' di 255 numeri altrimenti il contatore non basta piu'
    Poi invece di scrivere

    1 Mov BX, 0200

    sarebbe meglio fare

    codice:
    1 Mov BX, array_numeri ; così setti bx con l'indirizzo del primo valore da controllare (che devi sempre incrementare per controllare il valore successivo
    Originariamente inviato da Vincent81
    e di questi 20 numeri si vogliono sapere quanti sono 0 e quanti <> 0 il risultati vanno posti nei registri 0300 e 0301.
    Nelle locazioni di memoria 0300 e 0301 (che sono numeri decimali non esadecimali).
    Usa cmq uguali_a_zero e diversi_da_zero

    Originariamente inviato da Vincent81
    fin qui tutt'ok ma il codice in alcune parti proprio non mi è chiaro e ve lo riporto:

    1 Mov BX, 0200
    2 Mov CL, 14 questo è un numero decimale quindi effettivamente leggi 14 numeri, per scrivere l'esadecimale devi aggiungere h alla fine, quindi scrivere 14h
    3 Mov DL, 0
    4 Mov CH, 0 ;fino a qui tutto chiaro azzeriamo i due registri e mettiamo 0200 e 14 (20in decimale in CL
    5 Mov AL, [BX] ; mettiamo in AL il contenuto del registro BX (AL in teoria è 8 bit mentre il contenuto di BX non dovrebbe essere a 16 bit?) non ci metti il contenuto di bx, ma il valore puntato dall'indirizzo in memoria dal registro bx. se avessi fatto mov bx, array_numeri il valore in al sarebbe stato il primo numero nell'array
    6 Mov AL, 00 ; che senso ha se si e' appena inserito il contenuto di BX?
    7 JE5 ;Salta se operatore1 = operatore2 (questo salto non mi e' chiaro)
    8 INC DL
    9 INC BX
    10 DEC CL
    11 JNE 5 ; Salta se l'operatore1 <> operatore2 (se flag zero è 0)
    12 MOV [0301], DL
    13 MOV [0300], CH ; mette i risultati nei rispettivi registri
    14 INT 20 ;e in questo caso finirebbe il programma
    15 INC CH ; altrimenti incrementa CH (dovrebbe essere)
    16 JMP 9
    17 INC BX
    18 DEC CL ; passiamo al numero successivo e decrementiamo i numeri da confrontare
    19 JNE 5
    20 MOV [0300], CH
    21 INT 20

    se qualcuno mi chiarisse le idee (mi rinfrescherebbe alla grande la memoria XD) ne sarei veramente grato
    Prima dei jump devi modificarlo quel flag Zero usando cmp, che compara 2 registri.
    lolide
    Java Programmer

    Informati

  3. #3
    Grazie lolide per i consigli.
    Anche a me molte cose non risultano chiare, ti informo che questo programma è un compito corretto in classe dal professore di mio nipote quindi non mio.
    Riprendendo un po' l'assembly tra le mani ho notato subito anche io alcune incongruenze come i numeri esadecimali espressi senza h e lo strano utilizzo dei jump senza ancora aver studiato il confronto.

    Però leggendo sto cercando di capire una cosa.
    I Jump si possono comunque utilizzare senza confronti ma andando a valute i flag che vengono impostati a seguito di operazioni logico matematiche. Quindi ad esempio l'operazione MOV AL,00 modificherà qualcosa e in base al risultato effettuerà il salto condizionato JE 5.

    Mi sapreste quindi ricordare cosa genera l'istruzione MOV AL,00 (considerando che il passaggio precedente era MOV AL, [BX]?

  4. #4
    Sai che penso io ... che abbia sbagliato, invece di mov voleva usare cmp.

    cmp al,0 avrebbe un senso, mentre mov al, 0 non ha proprio senso e poi mov non influenza i registri flag
    lolide
    Java Programmer

    Informati

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.