450 likes | 564 Views
Troisième Partie Chapitre 3 Un Processeur à Pile. A Generic Processor. T. B. . . . 5 4 3 2 1 0. . . . 5 4 3 2 1 0. I. P. code. data. Code memory is addressable, random access. During program execution, it is “read only”
E N D
Troisième Partie Chapitre 3 Un Processeur à Pile
A Generic Processor T B . . . 5 4 3 2 1 0 . . . 5 4 3 2 1 0 I P code data
Code memory is addressable, random access. During program execution, it is “read only” The “Program counter” (P) contains the address in code memory of the next instruction to be fetched When an instruction is fetched it is kept in the Instruction register (I) to be executed by the control unit. The operation of this stack machine will be described by means of an executable C++ program that interprets the instructions just as the actual hardware would do. Stack processorCode Memory Usage
Data memory is addressable, random access. Part of it can be managed as a LIFO stack Base register (B) Top of Stack register (T) Data memory is used to store: Variables of active blocks (= activation record) Temporary variables Return addresses of subroutines Static and dynamic data links Procedure parameters Stack processorData Memory Usage
Data handling : CHS : Change sign of top of stack (tos) EXC : Exchange two topmost elements of stack ADD : Add two topmost elements of stack SUB : Subtract tos from underlying element MUL : Multiply two topmost elements of stack DIV : Divide underlying element by tos EQ? : Are two topmost elements equal ? NE? : Are two topmost elements different ? LT? : Is tos less than underlying element ? LE? : Is tos less than or equal to underlying element ? GT? : Is tos greater than underlying element ? GE? : Is tos greater than or equal to underlying element ? Stack processorInstructions
Data transfer : LIT,a : load a constant on tos. LOD,l,a : copy value from specified address to tos STO,l,a : move value from tos to specified address. LDI,l,a : copy value from indirect address to tos STI,l,a : move value from tos to indirect address. Miscellaneous : INT,a : Increment stack pointer by constant value. LAD,l,a : Load specified address on tos. Stack processorInstructions
Control : JMP,a : Jump to specified address in code JPT,a : Jump if the value TRUE is on tos. JPF,a : Jump if the value FALSE is on tos JSR,a : Call subroutine at specified address in code RET : Return from subroutine HLT : Stop execution Stack processorInstructions
Interpreter : Data Types enum Opcode {EXC,CHS,ADD,SUB,MUL,DIV, EQ?,NE?,LT?,LE?,GT?,GE?, LIT,LOD,STO,LDI,STI,LIT,LAD, JMP,JPT,JPF,JSR,RET,HLT }; struct Instr {Opcode opc; int l,a; }
Interpreter : Variables instr Code[1000]; int D[1000]; instr I; int P,B,T;
Main Loop Running = true; do { I = Code[P]; P = P + 1; switch (I.opc) {case CHS : ... break; case EXC : ... break; ... case HLT : Running = false; } } while Running
Data memory is addressable, random access. Part of it can be managed as a LIFO stack Base register (B) Top of Stack register (T) Data memory is used to store: Variables of active blocks (= activation record) Temporary variables Return addresses of subroutines Static and dynamic data links Procedure parameters Stack processorData Memory Usage
Instruction Interpretation (1) // CHS : Change sign of top of stack (tos) case CHS : D[T] = - D[T]; break; // EXC : Exchange two topmost elements of stack case EXC : D[T+1] = D[T-1]; D[T-1] = D[T]; D[T] = D[T+1]; break; // ADD : Add two topmost elements of stack case ADD : T = T-1; D[T] = D[T] + D[T+1]; break;
Instruction Interpretation (2) // EQ? : Are two topmost elements equal ? case EQ? : T = T-1; D[T] = D[T+1] == D[T];break; // NE? : Are two topmost elements different ? case NE? : T = T-1; D[T] = D[T+1] != D[T];break; // LT? : Is tos less than underlying element ? case LT? : T = T-1; D[T] = D[T+1] < D[T];break;
Instruction Interpretation (3) // JMP,a : Jump to specified address in code case JMP : P = I.a; break; // JPT,a : Jump if the value TRUE is on tos. case JPT : T = T-1; if( D[T+1])P = I.a; break; // JPF,a : Jump if the value FALSE is on tos case JPF : T = T-1; if(!D[T+1])P = I.a; break;
Evaluate B FALSE TRUE B L1 S2 S1 L2 Compilation Pattern : IF if (B){S1}; else {S2}; Evaluate B JPF L1 Code for S1 JMP L2 L1 :Code for S2 L2: ...
Compilation Pattern : Loop while (B) do {S} ; L1 :Evaluate B JPF L2 Code for S JMP L1 L2 : . . . L1 Evaluate B FALSE B TRUE S L2
L1 S Evaluate B TRUE B FALSE Compilation Pattern : Loop do {S} while (B); L1 :Code for S Evaluate B JPT L1 . . .
Data memory is addressable, random access. Part of it can be managed as a LIFO stack Base register (B) Top of Stack register (T) Data memory is used to store: Variables of active blocks (= activation record) Temporary variables Return addresses of subroutines Static and dynamic data links Procedure parameters Stack processorData Memory Usage
Data Transfer instructionsfor local variables T B . . . 5 4 3 2 1 0 . . . 5 4 3 2 1 0 0.a I P code data
Instruction Interpretation (4)Restricted to local variables // LOD,0,a : copy value from specified address to tos case LOD : T = T+1; D[T] = D[B + I.a]; break; // STO,0,a : move value from tos to specified address. case STO : D[B+I.a] = D[T]; T = T-1; break;
Instruction Interpretation (5) // LIT,a : load a constant on tos. case LIT : T = T + 1; D[T] = I.a; break; // INT,a : modify stack pointer ( a pos. or neg.) case INT : T = T + I.a; break;
3 b a a+3 Compilation Pattern : expression x = (a+3) * b // a,b,x local variables Reverse polish notation : a 3 + b *, LOD,0,a LIT,3 ADD LOD,0,b MUL STO,0,x 1 2 3 4 1 a+3 (a+3)*b 2 3 4
Evaluate N and M a = N L2 FALSE a < M S a = a+1 L1 Compilation Pattern : for loop for (a = N;a <= M; a++) S; Evaluate M Evaluate N L2 STO 0,a INT 1 restore access to a EXC GT? M < N => skip loop JPT L1 go to next statement INT 2 save M for future use EXC code for S INT -1 LAD 0,a put value of a on tos LIT 1 put a 1 above it ADD JMP L2 restart the loop
Data memory is addressable, random access. Part of it can be managed as a LIFO stack Base register (B) Top of Stack register (T) Data memory is used to store: Variables of active blocks (= activation record) Temporary variables Return addresses of subroutines Static and dynamic data links Procedure parameters Stack processorData Memory Usage
Procedure Call . . . Local Variables AFTER JSR T Return Address B BEFORE JSR . . .
Instruction Interpretation (6) // JSR,a : Call subroutine at specified address in code case JSR : D[T+1] = P; P = I.a; D[T+3] = base(l); D[T+2] = B; B = T + 2;break; // RET : Return from subroutine case RET : T = B - 2; B = D[T+2]; P = D[T+1];break;
Procedure Call . . . Local Variables AFTER JSR Dynamic Link T Return Address B BEFORE JSR . . . Dynamic Link
Instruction Interpretation (7) // JSR,a : Call subroutine at specified address in code case JSR : D[T+1] = P; P = I.a; D[T+3] = base(l); D[T+2] = B; B = T + 2; break; // RET : Return from subroutine case RET : T = B - 2; B = D[T+2]; P = D[T+1];break;
StaticLinks Data Memory Base Register ORANGE Activation Record YELLOW Activation Record GREEN Activation Record Static links Dynamic links PURPLE Activation Record BLUE Activation Record
Static Link Int function base( int l ); // l = level of globality relative to the present level // of nesting, is always 0 or 1 in C programs. { int btemp; btemp = B; // start @ current base pointer while (l>0) do { btemp = D[btemp+1] ; l = l - 1; } // skip static link 1 level up return btemp; }
Instruction Interpretation (8) // JSR,a : Call subroutine at specified address in code case JSR : D[T+1] = P; P = I.a; D[T+3] = base(l); D[T+2] = B; B = T + 2; break; // RET : Return from subroutine case RET : T = B - 2; B = D[T+2]; P = D[T+1];break;
Instruction Interpretation (9) // JSR,a : Call subroutine at specified address in code case JSR : D[T+1] = P; P = I.a; D[T+3] = base(l); D[T+2] = B; B = T + 2; break; // RET : Return from subroutine case RET : T = B - 2; B = D[T+2]; P = D[T+1]; break;
Procedure Call . . . To be done explicitly by programmer Local Variables Static Link AFTER JSR Dynamic Link T Return Address B BEFORE JSR . . .
Instruction Interpretation (10)For all variables // LOD,l,a : copy value from specified address to tos case LOD : T = T+1; D[T] = D[base(I.l) + I.a]; break; // STO,l,a : move value from tos to specified address. case STO : D[base(I.l)+I.a] = D[T]; T = T-1; break;
CCC abc CCC uvw Procedure Parameters Actual Parameters Formal Parameters DoCCC(abc) Subroutine DoCCC(xyz) CCC xyz End DoCCC DoCCC(uvw)
Parameter Passing Data Memory Base Register Called Block Activation Record Actual Parameters Static link Dynamic links Calling Block Activation Record
Data Transfer instructionsfor indirect addresses T B . . . 5 4 3 2 1 0 . . . 5 4 3 2 1 0 l.a I P code data
Instruction Interpretation (11) LDI,l,a : copy value from indirect address to tos case LDI :T = T+1; D[T] = D[D[base(I.l) + I.a]]; break; STI,l,a : move value from tos to indirect address. case STI :D[D[base(I.l) + I.a]] = D[T]; T = T-1; break; LAD,l,a : write address to tos case LAD :T = T+1; D[T] = base(I.l) + I.a;break;
Function Definition void P(int x, int y, int&z) { z=x+y; } . . . INT 3no local vars LOD 0,- 4x LOD 0,- 3y ADD STI 0,-2z:= … RET S.L. D.L. T R.A. Addr z B y x . . .
S.L. D.L. T R.A. Addr c B b 2 . . . Function Call intb,c ; … P(int 2,b,&c); ... LIT 2 first parameter LOD 0,b second parameter LAD 0,caddress of c JSR 1,P INT -3 remove parameters
t S.L. D.L. T R.A. y B x Ret. Val. . . . Function Definition int P(int x, int y); {int t; t =x+y; … return t; } INT 4allocate t LOD 0,-3 x LOD 0,-2 y ADD STO 0,+2 t = x + y … LOD 0,+2 get t on top STO 0,- 4Ret.Val. = t RET
t S.L. D.L. T R.A. b B 2 Ret. Val. x Function ApplicationDuring function execution intx,z,b:. . .; int P(…); … z =x+ P(int 2,b); … LOD 0,x LIT 0 return value LIT 2 LOD 0,b JSR 1,P INT -2 ADD STO 0,z
t S.L. D.L. T R.A. b B 2 Ret. Val. x Function ApplicationJust after return intx,z,b:. . .; int P(…); … z :=x+ P(int 2,b); … . . . LOD 0,x LIT 0 return value LIT 2 LOD 0,b JSR 1,P INT -2 ADD STO 0,z
Recursive Function Example A recursive function is a function that can call itself. Although few reasonable people would use a recursive function to compute the factorial of a number, this can be done and results in a simple example of recursive reasoning and programming. int fac(int n) { if (n > 1) return n * fac(n-1); else return 1; }
Recursive Function Example FAC INT 3 No local variables! LIT 1 Prepare to compare against 1 LOD 0,-2 the value of n GT? JPF ret1 if less or equal go to ret1 LOD 0,-2 Load n on top of stack LIT 0 Reserve for returned value LOD 0,-2 Load again n on top of stack LIT 1 Prepare for computing n-1 SUB the value of n-1 will be the actual parameter JSR 1,FAC for this recursive call of FAC. INT -1 Recover the space used by n-1 MUL compute the product n* FAC(n-1) STO 0,-3 Store that value at the reserved place RET and return from the current version of FAC Ret1 LIT 1 Prepare to return a value of 1. STO 0,-3 Store the returned value at the reserved place RET and return from the current version of FAC