PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

20
PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL Inserare de cod maşină în sursa unui program Borland Pascal Inserare de instrucţiuni scrise în limbaj de asamblare într-un program Pascal (asamblorul inline al mediului Borland Pascal 6.0).

description

PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL. I nserare de cod maşină în sursa unui program Borland Pascal I nserare de instrucţiuni scrise în limbaj de asamblare într-un program Pascal ( asamblor ul inline a l mediului Borland Pascal 6.0). INSERAREA DE COD MAŞINĂ ÎN TEXTUL SURSĂ PASCAL. - PowerPoint PPT Presentation

Transcript of PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

Page 1: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

PROGRAMAREA LOW LEVELÎN LIMBAJUL PASCAL

Inserare de cod maşină în sursa unui program Borland Pascal

Inserare de instrucţiuni scrise în limbaj de asamblare într-un program Pascal (asamblorul inline al mediului Borland Pascal 6.0).

Page 2: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

INSERAREA DE COD MAŞINĂ ÎN

TEXTUL SURSĂ PASCAL Instrucţiunea inline

inline ( element_inline { / element_inline })

constanta

-

+

ilator_variabidentifica

constanta

>

<

Exemplu:

inline (<$1234/>$44)

generează trei octeţi de cod: $34, $44, $00.

Page 3: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

INSERAREA DE COD MAŞINĂ ÎN

TEXTUL SURSĂ PASCAL Următorul exemplu de instrucţiune inline generează cod maşină pentru a copia un anumit număr de cuvinte la o adresă specificată. Procedura descrisă UmplereCuvinte va memora Contor cuvinte cu valoarea Data în memorie, începând cu primul octet de la adresa conţinută în variabila Dest.

Procedure UmplereCuvinte (var Dest; Contor, Data:Word);begin

inline($C4/$BE/Dest/ { LES DI, Dest[BP] }$8B/$8E/Contor/ { MOV CX, Contor[BP] }$8B/$86/Data/ { MOV AX, Data[BP] }$FC/ { CLD }$F3/$AB); { REP STOSW }

end;

Page 4: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

INSERAREA DE COD MAŞINĂ ÎN

TEXTUL SURSĂ PASCAL Directiva inline

aceeaşi sintaxă ca şi instrucţiunile inline permite scrierea de proceduri şi funcţii care în momentul invocării sunt expandate

într-o secvenţă dată de instrucţiuni în cod maşină (~ macrourile în limbaj de asamblare)

când se invocă o procedură sau funcţie inline, compilatorul generează codul dictat de directiva inline în loc de a genera cod de apel.

Eventualii parametri sunt puşi în stivă deoarece astfel de proceduri şi funcţii sunt, de fapt, macrouri, nu se generează în

mod automat cod de intrare şi cod de ieşire.

Function LongMul(x,y:Integer):LongInt;inline( $5A/ { POP DX ; DX:=y } $58/ { POP AX ; AX:=x } $F7/$EA); { IMUL DX ; DX:AX := x*y }

Corectie fata de exemplul de la pagina 311 din cartea de curs!!!

Page 5: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

ASAMBLORUL INLINE AL LUI

BORLAND PASCAL 6.0 Asamblorul inline al lui Borland Pascal 6.0 permite inserarea de cod asamblare direct

în sursa programelor Pascal

Instrucţiunea asm

asm Instrucţiune_Asm { Separator Instrucţiune_Asm } end

Exemplu:

asm mov ax, A; xchg ax, B; mov A, axend;

O instrucţiune asm trebuie să asigure integritatea regiştrilor BP, SP, SS şi DS

Page 6: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

ASAMBLORUL INLINE AL LUI

BORLAND PASCAL 6.0 Instrucţiunile asamblorului

[ Etichetă : ] { Prefix } [ Mnemonică [ Operand { , Operand } ]

• etichete Pascal (definite în secţiunea de declaraţii label a programului Pascal)

• etichete locale (vizibile doar în cadrul instrucţiunii asm care le defineşte; ca şi sintaxă, ele încep cu simbolul "@”)

label Start, Stop;...begin asm Start: ... jz Stop @1: ... loop @1 end; asm @1: ... jc @2 ... jmp @1 @2: end; goto Start;Stop:end;

Page 7: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

ASAMBLORUL INLINE AL LUI

BORLAND PASCAL 6.0 Instrucţiunile asamblorului

[ Etichetă : ] { Prefix } [ Mnemonică [ Operand { , Operand } ]

• REP, REPE/REPZ, REPNE/REPNZ

• SEGCS, SEGDS, SEGES, SEGSS

asm rep movsb { copiază CX octeţi de la adresa DS:SI la adresa ES:DI }

SEGES lodsw { încarcă în AX un cuvânt de la ES:SI şi nu de la DS:SI }

SEGCS mov ax,[bx] { echivalentă cu mov ax, cs:[bx] }

SEGES { se referă la instrucţiunea în limbaj de asamblare care urmează }

mov WORD PTR [DI],0 { devine mov WORD PTR ES:[DI], 0 }

end;

Page 8: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

ASAMBLORUL INLINE AL LUI

BORLAND PASCAL 6.0 Instrucţiunile asamblorului

[ Etichetă : ] { Prefix } [ Mnemonică [ Operand { , Operand } ]

• codurile de operaţii ale instrucţiunilor 8086/8087 şi 80826/80287

• directivele de asamblare: DB, DW şi DD (aceste date vor fi generate în segmentul de cod )

VarByte DB ?VarWord DW ?...mov al, VarBytemov bx, VarWord...

var VarByte: Byte; VarWord: Word;...asm ... mov al, VarByte mov bx, VarWord ...end;...

Asamblorul inline al lui Borland Pascal 6.0 nu suportă astfel de declaraţii de variabile. Construcţia precedentă poate fi descrisă astfel:

Page 9: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

ASAMBLORUL INLINE AL LUI

BORLAND PASCAL 6.0 Instrucţiunile asamblorului

[ Etichetă : ] { Prefix } [ Mnemonică [ Operand { , Operand } ]

• expresii - combinaţii de constante, regiştri, simboluri şi operatori, cuvinte rezervate: AH, CL, FAR, SEG, AL, CS, HIGH, SHL, AND, CX, LOW, SHR, AX, DH, MOD, SI, BH, DI, NEAR, SP, BL, DL, NOT, SS, BP, DS, OFFSET, ST, BX, DWORD, OR, TBYTE, BYTE, DX, PTR, TYPE, CH, ES, QWORD, WORD şi XOR.

Var ch:Char;...asm mov ch,1; { se referă la registrul CH }

mov &ch,1; { se referă la variabila ch }end;

Page 10: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

ASAMBLORUL INLINE AL LUI

BORLAND PASCAL 6.0 Expresii

• evaluează toate expresiile ca valori întregi pe 32 de biţi

• nu suportă valori reale şi nici şir de caractere (exceptând constantele şir de caractere)

• Constantele hexazecimale pot să fie scrise şi în sintaxa Pascal (precedate de simbolul "$")

• Referirea la o variabilă înseamnă deplasamentul acestei variabile în segmentul ei de bază (şi nu conţinutul ei, cum este în Pascal).

Var x: Integer;...asm mov ax, x+4; { memorează în registrul AX valoarea unui cuvânt memorat la 4 octeti de x si nu valoarea lui x plus 4! }

mov bx,x; { memorează în registrul BX valoarea lui x }

end;

Page 11: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

ASAMBLORUL INLINE AL LUI

BORLAND PASCAL 6.0 Expresii

• Identificatorii recunoscuţi de către asamblorul inline sunt: etichete Pascal, constante Pascal, nume de tipuri Pascal, variabile Pascal, proceduri şi funcţii Pascal şi simbolurile speciale: @Code, @Data şi @Result.

asm mov ax, SEG @Data mov ds, ax{memorează în registrul DS adresa de segment a segmentului curent de date}end;

În expresiile destinate asamblorului inline NU pot să apară:

• proceduri şi funcţii standard;• numele de tablouri Mem, MemW, MemL, Port, PortW; • constante şir de caractere mai lungi decât 4 octeţi;• constante reale şi mulţime;• proceduri şi funcţii inline;• etichete care nu au fost declarate în blocul curent;• simbolul @Result, în afara unei funcţii

Procedure X;var c: Integer;...asm mov ax,c { se generează codul mov ax, [BP-2] }end;...

Page 12: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

ASAMBLORUL INLINE AL LUI

BORLAND PASCAL 6.0

Function Suma(var x,y:Integer):Integer;beginasm les bx, x{ consideră că x este o adresă far, pe care o încarcă în ES (segmentul) şi în BX (offset-ul)} mov ax, es:[bx]{ memorează în AX valoarea găsită la adresa ES:[BX], adica valoarea parametrului x } les bx, y{ consideră că y este o adresă far, pe care o încarcă în ES (segmentul) şi în BX (offset-ul)} add ax, es:[bx]{ adună la AX valoarea găsită la adresa ES:[BX], adică valoarea parametrului y } mov @Result, ax{ pune valoarea din AX în locul de unde apelantul va lua rezultatul întors de funcţie }end;end;

Function Suma(x,y:Integer):Integer;begin asm

mov ax, xadd ax, ymov @Result, ax

{pune valoarea din AX în locul de unde apelantul va lua rezultatul întors de funcţie} end;end;

Page 13: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

ASAMBLORUL INLINE AL LUI

BORLAND PASCAL 6.0 Tipul unei expresii

asm mov al,[100h]

{ pune în registrul AL un octet de la adresa ds:[100H]; tipul asociat - se deduce din dimensiunea registrului AL - este 1}

mov bx,[100h]

{ se pune în BX un cuvînt de la adresa ds:[100H]; tipul asociat - se deduce din dimensiunea lui BX - este 2 }

end;

Uneori, o referinţă la memorie nu are un tip asociat, acesta deducându-se din tipul celorlalţi operanzi

asm inc WORD PTR [100h] imul BYTE PTR [100h]end;

Dacă totuşi tipul nu se poate deduce, asamblorul cere o conversie de tip explicită. Tipul unei referinţe la memorie poate fi modificat cu ajutorul operatorului de conversie PTR.

Page 14: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

ASAMBLORUL INLINE AL LUI

BORLAND PASCAL 6.0 Proceduri şi funcţii assembler

• Procedurile (funcţiile) assembler sunt proceduri (funcţii) scrise complet în asamblare inline, fără a fi necesară partea begin ... end.

• Ele se definesc cu ajutorul directivei assembler

Function LongMul(x,y:Integer):LongInt; assembler;asm mov ax,x imul yend;

• Utilizarea directivei assembler are ca efect realizarea de către compilator a câtorva optimizări la generarea codului de intrare în subrutină:

• NU generează cod pentru copierea in variabile locale a parametrilor valoare de dimensiune > 4 octeti, acesti parametri trebuie tratati ca si cum ar fi transmisi prin referinta• NU alocă o variabilă pentru întoarcerea rezultatului unei funcţii, exceptie facand functiile care intorc string• NU generează cadru de stivă pentru procedurile şi funcţiile care nu au parametri şi nici variabile locale ;

Funcţiile întorc rezultatul după cum urmează:• Integer, Char, Boolean, enumerare:• 1 octet - în AL• 2 octeţi - în AX• 4 octeţi - în DX:AX• Real - în DX:BX:AX• Single, Double, Extended, Comp - în ST(0)• Pointer - în DX:AX• String - în locaţia temporară punctată de @Result

Page 15: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

Proceduri şi funcţii assemblerExemplu: Funcţia ce operează asupra stringurilor este realizată cu ajutorul instrucţiunilor asamblorului inline, o variantă descrisă fără directiva assembler şi o variantă descrisă cu directiva assembler. Funcţia întoarce ca valoare un şir de caractere care reprezintă scrierea cu majuscule a

şirului de caractere care este parametrul funcţiei. Parametrul funcţiei este transmis prin valoare. Varianta 1Function UpperCase( Str:String): String;begin asm cld lea si, Str les di, @Result SEGSS lodsb stosb xor ah, ah xchg ax, cx jcxz @3 @1: SEGSS lodsb cmp al, 'a' jb @2 cmp al, 'z' ja @2 add al, 'A'-'a' @2: stosb loop @1 @3: end;end;

Varianta2Function UpperCase( Str:String): String; assembler;asm push ds cld lds si, Str les di, @Result lodsb stosb xor ah, ah xchg ax, cx jcxz @3@1: lodsb cmp al, 'a' jb @2 cmp al, 'z' ja @2 add al, 'Ă'-'a'@2: stosb loop @1@3: pop dsend;

Page 16: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

ACCESAREA REGIŞTRILOR ŞI APELAREA DE ÎNTRERUPERI IN

Borland Pascal 6.0 type registers = record

case Integer of 0: (AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags : Word);

1: (AL, AH, BL, BH, CL, CH, DL, DH : Byte);end;

definit în

unitul dos

Program Pascal care afişează pe ecran un text, folosind pentru aceasta funcţia DOS 9h:

uses dos;const mesaj: String= 'Hello, everybody ! $';var

reg: Registers;begin

reg.AH:= 9; { încarc în AH valoarea 9 }reg.DS:= Seg(mesaj); { încarc în DS:DX adresa far a şirului care va fi tipărit }reg.DX:= Ofs(mesaj[1]);Intr($21,reg); { apelarea întreruperii 21h }

end;

procedura oferita de unitul dos

Page 17: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

SCRIEREA DE RUTINE DE TRATARE A ÎNTRERUPERILOR ÎN LIMBAJUL

PASCAL salvarea lui CS şi a lui IP în stivă; salvarea în stivă a registrului de flag-uri; interzicerea apariţiei altor întreruperi; salt far la locaţia punctată de vectorul de întrerupere corespunzător.

Proceduri interrupt în Pascal

procedure MyInt(rFlags, rCS, rIP, rAX, rBX, rCX, rDX, rSI, rDS, rES, rBP:Word); interrupt;begin

...end;

• nu poate să fie apelată dintr-o altă procedură• trebuie să fie declarată far • parametrii corespund regiştrilor procesorului• Indiferent de lista parametrilor unei proceduri interrupt, compilatorul produce (automat) cod la intrarea în rutina pentru salvarea tuturor regiştrilor pe stivă• corespunzător, la ieşirea din rutină se restaurează automat aceşti regiştri şi se generează (tot automat) o instrucţiune iret

Page 18: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

SCRIEREA DE RUTINE DE TRATARE A ÎNTRERUPERILOR ÎN LIMBAJUL

PASCAL Proceduri interrupt în Pascal

push axpush bxpush cxpush dxpush sipush dipush dspush espush bpmov bp, spmov ax, seg @Datamov ds, ax

pop bppop espop dspop dipop sipop dxpop cxpop bxpop axiret

Cod de intrare Cod de iesire

Page 19: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

SCRIEREA DE RUTINE DE TRATARE A ÎNTRERUPERILOR ÎN LIMBAJUL

PASCAL Proceduri interrupt în Pascal

SetIntVec (NrInt, Vector)

• pentru a seta un anumit vector de întrerupere la o adresă specificată (instalarea unui nou handler – vezi functia DOS 25h)

• procedura definită în cadrul unit-ului DOS.

valoare de tip byte putând lua valori între 0 şi 255 si reprezentând numărul întreruperii

adresa la care se va seta vectorul de întrerupere corespunzător lui NrInt

GetIntVec (NrInt, Vector)

• care întoarce adresa memorată într-un anumit vector de întrerupere (obtinerea adresei vechiului handler – vezi functia DOS 35h)

• procedura definită în cadrul unit-ului DOS

Keep (cod_revenire)• Terminate and Stay Resident (vezi funcţia DOS 31h).

Page 20: PROGRAMAREA LOW LEVEL ÎN LIMBAJUL PASCAL

SCRIEREA DE RUTINE DE TRATARE A ÎNTRERUPERILOR ÎN LIMBAJUL

PASCAL Proceduri interrupt în PascalExemplu: program care modifică rutina de tratare a înteruperii 9, afişând la fiecare apăsare a tastei 'A'

mesajul 'Aţi apăsat tasta A'.

{$M $800,0,0 } { 2K stack, no heap }uses Crt, Dos;var c:char; OldHand : Procedure;{$F+}procedure MyHand; interrupt;var i:Byte;begin

i := Port[$60]; { se citeşte un octet din portul $60 al controlerului tastaturii}inline ($9C); { PUSHF - salvăm flagurile pe stivă }OldHand;if (i=65) then Writeln('Ati apasat tasta A')

end;{$F‑}begin

GetIntVec($9,@OldHand);SetIntVec($9,Addr(MyHand));Keep(0); { Terminate, stay resident }

end.