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

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

Embed Size (px)

Citation preview

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

1 M. Rebaudengo, M. Sonza Reorda

Politecnico di TorinoDip. di Automatica e Informatica

M. Rebaudengo - M. Sonza Reorda

L’Assembler 8086Programmazione Avanzata

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

2 M. Rebaudengo, M. Sonza Reorda

Sommario

• Procedure Assembler richiamabili da un programma C

• Recursione

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

3 M. Rebaudengo, M. Sonza Reorda

Procedure Assemblerrichiamabili da un

programma C

Sorgente C

SorgenteAssembler

Compilatore

Assemblatore

Oggetto

Oggetto

Linker Eseguibile

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

4 M. Rebaudengo, M. Sonza Reorda

Dichiarazionedella procedura

chiamataAl 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.

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

5 M. Rebaudengo, M. Sonza Reorda

Dichiarazionedella 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.

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

6 M. Rebaudengo, M. Sonza Reorda

Convenzione per i nomiIl 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.

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

7 M. Rebaudengo, M. Sonza Reorda

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.

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

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 l’opzione /Cp e linkare i vari moduli con l’opzione /NOI.

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

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:

C MASM

char BYTE

short, int WORD

long, float DWORD

double QWORD

long double TBYTE

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

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).

modello punt. a funzione punt. a dato

tiny WORD WORD

small WORD WORD

medium DWORD WORD

compact WORD DWORD

large DWORDDWORD

huge DWORD DWORD

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

11 M. Rebaudengo, M. Sonza Reorda

Convenzionesu parametri in

ingressoIl 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

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

12 M. Rebaudengo, M. Sonza Reorda

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.

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

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.

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

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

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

15 M. Rebaudengo, M. Sonza Reorda

Convenzionisui parametri di

uscitaIl 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.

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

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 all’inizio;

• liberare l’area locale di dati incrementando opportunamente il contenuto del registro SP;

• eseguire l’istruzione RET.

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

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 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.

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

18 M. Rebaudengo, M. Sonza Reorda

EsercizioCalcolo 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.

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

19 M. Rebaudengo, M. Sonza Reorda

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));

}

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

20 M. Rebaudengo, M. Sonza Reorda

Procedura AssemblerPUBLIC _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

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

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 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.

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

22 M. Rebaudengo, M. Sonza Reorda

Programma C chiamante

#include <stdio.h>

extern char *invert (char * str);

void main()

{

char *s;

s = strdup(”Salve Mondo !”);

printf(”%s\n”, invert(s));

}

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

23 M. Rebaudengo, M. Sonza Reorda

Procedura AssemblerPUBLIC _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

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

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

LOOP ciclo

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

25 M. Rebaudengo, M. Sonza Reorda

MOV AX, WORD PTR [BP+4] POP DI

POP SI

POP BP

RET

_invert ENDP

END

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

26 M. Rebaudengo, M. Sonza Reorda

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.

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

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));

}

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

28 M. Rebaudengo, M. Sonza Reorda

Procedura recursivaFACT PROC NEAR

PUSH BXCMP BX, 1JE returnDEC BXCALL FACTINC BXMUL BXJMP fine

return: MOV AX, 1XOR DX, DX

fine: POP BXRET

FACT ENDPEND

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

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

0x11x0 001100

001110

011100

011110

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

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;

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

31 M. Rebaudengo, M. Sonza Reorda

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

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

32 M. Rebaudengo, M. Sonza Reorda

Soluzione Assembler

.MODEL smallLF EQU 10CR EQU 13DIM EQU 30 ; dimensione massima della

; stringa da espandere.DATA

OBUFF DB DIM DUP ('0')IBUFF DB DIM DUP ('0')LEN DW 0ERR_MESS DB 'Carattere non ammesso$'

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

33 M. Rebaudengo, M. Sonza Reorda

.CODE

.STARTUPMOV CX, DIM ; lettura stringa di input

MOV SI, 0 MOV AH, 1lab1: INT 21H MOV IBUFF[SI], AL INC SI CMP AL, CR LOOPNE lab1 DEC SI MOV LEN, SI

XOR BX, BX CALL SPLIT

.EXIT

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

34 M. Rebaudengo, M. Sonza Reorda

SPLIT PROCPUSH AX

PUSH DX PUSH SI

CMP BX, LEN ; stringa vuota ? JNE ancora

MOV CX, LEN ; Sì: visualizza MOV AH, 2 XOR SI, SIlab2: MOV DL, OBUFF[SI] INT 21H INC SI LOOP lab2 MOV DL, CR INT 21H MOV DL, LF INT 21H JMP fine

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

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 finenot_z: CMP DL, '1' ; '1' JNE not_one

MOV OBUFF[BX], '1' INC BX CALL SPLIT DEC BX JMP fine

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

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

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

37 M. Rebaudengo, M. Sonza Reorda

error: MOV AH, 9 ; carattere diverso da 0, 1 e X

LEA DX, ERR_MESS INT 21Hfine: POP SI POP DX POP AX

RETSPLIT ENDP END