Giáo trình Chương trình dịch - Bài 11: Sinh mãm đích - Nguyễn Thị Thu Hương

Bộ sinh mã trung gian đưa ra mã ba địa chỉ „ Tối ưu trên mã ba địa chỉ „ Từ mã ba địa chỉ đã tối ưu sinh ra mã đích phù hợp với một mô tả máy ảo

pdf11 trang | Chia sẻ: huongthu9 | Lượt xem: 476 | Lượt tải: 0download
Bạn đang xem nội dung tài liệu Giáo trình Chương trình dịch - Bài 11: Sinh mãm đích - Nguyễn Thị Thu Hương, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
21/1/2010 1 Bài 12 Sinh mã đích 1 Nguyễn Thị Thu Hương Nội dung z Tổng quan về sinh mã đích z Máy ngăn xếp z Tổ chức bộ nhớ z Bộ lệnh Lớp KHMT K50 2 z Sinh mã cho các lệnh cơ bản z Xây dựng bảng ký hiệu z Biến z Tham số z Hàm, thủ tục và chương trình Chương trình đích „ Viết trên một ngôn ngữ trung gian „ Là dạng Assembly của máy giả định (máy ảo) „ Máy ảo làm việc với bộ nhớ stack 3 „ Việc thực hiện chương trình thông qua một interpreter „ Interpreter mô phỏng hành động của máy ảo thực hiện tập lệnh assembly của nó Chương trình đích được dịch từ „ Mã nguồn „ Mã trung gian 4 21/1/2010 2 Máy ngăn xếp z Máy ngăn xếp là một hệ thống tính toán z Sử dụng ngăn xếp để lưu trữ các kết quả trung gian của quá trình tính toán z Kiến trúc đơn giản Lớp KHMT K50 5 z Bộ lệnh đơn giản z Máy ngăn xếp có hai vùng bộ nhớ chính z Khối lệnh: chứa mã thực thi của chương trình z Ngăn xếp: sử dụng để lưu trữ các kết quả trung gian Máy ngăn xếp JMP 2 INC 4 LA 0,4 LC 1 RV DL RA SL Code buffer Stack PC B Lớp KHMT K50 6 ST P1 P2 V1 V2 tmp1 T T ↑ Máy ngăn xếp z Thanh ghi z PC (program counter): con trỏ lệnh trỏ tới lệnh hiện tại đang thực thi trên bộ đệm chương trình Lớp KHMT K50 7 z B (base) : con trỏ trỏ tới địa chỉ gốc của vùng nhớ cục bộ. Các biến cục bộ được truy xuất gián tiếp qua con trỏ này z T (top); trỏ tới đỉnh của ngăn xếp Máy ngăn xếp z Bản hoạt động (activation record/stack frame) z Không gian nhớ cấp phát cho mỗi chương trình con (hàm/thủ tục/chương trình chính) khi chúng được kích hoạt z Lưu giá trị tham số z Lưu giá trị biến cục bộ z Lưu các thông tin khác ề Lớp KHMT K50 8 z Giá trị trả v của hàm – RV z Địa chỉ cơ sở của bản hoạt động của chương trình con gọi tới (caller) – DL z Địa chỉ lệnh quay về khi kết thúc chương trình con – RA z Địa chỉ cơ sở của bản hoạt động của chương trình con bao ngoài – SL z Một chương trình con có thể có nhiều bản hoạt động 21/1/2010 3 Máy ngăn xếp RV DL RA SL Param I Local x Procedure P(I : integer); Var a : integer; Function Q; Var x : char; Begin return E d P frame Lớp KHMT K50 9 n ;Procedure R(X: integer); Var y : char; Begin y = Call Q; End; Begin Call R(1); End; RV DL RA SL Local x RV DL RA SL param x Local y R frame Q frame Máy ngăn xếp z RV (return value): Lưu trữ giá trị trả về cho mỗi hàm z DL (dynamic link): Sử dụng để hồi phục ngữ cảnh của chương trình gọi (caller) khi chương trình được gọi (callee) kết thúc Lớp KHMT K50 10 z RA (return address): Sử dụng để tìm tới lệnh tiếp theo của caller khi callee kết thúc z SL (static link): Sử dụng để truy nhập các biến phi cục bộ Máy ngăn xếp z Bộ lệnh LA Load Address t:=t+1; s[t]:=base(p)+q; LV Load Value t:=t+1; s[t]:=s[base(p)+q]; op p q Lớp KHMT K50 11 LC Load Constant t:=t+1; s[t]:=q; LI Load Indirect s[t]:=s[s[t]]; INT Increment T t:=t+q; DCT Decrement T t:=t-q; Máy ngăn xếp z Bộ lệnh J Jump pc:=q; FJ False Jump if s[t]=0 then pc:=q; t:=t-1; op p q Lớp KHMT K50 12 HL Halt Halt ST Store s[s[t-1]]:=s[t]; t:=t-2; CALL Call s[t+2]:=b; s[t+3]:=pc; s[t+4]:=base(p);b:=t+1; pc:=q; EP ExitProcedure t:=b-1; pc:=s[b+2]; b:=s[b+1]; EF ExitFunction t:=b; pc:=s[b+2]; b:=s[b+1]; 21/1/2010 4 Máy ngăn xếp z Bộ lệnh RC ReadCharacter read one character into s[s[t]]; t:=t-1; RI Read Integer read integer to s[s[t]]; t:=t-1; op p q Lớp KHMT K50 13 WRC WriteCharacter write one character from s[t]; t:=t-1; WRI Write Integer write integer from s[t]; t:=t-1; WLN New Line CR & LF Máy ngăn xếp z Bộ lệnh AD Add t:=t-1; s[t]:=s[t]+s[t+1]; SB Subtract t:=t-1; s[t]:=s[t]-s[t+1]; op p q Lớp KHMT K50 14 ML Multiply t:=t-1; s[t]:=s[t]*s[t+1]; DV Divide t:=t-1; s[t]:=s[t]/s[t+1]; NEG Negative s[t]:=-s[t]; CV Copy Top ofStack s[t+1]:=s[t]; t:=t+1; Máy ngăn xếp z Bộ lệnh EQ Equal t:=t-1; if s[t] = s[t+1] then s[t]:=1 elses[t]:=0; NE Not Equal t:=t-1; if s[t] != s[t+1] then s[t]:=1 elses[t]:=0; op p q Lớp KHMT K50 15 GT GreaterThan t:=t-1; if s[t] > s[t+1] then s[t]:=1 else s[t]:=0; LT Less Than t:=t-1; if s[t] < s[t+1] then s[t]:=1 elses[t]:=0; GE Greater orEqual t:=t-1; if s[t] >= s[t+1] then s[t]:=1 else s[t]:=0; LE Less orEqual t:=t-1; if s[t] <= s[t+1] then s[t]:=1 else s[t]:=0; Xây dựng bảng ký hiệu z Bổ sung thông tin cho biến z Vị trí trên frame z Phạm vi z Bổ sung thông tin cho tham số z Vị trí trên frame Lớp KHMT K50 16 z Phạm vi z Bổ sung thông tin cho hàm/thủ tục/chương trình z Địa chỉ bắt đầu z Kích thước của frame z Số lượng tham số của hàm/thủ tục 21/1/2010 5 Xây dựng bảng ký hiệu z Bổ sung thông tin cho biến z Vị trí trên frame (vị trí tính từ base của frame) z Phạm vi Lớp KHMT K50 17 struct VariableAttributes_ { Type *type; struct Scope_ *scope; int localOffset; }; Xây dựng bảng ký hiệu z Bổ sung thông tin cho tham số z Vị trí trên frame z Phạm vi Lớp KHMT K50 18 struct ParameterAttributes_ { enum ParamKind kind; Type* type; struct Scope_ *scope; int localOffset; }; Xây dựng bảng ký hiệu z Bổ sung thông tin cho phạm vi z Kích thước frame Lớp KHMT K50 19 struct Scope_ { ObjectNode *objList; Object *owner; struct Scope_ *outer; int frameSize; }; Xây dựng bảng ký hiệu z Bổ sung thông tin cho hàm z Vị trí z Số lượng tham số Lớp KHMT K50 20 struct FunctionAttributes_ { struct ObjectNode_ *paramList; Type* returnType; struct Scope_ *scope; int paramCount; CodeAddress codeAddress; }; 21/1/2010 6 Xây dựng bảng ký hiệu z Bổ sung thông tin cho thủ tục z Vị trí z Số lượng tham số Lớp KHMT K50 21 struct ProcedureAttributes_ { struct ObjectNode_ *paramList; struct Scope_* scope; int paramCount; CodeAddress codeAddress; }; Xây dựng bảng ký hiệu z Bổ sung thông tin cho chương trình z Vị trí Lớp KHMT K50 22 struct ProgramAttributes_ { struct Scope_ *scope; CodeAddress codeAddress; }; int sizeOfType(type* t) „ Trả về số ngăn nhớ trên stack mà một biến thuộc kiểu đó sẽ chiếm. Lớp KHMT K50 23 void declareObject(Object* obj) „ Đối tượng toàn cục …Đưa vào symtab->GlobalObjectList „ Đối tượng khác: …Đưa vào symtab->currentScope->objList Lớp KHMT K50 24 …Variable: „ Cập nhật scope = currentScope „ Cập nhật localOffset = currentScope- >frameSize „ Tăng kích thước frameSize 21/1/2010 7 void declareObject(Object* obj) „ Đối tượng khác: …Parameter „ Cập nhật scope = currentScope „ Cập nhật localOffset = currentScope->frameSize Lớp KHMT K50 25 „ Tăng kích thước frameSize „ Cập nhật paramList của owner „ Tăng paramCount của owner. void declareObject(Object* obj) „ Đối tượng khác: …Function „ Cập nhật outer = currentScope Lớp KHMT K50 26 …Procedure „ Cập nhật outer = currentScope kplrun z Là bộ thông dịch cho máy ngăn xếp $ kplrun [-s=stack-size] [-c=code-size] [-debug] [-dump] z Tùy chọn –s: định nghĩa kích thước stack Lớp KHMT K50 27 z Tùy chọn –c: định nghĩa kích thước tối đa của mã nguồn z Tùy chọn –dump: In mã ASM z Tùy chọn –debug: chế độ gỡ rối kplrun z Tùy chọn –debug: chế độ gỡ rối z a: địa chỉ tuyệt đối của địa chỉ tương đối (level, offset) Lớp KHMT K50 28 z v: giá trị tại địa chỉ tương đối (level,offset) z t: giá trị đầu ngăn xếp z c: thoát khỏi chế độ gỡ rối 21/1/2010 8 Instructions.c enum OpCode { OP_LA, // Load Address: OP_LV, // Load Value: OP_LC, // load Constant OP_LI, // Load Indirect OP_INT, // Increment t OP_DCT, // Decrement t OP J, // Jump OP_RC, // Read Char OP_RI, // Read Integer OP_WRC, // Write Char OP_WRI, // Write Int OP_WLN, // WriteLN OP_AD, // Add OP_SB, // Substract OP ML, // Multiple Lớp KHMT K50 29 _ OP_FJ, // False Jump OP_HL, // Halt OP_ST, // Store OP_CALL, // Call OP_EP, // Exit Procedure OP_EF, // Exit Function _ OP_DV, // Divide OP_NEG, // Negative OP_CV, // Copy Top OP_EQ, // Equal OP_NE, // Not Equal OP_GT, // Greater OP_LT, // Less OP_GE, // Greater or Equal OP_LE, // Less or Equal OP_BP // Break point. }; Instructions.c struct Instruction_ { enum OpCode op; WORD p; WORD q; }; struct CodeBlock_ { Instruction* code; CodeBlock* createCodeBlock(int maxSize); void freeCodeBlock(CodeBlock* codeBlock); void printInstruction(Instruction* instruction); void printCodeBlock(CodeBlock* codeBlock); void loadCode(CodeBlock* codeBlock, FILE* f); void saveCode(CodeBlock* codeBlock, FILE* f); int emitLA(CodeBlock* codeBlock, WORD p, WORD q); Lớp KHMT K50 30 int codeSize; int maxSize; }; int emitLV(CodeBlock* codeBlock, WORD p, WORD q); int emitLC(CodeBlock* codeBlock, WORD q); . int emitLT(CodeBlock* codeBlock); int emitGE(CodeBlock* codeBlock); int emitLE(CodeBlock* codeBlock); int emitBP(CodeBlock* codeBlock); codegen.c void initCodeBuffer(void); void printCodeBuffer(void); void cleanCodeBuffer(void); int serialize(char* fileName); int genLA(int level, int offset); int genLV(int level int offset); Lớp KHMT K50 31 , int genLC(WORD constant); . int genLT(void); int emitGE(void); int emitLE(void); Sinh mã lệnh gán V := exp // đẩy địa chỉ của v lên stack // đẩy giá trị của exp lên stack ST Lớp KHMT K50 32 21/1/2010 9 Sinh mã lệnh if If Then statement; // đẩy giá trị điều kiện dk lên stack FJ L L: Lớp KHMT K50 33 If Then st1 Else st2; // đẩy giá trị điều kiện dk lên stack FJ L1 J L2 L1: L2: Sinh mã lệnh while While Do statement L1: FJ L2 Lớp KHMT K50 34 co e o s a emen J L1 L2: Sinh mã lệnh for For v := exp1 to exp2 do statement CV // nhân đôi địa chỉ của v ST // lưu giá trị đầu của v L1: CV Lớp KHMT K50 35 LI // lấy giá trị của v LE FJ L2 CV;CV;LI;LC 1;AD;ST; // Tăng v lên 1 J L1 L2: DCT 1 Lấy địa chỉ/giá trị biến z Khi lấy địa chỉ/giá trị một biến cần tính đến phạm vi của biến z Biến cục bộ được lấy từ frame hiện tại Lớp KHMT K50 36 z Biến phi cục bộ được lấy theo các StaticLink với cấp độ lấy theo “độ sâu” của phạm vi hiện tại so với phạm vi của biến computeNestedLevel(Scope* scope) 21/1/2010 10 Lấy địa chỉ của tham số hình thức „ Khi LValue là tham số „ Cũng cần tính độ sâu như biến …Nếu là tham trị: địa chỉ cần lấy chính là địa chỉ Lớp KHMT K50 37 của tham trị …Nếu là tham biến: vì giá trị của tham biến chính là địa chỉ muốn truy nhập, địa chỉ cần lấy chính là giá trị của tham biến. Lấy giá trị của tham số hình thức „ Khi tính toán giá trị của Factor „ Cũng cần tính độ sâu như biến …Nếu là tham trị: giá trị của tham trị chính là giá Lớp KHMT K50 38 trị cần lấy. …Nếu là tham biến: giá trị của tham số là địa chỉ của giá trị cần lấy. Lấy địa chỉ của giá trị trả về của hàm z Giá trị trả về luôn nằm ở offset 0 trên frame z Chỉ cần tính độ sâu giống như với biến hay tham số hình thức Lớp KHMT K50 39 Sinh lời gọi hàm/thủ tục z Lời gọi z Hàm gặp trong sinh mã cho factor z Thủ tục gặp trong sinh mã lệnh CallSt ủ ầ ả Lớp KHMT K50 40 z Trước khi sinh lời gọi hàm/th tục c n ph i nạp giá trị cho các tham số hình thức bằng cách z Tăng giá trị T lên 4 (bỏ qua RV,DL,RA,SL) z Sinh mã cho k tham số thực tế z Giảm giá trị T đi 4 + k z Sinh lệnh CALL 21/1/2010 11 Sinh mã cho lệnh CALL (p, q) CALL (p, q) s[t+2]:=b; // Lưu lại dynamic link s[t+3]:=pc; // Lưu lại return address s[t+4]:=base(p); // Lưu lại static link b:=t+1; // Base mới và return value pc:=q; // địa chỉ lệnh mới Giả sử cần sinh lệnh CALL cho hàm/thủ tục A Lệnh CALL(p, q) có hai tham số: p: Độ sâu của lệnh CALL, chứa static link. Lớp KHMT K50 41 Base(p) = base của frame chương trình con chứa khai báo của A. q: Địa chỉ lệnh mới q + 1 = địa chỉ đầu tiên của dãy lệnh cần thực hiện khi gọi A. Hoạt động khi thực hiện lệnh CALL(p, q) 1. Điều khiển pc chuyển đến địa chỉ bắt đầu của chương trình con /* pc = p */ 2. pc tăng thêm 1 /* pc ++ */ 3. Lệnh đầu tiên thông thường là lệnh nhảy J để bỏ qua mã Lớp KHMT K50 42 lệnh của các khai báo hàm/ thủ tục cục bộ trên code buffer. 4. Lệnh tiếp theo là lệnh INT tăng T đúng bằng kích thước frame để bỏ qua frame chứa vùng nhớ của các tham số và biến cục bộ. Hoạt động khi thực hiện lệnh CALL(p, q) 5. Thực hiện các lệnh và stack biến đổi tương ứng. 6. Khi kết thúc 1. Thủ tục (lệnh EP): toàn bộ frame được giải phóng, con trỏ T đặt lên đỉnh frame cũ. Lớp KHMT K50 43 2. Hàm (lệnh EF): frame được giải phóng, chỉ chừa giá trị trả về tại offset 0, con trỏ T đặt lên đầu frame hiện thời (offset 0). Sinh mã đích từ mã ba địa chỉ „ Bộ sinh mã trung gian đưa ra mã ba địa chỉ „ Tối ưu trên mã ba địa chỉ 44 „ Từ mã ba địa chỉ đã tối ưu sinh ra mã đích phù hợp với một mô tả máy ảo

Các file đính kèm theo tài liệu này:

  • pdfgiao_trinh_chuong_trinh_dich_bai_11_sinh_mam_dich_nguyen_thi.pdf