1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Bài giảng thực hành chương trình dịch bài 5 phạm đăng hải

66 5 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Nội dung

Thực hành CHƯƠNG TRÌNH DỊCH Bài 5: Sinh mã Phạm Đăng Hải haipd@soict.hut.edu.vn Các thực hành Xây dựng bảng ký hiệu • • Giới thiệu máy ngăn xếp Vấn đề xây dựng bảng ký hiệu Sinh mã cho câu lệnh • • Giới thiệu thơng dịch KPLrun Sinh mã cho câu lệnh gán, rẽ nhánh, lặp Sinh mã lấy địa chỉ/giá trị • • • Lấy địa chỉ/giá trị biến, phần tử mảng tham số hình thức Sinh mã lấy địa giá trị trả hàm Sinh mã gọi thủ tục • 09/20/23 Sinh mã tham số thực tế Sinh mã đích Phân tích từ vựng Phân tích cú pháp Phân tích ngữ nghĩa Sinh mã 09/20/23 • Sinh mã cơng đoạn biến đổi từ cấu trúc ngữ pháp chương trình thành chuỗi lệnh thực thi máy đích • Cấu trúc ngữ pháp định phân tích cú pháp • Các lệnh máy đích đặc tả kiến trúc thực thi máy đích – KPL sử dụng kiến trúc máy ngăn xếp Máy ngăn xếp • Máy ngăn xếp hệ thống tính toán – Sử dụng ngăn xếp để lưu trữ kết trung gian q trình tính tốn – Kiến trúc đơn giản – Bộ lệnh đơn giản • Máy ngăn xếp có hai vùng nhớ – Khối lệnh: • Chứa mã thực thi chương trình – Ngăn xếp: • Lưu trữ kết trung gian 09/20/23 Máy ngăn xếp PC, B, T ghi máy PC JMP INC LA 0,4 LC ST Code buffer 09/20/23 T RV DL RA SL P1 P2 V1 V2 tmp1 B T Stack Máy ngăn xếp Thanh ghi • PC (program counter): – Con trỏ lệnh trỏ tới lệnh thực thi đệm chương trình • B (base): – Con trỏ trỏ tới địa sở vùng nhớ cục Các biến cục truy xuất gián tiếp qua trỏ • T (top); – Con trỏ, trỏ tới đỉnh ngăn xếp 09/20/23 Máy ngăn xếp Bản hoạt động (stack frame) • 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 – Lưu giá trị tham số – Lưu giá trị biến cục – Lưu thông tin quan trọng khác: • RV, DL, RA, SL • Một chương trình có nhiều hoạt động 09/20/23 Máy ngăn xếp Bản hoạt động (stack frame) • RV (return value): – Lưu trữ giá trị trả cho hàm • DL (dynamic link): – Địa sở hoạt động chương trình gọi tới (caller) – Được sử dụng để hồi phục ngữ cảnh chương trình gọi (caller) chương trình gọi (called) kết thúc • RA (return address): – Địa lệnh quay kết thúc chương trình – Sử dụng để tìm tới lệnh caller called kết thúc • SL (static link): – Địa sở hoạt động chương trình bao ngồi – Sử dụng để truy nhập biến phi cục 09/20/23 Máy ngăn xếp Bản hoạt động Procedure P(I : integer); Var a : integer; Function Q; Var x : char; Begin … return End; Procedure R(X: integer); Var y : char; Begin … y = Call Q; … End; Begin … Call R(1); … End; 09/20/23 Ví dụ Stack … RV DL RA SL Param I Local a … RV DL RA SL param x Local y … RV RV DL RA SL Local x P frame R frame Q frame Máy ngăn xếp Lệnh • Lệnh máy có dạng : Op p q – Op : Mã lệnh – p, q : Các tốn hạng • Các tốn hạng tồn đầy đủ, có tốn hạng, khơng tồn • Ví dụ J1 % Nhảy đến địa LA 0, % Nạp địa từ số 0+4 lên đỉnh stack HT 09/20/23 %Kết thúc chương trình 10 Lấy địa chỉ/giá trị biến • Khi lấy địa chỉ/giá trị biến cần tính đến phạm vi biến – Biến cục lấy từ frame – 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 thời • Hàm computeNestedLevel(Scope* scope) trả độ sâu biến Level = 0; Scope* tmp = symtab->currentScope; While (tmp != scope) {tmp = tmp ->outer, level++ }; 09/20/23 52 Lấy địa chỉ/giá trị biến • Tìm vị trí biến stack – Level = computeNestedLevel(Scope* scope) – Offset = OFFFSET(Var) • Lấy giá trị biến Var – genLV(Level, Offset) • Lấy địa biến Var – genLA(Level, Offset) 09/20/23 53 Lấy địa tham số hình thức • Khi LValue tham số, cần tính độ sâu biến • Việc lấy giá trị, phụ thuộc vào tham trị hay tham biến – Nếu tham trị: • Địa /giá trị giống với biến – Nếu tham biến: • 09/20/23 Địa biến địa truyền vào cho hàm/thủ tục 54 Lấy địa tham số hình thức • Tìm vị trí biến tham số stack – Level = computeNestedLevel(Scope* scope) – Offset = OFFFSET(Var) • Nếu tham trị, nạp giá trị lên stack • genLV(Level, Offset) • Nếu tham biến, nạp địa tham số: – genLA(Level, Offset) 09/20/23 55 Ví dụ Truyền theo giá trị Program Exp; Var N : integer; Procedure Add(a:integer; b:integer); Begin N := a+b; End; Begin N := 10; Call add(N,20*10); End 09/20/23 0: J 1: J 2: INT 3: LA 1,4 4: LV 0,4 5: LV 0,5 6: AD 7: ST 8: EP 9: INT 10: LA 0,4 11: LC 10 12: ST 13: INT 14: LV 0,4 15: LC 20 16: LC 10 17: ML 18: DCT 19: CALL 0,1 20: HL 56 Ví dụ Truyền theo biến Program Example1; Var N : integer; Procedure Add(Var a:integer); Begin a := 10*a; End; Begin Call add(N); Call WRITEI(N); End 09/20/23 0: J 10 1: J 2: INT 3: LV 0,4 4: LC 10 5: LV 0, 6: LI 7:ML 8: ST 9: EP 10: INT 11: INT 12: LA 0,4 13: DCT 14: CALL 0,1 15: LV 0,4 16: WRI 17: HL 57 Lấy địa giá trị trả hàm • Giá trị trả ln nằm offset frame • Chỉ cần tính độ sâu giống với biến hay tham số hình thức Program Exp; Var N : integer; Function Sqrt(a:integer): integer; Begin Sqrt := A * A; End; Begin N := Sqrt(10); Call WRITEI(N); End 09/20/23 0: J 1: J 2: INT 3: LA 0,0 4: LV 0,4 5: LV 0,4 6: ML 7: ST 8: EF 9: INT 10: LA 0,4 11: INT 12: LC 10 13: DCT 14: CALL 0,1 15: ST 16: HL 58 Sinh lời gọi hàm/thủ tục • Lời gọi – Hàm gặp sinh mã cho factor – Thủ tục gặp sinh mã lệnh CallSt • 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 lên stack cách – Tăng giá trị T lên (bỏ qua RV,DL,RA,SL) – Sinh mã cho k tham số thực tế • Đặt tham số(giá trị/ địa chỉ) lên đỉnh stack – Giảm giá trị T + k genDCT(4+k) – Sinh mã cho lệnh CALL genFun/ProcCall(obj) 09/20/23 59 Lệnh CALL (p, q) Lệnh CALL có hai tham số: – p: Độ sâu lệnh CALL, chứa static link Base(p) = base frame chương trình chứa khai báo chương trình A – q: Địa lệnh mới: địa dãy lệnh cần thực gọi A 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; 09/20/23 pc:=q; // Base return value // địa lệnh 60 Lệnh CALL (p, q) • Điều khiển pc chuyển đến địa bắt đầu chương trình /* pc = p */ • Lệnh thơng thường lệnh nhảy J để bỏ qua mã lệnh khai báo chương trình cục đoạn mã • Lệnh lệnh INT tăng T kích thước frame – Mục đích: bỏ qua frame chứa vùng nhớ tham số biến cục 09/20/23 61 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) 09/20/23 62 Sinh địa phần tử mảng • Biến mảng khai báo A : array(.n1.) of of array(.nk.) of integer/char chiếm n1 * …* nk nhớ frame • Phần tử A(.i1.) (.ik.) định vị địa = A + i1 * n2 *…* nk + i2* n3 *…* nk +… + ik-1 * nk + ik //Chỉ số • Địa tính tích lũy theo tiến trình duyệt số 09/20/23 63 Sinh địa phần tử mảng Program Exm; Var N : Array(.4.) of Array(.5.) of array(.6.) of integer; Begin 0: J 1: INT 124 N(.3.)(.4.)(.5.) := 10; 2: LA 0,4 End 9: ML 3: 4: 5: 6: 7: 8: 09/20/23 LC LC 30 ML AD LC LC 10: 11: 12: 13: 14: 15: 16: 17: AD LC LC ML AD LC 10 ST HL 64 Nhiệm vụ Bổ sung vào codegen.c • int computeNestedLevel(Scope* scope); • void genVariableAddress(Object* var) • void genVariableValue(Object* var) • void genParameterAddress(Object* param) • void genParameterValue(Object* param) • void genReturnValueAddress(Object* func) – Gán giá trị trả cho hàm • void genReturnValueValue(Object* func) • void genProcedureCall(Object* proc) • void genFunctionCall(Object* func) 09/20/23 65 Nhiệm vụ • • • • Cập nhật parser.c Type* compileLValue(void); void compileCallSt(void); Type* compileFactor(void); Type* compileIndexes(Type* arrayType); 09/20/23 66

Ngày đăng: 15/11/2023, 13:31

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w