Dimensioni

di il
21 risposte

21 Risposte - Pagina 2

  • Re: Dimensioni

    La idiv e la imul sono complementari alle div e mul
    in origine l'idiv e la imul erano delle semplici macro.
    che dopo aver fatto la divisione o la moltiplicazione settavano un flag che stava ad indicare che l'operazione era con segno o meno.
    poi per facilitare l'implementazione dei linguaggi ad alto livello furono trasformate in istruzioni.
    comunque non sono indispensabili e vengono usate in casi particolari.
    di solito vengono usate più dai compilatori che dai programmatori.
    sinceramente ne sconsiglio l'uso perchè funzionano solo con registri o locazioni di memoria non possono essere usate con elementi costanti cosa che invece div e mul possono fare.

    comunque se ti interessa l'assembler vai su questo sito: http://www.giobe2000.i e il migliore che io conosca e poi e pure in italiano il che non guasta.
  • Re: Dimensioni

    smalldragon ha scritto:


    ci avevo già pensato a riscrivere la cin e la cout ma pultroppo non ho le conoscenze sufficienti per poterlo fare!
    Di per se la cout non da molti problemi e sicuramente meno della cin. Comunque puoi partire dalle primitive del C o delle API Windows se non ti interessa la portabilità.
    In C per l'output puoi usare puts() che stampa stringhe pure,
    http://www.cplusplus.com/reference/clibrary/cstdio/puts/
    per l'input puoi usare fgets()
    http://www.cplusplus.com/reference/clibrary/cstdio/fgets/
    per acquisire una stringa di n caratteri, usando stdin come ultimo parametro.
    Usando l'allocazione dinamica della stringa, puoi avere l'input lungo quanto vuoi.
    In ambedue i casi dovrai stabilire un criterio per le procedure di conversione dati a stringa per l'output o da stringa a dati per l'input.
    Per esempio, puts() accetta solo const char* per cui se in uscita vuoi avere "ciao 1234", dove 1234 ti arriva come valore int, non puoi fare: puts("ciao"); puts(1234). Dovrai prima convertire 1234 in const char* usando o una funzione di libreria o una funzione fatta da te.
    Lo stesso vale a rovescio.
    Se non ti interessa la portabilità, le API Windows sono: WriteConsoleA

    (nota che vuole sapere il numero di caratteri da scrivere)

    ReadConsoleA

    da usare più o meno nello stesso modo dopo aver ottenuto l'handle da GetStdHandle

    nella mia povera funzione InsRightParola
    char *cptr e char *dptr ; sono dei puntatori a stringa ma vanno bene anche per i buffer
    sinceramente non vedo la convenienza di utilizzare un puntatore ad un singolo carattere.
    Non è che devi vederne la convenienza: devi vederne il potenziale problema. Chiamare quella funzione passando un puntatore a un singolo carattere è lecito, ma non ha senso. Al linguaggio però non interessa se ha senso o no la chiamata, ma solo se è fattibile o meno.
    la funzione non fa niente altro che aggiungere la stringa dptr alla fine della stringa cptr.
    il dover passare ogni volta le dimensioni delle stringhe sinceramente è una cosa assurda
    non tanto per questa funzione che unisce semplicemente 2 stringhe ma metti caso che ci fossero 10 stringhe da unire sarebbe assurdo ed ingestibile passargli 20 parametri.
    A dire il vero sarebbe assurdo creare una funzione con 10 stringhe: basta ripetere 10 la stessa funzione. Comunque stai facendo un errore di fondo: l'unica stringa di cui devi passare la lunghezza è quella in cui devi scrivere, non quella da cui leggi.
    Convenzionalmente, nelle funzioni che trattano ASCIIZ string, il parametro da cui leggere è const char*, per cui appena si vede tale parametro si capisce già che:
    1) non viene toccato
    2) la lunghezza si determina con strlen(), se il parametro non è NULL.
    non che poi il fatto che normalmente le stringhe vengono sovradimensionate per evitare facili sfondamenti.
    Questo perché in C le stringhe sono array di char NULL terminated (ripeto: NULL terminated. E' fondamentale questo!) e le routine di manipolazione dei buffer erano più semplici da esplicitare in ASM (invece di creare un dato di tipo nuovo).
    In C++ questo è risolto dalla classe std::string.
    anche per questo occorrerebbe un sistema per controllare le dimensioni all'interno delle funzioni.
    Ti ripeto che non è possibile fare questo senza indicare a priori le dimensioni della zona valida. Quando si sfora la zona valida il comportamento è indefinito e questo significa che non sempre si ha un crash. Puoi non avere crash una volta, due volte, n volte; ma alla n+1 si pianta tutto.
    Altre volte funziona due colpi e il terzo no. E' random la cosa.
    Non mi pare sia possibile nemmeno in ASM: perché dovrebbe esserlo in C che è stato pensato per essere un ASM portatile tra le varie architetture di CPU?
    per quanto riguarda l'assembler ti consiglio vivamente di impararlo e un linguaggio bellissimo ed anche semplicissimo.
    Non lo nego, ma il tempo è quel che è. Senza contare che di ASM c'é né uno per CPU, DSP, PIC etc...
    Non si sa mai comunque.
  • Re: Dimensioni

    Grazie per la documentazione vedro un pò di farmi venire qualche idea per migliorare la cin.
    non credo che la cout si possa migliorare più di tanto visto che funziona sotto console.
    con la storia del puntatore al singolo carattere mi hai fatto sorgere altri dubbi.
    1) come poterlo evitare senza usare la classe string in quanto se ricordo bene hanno una dimensione fissa a 255 caratteri e difficilmente mi servono tutti questi caratteri sarebbe uno spreco di memoria. (scusa ma e la mentalità assembler che ritorna!)
    2) come posso controllare che un puntatore punti ad un singolo carattere o a una stringa?

    per quanto riguarda i controlli sarò costretto a farmene una raggione!

    in assembler si poteva assegnare una dimensione non definita ad una stringa è cio si poteva fare in almeno due modi,che io ricordi, anche se era molto ma molto pericoloso si rischiava il crash del programma e raramente se c'erano particolari condizioni anche il crash di sistema.
    i metodi erano :
    1) assegnazione arbitraria di un indirizzo questo era possibile con il programma debug.exe o con i suoi cloni
    2) uso dei bridge si facevano delle routine che dislocassero le varie informazioni.
    esempio
    pippo db 5 dup (?) ;variabile su cui faccio il bridge
    a dw ? ; 2 caratteri
    c dd ? ; 4 caratteri
    ?????????? ; byte sparsi di aggancio del bridge
    adesso con delle routine apposite quando io inserivo pippo una parte del contenuto veniva assegnata alla variabile ed un altra parte veniva dislocata alla fine delle variabili dichiarate.
    cosi si aveva pippo = 3 caratteri inseriti + un puntatore che puntava a ds (segmento dati):pippo+12 e a questa locazione continuava la stringa.
    queste procedure erano usate come protezione contro le manomissioni dei programmi.
    questo sistema, cosi come te lo descritto, poteva mandava in crash solo i programmi ma ti assicuro che c'erano altri tipi di bridge che ti potevano mandare in crash il sistema.
    il sostanziale vantaggio oltre ad avere stringhe infinite era anche quello che con questo sistema si potevano passare i dati hai vari sotto programmi che poi li gestivano come meglio volevano.
    ciò avveniva perchè il programma veniva caricato in memoria e la memoria che non veniva allocata sepur scritta quando il programma terminava non si perdeva.
    così i dati restavano a disposizione di tutti i programmi che successivamente venivano lanciati bastava far puntare una variabile a quell'area e il passaggio dei parametri era bello e fatto.
    non credo che col c/c++ ma anche in assembler attuale si possa più fare una cosa del genere.
    sotto questo punto di vista hanno fatto bene.
    comunque se ti piace l'elettronica ti consiglio l'assembler dei pic cosi puoi capire anche meglio il funzionamento del computer e l'interfacciamento delle periferiche. e una gran ficata!
  • Re: Dimensioni

    smalldragon ha scritto:


    grazie per la documentazione vedro un pò di farmi venire qualche idea per migliorare la cin.
    non credo che la cout si possa migliorare più di tanto visto che funziona sotto console.
    Il massimo che si possa fare riguardo l'output è colorare l'output e la posizione del cursore usando le API Windows. Vedi qui:
    http://mariusbancila.ro/blog/2008/11/28/helper-class-for-console-functions/
    in fondo al post c'è il link con il sorgente.
    1) come poterlo evitare
    senza usare la classe string in quanto se ricordo bene hanno una dimensione fissa a 255 caratteri e difficilmente mi servono tutti questi caratteri sarebbe uno spreco di memoria.
    Puoi evitarlo solo scrivendo nella documentazione che il passare un puntatore a singolo carattere provoca le leggendarie 10 piaghe d'Egitto. Per quanto riguarda le std::string nessuna implementazione è così pazza da usare così tanti caratteri fissi. Al massimo alcune implementazioni forniscono 16 caratteri fissi, se poi si supera tale quantità la stringa viene riallocata dinamicamente. Il motivo (presunto) è che spesso le stringhe sono inferiori a 16 caratteri per cui si risparmia una allocazione dinamica del buffer interno. Dato che le allocazioni dinamiche sono più lente delle allocazioni su stack, si preferisce sprecare qualche bytes ma guadagnare in rapidità di esecuzione. E' comunque un dettaglio implementativo, per cui può capitare che un compilatore fornisca una std::string implementata come ti ho detto mentre un altro preferisca adottare un approccio totalmente dinamico.
    2) come posso controllare che un puntatore punti ad un singolo carattere o a una stringa?
    Semplice: non puoi. Se io ti scrivo (copiando):
    
    push edi
    mov edi, cptr
    
    sei in grado di dirmi da questa singole istruzioni se cptr è un array di caratteri o un singolo byte di quell'array di caratteri? Lo stesso vale in C.
    (Tieni sempre presente che in modalità release, le routine base tipo strcpy, memcpy etc... sono scritte in ASM. Le versioni in C code più che altro sono per debug.)
    per quanto riguarda i controlli sarò costretto a farmene una raggione!
    C'è di peggio, credimi.
  • Re: Dimensioni

    Grazie per l'ulteriore documentazione
    ti credo che c'è di peggio dei controllo lo sto sperimentando.
    comunque la sequenza
    push edi
    mov edi,cptr
    normalmente ciò si intendere nella seguente maniera:
    metto un indice nel registro edi che poi presumibilmente mi servira per indicizare un array.
    quindi in questo caso cptr e una variabile anche se ipoteticamente fosse un vettore si comporterebbe come se fosse una variabile normale caricando in edi la prima dword del vettore.

    perchè in assembler i vettori hanno bisogno dell'indicizazione indiretta esempio
    mov edi,offset cptr ; in questo caso e una dichiarazione esplicita
    oppure 
    mov edi,[cptr] ; in quest altro caso e implicita ma puo anche essere intesa come nel c++ 
    indirizzamento ad array di un solo carattere perchè vado a riempire edi con la locazione che mi da il dato contenente nella variabile cptr.
    poi c'è lindirizzamento implicito normale
    esempio : mov edi,cptr[ebx] ; in questo caso edi acquisisce il byte del vettore cptr ed indicizato da ebx equivale alla struttura c++
    a = cptr[indy] ; dove a e una semplice variabile ed indy e l'indice del vettore
    in assembler i vettori vengono gestiti in maniera simile al c++ utilizzando i puntatori.

    come vedi l'assembler non è poi così astruso come vogliono far credere e sicuramente lo è meno del c++.
    comunque cercherò di non impazzire con tutte queste stranezze del c++
  • Re: Dimensioni

    smalldragon ha scritto:


    normalmente ciò si intendere nella seguente maniera:
    metto un indice nel registro edi che poi presumibilmente mi servira per indicizare un array.
    Appunto, presumibilmente è la parola magica.
    in assembler i vettori vengono gestiti in maniera simile al c++ utilizzando i puntatori.
    Mi stupirebbe il contrario: se ti ricordi ho detto che il C è considerato un ASM portabile tra le diverse architetture hardware.
    come vedi l'assembler non è poi così astruso come vogliono far credere e sicuramente lo è meno del c++.
    Anche qui mi stupirei del contrario. Specie considerando che al momento il C++ (non il C bada bene) è il linguaggio più complesso sul mercato.
    comunque cercherò di non impazzire con tutte queste stranezze del c++
    Ci si abitua. L'importante è prenderlo a piccole dosi, perché nuoce gravemente alla salute.
  • Re: Dimensioni

    Per caso sai come si compila un modulo assembler sotto visual studio 2012?
    e poi una volta creato .obj come faccio ad agganciarlo,cioè a compilarlo, ad un programma c++.
    però non inserimi link che portino a guide microsoft che se loro fanno le guide comprensibili io sono dante alighieri, quello della divina commedia!
Devi accedere o registrarti per scrivere nel forum
21 risposte