Memoria

di il
28 risposte

28 Risposte - Pagina 2

  • Re: Memoria

    smalldragon ha scritto:


    vedo di farti un esempio per farti capire.
    Non mi hai fatto capire con quell'esempio, anzi hai complicato le cose.

    Intanto non capisco perché hai voluto mischiare codice sorgente C++ e sorgente Assembly se le due cose si possono più comodamente integrare in un unico sorgente C++ con la keyword _asm.

    Poi penso che tu non l'abbia neanche provato dato che fai una call a geteip ma nel codice esiste solo una label getip ... quanto meno avrebbe dovuto darti un errore in compilazione (anzi in fase di linking).

    Infine, tutto il (confuso) discorso sul modello flat mi lascia perplesso (anche dopo circa 30 anni di programmazione assembly) dato che proprio il modello flat presuppone un unico segmento dati e un un unico segmento di codice (proprio per questo flat!).
    Che c'entri poi un cambio di segmento per una chiamata di funzione che sta a pochi byte di distanza non lo capisco proprio.

    Comunque, il tuo codice, se scritto correttamente, funziona come dovrebbe e ottiene il valore dell'EIP al momento dell'esecuzione della pop. Ovvero
    
    #include <iostream>
    #include <iomanip>
    
    using namespace std;
    
    int eipstart=0;
    
    int pleftstringa(char *arg1, char *arg2, int arg3)
    {
    	_asm
    	{
    		call geteip
    	geteip:
    		pop eipstart
    
    		mov ecx,arg3
    		mov edi,arg2
    		mov esi,arg1
    
    		cmp ecx,0
    		jne uno
    		mov eax,2
    		jmp short fine
    uno:
    	    cmp byte ptr [esi],0
    		jne due
    		mov eax,1
    		jmp short fine
    due:
    		xor eax,eax
    		rep movsb
    		mov dword ptr [edi],0
    fine:
    	}
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	char pippo[71],pluto[68];
    	int ncar,indy,kindy,err,opz;
        ncar=0; err=0; kindy=0; opz=0;
        
    	for (indy=0;indy < 71;indy++) { pippo[indy]=' '; }
        
    	for (indy=0;indy < 68;indy++) { pluto[indy]=' '; }
    	
    	cout << "inserisci stringa una stringa max 70 caratteri : ";
    	cin.getline(pippo,71);
    	
    	cout << "quanti caratteri vuoi prendere ? ";
        cin >> ncar;
    
    	err = pleftstringa(pippo,pluto,ncar);
    	
    	cout << "hai preso i seguenti caratteri : " << pluto << "\n";
    	cout << "eip start : 0x" << hex << eipstart << endl;
    
    	return 0;
    }
    
    Fermo restando che, se non comprendi bene il mio suggerimento e non ti fidi, sei padrone di adottarne un altro.

    Oppure, se vuoi che la chiamata a getip riguardi una funzione esterna allora
    
    int geteip()
    {
    	_asm mov eax,[ebp+4]  // return address in stack frame
    }
    
    int pleftstringa(char *arg1, char *arg2, int arg3)
    {
    	_asm
    	{
    		call geteip
    		mov eipstart,eax
    
    		mov ecx,arg3
    		mov edi,arg2
    		mov esi,arg1
    ...
    
  • Re: Memoria

    Allora nel codice che avevo postato c' era un errore che ho fatto quando lo trascritto.
    avevo scritto all'interno del asm
    getip: invece di geteip:
    scusami e stata un distrazione.
    poi non poteva funzionare perchè la routine LenStringa non c'è all'interno del codice cheavevo inserito.
    comunque errore a parte non uso utilizzare la keyword _asm semplicemente perchè cosi capisco meglio dove sono gli errori e mi è più facile correggerli.
    da quanto mi fai capire se un file esterno viene compilato in un modo mentre la keyword _asm viene compilata in un altro deduco che o il compilatore ml (masm attuale),premetto che il prodotto che ho e originale, e un pezzotto o il pezzotto è la Keyword _asm visto che non riesco a capirlo uso ciò che capisco e l' ml e quanto al momento e più vicino hai vecchi e adorabili .asm compilati con masm e tasm!
    comunque il problema che ti volevo spiegare ahime non ci sono riuscito spero di riucirci adesso è:
    vedi righe circondate dagli asterischi
     \file .cpp
        #include "stdafx.h"
        #include "iostream"
        using std::cin;
        using std::cout;
        using std::endl;
        extern "C" int __stdcall LenStringa(char*);
        extern "C" int __stdcall pleftstringa(char *,char *,int);
        int _tmain(int argc, _TCHAR* argv[])
          {
        char pippo[71],pluto[68];
        int ncar,indy,kindy,err,opz;
                ncar=0; err=0; kindy=0; opz=0;
            for (indy=0;indy < 71;indy++) { pippo[indy]=' '; }
            for (indy=0;indy < 68;indy++) { pluto[indy]=' '; }
        cout << "inserisci stringa una stringa max 70 caratteri : ";
            cin.getline(pippo,71);
        cout << "quanti caratteri vuoi prendere ? ";
                          cin >> ncar;
                          err = pleftstringa(pippo,pluto,ncar);
        cout << "hai preso i seguenti caratteri : " << pluto << "\n";
                                         return 0;
        }
    file .asm
    .486
         .model flat,stdcall
          option casemap :none
         .code
         pleftstringa PROC Arg1:DWORD,Arg2:DWORD,Arg3:DWORD
              ; adesso se aggiungo
                                     ;*********************************************************************
                    call geteip  ; la procedura termina all interno della subroutine e non dovrebbe farlo.
                                     ;*********************************************************************
                   mov ecx,Arg3 ; da qui in poi non mi esegue più nulla perchè il programma e gia terminato. cosa che non dovrebbe accadere.
                    mov edi,Arg2
                    mov esi,Arg1
                    cmp ecx,0
                    jne uno
                    mov eax,2
                    jmp short fine
                uno:
                    cmp byte ptr [esi],0
                    jne due
                    mov eax,1
                    jmp short fine
                due:
                    xor eax,eax
                    rep movsb
                    mov dword ptr [edi],0
               fine:
                         ;**********************************************************************************
                    ret ; il programma dovrebbe terminare qui ma non lo fa!
                         ;************************************************************************************
               geteip:
                        pop eax
                        push eax
                        mov ebx,6
                             ;******************************************************************************************** 
                        ret ; il programma termina qui! anche se non dovrebbe farlo!
                             ;*******************************************************************************************
          pleftstringa endp
                      end
    
  • Re: Memoria

    smalldragon ha scritto:


    allora nel codice che avevo postato c' era un errore che ho fatto quando lo trascritto.
    avevo scritto all'interno del asm
    getip: invece di geteip:
    scusami e stata un distrazione.
    poi non poteva funzionare perchè la routine LenStringa non c'è all'interno del codice cheavevo inserito.
    Veramente la LenString continui a dichiararla ma non c'è e non la usi ... poco male.
    comunque errore a parte non uso utilizzare la keyword _asm semplicemente perchè cosi capisco meglio dove sono gli errori e mi è più facile correggerli.
    Ti consiglio invece di utilizzarla in quanto, al contrario, ti risparmi un sacco di errori e lasci al compilatore la gestione del preambolo, dello stack frame e del codice di terminazione (tutti argomenti chiave nell'interazione tra codice C/C++ e Assembly).
    da quanto mi fai capire se un file esterno viene compilato in un modo mentre la keyword _asm viene compilata in un altro
    Non è proprio così ...
    visto che non riesco a capirlo uso ciò che capisco
    è così ...
    vecchi e adorabili .asm compilati con masm e tasm!
    Se usi unicamente il macro assembler devi seguire certe regole, se integri del codice assembly all'interno di codice C/C++ devi seguire anche altre ... non c'è nulla di "adorabile" o "detestabile" ma semplicemente delle regole da seguire.
    comunque il problema che ti volevo spiegare
    Ti spiego perché ti succede ...

    Come ti ho detto prima, quando integri codice con la keyword _asm in un sorgente C/C++ non ti interessi (tanto) del codice che devi usare per l'ingresso/uscita dalle funzioni perché ci pensa il compilatore C/C++ (a meno di eccezioni per codice particolare).

    Con il codice contenuto in un file .asm e completamente trattato dal macro assembler, devi fare più attenzione. In quel caso non puoi fare una call (la call a geteip) all'interno della funzione pleftstringa perché il macro assembler assume per la geteip un codice di uscita per lo stack frame uguale a quello della funzione pleftstringa e non va bene.

    Rimedi semplicemente scrivendo la corretta dichiarazione per la geteip, ovvero
    
    geteip proc
    	pop eax
    	push eax
    
    	ret
    geteip endp
    
    ovviamente *dopo* la

    pleftstringa endp

    e prima della

    end

    P.S. Non capisco a cosa ti serva quella mov ebx,6 ... toglila
  • Re: Memoria

    Ho capito alla fine quelli della microsoft e company hanno deciso di pezzottare i compilatori asm a favore del c++.
    comunque la funzine lenstringa è definita esternamente con un altro sorgente asm perchè mi serve anche come funzione per il c++.

    oregon ha scritto:


    P.S. Non capisco a cosa ti serva quella mov ebx,6 ... toglila
    serve per conteggiare i byte che la ex subroutine che adesso dovrò trasformare in funzione occupa in memoria.
    se la levo la routine non viene conteggiata1
    in quanto la call mette nello stack l'indirizzo di ritorno del programma di conseguenza quando alla fine dovorò fare fine - inizio potrei incorrere nel non conteggio della stessa ex subroutine.
    in quanto, di solito, i compilatori usano mettere le funzioni esterne al programma alla fine,dopo il termine del programma, questo lo fanno perchè cosi e più facile è più veloce costruire l'eseguibile.
    anche per questo motivo la tecnica della pop non va bene perchè non calcolerebbe le funzioni esterne ma soloil flusso del programma.
    la cosa più scocciante e che dovrò calcolare a mano l'ammontare di ogni funzione, per quelle che faccio io in assembler potrei pure farlo.
    ma per le funioni di libreria, non mie, scritte in c++ o in assembler come potrei fare?

    visto che non mi viene un altro metodo per calcolare la dimensione del programma.
    comunque la funzione dovrebbe essere grosso modo così
    
    prendi_eip proc near 
            pop eax    ; prendo eip (1 byte perchè sfrutto un registro)
            push eax  ; rimetto a posto eip per non combinare casini! (1 byte)
            sub eax,3 ; levo 3 all' indirizzo eip perchè devo cominciare dalla prima istruzione e non da quella successiv che invece eip mi fornisce. (sono 3 byte perche uso unregistro e una costnte)
            inc ecx ; questo mi serve come flag per non conteggiare 2 volte la funzione.
    ; se al ritorno ecx > 1 allora la funione non sarà conteggiata (1 byte perchè uso un registro) 
            mov ebx,10 ; conterrà gli eventuali byte della routine (l'istruzione occupa 3 byte)
            ret (fine funzione occupa 1 byte)
    prendi_eip endp
    endp
    

    Se usi unicamente il macro assembler devi seguire certe regole, se integri del codice assembly all'interno di codice C/C++ devi seguire anche altre ... non c'è nulla di "adorabile" o "detestabile" ma semplicemente delle regole da seguire.
    il problema è che hanno cambiato le regole perchè ti assicuro che una volta si poteva fare sia in assembler puro e sia nell'interfaccimento con il c++.
  • Re: Memoria

    smalldragon ha scritto:


    ho capito alla fine quelli della microsoft e company hanno deciso di pezzottare i compilatori asm a favore del c++.
    Ma neanche per sogno. Non diamo la colpa sempre a Microsoft ... non c'entra nulla ... i vari compilatori fanno il loro lavoro bene e non c'è un favore per qualcosa e non per altro ...

    Tutte fantasie.
    serve per conteggiare i byte che la ex subroutine che adesso dovrò trasformare in funzione occupa in memoria. se la levo la routine non viene conteggiata1
    Beh, ancora non ho capito come tu voglia conteggiare le dimensioni del codice di ogni funzione.
    Fino ad ora ho pensato che facessi una cosa del genere

    --- Inizio funzione ... richiamo geteip e conserva il valore in eipstart
    ...
    --- Fine funzione ... richiamo geteip e calcolo eip_attuale-eipstart

    In questo calcolo non devi includere la dimensione della funzione geteip perché è usata per la misura, non fa parte del tuo programma.
    in quanto, di solito, i compilatori usano mettere le funzioni esterne al programma alla fine,dopo il termine del programma, questo lo fanno perchè cosi e più facile è più veloce costruire l'eseguibile.
    anche per questo motivo la tecnica della pop non va bene perchè non calcolerebbe le funzioni esterne ma soloil flusso del programma.
    Beh, mi sembrava scontato che si esaminasse solamente il tuo codice e non quello di libreria.
    Per quello di libreria non c'è modo di farlo.
    ma per le funioni di libreria, non mie, scritte in c++ o in assembler come potrei fare?
    Ripeto, non puoi.
    il problema è che hanno cambiato le regole perchè ti assicuro che una volta si poteva fare sia in assembler puro e sia nell'interfaccimento con il c++.
    Cosa si poteva fare? Anche adesso si può fare tutto con l'assembly (assembler è il compilatore) e non mi pare sia cambiato nulla di particolare ... ti assicuro anch'io che di assembly ne ho visto nella mia vita.
  • Re: Memoria

    oregon ha scritto:


    Cosa si poteva fare? Anche adesso si può fare tutto con l'assembly (assembler è il compilatore) e non mi pare sia cambiato nulla di particolare ... ti assicuro anch'io che di assembly ne ho visto nella mia vita.
    mi dispiace che hai dimenticato quello che si poteva fare con l'assembler. e pultroppo ora non lo si può più fare!

    per esempio (tornando al problema)
    ti assicuro che è cosi
    perchè una volta si poteva fare questo:
    
    prima proc near
     ; muovevo i segmenti negli appositi registri
    call a
    call b
    ........ ;(altro codice
    ........
    .........
    ..........
    jmp fine_programma
    a:
    ..... ; istruzioni del suo scopo
    ret
    b:
    ..... ; istruzioni del suo scopo
    ret
    fine_programma
    ;uscita
    prima endp
    end
     
    adesso non lo si puo più fare a meno che le routine non siano esterne al programma
    questo vuol dire che prima la tecnica della pop iniziale davanti e di quella finale ti restituiva l'esatta quantità di memoria del tuo programma.
    sotto questo punto di vista il compilatore asm lo hanno pezzottato a vantaggio del c++ e so anche il perchè!
    semplicemente perchè così, come hanno fatto, e più facile gestire i parametri.
    in quanto avendo un indirizzo fisso nello stack hanno risolto il conflitto tra rientri e parametri che prima angosciava parecchi programmatori soprattutto quelli c++ che si dovevano cimentare con l'assembler.
    poi un altro pezzotto che hanno fatto e l'accesso agli indirizzi fissi hardware e l'eliminazione o meglio la protezione alle funzioni basi di sistema quali ad esempio int 21h,int 15h etc etc.
    ma oltre a questi ce ne sono molti altri.

    lo scopo della mia funzione e quello di far vedere quanto spazio occupa in memoria un programma e quindi se uso delle funzioni esterne, anche non mie, anche quelle faranno parte del programma e quindi dovranno essere conteggiate.
    se la funzione non calcolasse le funzioni esterne non avrebbe senso in quanto a parte le funzioni esterne conoscendo le strutture che hai pui facilmente calcolarti, anche se maniera approssimativa, quanti byte occupa il tuo programma.
    per esempio un ciclo for standard se lo sai ottimizzare ti occupa non più 6 byte + le istruzioni del blocco.
    una if semplice (if a = b) ti occupa grosso modo 9 byte + istruzioni del blocco.
    vorrà dire che se non trovo un altro sistema dovrò rinunciare alla funzione.
    visto che la sola velocità non basta per giudicare una funzione.
  • Re: Memoria

    smalldragon ha scritto:


    mi dispiace che hai dimenticato quello che si poteva fare con l'assembler. e pultroppo ora non lo si può più fare!
    Mi sa che sei veramente fuori strada ... (assembly! assembler è il compilatore! ... e si scrive purtroppo ...)
    una volta si poteva fare questo:
    E si può fare ancora ... chi lo vieta ? Scusa se te lo dico ... ma non sai quello che dici !
    adesso non lo si puo più fare a meno che le routine non siano esterne al programma
    Al programma? A quale programma ?

    Te lo dico ancora ... sei fuori strada ...
    il compilatore asm lo hanno pezzottato a vantaggio del c++ e so anche il perchè!
    Completamente fuori strada ...
    poi un altro pezzotto che hanno fatto e l'accesso agli indirizzi fissi hardware e l'eliminazione o meglio la protezione alle funzioni basi di sistema quali ad esempio int 21h,int 15h etc etc.
    Ma che stai dicendo ???

    Sei rimasto alla modalità "reale" in cui girava la CPU con il vecchio DOS !
    Hai idea della differenza tra modalità "reale" e "protetta" del funzionamento delle CPU x86 e della loro evoluzione?

    Mi sa che hai molte, moltissime lacune teoriche sul funzionamento delle CPU e comunque, a basso livello di un computer (e di un sistema operativo) moderno.
    Se proprio vuoi avventurarti in scrittura di un device driver o di codice a ring 0 (modalità kernel) puoi farlo e avere tutto a disposizione.

    I "pezzotti" sono solo tue fantasie ...
    lo scopo della mia funzione e quello di far vedere quanto spazio occupa in memoria un programma e quindi se uso delle funzioni esterne, anche non mie, anche quelle faranno parte del programma e quindi dovranno essere conteggiate.
    In questo modo NON potrai mai farlo. Puoi solo controllare il tuo codice (ed ha anche un senso). Il resto è solo fantasia.
    vorrà dire che se non trovo un altro sistema dovrò rinunciare alla funzione.
    Sì .. rinuncia.

    Scusami se te lo ripeto e non te la prendere a male (non te lo dirò più).

    Tu hai una "vaga" conoscenza del mondo assembly e di cosa ci sta dietro ... ti consiglio di approfondire molto con testi e manuali (magari proprio i manuali dei produttori di CPU).
  • Re: Memoria

    prima proc near
    ; muovevo i segmenti negli appositi registri
    call a
    call b
    ........ ;(altro codice
    ........
    .........
    ..........
    jmp fine_programma
    a:
    ..... ; istruzioni del suo scopo
    ret
    b:
    ..... ; istruzioni del suo scopo
    ret
    fine_programma
    ;uscita
    prima endp
    end
    quel esempio di sopra ora lo puoi fare solo o se usi la keyword _asm o se definisci a e b come proc il che in molti casi non ha un gran senso.
    1) perchè se lo scrivi con _asm poi lo devi includere in tutte le tue routine con sempre più frammentazione del codice sorgente come se non bastassero le include necessarie per fare qualcosa di decente c++.
    2) e' inutile e molto senza senso scrivere funzioni esternamente o meglio dichiararle esterne se poi ti servono internamente non è che uno spreco di memoria! e le ottimizzazioni se ne vanno a quel paese.

    certo che conosco la differenza tra modalità reale e quella protetta.
    fidati che il compilatore e stato riscritto ed hanno fatto come minimo quelle modifiche che ti ho detto.
    comunque se già sai approssimativamente quanto spazio occupa in memoria il tuo codice a che ti serve se non puoi sapere la realtà?
    Cosa si poteva fare? Anche adesso si può fare tutto con l'assembly (assembler è il compilatore) e non mi pare sia cambiato nulla di particolare ... ti assicuro anch'io che di assembly ne ho visto nella mia vita.
    si potevano fare tante cose per esempio
    1)non lascire sempre attive le librerie che se per un malaugurato caso perdi la dll di turno il programma non funziona. (tutta memoria che molto spesso viene buttata!)
    2)lasciare libero accesso all' hardware senza dover sottostare alle loro librerie di accesso.
    3) lasciare la possibilità di poter sviluppare in assembler non solo routine ma interi programmi senza dover ricorrere al c++ o a sue librerie.
    e molte altre cose.
    comunque per i punti 2 e 3 posso capire le raggioni visto che l'hanno fatto per raggioni commerciali.
    comunque per tua informazione di manuali di microprocessori tengo tutti i microprocessi della intel dal 8080 al intel quad core tutti targati intel compresi schemi elettronici data shett compresi che ho tutti studiato sia a livello di programmazione che in fase elettrica.
    ho pure dei materiale sui processori amd
    ho pure manuali di assembler mips e mvs in questo caso pero ho solo la parte della programmazione non ho i data sheet.
    se vuoi qualche manuale su qualche microprocessore non hai che da chiedere.
    comunque mi è venuta un altra idea su come risolvere il problema della funzine.
  • Re: Memoria

    smalldragon ha scritto:


    quel esempio di sopra ora lo puoi fare solo o se usi la keyword _asm o se definisci a e b come proc il che in molti casi non ha un gran senso.
    Primo ... non è vero, se sai programmare in assembly, puoi farlo.
    Secondo ... non capisco perché non abbia senso comunque con la proc.
    1) perchè se lo scrivi con _asm poi lo devi includere in tutte le tue routine con sempre più frammentazione del codice sorgente come se non bastassero le include necessarie per fare qualcosa di decente c++.
    E che c'entrano le include con la "frammentazione" ???
    2) e' inutile e molto senza senso scrivere funzioni esternamente o meglio dichiararle esterne se poi ti servono internamente non è che uno spreco di memoria! e le ottimizzazioni se ne vanno a quel paese.
    "Esterne" ? A che? Ottimizzazioni "a quel paese" ... e perché mai???

    Mi sembra che tu stia farneticando, non sapendo esattamente quello che dici.
    fidati che il compilatore e stato riscritto ed hanno fatto come minimo quelle modifiche che ti ho detto.
    Sì, è i marziani stanno nell'area 51 ... ma finiamola ... cerchiamo di essere seri.
    si potevano fare tante cose per esempio
    1)non lascire sempre attive le librerie che se per un malaugurato caso perdi la dll di turno il programma non funziona. (tutta memoria che molto spesso viene buttata!)
    Eh???? Ma che dici? Ma che stai dicendo????
    Che vuol dire "lasciare attive le librerie" ???
    Ti stai inventando una tua informatica e una tua programmazione o semplicemente non capisci quello che scrivi???
    2)lasciare libero accesso all' hardware senza dover sottostare alle loro librerie di accesso.
    Questa frase vuol dire che tu non hai capito veramente nulla di modalità reale e di modalità protetta ... E' la CPU che ti vieta l'accesso diretto all'hardware se il tuo software non lavora a "ring 0". E dato che a "ring 0" gira solo il kernel e i driver, il modo per accedere all'hardware esiste ed è semplice ... scrivi un driver (in C, in assembly o con tutti e due i linguaggi) e accedi a quello che vuoi senza chiedere nulla a nessuna libreria!
    3) lasciare la possibilità di poter sviluppare in assembler non solo routine ma interi programmi senza dover ricorrere al c++ o a sue librerie.
    E chi te lo vieta??? Forse perché non lo sai fare ...
    comunque per i punti 2 e 3 posso capire le raggioni visto che l'hanno fatto per raggioni commerciali.
    Ragioni (con una sola g) commerciali per cosa???? Per la modalità protetta???

    Stai farneticando ...
    data shett
    datasheet ....
    se vuoi qualche manuale su qualche microprocessore non hai che da chiedere.
    I manuali si devono anche capire ...

    Comunque, ne ho abbastanza di questa discussione "surreale" ... solo un consiglio a questo punto ... lascia stare l'assembly (non assembler) e dedicati ad altro.
  • Re: Memoria

    Ragazzi non siete un pò off-topic? Lo devo spostare in assembler?
  • Re: Memoria

    Beh, inizialmente il problema era C/C++ ... ma se si vuole ottenere il valore del registro eip è naturale che ci si sposti su assembly ... (non assembler ... )
  • Re: Memoria

    smalldragon ha scritto:


    quel esempio di sopra ora lo puoi fare solo o se usi la keyword _asm o se definisci a e b come proc il che in molti casi non ha un gran senso.
    Per concludere questo discorso e per completare la risposta, sperando che tu leggerai con attenzione e comprenderai questa risposta, il problema che hai su quel codice deriva dal fatto che tu non consideri che quando si interfaccia codice C/C++ con Assembly (ma in generale, tra linguaggi diversi e Assembly) bisogna rispettare delle regole per il codice di prologo e per quello di epilogo. Tale codice è necessario alla corretta gestione dello stack frame.

    La gestione automatica di questo codice lo realizza l'Assembler (il MASM) in base alla direttiva PROC per cui, tutto quello che esiste tra la PROC e l'ENDP viene identificata come una funzione che ha un codice di prologo all'inizio e un codice di epilogo inserito prima di ogni istruzione ret.

    Naturalmente, se esistono (come nel tuo codice in questione) delle ret all'interno del codice, queste verranno precedute dal codice d'epilogo e ovviamente tutto non funzionerà.

    In questi casi, devi impedire che il codice d'epilogo venga emesso automaticamente e devi aggiungerlo tu esplicitamente solo dove serve. Per impedire l'emissione del codice d'epilogo, scriverai

    option epilogue:none

    Il tuo codice diventerà quindi
    
    .486
    .model flat,stdcall
    
    option casemap :none
    option epilogue:none	; impedisce l'emissione del codice d'epilogo
    
    .code
    
    prima proc 
    	call a
    	call b
    	jmp fine_programma
    
    a:
    	nop
    	ret
    
    b:
    	nop
    	ret 
    
    fine_programma:
    	mov eax,12345	; restituisce un valore
    	ret 
    prima endp
    end
    
    Nel caso di gestione di parametri di input, il codice di epilogo dovrai aggiungerlo esplicitamente prima della ret dove effettivamente termina il codice e quindi avrai
    
    fine_programma:
    	mov eax,12345
    	leave			; epilogo, pulizia stack frame
    	ret 4			; per un solo parametro intero a 32 bit
    prima endp
    
    Ovviamente, tutto ciò in un contesto di codice sorgente mixed ... tutto ciò non è assolutamente necessario se il tuo codice assembly non interagisce con codice scritto in altri linguaggi.
  • Re: Memoria

    Grazie per l'informazione del "option epilogue:none" e della sua gestione.
    questa veramente non la sapevo ne terrò conto in fururo.
    per quanto riguarda l'altra discussione credo che e meglio finirla qui tanto alla fine ogni uno resta della stessa idea.
  • Re: Memoria

    smalldragon ha scritto:


    grazie
    Prego ... di nulla.
    questa veramente non la sapevo
    Ti assicuro che ce ne sono veramente tante cose che non sappiamo ...
    per quanto riguarda l'altra discussione credo che e meglio finirla qui tanto alla fine ogni uno resta della stessa idea.
    Sono d'accordo anche se non si tratta di "idee personali" ... sui fatti c'è poco da discutere.

    Se hai bisogno di aiuto su codice Assembly (anche mixed con C/C++), fatti sentire ...
Devi accedere o registrarti per scrivere nel forum
28 risposte