Programmazione Avanzata

Slides:



Advertisements
Presentazioni simili
Introduzione al linguaggio C++
Advertisements

Introduzione al linguaggio C
in un programma Assembler
Procedure In assembler.
PUNTATORI Introduzione
MATLAB.
MATLAB. Scopo della lezione Programmare in Matlab Funzioni Cicli Operatori relazionali Esercizi vari.
Massa Laura Mela Enrica
Informatica Generale Marzia Buscemi
Introduzione al linguaggio C
Anno accademico Array e puntatori in C.
Programmazione Procedurale in Linguaggio C++
1 Istruzioni, algoritmi, linguaggi. 2 Algoritmo per il calcolo delle radici reali di unequazione di 2 o grado Data lequazione ax 2 +bx+c=0, quali sono.
Indirizzi delle variabili A ogni variabile sono associati tre concetti fondamentali: il valore memorizzato; il tipo dati di appartenenza; lindirizzo. Il.
Caratteri e stringhe di caratteri
Funzioni definite dall’utente
Laboratorio di informatica: ASSEMBLER
Università degli Studi di Roma La Sapienza Architettura degli elaboratori II Funzioni.
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Corso di Fondamenti di programmazione a.a. 2009/2010 Prof.ssa Chiara Petrioli.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Puntatori Marco D. Santambrogio – Ver. aggiornata al 21 Marzo 2013.
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Lab 2 – Info B Marco D. Santambrogio – Riccardo Cattaneo –
Informatica di base A.A. 2003/2004 Algoritmi e programmi
File.
1 Corso di Laurea in Biotecnologie Informatica (Programmazione) Introduzione a JAVA Anno Accademico 2009/2010.
Corso di Informatica (Programmazione)
1 Corso di Informatica (Programmazione) Lezione 13 (21 novembre 2008) Programmazione in Java: stringhe e array.
MATLAB. …oggi… Programmare in Matlab Programmare in Matlab Funzioni Funzioni Cicli Cicli Operatori relazionali Operatori relazionali Esercizi vari Esercizi.
eliana minicozzi linguaggi1a.a lezione2
CALCOLATORI ELETTRONICI Gestione delle subroutine.
Il linguaggio Fortran 90: 4. Array: Vettori e Matrici
Gestione delle subroutine
Procedure e funzioni nei linguaggi di alto livello Lab Programmazione - turno /2006.
Approfondimento delle classi
memoria gestita staticamente:
Strutture di controllo nel C
Esercizi FUNZIONI Passaggio di parametri per valore, variabili e tipi locali e globali, prototipo.
Strutture di controllo in C -- Flow Chart --
Esercizi Puntatori, struct con campi puntatore, puntatori a struct, rapporto tra array e puntatori. FUNZIONI Passaggio di parametri per indirizzo, passaggio.
I File.
Le funzioni.
Programmazione modulare nel linguaggio C
Istruzioni per il Controllo del Processore
Scheda Ente Ente Privato Ente Pubblico. 2ROL - Richieste On Line.
Introduzione al linguaggio assembly del microprocessore a parte
Introduzione al linguaggio assemby del microprocessore a parte
2000 Prentice Hall, Inc. All rights reserved. Capitolo 10 (Deitel) Strutture, unioni ed enumerazioni Sommario Introduzione Definire le strutture.
Istruzioni per la Manipolazione dei Bit
Il linguaggio C Le funzioni C Language Il passaggio dei parametri
Prof.ssa Chiara Petrioli -- Fondamenti di programmazione, a.a. 2009/2010 Corso di Fondamenti di programmazione a.a. 2009/2010 Prof.ssa Chiara Petrioli.
INTERFACCIAMENTO ASSEMBLY - C++
Unità Didattica 3 Linguaggio C
Introduzione al linguaggio assembly del microprocessore a parte
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Array e stringhe Marco D. Santambrogio – Ver. aggiornata al 9 Agosto 2013.
14 marzo 2002 Avvisi:.
1Piero Scotto - C14. Finalità del corso Programma Materiale Requisiti Spendibilità 2Piero Scotto - C14.
2000 Prentice Hall, Inc. All rights reserved. Attivazione di funzioni La chiamata/attivazione di funzione viene indicata citando il nome della funzione.
Sviluppare un programma in C che, dato un array da 100 elementi interi caricato con numeri casuali compresi tra [10,100], sia in grado di cercare il valore.
1 M. Rebaudengo, M. Sonza Reorda Politecnico di Torino Dip. di Automatica e Informatica M. Rebaudengo - M. Sonza Reorda L’Assembler 8086 Istruzioni per.
Programmazione in linguaggio C
1 M. Rebaudengo Routine di servizio dell’interrupt.
IL GIOCO DEL PORTIERE CASISTICA. Caso n. 1 Il portiere nella seguente azione NON commette infrazioni.
Parte 3 Lo stato: variabili, espressioni ed assegnazioni
1 M. Rebaudengo, M. Sonza Reorda Politecnico di Torino Dip. di Automatica e Informatica M. Rebaudengo - M. Sonza Reorda L’Assembler 8086 Procedure e Macro.
1 M. Rebaudengo, M. Sonza Reorda Politecnico di Torino Dip. di Automatica e Informatica M. Rebaudengo - M. Sonza Reorda L’Assembler 8086 Istruzioni per.
Fondamenti di Informatica II Ingegneria Informatica (A-I) Prof. M.T. PAZIENZA a.a – 3° ciclo.
Allievi Elettrici - AA Le funzioni ricorsive in C
1 M. Rebaudengo, M. Sonza Reorda Politecnico di Torino Dip. di Automatica e Informatica M. Rebaudengo - M. Sonza Reorda L’Assembler 8086 Istruzioni per.
1 Il linguaggio C Precisazioni sull’esperienza in laboratorio.
Operatori di incremento e decremento
1 M. Rebaudengo, M. Sonza Reorda Politecnico di Torino Dip. di Automatica e Informatica M. Rebaudengo - M. Sonza Reorda L’Assembler 8086 Istruzioni per.
Transcript della presentazione:

Programmazione Avanzata L’Assembler 8086 Programmazione Avanzata M. Rebaudengo - M. Sonza Reorda Politecnico di Torino Dip. di Automatica e Informatica

Sommario Procedure Assembler richiamabili da un programma C Recursione

Procedure Assembler richiamabili da un programma C Compilatore Sorgente C Oggetto Linker Eseguibile Assemblatore Sorgente Assembler Oggetto

Dichiarazione della procedura chiamata Al fine di poter linkare una procedura Assembler con un programma chiamante C occorre che ci sia compatibilità tra i segmenti usati. È necessario utilizzare lo stesso modello di memoria sia per il modulo C che per il modulo Assembler: la procedura Assembler va dichiarata NEAR per modelli tiny, small e compact, mentre va dichiarata FAR per modelli medium, large o huge.

Dichiarazione della procedura chiamata (segue) Il nome della procedura Assembler deve essere reso pubblico tramite una dichiarazione PUBLIC, così come il nome di ogni altra variabile che si vuole rendere accessibile dall’esterno. I nomi di tutte le variabili e procedure definite esternamente al modulo Assembler e da esso utilizzate vanno dichiarate esterne attraverso la direttiva EXTRN.

Convenzione per i nomi Il compilatore altera il nome degli identificatori prima di memorizzarli nel file oggetto. Tutti i nomi delle entità comuni ai moduli C ed a quello Assembler devono tener conto del fatto che il compilatore C premette sempre, nella costruzione della symbol table, un carattere ‘_’. Il nome della procedura Assembler deve iniziare con tale carattere, così come quello di tutte le variabili pubbliche utilizzabili dal modulo C.

Convenzioni per i nomi (segue) Utilizzando l’opzione di linguaggio nella direttiva .MODEL, l’assemblatore aggiunge il carattere _ davanti a tutti gli identificatori del modulo Assembler.

Convenzioni per i nomi (segue) Il linguaggio C è case sensitive; per fare in modo di preservare il case degli identificatori è necessario compilare i moduli Assembler con l’opzione /Cp e linkare i vari moduli con l’opzione /NOI.

Compatibilità del tipo di dato Il linguaggio C presenta una molteplicità di tipi di dato, mentre il linguaggio Assembler presenta un numero ristretto di possibili tipi di dato: C MASM char BYTE short, int WORD long, float DWORD double QWORD long double TBYTE

Compatibilità del tipo di dato (segue) I puntatori in C specificano indirizzi di variabili o di funzioni. In base al modello di memoria utilizzato un puntatore occupa una word (puntatore di tipo NEAR) oppure una doubleword (puntatore di tipo FAR). modello punt. a funzione punt. a dato tiny WORD WORD small WORD WORD medium DWORD WORD compact WORD DWORD large DWORD DWORD huge DWORD DWORD

Convenzione su parametri in ingresso Il codice generato dal compilatore C passa i parametri alle procedure mettendoli nello stack in ordine inverso rispetto a quello in cui appaiono nella chiamata. Ai parametri si può fare accesso attraverso il registro BP. Le prime istruzioni da eseguire all’interno della procedura Assembler sono le seguenti: PUSH BP MOV BP, SP

Variabili locali All’interno della procedura può essere allocato spazio per eventuali variabili locali, così come accade nei linguaggi di alto livello. Per fare questo è necessario riservare un’area dello stack utilizzabile per la memorizzazione di variabili locali. Tale operazione può essere fatta o con un numero opportuno di istruzioni PUSH, oppure decrementando il contenuto di SP attraverso un’istruzione SUB.

Salvataggio dei registri Il compilatore C della Microsoft richiede che eventuali procedure chiamate da un programma C non modifichino i valori contenuti nei registri SI, DI, SS, DS e BP. Nel caso in cui tali registri debbano essere utilizzati, devono essere opportunamente salvati nello stack e poi ripristinati al termine.

Frame Parametro n Parametro 1 Indirizzo di ritorno BP Registro BP . . . Parametro 1 Indirizzo di ritorno BP Registro BP Area locale di dati Registri salvati SP . . . SS

Convenzioni sui parametri di uscita Il parametro eventualmente ritornato dalla procedura Assembler è atteso dal chiamante nel registro accumulatore. Se il tipo del dato di ritorno è un char il parametro è passato attraverso il registro AL; se il tipo è un int od un indirizzo di tipo NEAR il registro utilizzato è AX; se il tipo è un long od un indirizzo di tipo FAR il parametro di ritorno è copiato nella coppia di registri DX, AX.

Uscita dalla procedura Le operazioni da effettuare a conclusione della procedura sono: ripristinare i valori dei registri eventualmente salvati all’inizio; liberare l’area locale di dati incrementando opportunamente il contenuto del registro SP; eseguire l’istruzione RET.

Procedura C chiamante Il nome della procedura chiamata e tutte le variabili globali definite nel modulo Assembler devono essere dichiarate come extern all’interno della procedura C. È compito del programma chiamante C svuotare lo stack dello spazio destinato ai parametri di ingresso. Tale operazione è effettuata dal compilatore C in maniera automatica.

Esercizio Calcolo di un’espressione aritmetica. Si vuole scrivere una procedura Assembler di nome power2 richiamabile da un programma scritto in linguaggio C per il calcolo dell’espressione X*2Y. Alla procedura power2 vengono passati i due parametri interi X e Y; la funzione restituisce nel registro AX il risultato dell’espressione. Si supponga che il programma chiamante sia compilato usando il modello di memoria small.

Programma C chiamante #include <stdio.h> extern int power2 (int factor, int power); void main() { printf(”3 volte 2 elevato 5=%d\n”, power2(3,5)); }

Procedura Assembler PUBLIC _power2 .MODEL small .CODE _power2 PROC PUSH BP MOV BP, SP MOV AX, [BP+4] ; primo parametro MOV CX, [BP+6] ; secondo parametro SHL AX, CL POP BP RET _power2 ENDP END

Esercizio Si vuole eseguire una procedura Assembler di nome invert richiamabile da un programma scritto in linguaggio C per l’inversione del contenuto di una stringa: al termine dell’esecuzione, gli elementi del vettore devono essere memorizzati nell’ordine inverso rispetto a quello iniziale.

Programma C chiamante #include <stdio.h> extern char *invert (char * str); void main() { char *s; s = strdup(”Salve Mondo !”); printf(”%s\n”, invert(s)); }

Procedura Assembler PUBLIC _invert .MODEL small .CODE _invert PROC PUSH BP MOV BP, SP PUSH SI PUSH DI MOV AX, DS MOV ES, AX MOV DI, WORD PTR [BP+4] MOV SI, DI XOR AX, AX

MOV CX, 0FFFFH REPNE SCASB SUB DI, 2 NOT CX DEC CX SHR CX, 1 ciclo: MOV AH, [SI] XCHG AH, [DI] MOV [SI], AH INC SI DEC DI LOOP ciclo

MOV AX, WORD PTR [BP+4] POP DI POP SI POP BP RET _invert ENDP END

La recursione L’Assembler permette la recursione, che deve però essere gestita dal programmatore stesso. Nulla vieta che una procedura richiami se stessa: in tal caso l’indirizzo di ritorno messo nello stack è quello della procedura stessa e nello stack si accumuleranno tanti di questi indirizzi quante sono le chiamate recursive.

Esempio I: Fact Si realizzi una procedura di nome FACT che legge un numero nel registro BX e ne calcola il fattoriale, scrivendo il risultato nel registro AX. La versione C della stessa procedura è: int fact ( int x) { if( x == 1) return( 1); return( x * fact( x-1)); }

Procedura recursiva FACT PROC NEAR PUSH BX CMP BX, 1 JE return DEC BX CALL FACT INC BX MUL BX JMP fine return: MOV AX, 1 XOR DX, DX fine: POP BX RET FACT ENDP END

Esempio II: Split Si vuole scrivere un programma in grado di espandere (splitting) stringhe di bit contenenti 0, 1 e X, producendo tutte le possibili stringhe ottenibili da quella data, tramite la sostituzione di ciascuna X con un 1 o uno 0. Esempio 0x11x0  001100 001110 011100 011110

Soluzione C void split(void) { if (curr_index==len) { printf("%s\n", obuff); return; } else switch (ibuff[curr_index]) { case '0': obuff[curr_index++] = '0'; split(); break; case '1': obuff[curr_index++] = '1';

case 'X': obuff[curr_index++] = '0'; split(); obuff[curr_index-1] = '1'; break; } return;

Soluzione Assembler .MODEL small LF EQU 10 CR EQU 13 DIM EQU 30 ; dimensione massima della ; stringa da espandere .DATA OBUFF DB DIM DUP ('0') IBUFF DB DIM DUP ('0') LEN DW 0 ERR_MESS DB 'Carattere non ammesso$'

.CODE .STARTUP MOV CX, DIM ; lettura stringa di input MOV SI, 0 MOV AH, 1 lab1: INT 21H MOV IBUFF[SI], AL INC SI CMP AL, CR LOOPNE lab1 DEC SI MOV LEN, SI XOR BX, BX CALL SPLIT .EXIT

SPLIT PROC PUSH AX PUSH DX PUSH SI CMP BX, LEN ; stringa vuota ? JNE ancora MOV CX, LEN ; Sì: visualizza MOV AH, 2 XOR SI, SI lab2: MOV DL, OBUFF[SI] INT 21H INC SI LOOP lab2 MOV DL, CR MOV DL, LF JMP fine

ancora: MOV DL, IBUFF[BX] ; No, ;considera il primo carattere CMP DL, '0' JNE not_z MOV OBUFF[BX], '0' ; '0' INC BX CALL SPLIT DEC BX JMP fine not_z: CMP DL, '1' ; '1' JNE not_one MOV OBUFF[BX], '1'

not_one: CMP DL, 'X' ; 'X' JNE error MOV OBUFF[BX], '0' ; trasforma la X in 0 INC BX CALL SPLIT DEC BX MOV OBUFF[BX], '1' ; trasforma la X in 1 JMP fine

error: MOV AH, 9 ; carattere diverso da 0, 1 e X LEA DX, ERR_MESS INT 21H fine: POP SI POP DX POP AX RET SPLIT ENDP END