III.Sinh mã 1. Mục đích và nhiệm vụ -Sinh mã : là giai đoạn cuối của quá trình dịch, sinh mã tốt là rất khó và sinh mã ra thờng gắn với một loại máy tính nào đó. -Tiêu chuẩn quan trọng đối với bộ sinh mã là phải tạo mã đúng, đặt tiêu chuẩn này lên hàng đầu còn giúp cho việc thiết kế xây dựng và bảo trì bộ sinh mã trở nên đinh hớng tốt hơn, dễ thực hiện hơn và tiết kiệm hơn. Trong thực tế sinh mã máy đòi hỏi nhiều kinh nghiệm, am hiểu về ngôn ngữ lập trình và kyc thuật máy tính. Sau khi hoàn thành ở mức phân tích, chơng trình dịch chuyển sang giai đoạn sinh mã với đầu vào là chơng trình nguồn ở dạng cây cú pháp hoặc cây mã trung gian. Giai đoạn sinh mã bao gồm : + Sinh mã trung gian + Tối u mã + Sinh mã đích Chơng trình đích mà chúng ta tạo ra ở đây là chơng trình hợp ngữ Assemble và nghiên cứu phơng pháp sinh mã cho : + Lệnh gán + Biểu thức số học + Cấu trúc điều khiển 2. Dạng mã ba địa chỉ Dạng mã ba địa chỉ là lênh có dạng : x := y Operator z Trong đó : x, y, z là các biến hoặc bộ nhớ trung gian. Operator : là toán tử ( phép toán) - Dạng mã ba địa chỉ là câu lệnh có hai đa chỉ cho toán hạng và một địa chỉ cho toán tử. Nó đợc sử dụng ở bớc sinh mã trung gian. - Mọi biểu thức số học hoặc câu lệnh đều có thể đợc biễu diễn dới dạng mã ba địa chỉ Ví dụ : Với câu lệnh : A:= X + Y + Z *150 Mã ba địa chỉ sẽ là : T1:= Z*150 T2:= Y + T1 A:= X + T2 Các câu lệnh dạng mã ba địa chỉ: 1- Lệnh : X := Y Operator Z : là phép toán số học hai ngôi hoặc phép toán logic Ví dụ: X:=Y + Z hoặc A: = B and C 2- Lệnh : X:= Operator Y : là phép toán một ngôi , là phép toán lấy số âm hoặc đảo logic. Ví dụ: X:= -Y hoặc A:= Not B 3- Lệnh : X:= Y là phép gán giá trị Y cho X (X đợc gán bởi Y) 4- Lệnh nháy không điều kiện: Go to Nhan(Pascal) JMP Nhan ( Assemble) 5- Lệnh nháy có điều kiện : If BT logic then Goto Nhan (Pascal) JA, JB, JG , JE, JLE, (Assemble) 6- Các lệnh là lời gọi hàm, gọi thủ tục, lênh lấy chỉ số mã, lấy địa chỉ con trỏ 3. Các vấn đề của bộ sinh mã a. Đầu vào : là văn bản chơng trình nguồn đã qua giai đoạn phân tích có thể biểu diễn dới dạng cây phân tích. b. Đầu ra : Bộ mã của chơng trình đối tợng gồm: -Một chơng trình hoàn toàn bằng ngôn ngữ máy có thể chạy đợc trên máy tính -Chơng trình ngôn ngữ máy có thể định vị lại đợc ( có thể chèn, thêm một đoạn mã). -Chơng trình hợp ngữ Assemble -Một chơng trình bằng ngôn ngữ lập trình khác c. Quản lý bộ nhớ -Việc chuyển đổi tơng ứng từ tên biến, tên hằng trong chơng trình nguồn thành địa chỉ dữ liệu trong lúc chạy của chơng trình chính đợc thực hiện phối hợp giữa các phần trớc và phần sinh mã, thông qua bảng ký hiệu có thể xác định đợc một địa chỉ tơng đối trong miền dữ liệu. d. Chọn chỉ thị lệnh -Tính chất của tập các chỉ thị lệnh xác định mức độ phức tạp của việc chọn chỉ thị lệnh. -Tính thống nhất và tính đầy đủ là nhân tố quan trọng -Đối với mỗi câu lênh dạng mã ba địa chỉ ta có thể thiết kế bộ khung để sinh mã cho nó. Để khi sinh mã ta chỉ việc sử dụng bộ khung này để tạo ra mã. VD: Với câu lệnh : X:= Y + Z khung mã của nó là Mov AL,Y Add AL,Z Mov X,AL Khi sinh mã cho các lệnh A:= B+ C, B:= C+D Khi đó chỉ cần sử dụng khung mã trên để có đoạn mã, khi đó ta sẽ có Mov AL,B Mov AL,C Add AL,Z Add AL,D Mov X,AL Mov B, AL -Sau khi tạo ra đoạn mới ta phải thực hiện tối u bằng cách loại bỏ các mã lênh trung gian mang tính chất chuyển đổi mà không ảnh hởng đến chơng trình. e. Sử dụng thanh ghi -Các lệnh tính toán đối với thanh ghi thờng nhanh hơn và gọn hơn tính toán với bộ nhớ. Do vậy, việc sử dụng thanh ghi có hai vấn đề : + Trong khi dùng thanh ghi ta chọn tập các biến sẽ đợc đặt trong các thanh ghi tại một vị trí của chơng trình + Trong giai đoạn gán thanh ghi ta chỉ thị một thanh ghi để lu giá trị một biến tránh trờng hợp gây tranh chấp xung đột. f. Máy đích - Máy đích là máy sẽ chạy chơng trình đích mà bộ sinh mã tạo ra ở đây ta sử dụng máy thực để mô tả và mã do bộ sinh mã tạo ra là dạng mã Assemble. Các câu lệnh có dạng Operator Đích, nguồn Trong đó : Operator : là phép xử lý có thể là Mov, Add, Sub, Cmp, Mul, Div, . Nguồn, đích là các địa chỉ dữ liệu chịu sự tác động của phép xử lý. Đích và nguồn có thể là biến hoặc hằng. Nhng tối thiểu phải có sự tham gia của một thanh ghi. 4. Sinh mã cho lệnh gán và biểu thức số học Dựa vào cây cú pháp ( là cây mô tả lệnh gán hoặc biểu thức số học) đợc xây dựng trong quá trình phân tích cú pháp. Từ cây này ta dịch sacng mã đích trong quá trình dịch phải tham khảo các ký hiệu trong bảng ký hiệu. Ta có thể xem cây cú pháp là cây mã chơng trình trung gian. Mà tại nút thứ n trên cây có đoạn mã lênh, kí hiệu là C(n). Khi đó để sinh mã một nút n của cây chúng ta phải ghép các đoạn mã con hoặc cháu theo một trật tự nhất định. Trật tự đó là tính từ dới lên và từ trái qua phải của cây. Có ba dạng nút trên cây a) b) c) Trong đó : Ký hiệu là một nút (cây con). Riêng nút trái của dạng a là một tên biến VD1: Với lệnh gán A:= < id1> + <id2> + <id3> ta sẽ biểu diễn nh sau : := + * - Nút dạng a, giá trị cây con bên phải đợc phát cho bên biến bên trái. - Nút dạng b, c, mã lệnh C(n) là giá trị của cây con bên trái công hoặc nhân giá trị cây con bên phải. Để tiện cho việc sinh mã ngời ta quy định bậc của cây Bậc của nút thứ n trên cây, ký hiệu là b(n) B(n) = { 0 nếu n là nút lá Max (b (ni) )+1 nếu nút n có k con n1,n2, nk i:=1, ,k VD2: Với ví dụ 1 trên ta có b (n0) = 1 ; b (n1) = (1+1) = 2 ; b (n2) = (2+1) = 3 a. Giải thuật sinh mã cho lệnh gán Vào: Cây mã trung gian biểu diễn lệnh gán xâu Ra : mã lệnh Quá trình thực hiện: Thực hiện bớc 1 hoặc 2 cho nút bậc 0. Bớc 1: + nút thứ j trong bảng ký hiệu giả sử có tên là x thì Cj = x + Nút thứ j trong bảng ký hiệu giả sử có giá trị k thì Ck = k Bớc2: Nút n thuộc các nút : = , +, *, -, /, có C(n) = Bớc 3: nút n là nút dạng a, có 3 con n1, n2, n3, khi đó : C(n) là : Mov Ri, C(n3) Mov C(n) , Ri Ri là thanh ghi nào đó Bớc 4: nút n là nút dạng b, có 3 con n1, n2, n3, Khi đó C(n) là : Mov Ri, C(n1) Add Ri , C(n3) Mov C(n) , Ri Bớc 5: Nút n là nút dạng c, có 3 con là n1, n2, n3 Khi đó C(n) là : Mov Ri, C(n1), Mov Rj , C(n3) Nul Ri Mov C(n), Ri Với Ri = Ri * Rj Ri= Work A := <id1> + <id2> * <id3> n 1 n 0 n 2 Rj= Byte VD: Sinh m· cho lÖnh g¸n A:= X + Y + Z *150 Ta cã c©y m· trung gian lµ : Sinh m· : Bíc 1: + C(n 01 ) = Z , C(n 11 ) = Y , C(n 21 ) = X , C(n 31 ) = A + C(n 03 ) = 150 , Bíc 2: C¸c nót n 02 , n 12 , n 22 , n 32 cã m· b»ng φ Bíc 3: Nót n 0 cã 3 con n 01 ,n 02 ,n 03 , m· lÖnh C(n 0 ) lµ Mov AH,0 ; AL = C(n 01 ) Mov AL, Z ; BL = C(n 03 ) Mov BL, 150 Mul BL Mov Temp1, AL Bíc 4: Nót n 1 cã 3 con n 11 , n 12 , n 13 m· lÖnh C(n 1 ) lµ : Mov AL, Temp1 Add Al, Y Mov Temp2, AL Bíc 4 : Nót n 2 cã 3 con n 21 , n 22 , n 23 m· lÖnh C(n) lµ Mov AL, Temp2 Add AL, X Mov Temp3, AL Bíc 5 : Nót n 3 cã 3 con n 31 , n 32 , n 33 m· lÖnh lµ Mov AL, Temp3 Mov A, AL VËy m· thu ®îc: Mov AH, 0 Mov Al,Z Mov BL, 150 Mul BL Mov Temp1, AL ;1 Mov AL, Temp1 ;2 Add AL, Y A := x + y + n 2 n 1 n 3 Z * 150 n 0 Mov Temp2, AL ; 3 Mov AL, TEMP2 ;4 Add AL,X Mov Temp3, AL ;5 Mov AL, Temp3 ;6 Mov A, AL Tối u mã : Ta thấy các cặp lệnh ( 1, 2) ; (3, 4); (5, 6); là d thừa vì vậy ta loại bỏ các lệnh này. Ta có mã lệnh : Mov AH ,0 Mov AL, Z Mov BL, 150 Mul BL Add AL, Y Add AL, X Mov A, AL b.Giải thuật cho sinh mã cho biểu thức số học Vào : Xâu biểu thức số học Ra : Mã lệnh Assembly Cấu trúc dữ liệu : Dữ liệu 2 Stack : + 1 Stack toán tử : STT + 1 Stack toán hạng : STH và 1 Buffer Khởi tạo : STT và STH chứa $ (đáy) Buffer chứa $ Repeat {Dựa vào việc phát hiện từ cán và quan hệ u tiên} - Nếu ký hiệu tiếp đến trong Buffer là toán hạng thì dịch chuyển vào STH - Nếu ký hiệu tiếp đến trong Buffer là toán tử thì ta so sánh với toán tử ở đỉnh STT. Nếu lớn hơn thì dịch chuyển vào STT. Ngợc lại nếu nhỏ hơn thì : Repeat Gỡ 2 toán hạng ở đỉnh STH Gỡ 1 toán tử ở đỉnh STT Thực hiện sinh mã cho toán tử và hai toán hạng đó. Đẩy kết quả đó vào STH. Until Độ u tiên ở đỉnh STT < Toán tử tiếp đến trong Buffer dịch chuyển vào STT - Nếu gặp ngoặc trái thì xem biểu thức trong mã cùng cấp cần sinh mã là xâu mới cần sinh mã, đẩy ngoặc trái vào STT làm đáy mới. Với ký hiệu kết thúc xâu mới là ngoặc phải cùng cấp. - Nếu Buffer rỗng Repeat Gỡ 2 toán hạng ở đỉnh STH Gỡ 1 toán tự ở đỉnh STT Sinh mã cho toán tử và 2 toán hạng đó đẩy kết quả vào STH Until STT= (rỗng) Until STT = VD : Sinh mã nhập biểu thức = a + b * ( c + d) Lập bảng Bớc STT STH Buffer Hành động 0 1 2 3 4 5 6 7 8 9 10 11 $ $ $+ $+ $+* $+*( $+*( $+*(+ $+*(+ $+* $+ $ $ $a $a $ab $ab $ab $abc $abc $abcd $abt1 $at2 $t3 a+b*(c+d)$ +b*(c+d)$ b*(c+d)$ *(c+d)$ (c+d)$ c+d)$ +d)$ d)$ )$ $ $ $ Dịch chyển STH Dịch chyển STT Dịch chyển STH Dịch chyển STT Dịch chyển STT Dịch chuyển c STH Dịch chyển+ STT Dịch chyểnd STH Gỡ d,c và gỡ + Mov AL, d Add AL, c Mov t1,AL Push (t1,STH) Gỡ T1,b; Gỡ * Mov AH, 0 Mov AL, t1 Mov BL,b Mul BL Mov t2, AX Push (t2, STH) Gỡ t2, a; gỡ + Mov AX, t2 Add AX, a Mov t3, AX Push (t3, STH) Dừng Mã thu đợc là Mov AL, d Add AL, c Mov t1, AL Mov AH, 0 Mov AL, t1 Mov BL, b Mul BL Mov t2, AX Mov AX, t2 Add AX, a Mov t3, AX Tối u hoá Mov AL, d Add AL, c Mov AH, 0 Mov BL, b Mul BL Add AX, a Mov t3, AX 5. Sinh mã cho các cấu trúc điều khiển Rẽ nhánh : + Rẽ 2 nhánh : - if then - if then else + Rẽ nhiều nhánh : - Case of and - Case .of .else and Lặp : + While do + Repeat .Until + For chuyển sang dạng While và sinh mã theo While Một số ví dụ : VD1: Sinh mã cho đoạn chơng trình sau: 1). If a>b then a: = a-b 2). If a+b >c then a:= a+c else b:= b+c Giải: 1. Mov AL, a Cmp AL, b JLE Tiep Sub AL, b Mov a, AL Tiep 2. Mov AL,a Add AL,b Cmp AL,c JLE ELSE Mov AL,a Add AL,c Mov a, AL Jmp Tiep ELSE Mov AL,b Add AL,c Mov b, AL Tiep: VD2: Sinh m· cho ®o¹n ch¬ng tr×nh sau : Case chon of 1: Begin S:= a*b; c:= (a+b)*2; End; 2: Begin S:= 3.14*R*R; c:= 2*3.14*R; End; End; Gi¶i: Mov CL,chon Cmp CL,1 JNE L1 Mov AH,0 Mov AL,a Mov BL,b Nul BL Mov S,AL Mov AL,a Add AL,b Mov BL,2 Mul BL Mov c,AL Jmp Tiep L1: Cmp CL,2 JNE Tiep Mov AL, 3.14 Mov BL,R Mul BL Mul BL Mov S,AL Mov AL, 3.14 Mul BL Mov BL,2 Mul BL Mov C,AL Tiep: Bµi tËp: 1. Sinh m· cho ®o¹n ch¬ng tr×nh sau : tt:= csm- csc; Case dtt of 1 100: tt := dtt*5; 101 200: tt:= 500 +(dtt-100)*6.5 Else tt := 2300+(dtt-200)*9.5 End; 2. While a<>b do If a>b then a:= a-b Else b:= b-a; USCLN := a; 3. S1:= 0 ; S2:=0; i:=1; Repeat If i mod 2 = 0 then S2:= S2+i Else S1:= S1+i; I:=i+1; Until i>n; 3. KT:=1; If x<2 then KT:=0 Else For i:=2 to x-1 do If x mod y = 0 then KT:= 0 . đoạn sinh mã với đầu vào là chơng trình nguồn ở dạng cây cú pháp hoặc cây mã trung gian. Giai đoạn sinh mã bao gồm : + Sinh mã trung gian + Tối u mã + Sinh. III .Sinh mã 1. Mục đích và nhiệm vụ -Sinh mã : là giai đoạn cuối của quá trình dịch, sinh mã tốt là rất khó và sinh mã ra thờng gắn với