ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

di il
20 risposte

ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

Ciao ragazzi,sto studiando assembly(x8086) e mi trovo dinanzi ad un problema a cui non riesco a dare una risposta:come muovermi dentro un doubleword.

ipotizziami che io abbia una variabile(array) del tipo

database DD 121,1233,2334,ETC....

ora so che il doubleword è costituito da 32 bit...di questi 32 bit io voglio accedere esclusivamente ai bit dal 8 al 23 cosi da potere salvare il loro contenuto in un registro AX. Dalla teoria presumo che la memoria si muove sempre un byte alla volta quindi per accedere al suddetto range mi basta scrivere

MOV AX, WORD PTR database[1]

inoltre rifacendomi sempre alla teoria penso che il comando precedente mettere nella parte bassa(AL) i bit dal 8 al 15 e nella parte alta(AH) i bit dal 16 al 23..

confermate il mio ragionamento??? è corretto???

grazie dell'aiuto

20 Risposte

  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    Ciao
    allora iniziamo dalle basi i vettori a prescidere dalle dimensioni iniziano sempre da 0!
    il tuo vettore e costituito dai seguenti elementi 00 00 00 79h,00 00 04 d1h,00 00 09 1eh etc etc
    adesso se tu fai mov ax,word ptr database[1]
    ax = 00 00 perchè
    00 I byte a posizione 0
    00 II byte a posizione 1
    00 III byte a posizione 2
    79 III byte a posizione 3
    adesso se tu vuoi prende il valore devi fare mov ax,word ptr database[2] cosi da prelevare la posizione 2 e la posizione 3 quelle che contengono il valore
    per il prossimo valore dovrai fare, se gia sai che i valori rientrano in una word, + 4 cosi da scartare i valori di 00 00 che precedono i tuoi dati
    esempio:
    .data
    database dd 00000079h,000004d1h,0000091eh,00000afah
    .code
    mov si,2
    mov cx,4
    loop1: mov ax,word ptr [si]
    add si,4
    ; fai quello che vuoi con i dati presi
    loop loop1 
    
    se invece non sai se i dati stiano o meno in una word basta che l' precedente sarà:
    .data
    database dd 00000079h,010004d1h,0004091eh,44000afah
    .code
    mov si,0
    mov cx,4
    loop1: mov ax,word ptr [si]
    add si,2
    ; fai quello che vuoi con i dati presi
    loop loop1 
    
    spero di esserti stato d'aiuto
  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    tanoferr ha scritto:


    confermate il mio ragionamento??? è corretto???
    Sì, questo mi sembra corretto.

    Non ho capito cosa intende smalldragon ... o meglio forse lui non ha letto bene che tu vuoi i due byte di mezzo ...
    In pratica, se

    database DD 0x11223344

    lui vuole ottenente in AX = 2233
  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    Avevo capito che lui volesse prendere i dati numerici e basta
    comunque per prendere i valori di mezzo basta applicare la formula
    (numero record - 1 *4)+2 se sai che i valori sono di tipo word
    altrimenti (numero record - 1 *4)
    data
    database dd 00000079h,010004d1h,0004091eh,44000afah
    numero_record db ?
    .code
    mov byte ptr numero_record,3 
    mov cx,4
    dec byte ptr numero_record
    cmp numero_record,0
    jl label1
    inc byte ptr numero_record
    label1: xor ax,ax
    mov al,numero_record
    mul cx
    mov esi,eax
    add esi,2 ; se sai che la dimensione dei dati e word altrimenti non serve questa riga
    xor eax,eax
    lmov ax,word ptr [si]
    ; fai quello che vuoi con i dati presi
    
    spero di aver colmato la mia precedente lacuna e di aver capito bene!
  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    In realtà hai peggiorato le cose perché lui parla di x8086 quindi niente registri esi o eax o simili ... Ma perché complicare le cose?
  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    .data
    database dd 00000079h,010004d1h,0004091eh,44000afah
    numero_record db ?
    .code
    mov byte ptr numero_record,3
    mov cx,4
    dec byte ptr numero_record
    cmp numero_record,0
    jl label1
    inc byte ptr numero_record
    label1: xor ax,ax
    mov al,numero_record
    mul cx
    mov si,ax
    add si,2 ; se sai che la dimensione dei dati e word altrimenti non serve questa riga
    xor ax,ax
    mov ax,word ptr [si]
    ; fai quello che vuoi con i dati presi
    ecco riportato tutto all' 8086
  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    @smalldragon ... così lo confondi ...

    Non c'è alcun riferimento all'indirizzo base (database) dell'array nel tuo codice, fai strane operazioni con il numero di record, invece di fare due shift a sinistra addirittura scomodi la mul, alla fine non si sa perché incrementi di due, usi xor ax,ax inutili ...

    Insomma, lui voleva solo sapere se era giusto quello che chiedeva, non voleva altro codice non funzionante ...
  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    Hai raggione
    l'errore che ho commesso sta:
     mov ax, word ptr [si]
    deve diventare
    
      mov ax,word ptr database[si]
    
    cosi adesso e funzionante!
    comunque la mul serve per posizionarsi sul elemento di cui si vuol prendere il valore!
    le 2 shift servono solo a scartare gli 0 che non si vogliono.
    la xor serve invece per pulire il registro che dovrà ospitare i dati.
    anche se in realtà non serve visto che stiamo parlando di word. ma e istintivamente pulisco sempre i registri prima di caricarli anche se a volte è inutile.
  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    "Pulire" un registro che caricherai subito dopo non ha alcun senso in programmazione.

    Due shift a sinistra sono equivalenti ad una moltiplicazione per 4.


    P.S. Mi basta aver ragione con una g ...
  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    X i casi del posizionamento per gli elementi 0 - 3 convengono gli shift
    per tutti gli altri casi conviene la mul
    e siccome volevo fare un caso generico l'istruzione giusta era la mul.
  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    Scusa, ma che dici? Giustifica quello che hai scritto perché non capisco. Cosa succede, ad esempio, con l'elemento 4 ?
  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    Allora e molto semplice
    una istruzione shl a memoria x intenderci shl word ptr database[..],1
    impiega 4 cicli di clock
    richiede 2 accessi in memoria
    ed occupa 4 byte
    dovendo effettuare un posizionamento al 4 record
    dovremo fare:
    ;caso 1:
    shl word ptr database[0],1
    shl word ptr database[1],1
    shl word ptr database[2],1
    shl word ptr database[3],1 :solo per il posizionamento
    shl word ptr database[4],1 ; per prendere i dati interessati
    ;caso 2:
    mov cl,4
    shl word ptr database[0],cl
    caso 1:
    5 *4 = 20 cicli di clock
    5*2= 10 accessi in memoria
    5*4= 20 byte impiegati
    caso 2:
    cicli di clock = cicli di clock[caso1]+1
    accessi in memoria = accessi in memoria [caso1]
    byte impiegati = byte impiegati[caso1]+3
    mov cx,4
    mov ax,numero record
    mul cx
    mentre la Mul darà:
    cicli di clock = 1+1+13=15
    nessun accesso in memoria
    byte impiegati minimi = 3+3+2=8
    byte impiegati massimi = 4+4+10
    sapendo ciò ed essendo shl più diretta della mul
    avremo che shl pur rimettendoci con gli accessi in memoria conviene rispetto alla mul
    per quanto riguarda la velocità di esecuzione
    per i primi indici cioè 0-1-2
    12 cicli di clock contro i 15 della Mul
    per l'indice 3 la differenza e minima
    dopo non conviene più!
    mentre se vediamo l'aspetto dei byte utilizzati
    vediamo che l' shl conviene solo per gli indici 0 e 1
    4 contro minimo 8 massimo 10
    e 8 contro minimo 8 massimo 10
    i dati si riferiscono al processore 486 con i nuovi processori si saranno sicuramente accellerate entrambe le istruzioni.
    ma alla fine non cambiano di molto i risultati.
  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    Ma che stai dicendo???

    Perché fai lo shift di database[0], database[1] e così via?

    Cosa c'entra tutto questo?? E' solo sbagliato e confuso. NON devi shiftare i valori da leggere!

    Ti ho SOLO detto di non utilizzare la mul nel calcolo e sostituirlo con due shift e basta.

    Allora, se il tuo numero di record, per comodità, è una word
    
    numero_record dw ?
    
    allora scrivi semplicemente
    
    mov si,numero_record
    shl si,1
    shl si,1
    mov ax,word ptr database[si+1]
    
    e hai finito.

    Siamo alle basi dell'assembly 8086
  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    Il 8086 è un po' limitato, purtroppo niente mov ax, [si+4*bx+1]

    Ma anche senza questo trucco, ci sono soluzioni piu' facili:
    include \masm32\MasmBasic\DosBasic.inc
    .data
    database dd 11223344h, 55667788h, 99AABBCCh
    .code
      Init
      mov si, offset database+1
      .Repeat
    	lodsd	; mov eax, [si] & add si, 4
    	Print Hex$(ax), " ", CrLf$
      .Until si>offset database+1+2*DWORD
      Exit
    end start
    Risultato:
    2233
    6677
    AABB

    Una variante:
      xor bx, bx
      .Repeat
    	mov ax, word ptr database[bx+1]
    	Print Hex$(ax), " ", CrLf$	; DosBasic (puoi utilizzare altre librerie, ovviamente)
    	add bx, 4
      .Until bx>2*DWORD
  • Re: ARRAY DI DOUBLEWORD E TRASFERIMENTO IN UN REGISTRO

    Ma anche ...
    Ma devi usare un ciclo per arrivare all'elemento ennesimo ... non lo fai direttamente come indicato prima.

    Ovvero devi partire da un valore

    numero_record

    0-based , per indicare il valore da ottenere.

    Leggere tutti i valori con un ciclo (step 4) è banale.
Devi accedere o registrarti per scrivere nel forum
20 risposte