طراحي و پیاده سازی زبانها کنترل زیربرنامه Narges S. Bathaeian كد تابع main متغيرهاي global …… پارامترهاي تابع x آدرس برگشت متغيرهاي محلي تابع x متغيرهاي موقت تابع x ........ …… كد تابع 1 ........ كد تابع 2 ........ Narges S. Bathaeian حافظه تخصيص داده شده به يك برنامه شكل كلي حافظه بعد از loadبرنامه ... Code segment Data segment متغيرهاي global …… پارامترهاي تابع x آدرس برگشت متغيرهاي محلي تابع x متغيرهاي موقت تابع x ........ پارامترهاي تابع y آدرس برگشت متغيرهاي محلي تابع y متغيرهاي موقت تابع y …….. Activation record Activation recordتابع x Activation recordتابع y Narges S. Bathaeian activation record Remember that data storage for subprograms is in an activation record. var X: integer; X is of type integer. L-value of X is some specific offset in an activation record. Goal is to look at locating activation record for P. Given an expression: X = Y + Z 1. Locate activation record containing Y. 2. Get L-value of Y from fixed location in activation record. 4 3. Repeat process for Z and then X. انواع محيطهاي اجرا simple call-return :)fully static( كامال ايستا FORTRAN77 )stack based( مبتني بر پشته C, PASCAL Narges S. Bathaeian )fully dynamic( كامال پويا LISP Fully static قبل از اجراي برنامه ,يك Activation recordبراي هر تابع ,در نظر گرفته مي شود. همه متغيرها ( )global, localاز يك آدرس ثابت قابل دستيابي هستند. پارامترهاي توابع تنها اشاره گر به مكانهايي از تابع صدا زننده هستند. توابع بازگشتي نمي توانيم داشته باشيم. پوينتر نمي توانيم داشته باشيم. Narges S. Bathaeian شكل كلي حافظه در محيط كامال ايستا(الگوی )اول main كد تابع 1 كد تابع .… n كد تابع global متغيرهاي main تابعActivation record 1 تابعActivation record …. n تابعActivation record Narges S. Bathaeian شكل كلي حافظه در محيط كامال ايستا(الگوی متغيرهاي )common( global دوم) آدرس دستور كد تابع main پارامترها و متغيرهای محلی آدرس دستور كد تابع 1 پارامترها و متغيرهای محلی آدرس دستور كد تابع 2 پارامترها و متغيرهای محلی …. Narges S. Bathaeian PROGRAM TEST COMMON MAXSIZE INTEGER MAXSIZE REAL TABLE(10), TEMP MAXSIZE = 10 READ *, TABLE(1), TABLE(2), TABLE(3) CALL QUADMEAN(TABLE,3,TEMP) PRINT *, TEMP END SUBROUTIN QUADMEAN(A, SIZE, QMEAN) COMMON MAXSIZE INTEGER MAXSIZE, SIZE REAL A(SIZE), QMEAN, TEMP INTEGER K TEMP = 0.0 IF(( SIZE.GT.MAXSIZE).OR.(SIZE.LT.1)) GOTO 99 DO 10 K=1, SIZE TEMP = TEMP+ A(K) * A(K) 10 CONTINUE 99 QMEAN = SQRT(TEMP/SIZE) RETURN END مثال از يك برنامه FORTRAN Narges S. Bathaeian مثال از يك برنامه FORTRAN MAXSIZE TEST تابعAct. rec TABLE(1) … TABLE(10) TEMP 3 QUADMEAN تابعAct. rec PROGRAM TEST COMMON MAXSIZE INTEGER MAXSIZE REAL TABLE(10), TEMP MAXSIZE = 10 READ *, TABLE(1), TABLE(2), TABLE(3) CALL QUADMEAN(TABLE,3,TEMP) Return addr. (IP = PC) PRINT *, TEMP END SUBROUTIN QUADMEAN(A, SIZE, QMEAN) COMMON MAXSIZE INTEGER MAXSIZE, SIZE REAL A(SIZE), QMEAN, TEMP INTEGER K TEMP = 0.0 IF(( SIZE.GT.MAXSIZE).OR.(SIZE.LT.1)) GOTO 99 DO 10 K=1, SIZE TEMP = TEMP+ A(K) * A(K) 10 CONTINUE 99 QMEAN = SQRT(TEMP/SIZE) RETURN END Narges S. Bathaeian A SIZE QMEAN RETURN ADDRESS TEMP K Stack based ... Code segment Stack activation record با فراخواني تابع مي شود وpush , stack مربوط به آن در , stack از,هنگام بازگشت به تابع صدازننده . مي شودpop دو نوع Static scope C مانند زبان: local procedure بدون Pascal مانند زبان: local procedure با Dynamic Scope Heap Narges S. Bathaeian Activation record structure PZ09A Programming Language design and Implementation -4th Edition Copyright©Prentice Hall, 2000 x: 15 #include <stdio.h> int x , y ; int gcd ( int u , int v ) { if (v==0) return u; else return gcd(v , u % v); } y: 10 مثال از يك برنامه C Act. rec تابعmain u : 15 v : 10 EP IP u : 10 v :5 EP IP main() { u :5 scanf(“%d%d”, &x , &y ); v :0 printf(“%d\n”,gcd(x,y)); EP return 0; IP } Control link = EP: Environment Pointer Narges S. Bathaeian CEP sp توضيحات frame ( FP = )Current Environment Pointer( CEP :)pointerرجيستري كه در آن آدرس activation recordجاري در آن است. :stack pointer : spرجيستري كه در آن آدرس سر stackدر آن است. :EPآدرس activation recordقبلي را دارد. آدرس متغيرهاي pushشده مي تواند با توجه به CEPو اندازه بايت الزم تعيين شوند. متغيرهاي محلي تابع و موقت بعد از return addressدر تابع pushمي شوند. CEPها تشکیل یک زنجيره بنام )Dynamic chain pointer( DCPمی دهند. Narges S. Bathaeian هنگام فراخواني يك تابع (:)prologue آرگومانها محاسبه شده و در push , stackمي شوند. مقدار CEPدر push , stackمي شود)EP(. مقدار جديد CEPبرابر spجاري مي شود. آدرس بازگشت ( )PCدر push , stackمي شود)IP( . يك jumpبه ابتداي كد تابع فراخواني شده انجام مي شود. Narges S. Bathaeian هنگام بازگشت از يك تابع (:)Epilogue مقدار CEPدر spريخته مي شود. مقدار EPبه داخل CEPريخته مي شود. يك پرش با توجه به آدرس موجود در return addressبه كد انجام مي شود. آرگومانها از pop , stackمي شوند تا مقدار spتصحيح شود. Narges S. Bathaeian #include <stdio.h> int x , y ; int gcd ( int u , int v ) { int t; if (v==0) return u; else { t= gcd(v , u % v); return t;} } main() { scanf(“%d%d”, &x , &y ); printf(“%d\n”,gcd(x,y)); return 0; } مثال از يك برنامه C x: 15 y: 10 Act. rec تابعmain CEP= XX00 sp = XX04 pc = X0X0 Narges S. Bathaeian x: 15 #include <stdio.h> int x , y ; int gcd ( int u , int v ) { int t; pc = X0XA if (v==0) return u; else { t= gcd(v , u % v); return t;} } y: 10 مثال از يك برنامه C Act. rec تابعmain u : 15 v : 10 XX00 X0X0 t: main() { scanf(“%d%d”, &x , &y ); printf(“%d\n”,gcd(x,y)); return 0; } Narges S. Bathaeian CEP=XX0B sp=XX11 x: 15 #include <stdio.h> int x , y ; int gcd ( int u , int v ) { int t; if (v==0) return u; else { t= gcd(v , u % v); return t;} } y: 10 مثال از يك برنامه C Act. rec تابعmain u : 15 v : 10 XX00 X0X0 t : pc = X0XD main() { scanf(“%d%d”, &x , &y ); printf(“%d\n”,gcd(x,y)); return 0; } Narges S. Bathaeian CEP=XX0B sp=XX0F x: 15 #include <stdio.h> int x , y ; int gcd ( int u , int v ) { int t; if (v==0) return u; else { t= gcd(v , u % v); return t;} } main() { scanf(“%d%d”, &x , &y ); printf(“%d\n”,gcd(x,y)); return 0; } y: 10 مثال از يك برنامه C Act. rec تابعmain u : 15 v : 10 XX00 X0X0 t: u : 10 v :5 XX0B X0XD t : Narges S. Bathaeian CEP sp محاسبه offsetمتغيرها در زمان كامپايل آدرس EPدر هر activation recordمبنا در نظر گرفته مي شود. آدرس متغير هايي كه در باالي EPهستند (پارامترهاي تابع) با مقدار مثبت و بقيه با مقدار منفي نمايش داده مي شوند. Narges S. Bathaeian x: 15 مثال y: 10 Act. rec تابعmain :فرض u : 15 v : 10 XX00 X0X0 t: u : 10 v :5 XX0B X0XD t : CEP Int : 2 byte Float : 4 byte Address : 4 byte Char : 1 byte Double : 8 byte v: +4 u: +6 t: -6 Narges S. Bathaeian Procedureهاي تودر تو در هر حوزه ( )scopeبه اسامی تعریف شده در آن حوزه میتوان دسترس ی داشت .پس: هر procedureبه procedureهاي فرزند و برادر خود دسترس ي دارد و مي تواند آنها را فراخواني كند. حوزه متغيرهاي تعريف شده در يك حوزه ,آن حوزه و حوزه های فرزند آن حوزه است. پياده سازي: ) SCP (static chain pointerیا : Access linkآدرس Act. Recپدر (دسترس ي به procedureپدر) فراخواني شده از پدر فراخواني شده از برادر Narges S. Bathaeian program test; Var x,y:integer; Procedure p; … procedure q; begin … r; … end; procedure r; … begin … end; Begin … p; … End; از يك برنامه1 مثال Pascal x: 15 y: 10 Act. rec تابعmain test P q Narges S. Bathaeian اجازه دسترسيها در زمان كامپايل نگهداري مي .شود r از يك برنامه1 مثال Pascal x: 15 y: 10 Act. rec تابعmain Act. Rec p program test; Var x,y:integer; Procedure p; … procedure q; begin … r; … end; procedure r; … begin … end; Begin … p; … End; … No SCP DCP … Narges S. Bathaeian از يك برنامه1 مثال Pascal program test; Var x,y:integer; Procedure p; … procedure q; begin x: 15 … r; … Act. rec تابعmain Act. Rec q Act. Rec p end; procedure r; … begin … q; … end; Begin … p; … End; y: 10 … No SCP DCP … … SCP DCP … :فراخواني از طرف پدر . قرار داده مي شودSCP درCEP مقدار Narges S. Bathaeian از يك برنامه1 مثال x: 15 Pascal y: 10 program test; Var x,y:integer; Procedure p; … procedure q; begin … r; … end; procedure r; … begin … q; … end; Begin … p; … End; Act. Rec r Act. Rec q Act. Rec p Act. rec تابعmain … No SCP DCP … … SCP DCP … … SCP DCP … Narges S. Bathaeian :فراخواني از طرف برادر . قرار داده مي شودSCP برادر درSCP مقدار از يك برنامه2 مثال x: 15 Pascal y: 10 Act. rec تابعmain Act. Rec r Act. Rec q Act. Rec p program test; Var x,y:integer; Procedure p; … procedure q; procedure r; … begin … r; … end; begin … q; … end; Begin … p; … End; … No SCP DCP … … SCP DCP … … SCP DCP … Narges S. Bathaeian SCP زنجيره Displays The idea: Put the static links in a separate stack called a display. The entries in the display are pointers to the Act_recs that have the variables in the referencing environment. Represent references as (display_offset, local_offset) where display_offset is the same as chain_offset Narges S. Bathaeian Displays For a call to procedure P with a static_depth of k: Save, in the new Act_rec, a copy of the display pointer at position k Put the link to the Act_rec for P at position k in the display Narges S. Bathaeian Displays (Example) program MAIN_3; procedure BIGSUB; procedure SUB1; end; { SUB1 } procedure SUB2; procedure SUB3; end; { SUB3 } end; { SUB2 } end; { BIGSUB } end. { MAIN_3 } Narges S. Bathaeian Displays (Example) Case 1: SUB2 calls SUB1 Before the call, we have: A.R. for SUB2 A.R. for BIGSUB program MAIN_3; procedure BIGSUB; procedure SUB1; end; { SUB1 } procedure SUB2; procedure SUB3; end; { SUB3 } end; { SUB2 } end; { BIGSUB } end. { MAIN_3 } 2 1 0 A.R. for MAIN_3 Stack Display After the call, we have: A.R. for SUB1 A.R. for SUB2 A.R. for BIGSUB 2 1 0 A.R. for MAIN_3 Stack Narges S. Bathaeian Display Displays (Example) Case 2: SUB2 calls SUB3 Before the call, we have: AR. for SUB2 AR. for BIGSUB program MAIN_3; procedure BIGSUB; procedure SUB1; end; { SUB1 } procedure SUB2; procedure SUB3; end; { SUB3 } end; { SUB2 } end; { BIGSUB } end. { MAIN_3 } 2 1 0 AR. for MAIN_3 Stack Display After the call, we have: AR. for SUB3 AR. for SUB2 3 2 1 0 AR. for BIGSUB AR. for MAIN_3 Stack Narges S. Bathaeian Display Displays (Example) Case 3: SUB3 calls SUB1 Before the call, we have: AR. for SUB3 AR. for SUB2 3 2 1 0 AR. for BIGSUB program MAIN_3; procedure BIGSUB; procedure SUB1; end; { SUB1 } procedure SUB2; procedure SUB3; end; { SUB3 } end; { SUB2 } end; { BIGSUB } end. { MAIN_3 } AR. for MAIN_3 Stack Display After the call, we have: AR. for SUB1 AR. for SUB3 AR. for SUB2 3 2 1 0 AR. for BIGSUB AR. for MAIN_3 Stack Narges S. Bathaeian Display Dynamic scope rule refers to most recent activation record (DCP) Not fully stack based Stack: function calls Eamples Lisp … Narges S. Bathaeian Static vs. Dynamic Scope Example var x=1; function g(z) { return x+z; } function f(y) { var x = y+1; return g(y*x); } f(3); outer block x 1 f(3) y x 3 z 12 g(12) 4 Which x is used for expression x+z ? static scope dynamic scope slide 36 Retention vs. Deletion Retention Deletion Fortran Static and global variables in C Narges S. Bathaeian Local variables in C, Pascal Parameter passing Parameter: A variable in a procedure that represents some other data from the procedure that invoked the given procedure. Parameter transmission: How that information is passed to the procedure. The parameter is also called the formal argument.The data from the invoking procedure is called the actual argument or sometimes just the argument. • • • • • Usual syntax: Actual arguments: call P(A, B+2, 27+3) Parameters: Procedure P(X, Y, Z) What is connection between the parameters and the arguments? Call by name Call by reference Call by value 38 Call by result (or value-result) Language dependent • • • Difference languages have different mechanisms: ALGOL - name, value Pascal - value, reference C - value (BUT pointers give us reference Constant tension between desire for efficiency and semantic correctness in defining parameter transmission. 39 Call by name Substitute argument for parameter at each occurrence of parameter: Invocation: P(A, B+2, 27+3) Definition: procedure P(X,Y,Z) {int I; I=7; X = I + (7/Y)*Z;} Meaning: P(X,Y,Z) {int I; I=7; A=I+(7/(B+2))*(27+3);} This is a true macro expansion. Simple semantics, BUT: 1. Implementation. How to do it? 2. Aliases. What if statement of P were: I = A? 3. Expressions versus statements: If we had D=P(1,2,3) and a return(42) in P, what does semantics mean? 4. Error conditions: P(A+B, B+2, 27+3) 40 Implementation of call by name A thunk is the code which computes the L-value and Rvalue of an argument. For each argument, pass code address that computes both L-values and R-values of arguments. P(A, B+2, 27+3) generates: jump to address address address address address address To assign To assign To assign subroutine P of thunk to return L-value(A) of thunk to return R-value(A) of thunk to return L-value(B+2) of thunk to return R-value(B+2) of thunk to return L-value(27+3) of thunk to return R-value(27+3) to X, call thunk 1, To access X, call thunk 2 to Y, call thunk 3, To access Y, call thunk 4 to Z, call thunk 5, To access Z, call thunk 6 Issue: Assignment to (B+2): How? Call by name is conceptually convenient, but inefficient. 41 Examples of Call by Name 1. P(x) {x = x + x;} Seems simple enough … Y = 2; P(Y); write(Y) means Y = Y+Y write(Y) prints 4 2. int A[10]; for(I=0; I<10; I++) {A[I]=I;}; I=1; P(A[I]) A[1] = A[1] + A[1] A[1] set to 2 3. But: F {I = I + 1; return I;} What is: P(A[F])? P(A[F]) A[F] = A[F]+A[F] A[I++] = A[I++]+A[I++] A[2] = A[3]+A[4] 4. Write a program to exchange values of X and Y: (swap(X,Y)) Usual way: swap(x,y) {t=x; x=y; y=t;} Cannot do it with call by name. Cannot handle both of following: swap(I, A[I]) swap(A[I],I) One of these must fail. 42 Call by reference Pass the L-value of the argument for the parameter. Invocation: P(A, B+2, 27+3) Implementation: Temp1 = B+2 Temp2 = 27+3 jump to subroutine P L-value of A L-value of Temp1 L-value of Temp2 This is the most common parameter transmission mechanism. In the procedure activation record, parameter X is a local variable whose R-value is the L-value of the argument. 43 Call by value Pass the R-value of the argument for the parameter. Invocation: P(A, B+2, 27+3) Implementation: Temp1 = Temp2 = jump to R-value R-value R-value B+2 27+3 subroutine P of A of Temp1 of Temp2 In procedure activation record, parameter X is a local variable whose R-value is the R-value of the argument. 44 Call by reference in C C only has call by value, BUT pointer variables allow for simulating call by reference: P(i, j) passes i and j by value. P(&i, &j) passes L-values of i and j. P(*x, *y) {*x = *y + 1;} arguments are addresses (pointers) 45 Call by result (or valueresult) Call by value, AND pass back the final value to argument upon return. Parameter is a local value in procedure. Similar to call by reference, except for aliasing. Narges S. Bathaeian Pass by value مقدار يك پارامتر قبل از فراخواني تابع محاسبه شده و نتيجه فرستاده مي شود. تغيير پارامتر در تابع فراخواني شده ,تاثيري در تابع فراخواني كننده ندارد .مگر اينكه اشاره گر به متغير فرستاده شده باشد. ADA , Pascal , C Narges S. Bathaeian )void inc2(int x ;{ ++x بي تاثير } ;++x )void inc2(int *x ;){ ++(*x موثر } ;)++(*x Pass by reference مقدار آدرس پارامتر فرستاده مي شود. عنوان پارامتر در تابع فراخواني شده ,مجازي است. & C++ : Fortran77 Pascal : var )void inc2(int &x ;{ ++x } ;++x در تابع فراخواني شده, آدرس پارامتر كه بطور نسبي فرستاده شده بايد با توجه به SCPدوباره محاسبه شود. Narges S. Bathaeian Pass by value-result مقدار يك پارامتر قبل از فراخواني تابع محاسبه شده و نتيجه فرستاده مي شود .سپس مقدار پارامتر پس از تغيير در تابع فراخواني شده ,دوباره در مكان اول خود كپي مي شود. )void p(int x, int y ;{ ++x } ;++y ADA : in out پياده سازي؟ a=2 Narges S. Bathaeian )(main ;{ int a=1 ;)p(a,a ;)printf(“%d”, a ;return 0 } Pass by name مقدار يك پارامتر قبل از فراخواني تابع محاسبه نشده و در تابع فراخواني شده محاسبه مي شود. هر پارامتر ,خود يك procedure است. Algol60 نتايج غير منتظره پياده سازي مشكل Lazy evaluating a[1]=1 a[2]=2 ;i=2 ;]int a[10 ;int i )void p(int x ;{ ++i } ;++x )(main ;{ i=a[1]=a[2]=1 ;)]p(a[i ;)]printf(“%d %d”, a[1],a[2 ;return 0 Narges S. Bathaeian } Block برخي زبانها مانند Cبلوك بندي مي شوند. Scopeمتغيرهاي تعريف شده در يك بلوك ,آن بلوك و بلوكهاي فرزند آن بلوك است. ... )(main { ;int i,j { ;int k=0 ;i=j=1 … } k=… //undefined variable k … } Narges S. Bathaeian پياده سازي بلوك با وارد شدن به يك بلوك متغيرها در push ,stackمي شوند. با خارج شدن از يك بلوك متغيرها از pop ,stackمي شوند. در محاسبه offsetمتغيرها در زمان كامپايل بايد دقت شود .بلوكهاي برادر از offsetيكساني شروع مي شوند. Narges S. Bathaeian Fully Dynamic را به عنوان آرگومان برگشتيprocedure مي توان يكModula2 در . ديگر داشتprocedure . پياده سازي مي شودheap كامال در :مثال صوري typedef int (*proc)(void); proc g(int x) { int f(void) {return x; } return f; } main() { proc c; c = g(2); printf(“%d”,c()); return 0; } Narges S. Bathaeian تخصيص حافظه در خواست تخصيص حافظه توسط برنامه malloc , new پيدا كردن فضاي مناسب خالي در حافظه در خواست آزادسازي حافظه توسط برنامه free آزادسازي حافظه و اضافه كردن آن به ليست فضاهاي خالي Narges S. Bathaeian Dynamic environment براي مواقعي كه طول عمر يك متغير بيشتر از procedureمربوطه است. بخاطر popشدن procedureبا stackقابل پياده سازي نيست. مثال: )int *dangle(void ;{ int x };return &x آدرس xیک آرگومان برگشتي است .پس بايد در قسمتي جدا از stackتعريف شده باشد. ... Code segment Stack Heap Narges S. Bathaeian