La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

1 M. Rebaudengo, M. Sonza Reorda Politecnico di Torino Dip. di Automatica e Informatica M. Rebaudengo - M. Sonza Reorda LAssembler 8086 Programmazione.

Presentazioni simili


Presentazione sul tema: "1 M. Rebaudengo, M. Sonza Reorda Politecnico di Torino Dip. di Automatica e Informatica M. Rebaudengo - M. Sonza Reorda LAssembler 8086 Programmazione."— Transcript della presentazione:

1 1 M. Rebaudengo, M. Sonza Reorda Politecnico di Torino Dip. di Automatica e Informatica M. Rebaudengo - M. Sonza Reorda LAssembler 8086 Programmazione Avanzata

2 2 M. Rebaudengo, M. Sonza Reorda Sommario Procedure Assembler richiamabili da un programma C Recursione

3 3 M. Rebaudengo, M. Sonza Reorda Procedure Assembler richiamabili da un programma C Sorgente C Sorgente Assembler Compilatore Assemblatore Oggetto Linker Eseguibile

4 4 M. Rebaudengo, M. Sonza Reorda 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.

5 5 M. Rebaudengo, M. Sonza Reorda 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 dallesterno. I nomi di tutte le variabili e procedure definite esternamente al modulo Assembler e da esso utilizzate vanno dichiarate esterne attraverso la direttiva EXTRN.

6 6 M. Rebaudengo, M. Sonza Reorda 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.

7 7 M. Rebaudengo, M. Sonza Reorda Convenzioni per i nomi (segue) Utilizzando lopzione di linguaggio nella direttiva.MODEL, lassemblatore aggiunge il carattere _ davanti a tutti gli identificatori del modulo Assembler.

8 8 M. Rebaudengo, M. Sonza Reorda 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 lopzione /Cp e linkare i vari moduli con lopzione /NOI.

9 9 M. Rebaudengo, M. Sonza Reorda 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: CMASM charBYTE short, intWORD long, floatDWORD doubleQWORD long doubleTBYTE

10 10 M. Rebaudengo, M. Sonza Reorda 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 ). modellopunt. a funzionepunt. a dato tinyWORDWORD smallWORDWORD mediumDWORDWORD compactWORDDWORD largeDWORDDWORD hugeDWORDDWORD

11 11 M. Rebaudengo, M. Sonza Reorda 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 allinterno della procedura Assembler sono le seguenti: PUSH BP MOVBP, SP

12 12 M. Rebaudengo, M. Sonza Reorda Variabili locali Allinterno della procedura può essere allocato spazio per eventuali variabili locali, così come accade nei linguaggi di alto livello. Per fare questo è necessario riservare unarea 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 unistruzione SUB.

13 13 M. Rebaudengo, M. Sonza Reorda 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.

14 14 M. Rebaudengo, M. Sonza Reorda Frame Indirizzo di ritorno Parametro n... Parametro 1 Registro BP Area locale di dati Registri salvati... BP SS SP

15 15 M. Rebaudengo, M. Sonza Reorda 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.

16 16 M. Rebaudengo, M. Sonza Reorda Uscita dalla procedura Le operazioni da effettuare a conclusione della procedura sono: ripristinare i valori dei registri eventualmente salvati allinizio; liberare larea locale di dati incrementando opportunamente il contenuto del registro SP ; eseguire listruzione RET.

17 17 M. Rebaudengo, M. Sonza Reorda Procedura C chiamante Il nome della procedura chiamata e tutte le variabili globali definite nel modulo Assembler devono essere dichiarate come extern allinterno 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.

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

19 19 M. Rebaudengo, M. Sonza Reorda Programma C chiamante #include extern int power2 (int factor, int power); void main() { printf(3 volte 2 elevato 5=%d\n, power2(3,5)); }

20 20 M. Rebaudengo, M. Sonza Reorda 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 _power2ENDP END

21 21 M. Rebaudengo, M. Sonza Reorda Esercizio Si vuole eseguire una procedura Assembler di nome invert richiamabile da un programma scritto in linguaggio C per linversione del contenuto di una stringa: al termine dellesecuzione, gli elementi del vettore devono essere memorizzati nellordine inverso rispetto a quello iniziale.

22 22 M. Rebaudengo, M. Sonza Reorda Programma C chiamante #include extern char *invert (char * str); void main() { char *s; s = strdup(Salve Mondo !); printf(%s\n, invert(s)); }

23 23 M. Rebaudengo, M. Sonza Reorda 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

24 24 M. Rebaudengo, M. Sonza Reorda 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 LOOPciclo

25 25 M. Rebaudengo, M. Sonza Reorda MOV AX, WORD PTR [BP+4] POPDI POP SI POP BP RET _invertENDP END

26 26 M. Rebaudengo, M. Sonza Reorda La recursione LAssembler permette la recursione, che deve però essere gestita dal programmatore stesso. Nulla vieta che una procedura richiami se stessa: in tal caso lindirizzo di ritorno messo nello stack è quello della procedura stessa e nello stack si accumuleranno tanti di questi indirizzi quante sono le chiamate recursive.

27 27 M. Rebaudengo, M. Sonza Reorda 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)); }

28 28 M. Rebaudengo, M. Sonza Reorda Procedura recursiva FACT PROC NEAR PUSH BX CMP BX, 1 JEreturn DEC BX CALL FACT INC BX MUL BX JMP fine return:MOV AX, 1 XOR DX, DX fine:POP BX RET FACTENDP END

29 29 M. Rebaudengo, M. Sonza Reorda 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 0x11x

30 30 M. Rebaudengo, M. Sonza Reorda 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'; split(); break;

31 31 M. Rebaudengo, M. Sonza Reorda case 'X': obuff[curr_index++] = '0'; split(); obuff[curr_index-1] = '1'; split(); break; } return; }

32 32 M. Rebaudengo, M. Sonza Reorda Soluzione Assembler.MODELsmall LFEQU10 CREQU13 DIM EQU 30 ; dimensione massima della ; stringa da espandere.DATA OBUFF DBDIM DUP('0') IBUFF DB DIM DUP ('0') LEN DW 0 ERR_MESSDB 'Carattere non ammesso$'

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

34 34 M. Rebaudengo, M. Sonza Reorda 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 INT 21H MOV DL, LF INT 21H JMP fine

35 35 M. Rebaudengo, M. Sonza Reorda 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' INC BX CALL SPLIT DEC BX JMP fine

36 36 M. Rebaudengo, M. Sonza Reorda 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 INC BX CALL SPLIT DEC BX JMP fine

37 37 M. Rebaudengo, M. Sonza Reorda 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


Scaricare ppt "1 M. Rebaudengo, M. Sonza Reorda Politecnico di Torino Dip. di Automatica e Informatica M. Rebaudengo - M. Sonza Reorda LAssembler 8086 Programmazione."

Presentazioni simili


Annunci Google