Aplicaţii mixte C-ASM
1.1. Transferul parametrilor
• compilatorul de Borland C realizează tra nsferul parametrilor spre funcţii prin stivă (în ordinea
dreapta-stânga), apelul unei funcţii C din ASM presupune plasarea parametrilor în stivă şi apoi
apelarea funcţiei C;
• deoarece în C descărcarea stivei este făcută de modulul apelant, un program ASM trebuie să descarce
stiva după apelarea unei funcţii C.
1.2. Întoarcerea rezultatelor
După executarea unei funcţiiC, rezultatul se va întoarce în funcţie de dimensiunea zcestuia, în felul următor:
• 1 octet: în registrul AL (char);
• 2 octeţi: în registrul AX (int şi short);
• 4 octeţi: în perechea de registre DX:AX (long şi float);
• float (4 octeţi), double (8 octeţi), long double (10 octeţi): într-o zonă specială a bibliotecii de
virgulă mobilă sau în vârful stivei coprocesorului matematic. O soluţie pentru rezultatele de tip real
ar fi ca funcţia să întoarcă pointeri la aceste valori.
1.3. Numele simbolurilor externe
În C numele simbolurilor externe (nume de variabile, nume de funcţii) sunt generate implicit cu caracterul
“_” precedând numele simbolului. Cu alte cuvinte, parametrii din C, utilizaţi şi în modulul scris în limbaj de
asamblare, vor fi precedaţi de caracterul “_”. În modulul în care simbolurile sunt definite, ele se declară
PUBLIC, iar în modulele în care ele sunt referite se declară EXTRN. În unul din module (C sau ASM),
trebuie să existe funcţia main, care în ASM se declară în felul următor:
public _main
_main proc
……….
ret
_main endp
Următoarea aplicaţie mixtă calculează recursiv factorialul unui număr citit de la tastatură:
Modulul C:
#include <stdio.h>
#include <conio.h>
Modulul ASM:
.model tiny
extrn _clrscr:near, _scanf:near, _printf:near, _getch:near
public _main
.stack 1024
sablon struc
_bp dw ?
_ip dw ? ;_cs_ip dd ? - modificare I
_n dw ?
sablon ends
.data
n dw ?
MesRd db 'Introduceti un intreg: ',0
MesWr db 'Factorialul este %d...',0
scan db '%d',0
.code
Factorial proc near ;Factorial proc far - modificare I
push bp
mov bp,sp
;+ push ds - modificare II
;+ push es - modificare II
push dx
push bx
mov bx,[bp]._n
cmp bx,1
jne et1
mov ax,1
jmp et2
et1: dec bx
push bx ; parametru salvat in stiva
call near ptr Factorial ; call far ptr Factorial - modificare I
add sp,2
mul [bp]._n
et2: pop bx
pop dx ; ax - contine rezultatul deci nu se restaureaza
;+ pop es - modificare II
;+ pop ds - modificare II
pop bp ; ===> ax nu trebuie salvat in stiva la inceputul proc
retn ;retf - modificare I
Factorial endp
_main proc near ;_main proc far - modificare I
call near ptr _clrscr ; call far ptr _clrscr - modificare I
;+ mov ax, seg MesRd - modificare II
;+ push ax - modificare II
lea ax, MesRd
push ax
call near ptr _printf ; call far ptr _printf - modificare I
add sp,2 ; add sp, 4 - modificare II
;+ mov ax, seg n - modificare II
;+ push ax - modificare II
lea ax, n
push ax
;+ mov ax, seg scan - modificare II
;+ push ax - modificare II
lea ax, scan
push ax
call near ptr _scanf ; call far ptr _scanf - modificare I
add sp,4 ; add sp, 8 - modificare II
mov ax,n
push ax
call near ptr Factorial ; call far ptr Factorial - modificare I
add sp,2
push ax
;+ mov ax, seg MesWr - modificare II
;+ push ax - modificare II
lea ax,MesWr
push ax
call near ptr _printf ; call far ptr _printf - modificare I
add sp,4 ; add sp, 6 - modificare II
call near ptr _getch ; call far ptr _getch - modificare I
retn ; retf - modificare I
_main endp
end
Observaţie: Modificările I trebuie făcute în cazul utilizării modelelor de memorie cu apel de procedură de
tip far, iar modificările II trebuie făcute atunci când se folosesc modele de memorie cu adrese fizice
(complete). În cel de-al doilea caz, simbolul @data trebuie modificat cu simbolul DGROUP.
2. Aplicaţii
Să se realizeze funcţii care rezolvă recursiv următoarele probleme:
1. Calculaţi suma cifrelor unui număr
+ >
=
=
%10 ( 10/ ), 0
,0 0
( )
n sumac n n
n
sumac n
2. Calculaţi
>
=
=
( , % ), 0
, 0
( , )
cmmdc b a b b
a b
cmmdc a b
3. Se dă un şir ordonat crescător. Realizaţi funcţia ce implementează căutarea binară.
+ <
− >
= = +
>
=
cauta m d val a m val
cauta s m val a m val
a m val unde m s d
s d
cauta s d val
( ,1 , ), [ ]
( , ,1 ), [ ]
,1 [ ] , ( 2/)
,0
( , , )
4. Suma elementelor unui vector
+ − >
=
=
[ ] ( ),1 0
],0[ 0
( )
a i sumas i i
a i
sumas i
5. Verificarea dacă un vector e palindrom
+ −
=
>=
=
pali s d in rest
a s a d
s d
pali s d
( ,1 ),1
,0 [ ]! [ ]
,1
( , )
6. Descompunerea unui număr în factori primi
+
=
=
desc n d in rest
scrie d desc n d d daca d n
n
desc n d
( , ),1
, ( / , ), |
,1 1
( , )
7. Conversia unui număr din baza 10 în baza 2.
8. Calculul coeficientului de grad n al polinomului Cebîşev de speta I.
⋅ − − −
=
=
=
( ) 1
( ) 2
2
, 1
,1 0
( )
x Tn
x Tn
x n
n
x Tn
9. Calculaţi valoarea functiei Ackermann
− −
− =
+ =
A m A m n inrest
A m n
n m
A m n
( ,1 ( , 1)),
( ),1,1 0
,1 0
( , )
10. Cautarea minimului şi maximului intr-un sir de n valori.
11. Determinarea numărului de apariţii a unei valori într-un şir.
1.1. Transferul parametrilor
• compilatorul de Borland C realizează tra nsferul parametrilor spre funcţii prin stivă (în ordinea
dreapta-stânga), apelul unei funcţii C din ASM presupune plasarea parametrilor în stivă şi apoi
apelarea funcţiei C;
• deoarece în C descărcarea stivei este făcută de modulul apelant, un program ASM trebuie să descarce
stiva după apelarea unei funcţii C.
1.2. Întoarcerea rezultatelor
După executarea unei funcţiiC, rezultatul se va întoarce în funcţie de dimensiunea zcestuia, în felul următor:
• 1 octet: în registrul AL (char);
• 2 octeţi: în registrul AX (int şi short);
• 4 octeţi: în perechea de registre DX:AX (long şi float);
• float (4 octeţi), double (8 octeţi), long double (10 octeţi): într-o zonă specială a bibliotecii de
virgulă mobilă sau în vârful stivei coprocesorului matematic. O soluţie pentru rezultatele de tip real
ar fi ca funcţia să întoarcă pointeri la aceste valori.
1.3. Numele simbolurilor externe
În C numele simbolurilor externe (nume de variabile, nume de funcţii) sunt generate implicit cu caracterul
“_” precedând numele simbolului. Cu alte cuvinte, parametrii din C, utilizaţi şi în modulul scris în limbaj de
asamblare, vor fi precedaţi de caracterul “_”. În modulul în care simbolurile sunt definite, ele se declară
PUBLIC, iar în modulele în care ele sunt referite se declară EXTRN. În unul din module (C sau ASM),
trebuie să existe funcţia main, care în ASM se declară în felul următor:
public _main
_main proc
……….
ret
_main endp
Următoarea aplicaţie mixtă calculează recursiv factorialul unui număr citit de la tastatură:
Modulul C:
#include <stdio.h>
#include <conio.h>
Modulul ASM:
.model tiny
extrn _clrscr:near, _scanf:near, _printf:near, _getch:near
public _main
.stack 1024
sablon struc
_bp dw ?
_ip dw ? ;_cs_ip dd ? - modificare I
_n dw ?
sablon ends
.data
n dw ?
MesRd db 'Introduceti un intreg: ',0
MesWr db 'Factorialul este %d...',0
scan db '%d',0
.code
Factorial proc near ;Factorial proc far - modificare I
push bp
mov bp,sp
;+ push ds - modificare II
;+ push es - modificare II
push dx
push bx
mov bx,[bp]._n
cmp bx,1
jne et1
mov ax,1
jmp et2
et1: dec bx
push bx ; parametru salvat in stiva
call near ptr Factorial ; call far ptr Factorial - modificare I
add sp,2
mul [bp]._n
et2: pop bx
pop dx ; ax - contine rezultatul deci nu se restaureaza
;+ pop es - modificare II
;+ pop ds - modificare II
pop bp ; ===> ax nu trebuie salvat in stiva la inceputul proc
retn ;retf - modificare I
Factorial endp
_main proc near ;_main proc far - modificare I
call near ptr _clrscr ; call far ptr _clrscr - modificare I
;+ mov ax, seg MesRd - modificare II
;+ push ax - modificare II
lea ax, MesRd
push ax
call near ptr _printf ; call far ptr _printf - modificare I
add sp,2 ; add sp, 4 - modificare II
;+ mov ax, seg n - modificare II
;+ push ax - modificare II
lea ax, n
push ax
;+ mov ax, seg scan - modificare II
;+ push ax - modificare II
lea ax, scan
push ax
call near ptr _scanf ; call far ptr _scanf - modificare I
add sp,4 ; add sp, 8 - modificare II
mov ax,n
push ax
call near ptr Factorial ; call far ptr Factorial - modificare I
add sp,2
push ax
;+ mov ax, seg MesWr - modificare II
;+ push ax - modificare II
lea ax,MesWr
push ax
call near ptr _printf ; call far ptr _printf - modificare I
add sp,4 ; add sp, 6 - modificare II
call near ptr _getch ; call far ptr _getch - modificare I
retn ; retf - modificare I
_main endp
end
Observaţie: Modificările I trebuie făcute în cazul utilizării modelelor de memorie cu apel de procedură de
tip far, iar modificările II trebuie făcute atunci când se folosesc modele de memorie cu adrese fizice
(complete). În cel de-al doilea caz, simbolul @data trebuie modificat cu simbolul DGROUP.
2. Aplicaţii
Să se realizeze funcţii care rezolvă recursiv următoarele probleme:
1. Calculaţi suma cifrelor unui număr
+ >
=
=
%10 ( 10/ ), 0
,0 0
( )
n sumac n n
n
sumac n
2. Calculaţi
>
=
=
( , % ), 0
, 0
( , )
cmmdc b a b b
a b
cmmdc a b
3. Se dă un şir ordonat crescător. Realizaţi funcţia ce implementează căutarea binară.
+ <
− >
= = +
>
=
cauta m d val a m val
cauta s m val a m val
a m val unde m s d
s d
cauta s d val
( ,1 , ), [ ]
( , ,1 ), [ ]
,1 [ ] , ( 2/)
,0
( , , )
4. Suma elementelor unui vector
+ − >
=
=
[ ] ( ),1 0
],0[ 0
( )
a i sumas i i
a i
sumas i
5. Verificarea dacă un vector e palindrom
+ −
=
>=
=
pali s d in rest
a s a d
s d
pali s d
( ,1 ),1
,0 [ ]! [ ]
,1
( , )
6. Descompunerea unui număr în factori primi
+
=
=
desc n d in rest
scrie d desc n d d daca d n
n
desc n d
( , ),1
, ( / , ), |
,1 1
( , )
7. Conversia unui număr din baza 10 în baza 2.
8. Calculul coeficientului de grad n al polinomului Cebîşev de speta I.
⋅ − − −
=
=
=
( ) 1
( ) 2
2
, 1
,1 0
( )
x Tn
x Tn
x n
n
x Tn
9. Calculaţi valoarea functiei Ackermann
− −
− =
+ =
A m A m n inrest
A m n
n m
A m n
( ,1 ( , 1)),
( ),1,1 0
,1 0
( , )
10. Cautarea minimului şi maximului intr-un sir de n valori.
11. Determinarea numărului de apariţii a unei valori într-un şir.
Niciun comentariu:
Trimiteți un comentariu