Sunteți pe pagina 1din 27

Cap.

8
Programarea
multimodul

Cerinele unui modul


asamblare la legarea cu un
Directiva PUBLIC
alt
modul
- exporta simboluri definite n modulul asamblare n alte module

PUBLIC [limbaj] simbol {,[limbaj] simbol}

PASCAL, C, BASIC, ASSEMBLER,


FORTRAN, PROLOG sau NOLANGUAGE

nume de proceduri
nume de variabile de memorie
etichete definite cu ajutorul directivelor EQU sau =,
ale cror valori se reprezint pe 1 sau 2 octei.

Ex: PUBLIC C ProcA


- impune ca simbolul ProcA s fie exportat n celelalte module ca _ProcA, conform regulilor limbajului
C.

Cerinele unui modul


asamblare la legarea cu un
Directiva EXTRN
alt
modul

- face vizibile n modulul curent simboluri definite n alte module


EXTRN definiie {,definiie}

[limbaj] nume : tip

numele simbolului care


este definit n alt modul

Ex: EXTRN ProcA: near

ABS, BYTE, DATAPTR, DWORD,


NEAR, FAR, FWORD, PROC,
QWORD, TBYTE, UNKNOWN,
WORD

Legarea mai multor module


asamblare
Modul 1

End start

Modul 2

End

Modul 3

End

- fiecare modul are n final o directiv END


- numai directiva END a modulului ce conine instruciunea de la care programul
trebuie s-i nceap execuia va conine specificarea adresei de start.

Exemplu
Modulul main.asm

Modulul sub.asm

Declaratii variabile

Declaratii variabile

Sir1 db
Sir2 db
SirFinal db
public SirFinal

extrn SirFinal: byte

Declaratii subrutine

Declaratii subrutine

extrn Concatenare:near

Concatenare proc
(Sir1, Sir2): byte;
public Concatenare

Apeluri subrutine
SirFinal = Concatenare(Sir1, Sir2)

Programul principal main.asm:

Modulul secundar sub.asm:

.MODEL SMALL
.STACK 200
.DATA
Sir1 DB 'Buna ', 0
Sir2 DB 'dimineata!', '$', 0
SirFinal DB 50 DUP (?)
PUBLIC SirFinal
; se poate nlocui cu GLOBAL SirFinal:BYTE
.CODE
EXTRN Concatenare:PROC
Start:
mov ax, @data
mov ds, ax
; ncrcarea registrului ds
mov ax, OFFSET Sir1
mov bx, OFFSET Sir2
call Concatenare
;SirFinal:=Sir1+Sir2
mov ah, 9
mov dx, OFFSET SirFinal
int 21h
;tiprirea irului obinut
mov ah, 4ch
int 21h
; terminarea programului
END Start

.MODEL SMALL
.DATA
EXTRN SirFinal:BYTE
; se poate nlocui cu GLOBAL SirFinal:BYTE
.CODE
PUBLIC Concatenare
Concatenare PROC
cld
mov di, SEG SirFinal
mov es, di
mov di, OFFSET SirFinal ;es:di <- adresa irului final
mov si, ax
; ds:si <- adresa primului ir
Sir1Loop:
lodsb
; al <- caracterul curent
and al, al
; verific dac e zeroul final
jz cont
stosb
; dac nu, l pune n destinaie
jmp Sir1Loop
; reia operaiile
cont:
mov si, bx
; ds:si <- adresa celuilalt ir
Sir2Loop:
lodsb
stosb
; ncarc i zeroul final
and al, al
jnz Sir2Loop
ret
; revenirea din procedur
Concatenare ENDP
END

Programul principal main.asm:

Modulul secundar sub.asm:

DATA SEGMENT
Sir1 DB 'Buna ', 0
Sir2 DB 'dimineata!', '$', 0
SirFinal DB 50 DUP (?)
PUBLIC SirFinal
DATA ENDS

ASSUME CS:CODE

CODE SEGMENT
EXTRN Concatenare:PROC
(sau EXTRN Concatenare:FAR)
Start:
mov ax, data
mov ds, ax
mov ax, OFFSET Sir1
mov bx, OFFSET Sir2
call FAR PTR Concatenare
(si atunci ramane call Concatenare)
;SirFinal:=Sir1+Sir2
mov ah, 9
mov dx, OFFSET SirFinal
int 21h
;tiprirea irului obinut
mov ah, 4ch
int 21h
END Start

EXTRN SirFinal:BYTE
PUBLIC Concatenare
CODE SEGMENT
Concatenare PROC
cld
mov di, SEG SirFinal
mov es, di
mov di, OFFSET SirFinal ;es:di <- adresa irului final
mov si, ax
; ds:si <- adresa primului ir
Sir1Loop:
lodsb
; al <- caracterul curent
and al, al
; verific dac e zeroul final
jz cont
stosb
; dac nu, l pune n destinaie
jmp Sir1Loop
; reia operaiile
cont:
mov si, bx
; ds:si <- adresa celuilalt ir
Sir2Loop:
lodsb
stosb
; ncarc i zeroul final
and al, al
jnz Sir2Loop
ret
; revenirea din procedur
Concatenare ENDP
END

Cele dou module vor fi asamblate separat:


TASM MAIN[.ASM]
TASM SUB[.ASM]
Editarea legturilor se va face:
TLINK MAIN[.OBJ]+SUB[.OBJ]
sau
TLINK MAIN[.OBJ] SUB[.OBJ]
Va rezulta un program executabil main.exe care, lansat n execuie, va tipri mesajul
"Buna dimineata!".

Legarea de module
asamblare cu module scrise
n limbaje de nivel nalt

Cerine ale editorului de legturi.


Intrarea n procedur.
Nealterarea valorilor unor regitri.
Transmiterea i accesarea parametrilor.
Alocarea de spaiu pentru datele locale (opional).
ntoarcerea unui rezultat (opional).
Revenirea din procedur.

Cerine ale editorului de legturi.

Intrarea n procedur.
Nealterarea valorilor unor regitri.
Transmiterea i accesarea parametrilor.
Alocarea de spaiu pentru datele locale (opional).
ntoarcerea unui rezultat (opional).
Revenirea din procedur.

- numele segmentelor sunt impuse de limbajele de nivel nalt cu care se face legtura;
- orice simbol care este definit n modulul scris n limbaj de asamblare i se dorete a fi
folosit n modulul scris n limbaj de nivel nalt trebuie fcut vizibil n acesta din urm,
utiliznd directiva PUBLIC;
- orice simbol care este definit n modulul scris n limbaj de nivel nalt i care va fi utilizat
n modulul scris n limbaj de asamblare trebuie declarat ca extern n acesta din urm,
utiliznd directiva EXTRN;

T
u
r
b
o
A
s
s
e
m
b
l
e
r
*
T
u
r
b
o
P
a
s
c
a
l

Cerine ale editorului de legturi.

Intrarea n procedur.
Nealterarea valorilor unor regitri.
Transmiterea i accesarea parametrilor.
Alocarea de spaiu pentru datele locale (opional).
ntoarcerea unui rezultat (opional).
Revenirea din procedur.

Directiva de compilare $L (poate s apar oriunde n textul surs Pascal. )


{$L nume[.obj]}
Fiierul nume.obj s ndeplineasc condiiile:
- toate procedurile i funciile trebuie s se afle ntr-un segment numit CODE sau CSEG, sau ntr-un
segment al crui nume se termin cu _TEXT;
- toate datele iniializate trebuie s fie plasate ntr-un segment numit CONST sau ntr-un segment al
crui nume se termin cu _DATA;
- toate datele neiniializate trebuie s fie plasate ntr-un segment numit DATA sau DSEG, sau ntr-un
segment al crui nume se termin cu _BSS;
Declaraiilor de tip standard din Pascal le corespund, n limbaj de asamblare, urmtoarele tipuri:
Integer WORD
Real FWORD
Single DWORD
Pointer DWORD

T
u
r
b
o
A
s
s
e
m
b
l
e
r

Cerine ale editorului de legturi.

Intrarea n procedur.
Nealterarea valorilor unor regitri.
Transmiterea i accesarea parametrilor.
Alocarea de spaiu pentru datele locale (opional).
ntoarcerea unui rezultat (opional).
Revenirea din procedur.

Turbo Pascal
- Un subprogram utilizat in programul Pascal dar definit
ntr-un alt modul trebuie s fie declarat cu ajutorul
directivei EXTERNAL (numai la nivelul cel mai exterior al
programului sau unitii):

Procedure AsmProc (a:Integer; b:Real); external;

T
u
r
b
o

Function AsmFunc (c:Word; d:Byte): Integer; external;

P
a
s
c
a
l

Turbo Assembler
Singurele obiecte care pot fi exportate dintr-un modul
scris n limbaj de asamblare ntr-un program sau unitate
Pascal sunt etichetele de instruciuni sau nume de
proceduri declarate PUBLIC.
CODE SEGMENT
AsmProc PROC NEAR
PUBLIC AsmProc
...
AsmProc ENDP
AsmFunc PROC NEAR
PUBLIC AsmFunc
...
AsmFunc ENDP
CODE ENDS
END

T
u
r
b
o
A
s
s
e
m
b
l
e
r
*
T
u
r
b
o
P
a
s
c
a
l

Cerine ale editorului de legturi.

Intrarea n procedur.
Nealterarea valorilor unor regitri.
Transmiterea i accesarea parametrilor.
Alocarea de spaiu pentru datele locale (opional).
ntoarcerea unui rezultat (opional).
Revenirea din procedur.

Turbo Assembler
- Un modul TASM poate accesa orice procedur,
funcie, variabil sau constant cu tip declarat la
nivelul cel mai exterior al unui program sau al unei
uniti Pascal, inclusiv rutinele din biblioteci. Acest
lucru se face cu ajutorul declaraiei EXTRN
DATA SEGMENT
ASSUME DS:DATA
EXTRN A: BYTE
EXTRN B: WORD
EXTRN C: BYTE
...
DATA ENDS
CODE SEGMENT
EXTRN ProcA:NEAR
EXTRN FuncA:FAR
...
; aici pot fi utilizate variabilele a, b, c i pot fi
apelate subprogramele ProcA, FuncA
CODE ENDS

Turbo Pascal
...
{variabile globale}
Var a: Byte;
b: Word;
c: ShortInt;
...
Procedure ProcA;
...
{$F+}
Function FuncA:Integer;
...

Cerine ale editorului de legturi.

Intrarea n procedur.

Nealterarea valorilor unor regitri.


Transmiterea i accesarea parametrilor.
Alocarea de spaiu pentru datele locale (opional).
ntoarcerea unui rezultat (opional).
Revenirea din procedur.

- n momentul n care se face un apel de procedur sau funcie, apelatorul pune mai nti
n stiv adresa de revenire, pe urm d controlul subprogramului apelat folosind pentru
aceasta o instruciune CALL.
- Aceast adres de revenire poate s fie o adres FAR sau o adres NEAR, n funcie
de modelul de memorie n care este compilat sau asamblat modulul.
- Este foarte important ca instruciunea de revenire din subprogram s execute o revenire
care s corespund apelului.
- Dac se dorete apelarea dintr-un modul scris n limbaj de nivel nalt (respectiv limbaj
de asamblare) a unui subprogram scris n limbaj de asamblare (respectiv limbaj de nivel
nalt), editorul de legturi care leag cele dou module nu verific dac tipul apelului (far
sau near) corespunde cu tipul revenirii. Aceast potrivire cade n sarcina programatorului.

Cerine ale editorului de legturi.


Intrarea n procedur.

Nealterarea valorilor unor regitri.

Transmiterea i accesarea parametrilor.


Alocarea de spaiu pentru datele locale (opional).
ntoarcerea unui rezultat (opional).
Revenirea din procedur.

- Limbajele de nivel nalt impun ca anumii regitri s-i pstreze la ieire valoarea cu care intr ntr-o
procedur.
- n acest scop, dac subprogramul, definit n limbaj de asamblare, modific unii dintre acetia, atunci
valorile lor de intrare trebuie salvate (eventual n stiv). Ele vor fi restaurate nainte de revenirea din
procedur.

Turbo Pascal Turbo Assembler


- Cnd este fcut un apel la o funcie sau procedur trebuie pstrat nealterat valoarea a patru
regitri: SS, DS, BP, SP
- n momentul apelului:
SS puncteaz spre segmentul de stiv
DS puncteaz spre segmentul de date global (numit DATA)
BP puncteaz spre baza stivei
SP puncteaz vrful stivei.

Cerine ale editorului de legturi.


Intrarea n procedur.
Nealterarea valorilor unor regitri.

Transmiterea i accesarea parametrilor.

Alocarea de spaiu pentru datele locale (opional).


ntoarcerea unui rezultat (opional).
Revenirea din procedur.

- prin referin NEAR: n stiv se pune, pe un cuvnt, offset-ul adresei;


- prin referin FAR: n stiv se pun dou cuvinte; mai nti se pune segmentul, pe urm se pune
offset-ul;
- prin valoare: n stiv se pune valoarea parametrului.

Turbo Pascal Turbo Assembler


Procedure ProcA(i:integer; var j:integer); external;
- presupunem ca apelul este de tip NEAR
ProcA PROC NEAR
PUBLIC ProcA
j EQU DWORD PTR [BP+4]
i EQU WORD PTR [BP+8]
PUSH BP ; cod de intrare in ProcA
MOV BP, SP
...
MOV AX, i
; ncarc n AX valoarea parametrului i
LES DI, j
MOV ES:[DI], AX
; j:=i

BP=SP

Stiva dupa executia


codului de apel pt ProcA

BP iniial
offset. adr. revenire
offset j
adr. seg. j
valoarea lui i

! Turbo Pascal parametri transmisi prin referinta sunt de tip far

BP+2
BP+4
BP+6
BP+8

T
u
r
b
o
A
s
s
e
m
b
l
e
r

Cerine ale editorului de legturi.


Intrarea n procedur.
Nealterarea valorilor unor regitri.

Transmiterea i accesarea parametrilor.

Alocarea de spaiu pentru datele locale (opional).


ntoarcerea unui rezultat (opional).
Revenirea din procedur.

Parametri transmisi prin valoare


TIP

CE SE PUNE N STIV

Char

- octet fr semn

Boolean

- octet (valoare 0 sau 1)

tip enumerare

- octet fr semn, dac enumerarea are cel mult 256 de valori


- cuvnt fr semn, n caz contrar

T
u
r
b
o

Real

- 6 octei n stiv (excepie !)

tip reprezentat n
virgul flotant

- 4, 6, 8, 10 octei n stiva coprocesorului numeric

Pointer

- 2 cuvinte n stiv

String

- pointer (far) la valoare

P
a
s
c
a
l

tip mulime

- adresa unei mulimi care ocup 32 de octei

Array, Record

- valoarea n stiv, dac lungimea este de 1, 2 sau 4 octei


- pointer la valoare, n caz contrar

Cerine ale editorului de legturi.


Intrarea n procedur.
Nealterarea valorilor unor regitri.
Transmiterea i accesarea parametrilor.

Alocarea de spaiu pentru datele locale (opional).

ntoarcerea unui rezultat (opional).


Revenirea din procedur.

- Dac valoarea lor nu trebuie s se pstreze ntre dou


apeluri consecutive ale procedurii atunci acestea vor fi
alocate n segmentul de stiv i le vom numi date volatile.
- n caz contrar spunem c este vorba despre date statice i
spaiul pentru ele va fi alocat ntr-un segment diferit de
segmentul de stiv, de exemplu n segmentul de date.
Alocarea de spaiu pentru datele statice se face folosind
directivele cunoscute DB, DW, DD .a.
- Alocarea unui numr de n octei (n fiind numr par) pentru
datele locale volatile se poate face cu urmtoarea
instruciune:
sub sp, n

Definire si alocare pt 2
variabile locale in cadrul
unei proceduri externe TP
(scrisa in limbaj de
asamblare si utilizata in
Turbo Pascal)
push bp
mov bp, sp
sub sp, 4
minim EQU [bp-2]
maxim EQU [bp-4]
...
mov ax, 1
mov minim, ax
mov maxim, ax

ntoarcerea unui rezultat

- prin intermediul registrilor, daca valoarea intoarsa este reprezentata pe mai putin de 4 octeti
- exceptie: valorile de tip real, avnd lungimea de 6 octei, sunt returnate tot prin
intermediul regitrilor (n DX:BX:AX).
- dac valoarea ntoars este mai lung exist alte metode de transmitere a rezultatului ctre apelator

Turbo Pascal Turbo Assembler


- rezultat scalar :

1 octet n AL
2 octei n AX
4 octei n DX:AX (DX conine partea high)

- rezultat real

n DX:BX:AX

- rezultat reprezentat n virgul flotant: n regitrii coprocesorului numeric;


- rezultat string :
ntr-o zon temporar alocat de Turbo Pascal n momentul compilrii
programului care conine un apel de astfel de funcie; un pointer la aceast zon este pus n stiv
nainte de a ncepe s pun parametrii. Acest pointer nu face parte din lista de parametri, deci nu
afecteaz numrul de octei ce trebuie scoi din stiv la revenirea din procedur (vezi codul de
ieire);
- rezultat pointer:

n DX se pune adresa de segment, iar n AX se pune deplasamentul.

Cerine ale editorului de legturi.


Intrarea n procedur.
Nealterarea valorilor unor regitri.
Transmiterea i accesarea parametrilor.
Alocarea de spaiu pentru datele locale (opional).
ntoarcerea unui rezultat (opional).

Revenirea din procedur.

- refacerea valorilor regitrilor


- refacerea stivei astfel nct n vrf s conin adresa de revenire.
MOV SP, BP
POP BP

- dac limbajul de nivel nalt pretinde apelatorului eliberarea spaiului ocupat n stiv de
parametri, aceasta se face cu instruciunea
ret n
unde n este numrul de octei care sunt ocupai de ctre parametri

Exemplu
Modulul M1 (Turbo Pascal)

Declaraii variabile

Modulul M2 (asamblare)

Declaraii variabile

var glob:string;
s:string;

Definiii i declaraii subrutine

Definiii i declaraii subrutine

function Asmf
(s:string):string; far; external;

Asmf proc
(s:string):string; far; public;
extrn CitSir: far

function CitSir:string;far;

Apeluri subrutine

Apeluri subrutine

s:=CitSir;
s := Asmf(s);

CitSir;

P.pas
directiva de compilare $L

program TPandASM;
var glob: string; s: string;
{$L asmf.obj}
function Asmf (s: string): string; far; external;
function CitSir: string; far;
var Strn: string;
begin
write ('Sirul: ');
readln (Strn);
CitSir := Strn;
end;
begin
s := CitSir;
glob := 'abc123';
s := Asmf(s);
writeln(s);
readln;
end.

declararea funciei Asmf ca fiind extern; aceast funcie


este definit n modulul scris n limbaj de asamblare dar va fi
folosit n acest modul;

prezena directivei far indic modul de apel al acestui


subprogram, i anume prin specificarea att a adresei de
segment ct i a deplasamentului n cadrul acestui segment}
nu este nevoie de prezena vreunei directive Turbo Pascal
pentru a face aceast funcie vizibil n modulul scris n
limbaj de asamblare, deoarece un modul scris n limbaj de
asamblare poate accesa orice procedur, funcie, variabil
sau constant cu tip declarat la nivelul cel mai exterior al
unui program sau al unei uniti Pascal, inclusiv rutinele din
biblioteci, prin folosirea declaraiei extrn n modulul
asamblare

Asmf.asm
assume cs:_TEXT, ds:_DATA
_DATA segment
extrn glob:byte
_DATA ends
_TEXT segment
extrn CitSir: far
Asmf proc far
public Asmf
push bp
mov bp, sp
sub sp, 100h
sub sp, 100h
rez equ dword ptr [bp+10]
copieSir equ byte ptr [bp-100h]
sloc equ byte ptr [bp-200h]
push ds
lds si, [bp+6]
mov bx, ss
mov es, bx
lea di, copieSir
cld
mov cx, 00FFh
rep movsb

pentru a se putea face legtura ntre acest modul i modulul scris n Turbo
Pascal, modulul scris n limbaj de asamblare trebuie s ndeplineasc
urmtoarele condiii:
- toate procedurile i funciile trebuie s se afle ntr-un segment numit CODE
sau CSEG, sau ntr-un segment al crui nume se termin cu _TEXT;
- toate datele declarate trebuie s fie plasate ntr-un segment numit CONST
sau ntr-un segment al crui nume se termin cu _DATA;
declaraia variabilei glob, definit n modulul Turbo Pascal
declaraia funciei CitSir, care a fost definit n modulul Turbo Pascal,
dar va fi folosit n modulul curent; tipul subrutinei este far
funcia Asmf este definit n acest modul dar va fi folosit n modulul
Turbo Pascal
izolarea stivei
se aloc n stiv 100h octei pentru copia parametrului de tip
string transmis prin valoare
se aloc n stiv 100h octei pentru rezultatul de tip string ntors
de ctre funcia CitSir, care va fi apelat n acest subprogram

Fig. 8.2. Organizarea stivei dup apelul i intrarea n funcia Asmf.


SP
256 octei pentru
rezultatul de tip
string ntors de
funcia CitSir
256 octei pentru copia
parametrului de tip string
transmis funciei Asmf
BP
Adresa de
revenire
Adresa irului transmis
ca parametru
Adresa zonei de memorie
unde va fi stringul
rezultat
ntors de ctre funcia Asmf

BP-200h
(sloc)

BP-100h
(copieSir)

BP iniial
offset adr. revenire

BP+0
BP+2

seg. adr. revenire


offset s

BP+6

adr. seg. s
offset rez
adr. seg. rez

BP+10

Efect al codului de intrare


n Asmf, scris explicit de
catre programator pentru ca
procedura este scrisa in
asamblare si codul de intrare
nu este generat automat

Efect al codului de apel al


funciei Asmf, generat
automat de catre
compilatorul Turbo
Pascal pentru ca apelul
subprogramului are loc in
Turbo Pascal

Asmf.asm

spaiul pentru irul rezultat este alocat n stiv, aadar adresa de


segment a irului rezultat este ss
salvm n stiv aceast adres si deplasamentul
apelul funciei CitSir, care citete un ir i l depune la adresa
ss:sloc

push ss
lea ax, sloc
push ax
call CitSir

Efect al lui call CitSir


Generat explicit de ctre
programator

.
.
.
offset adr. revenire
seg. adr. revenire
offset sloc
adr. seg. sloc (SS)
.
.
.

Efect al codului de apel al funciei


CitSir (fa de apelul funciei Asmf,
aici lipsesc parametri deoarece CitSir
nu are parametri), scris explicit de
catre programator pentru ca
procedura este apelata in asamblare
si codul de apel nu este generat
automat
Stackframe-ul rutinei
apelante Asmf (vezi
figura 8.2.)

Fig. 8.3. Organizarea stivei dup apelul rutinei CitSir.

Asmf.asm
pop ax
pop ax
les di, rez
cld
mov bx, ss
mov ds, bx
lea si, copieSir
mov ch, 0
mov cl, byte ptr [si]
inc si
push di
inc di
cmp cx, 10
jb et1
mov cx, 10
et1:
rep movsb
push ss
pop ds
lea si, sloc
mov cl, byte ptr [si]
inc si
cmp cx, 10
jb et2

eliberarea zonei din stiv n care s-a pus adresa


irului rezultat este responsabilitatea apelatorului
alternativ add sp, 4

numrul de elemente al irului transmis ca


parametru se afl n primul octet al irului

instruciunea movsb se va executa de cx


ori; aceast instruciune copiaz la adresa
es:di (unde se afl irul rezultat) un octet de
la adresa ds:si (unde se afl copia irului
transmis ca parametru)

n continuare vom copia n irul rezultat


primele 10 caractere din irul returnat de ctre
funcia CitSir (irul sloc)
n acest scop, ncrcm n ds:si adresa de
nceput a irului sloc

Asmf.asm
et2:
rep movsb
lea si, glob
mov ax, _DATA
mov ds, ax
mov cl, byte ptr [si]
inc si
cmp cx, 10
jb et3
mov cx, 10
et3:
rep movsb
pop ax
mov bx, di
sub bx, ax
dec bx
les di, rez
mov es:[di], bl
pop ds
mov sp, bp
pop bp
ret 4
asmf endp
_TEXT ends
end

restaurm valoarea pe care ds o avea la


intrarea n subrutin

refacem valorile lui sp i bp (parte a


codului de ieire din subrutina Asmf
cu aceast ocazie se elibereaz cei 200h
octei alocai pentru stringul ntors de CitSir
i pentru copia parametrului transmis ctre
Asmf
ieire din funcie cu scoaterea din stiv a
4 octei (este vorba despre scoaterea din
stiv a parametrului 2 octei pentru
adresa de segment i 2 octei pentru
deplasament)
eliberarea spaiului din stiv ocupat de
parametri face parte tot din codul de ieire
din subrutin

Cod de iesire din functia Asmf, scris explicit de catre


programator, deoarece functia este scrisa in asamblare
si codul de iesire nu este generat automat

S-ar putea să vă placă și