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