Bài giảng Nhập môn chương trình dịch - Bài 6: Sinh mã trung gian - Hoàng Anh Việt

Ngôn ngữ trung gian

• Là ngôn ngữ cho một loại máy trừu tượng

• Cho phép sinh mã không phụ thuộc vào máy

đích

• Cho phép tối ưu mã trước khi sinh mã máy thật

sự

Cây cú pháp

thông tin điều khiển

Pentium

Java bytecode

AMD

pdf 27 trang yennguyen 3580
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Nhập môn chương trình dịch - Bài 6: Sinh mã trung gian - Hoàng Anh Việt", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

Tóm tắt nội dung tài liệu: Bài giảng Nhập môn chương trình dịch - Bài 6: Sinh mã trung gian - Hoàng Anh Việt

Bài giảng Nhập môn chương trình dịch - Bài 6: Sinh mã trung gian - Hoàng Anh Việt
1Bài 6. 
SINH MÃ TRUNG GIAN
Hoàng Anh Việt 
Viện CNTT&TT - ĐHBKHN
Mô tả các bước dịch (1)
Mã nguồn (dãy các kí tự)
If (a == 0) min = a; Phân tích từ vựng
Phân tích cú pháp
Phân tích ngữ nghĩa
Dãy các từ tố (token)
Cây cú pháp
Cây cú pháp điều khiển
If ( Id:a == 0 ) Id:min = Id:a ;
if
== = ;
a 0 min a
if
== = ;
a 0 min aint int int
lvalue
int
intboolean
Mô tả các bước dịch (2)
if
== = ;
a 0 min aint int int
lvalue
int
intboolean Sinh mã trung gian
Sinh mã assembly
Tối ưu mã
SEQ(CJUMP(TEMP(a) == 0, L1, L2),
LABEL(L1),
TEMP(min) = TEMP(a)
LABEL(L2))
cmp rb, 0
jnz L2
L1: mov ra, rb
L2:
cmp ecx, 0
cmovz edx,ecx
Ngôn ngữ trung gian
• Là ngôn ngữ cho một loại máy trừu tượng
• Cho phép sinh mã không phụ thuộc vào máy 
đích
• Cho phép tối ưu mã trước khi sinh mã máy thật 
sự 
Cây cú pháp 
+ 
thông tin điều khiển
Pentium
Java bytecode
AMD
Ngôn ngữ trung gian
• Dễ sinh ra từ cây cú pháp
• Dễ sinh mã máy
• Số lượng lệnh nhỏ, gọn
– Dễ tối ưu mã
– Dễ chuyển sang loại mã máy khác
Cây cú pháp (>40 nút)
Mã trung gian (13 nút)
Pentium (>200 lệnh)
Ngôn ngữ trung gian
• Một dạng thể hiện của chương trình nằm giữa 
cây cú pháp điều khiển và mã máy
• Sử dụng
– Lệnh nhảy
– Thanh ghi
– Vị trí trên bộ nhớ
Cây cú pháp 
+ 
thông tin điều khiển
Pentium
Java bytecode
AMD
Mã trung 
gian
Tối ưu mã
Một ngôn ngữ trung gian
• IR (Intermediate Representation) là một cây thể 
hiện các lệnh của một loại máy trừu tượng
• Nút lệnh không trả lại giá trị, được thực hiện theo 
thứ tự nhất định
– Ví dụ: MOVE, SEQ, CJUMP
• Nút biểu thức trả lại giá trị, các nút con có thể thực 
hiện theo thứ tự bất kì
– Ví dụ: ADD, SUB
– Cho phép tối ưu mã
Mô tả các nút biểu thức của IR
• CONST(i): hằng số nguyên i
• TEMP(t): thanh ghi t, máy trừu tượng có vô hạn thanh ghi.
• OP(e1, e2): các phép toán
– Số học: ADD, SUB, MUL, DIV, MOD
– Logic: AND, OR, XOR, LSHIFT, RSHIFT
– So sánh: EQ, NEQ, LT, GT, LEQ, GEQ
• MEM(e): giá trị bộ nhớ ở vị trí e
• CALL(f, a0, a1, ): giá trị của hàm f với các tham số a0, a1, 
• NAME(n): địa chỉ của lệnh hoặc dữ liệu có tên là n
• ESEQ(s, e): giá trị của e sau khi lệnh s được thực hiện
CONST
• Nút CONST đại diện cho hằng số
• Giá trị của nút là i
CONST(i)
TEMP
• Nút TEMP đại diện cho một thanh ghi 
trong số vô hạn các thanh ghi của máy 
trừu tượng
• Các biến cục bộ và các biến tạm
• Để dễ viết, ký hiệu FP = TEMP(FP) là 
địa chỉ bắt đầu bộ nhớ của hàm
• Giá trị của nút là giá trị của thanh ghi 
tại thời điểm tính toán
TEMP(t)
Toán tử
• Máy trừu tượng có nhiều phép toán
• Tính giá trị của e1 và e2, sau đó áp dụng phép toán với 
các giá trị này
• e1 và e2 phải là hai nút có giá trị
• Có thể tính giá trị e1 và e2 theo thứ tự bất kì
OP
e1 e2
OP(e1, e2)
MEM
• Nút MEM đại diện cho một vị trí trong bộ nhớ
• Giá trị của nút là giá trị tại vị trí e trong bộ nhớ
MEM
e
MEM(e)
CALL
• Nút CALL đại diện cho một lời gọi hàm
• Không định nghĩa cách cài đặt việc truyền 
tham số, quản lý ngăn xếp
• Giá trị của nút là giá trị của hàm
CALL
ef
CALL(ef, e0, e1,)
e0e1e2
Địa chỉ của hàm Tham số
NAME
• Nút NAME đại diện cho địa chỉ của một tên 
trên bộ nhớ
• VD: địa chỉ của một nhãn nhảy
NAME(n)
ESEQ
• Nút ESEQ tính toán giá trị của biểu thức e sau 
khi thực hiện lệnh s
ESEQ
s e
ESEQ(s, e)
Mô tả các nút lệnh của IR
• MOVE(dest, e): chuyển giá trị của e vào dest
• EXP(e): tính toán giá trị của e, không cần lưu lại kết 
quả
• SEQ(s1, s2,  sn): thực hiện các lệnh theo thứ tự
• JUMP(e): nhảy đến địa chỉ e
• CJUMP(e, l1, l2): nhảy đến l1 hoặc l2 tuỳ thuộc vào 
giá trị của e là true hoặc false
• LABEL(n): tạo ra nhãn có tên n
Ví dụ n = 0;
while (n < 10) 
{
n = n + 1;
}
SEQ(
MOVE(TEMP(n), CONST(0)),
LABEL(HEAD),
CJUMP(LT(TEMP(n), CONST(10)), NAME(BODY), NAME(END)),
LABEL(BODY),
MOVE(TEMP(n), ADD(TEMP(n), CONST(1))),
JUMP(NAME(HEAD)),
LABEL(END)
)
SEQ
MOVE LABEL(HEAD)CJUMP LABEL(BODY)MOVE LABEL(END)JUMP
TEMP(n) CONST(0) LT NAME(BODY)
TEMP(n) CONST(10)
NAME(END)
TEMP(n) ADD
TEMP(n) CONST(1)
NAME(HEAD)
Cấu trúc của IR
• Gốc của cây là một nút lệnh
• Các nút biểu thức nằm dưới nút lệnh
• Chỉ có nút biểu thức ESEQ có nút lệnh nằm 
dưới
• Có thể duyệt cây IR để chạy chương trình
Sinh cây IR (mã trung gian)
• Kỹ thuật: phương pháp dịch sử dụng cú pháp 
điều khiển (giống kiểm tra kiểu)
• Chuyển cây cú pháp điều khiển thành cây IR
• Mỗi cây con của cây cú pháp được chuyển 
thành một cây con dạng IR có cùng giá trị
Sinh cây IR
• Giống kiểm tra kiểu: thêm một phương thức 
vào nút tương ứng trong cây cú pháp
abstract class ASTNode {
IRNode translate(SymTab A) {  }
}
• Cài đặt kiểu đệ quy
• Vấn đề: giống như kiểm tra kiểu, cần mô tả 
chính xác cách viết hàm translate()
Biểu thức
• Các nút của cây cú pháp thể hiện biểu thức 
được chuyển thành nút IR tương ứng
• Kí hiệu [e] là biểu diễn IR của nút e trong cây 
cú pháp
ADD
[e1] [e2]
+
e1 e2
Câu lệnh
• Dãy các lệnh được biểu diễn bằng nút SEQ 
trong biểu diễn IR
• Nếu [s1] và [s2] là biểu diễn IR của nút s1 và s2
• thì SEQ([s1], [s2]) là biểu diễn IR của s1; s2
SEQ
[s1] [s2]
s1; s2
Biến
• Biến cục bộ v chuyển thành nút TEMP(v)
• Tham số thứ i nằm ở vị trí 
MEM(ADD(FP,4*i+4))
v
TEMP(v)
MEM
ADD
FP CONST(4*i+4)
arg n-1
arg 1
arg 0
return 
addr
FP
SS
Stack
Phép gán
• Phép gán v = e chuyển thành nút MOVE(dest, 
[e]) với dest là địa chỉ của v, [e] là biểu diễn IR 
của e
• Ví dụ
x = 2
MOVE
CONST(2)MEM
ADD
FP CONST(8)
Phép gán
• Cách dịch
• Vấn đề: nút MOVE không có giá trị, làm thế 
nào để dịch x = (y = 2)?
e1 = e2 MOVE
[e2][e1]
ESEQ
[e1]
e1 = e2
MOVE
[e2][e1]
Phép gán
• Như vậy, [e1] phải chạy 2 lần, cần lưu lại giá 
trị của [e1]
e1 = e2
MOVE
[e2]TEMP(te)
ESEQ
TEMP(te)SEQ
MOVE
TEMP(te)[e1]
Thảo luận
27

File đính kèm:

  • pdfbai_giang_nhap_mon_chuong_trinh_dich_bai_6_sinh_ma_trung_gia.pdf