bài giảng môn nguyên lý các ngôn ngữ lập trình C4

40 654 0
bài giảng môn nguyên lý các ngôn ngữ lập trình C4

Đ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

Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại BÀI 4: PHẠM VI, HÀM VÀ QUẢN LÝ BỘ NHỚ Trong chương quản lý nhớ ngôn ngữ cấu trúc khối mô tả cấu trúc liệu thời gian thực mà sử dụng cài đặt tham chiếu đơn giản Các đặc trưng ngôn ngữ lập trình mà tạo nên liên kết tên chương trình với vị trí nhớ quan tâm phạm vi, mà cho phép hai tên cú pháp khác tham chiếu đến hai vị trí khác nhau, lời gọi hàm, mà lời gọi yêu cầu vùng nhớ lưu trữ tham số hàm biến cục Một số chủ đề quan trọng chương truyền tham số, truy cập biến tổng thể tối ưu nhớ gắn kết với kiểu gọi hàm chuyên biệt gọi tail call Chúng ta thấy quản lý nhớ trở nên phức tạp ngôn ngữ có khai báo hàm lồng mà cho phép hàm truyền tham số trả kết lời gọi hàm 2.1 Ngôn ngữ cấu trúc khối Hầu hết ngôn ngữ lập trình đại cung cấp dạng khối Khối vùng đoạn chương trình, xác định đánh dấu bắt đầu kết thúc, mà chứa khai báo cục vùng Sau số dòng mã C minh họa cho ý tưởng oạAn toàn bảo mật thông itn 13 Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Trong đoạn code có hai khối Mỗi khối bắt đầu mở ngoặc trái { kết thúc đóng ngoặc phải } Khối bắt đầu mở ngoặc móc thứ đóng ngoặc móc phải sau Khối lồng khối Nó bắt đầu mở ngoặc móc thứ hai đóng ngoặc móc phải thứ Biến x khai báo block biến y block Một biến khai báo bên block coi cục block Một biến khai báo block bao bọc block xét coi tổng thể block bên Trong ví dụ này, x cục block ngoài, y cục block x tổng thể block C, Pascal, ML ngôn ngữ cấu trúc khối Các khối xác định {…} C, begin … end Pascal let…in…end ML Thân thủ tục hàm khối ngôn ngữ lập trình Cơ chế quản lý nhớ liên kết với cấu trúc khối cho phép hàm gọi đệ qui Các phiên Fortran sử dụng rộng rãi năm 1960 1970 không cấu trúc khối Trong Fortran kinh điển, biến bao gồm tham số thủ tục (được gọi subroutine Fortran) gán với vị trí nhớ cố định Điều làm cho gọi thủ tục đệ qui, trực tiếp gián tiếp Nếu Fortran, procedure P gọi Q Q gọi R sau R thử gọi P, lần gọi P thứ hai không cho phép Giả sử P gọi lần hai, chuỗi gọi đó, lần gọi hai ghi đè lên tham số địa trả lần gọi thứ Điều làm cho gọi để trả kết cách đắn Các ngôn ngữ cấu trúc khối đặc trưng tính chất sau: 14 • Các biến khai báo vị trí khác chương trình • Mỗi khai báo nhìn thấy bên vùng chương trình gọi block Block lồng nhau, không chồng cắt phần Nói cách khác, hai block chứa biểu thức lệnh chung đó, block chứa chọn vẹn block • Khi chương trình bắt đầu thực lệnh chứa block thời gian thực, nhớ cấp cho biến khai báo block • Khi chương trình thoát khỏi block, số toàn bộ nhớ cấp cho biến khai báo block thu hồi • Định danh mà không khai báo block thời coi tổng thể block tham chiếu đến thực thể có tên khai báo block bao bọc gần An toàn bảo mật thông tin Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Có vẻ ngạc nhiên hầu hết phức tạp liên quan đến việc truy cập biến tổng thể Tuy nhiên, điều thực tế kết việc quản lý nhớ dựa ngăn xếp Ngăn xếp sử dụng làm cho dễ dàng cấp truy cập biến cục Trong biến cục đặt gần, biến tổng thể cất ngăn xếp số ghi kích hoạt Mô hình máy tính đơn giản Chúng ta sử dụng mô hình máy tính đơn giản Hình sau để xem xét việc quản trị nhớ ngôn ngữ cấu trúc khối Hình vẽ 4.1 : Ngăn xếp chương trình oạAn toàn bảo mật thông itn 15 Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Mô hình máy Hình 4.1 tách nhớ code khỏi nhớ liệu Bộ đếm chương trình lưu trữ địa lệnh chương trình tăng cách bình thường sau lệnh Khi chương trình vào block mới, ghi kích hoạt activation record chứa nhớ cho biến cục khai báo block bổ sung thêm vào ngăn xếp thời gian chạy (run-time stack – vẽ đỉnh nhớ liệu), trỏ môi trường thiết lập đến ghi Khi chương trình thoát khỏi khối, ghi kích hoạt xóa khỏi ngăn xếp trỏ môi trường đặt lại vị trí cũ Chương trình lưu lại liệu, mà tồn lâu sau thực khối thời, đống heap Trên thực tế, ghi kích hoạt cấp bị thu hồi, thường gọi stack discipline Mặc dù hầu hết ngôn ngữ cấu trúc khối cài đặt ngăn xếp, hàm bậc cao làm cho stack discipline bị lỗi Tuy Hình 4.1 có số ghi, nói chung dùng để lưu trữ địa liệu thời gian ngắn, không bàn đến ghi lệnh mà lưu trữ đoạn code nhớ Cài đặt tham chiếu Cài đặt tham chiếu cài đặt ngôn ngữ mà thiết kế để xác định hành vi ngôn ngữ Nó không cần phải cài đặt hiệu Mục đích chương cho bạn thông tin việc khối cài đặt hầu hết ngôn ngữ lập trình để bạn hiểu nhớ cần cấp phát, kiểu liệu lưu trữ ngăn xếp thời gian chạy, làm để chương trình thực truy cập đến nhớ liệu cần thiết Chúng ta làm điều cách mô tả cài đặt tham chiếu Vì mục đích hiểu chương trình xây dựng chương trình dịch, chương trình tham chiếu đơn giản trực tiếp Các phương pháp hiệu để làm nhiều việc mà mô tả chương này, tùy thuộc vào ngôn ngữ cụ thể, tìm sách chương trình dịch Ghi C Ngôn ngữ lập trình C thiết kế làm cho C dễ dịch dễ thực hiện, tránh số kỹ thuật phạm vi tổng quát quản trị nhớ mô tả chương Hiểu trường hợp tổng quát xét cho lập trình viên C hiểu số cách mà C đơn giản ngôn ngữ khác Thêm vào đó, lập trình viên C, người mà muốn hiệu việc truyền hàm môi trường cho hàm khác, sử dụng ý tưởng mô tả chương cho chương trình họ Một số cài đặt thương mại C C++ thực tế hỗ trợ tham số hàm giá trị trả với việc giữ phạm vi tĩnh việc sử dụng bao đóng (Sẽ bàn đến mục 4.4) Thêm vào thư viện C++ Standard Template Library cung cấp dạng bao đóng hàm nhiều lập trình viên dùng chúng cách hữu ích cho đối số hàm giá trị trả 16 An toàn bảo mật thông tin Trần Văn Dũng BM Khoa học máy tính 2.2 Bài 4: Mã khối đại Khối In-line Khối in-line khối mà không thân hàm thủ tục Trước hết tìm hiểu khối in-line trường hợp đơn giản so với khối gắn kết với lời gọi hàm 2.2.1 Bản ghi kích hoạt biến cục Khi chương trình chạy đến khối in-line, không gian cần cấp cho biến khai báo khối Chúng ta làm điều cách cấp nhớ gọi ghi kích hoạt (activation record) ngăn xếp thời gian chạy Bản ghi kích hoạt gọi khung ngăn xếp (stack frame) Để thấy rõ làm việc nào, xét ví dụ đoạn code sau Nếu code phần chương trình lớn hơn, ngăn xếp chứa không gian cho biến khác, trước khối thực Khi bắt đầu vào khối ngoài, ghi kích hoạt chứa không gian cho x y đẩy vào ngăn xếp Khi lệnh đặt giá trị cho x y thực hiện, làm cho giá trị x y lưu ghi kích hoạt Khi bắt đầu vào khối trong, ghi kích hoạt khác chứa không gian cho z bổ sung vào ngăn xếp Sau giá trị z gán, ghi kích hoạt chứa giá trị lấy khỏi ngăn xếp Cuối cùng, thoát khỏi khối ngoài, ghi kích chứa không gian cho x y lấy khỏi ngăn xếp Chúng ta thấy rõ điều qua việc sử dụng dãy hình vẽ ngăn xếp Như Hình 4.1, ngăn xếp tăng giảm nhớ Hình 4.2 sau Hình 4.2 : Ngăn xếp tăng, giảm trình thực chương trình oạAn toàn bảo mật thông itn 17 Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Tối ưu đơn giản bao gồm kết hợp khối lồng nhỏ vào khối Đối với chương trình ví dụ trước, tiết kiệm thời gian việc đẩy vào lấy khối cho z, cách cho z lưu ghi kích hoạt x y Tuy nhiên, muốn thể trường hợp tổng quát việc sử dụng ví dụ nhỏ, không sử dụng tối ưu bàn tiếp việc cấp nhớ ngăn xếp Trong ví dụ chương trình xét, giả thiết ghi kích hoạt cấp ngăn xếp thời gian chạy chương trình bắt đầu khối Số vị trí mà cần cấp thời gian chạy phụ thuộc vào số biến khai báo khối kiểu chúng Vì số lượng nhớ biết trước thời gian dịch, chương trình dịch cần xác định định dạng ghi kích hoạt lưu thông tin phần mã dịch Các kết trung gian Nói chung, ghi kích hoạt chứa không gian cho kết trung gian Đây giá trị mà tên cho trước code, cần lưu tạm thời Chẳng hạn, ghi cho khối sau: có dạng giá trị biểu thức x+y x–y tính toán lưu trữ trước chúng nhân Trên máy tính đại, có đủ ghi để nhiều kết trung gian lưu trữ ghi mà không đặt ngăn xếp Tuy nhiên, việc cấp ghi kỹ thuật cài đặt mà không ảnh hưởng đến thiết kế ngôn ngữ lập trình, không bàn luận ghi việc cấp ghi 18 An toàn bảo mật thông tin Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Phạm vi thời gian sống Quan trọng cần phân biệt phạm vi khai báo thời gian sống vị trí cấp • Phạm vi: vùng văn mà khai báo nhìn thấy • Thời gian sống quãng thời gian chạy chương trình, vị trí nhớ cấp kết khai báo Chúng ta so sánh thời gian sống phạm vi qua ví dụ sau, gạch dọc sử dụng để điểm vào điểm khối Trong ví dụ này, khai báo bên x giấu khai báo bên Khối bên gọi lỗ hổng phạm vi khai báo bên x, x bên truy cập khối bên Ví dụ thời gian sống không trùng với phạm vi, thời gian sống x bên bao gồm thời gian khối bên thực hiện, phạm vi x bên không bao gồm phạm vi bên Các khối ghi kích hoạt ML Qua việc tranh luận khối ghi kích hoạt, tuân theo qui ước chương trình bước vào khối mới, ghi kích hoạt cấp ngăn xếp thời gian chạy Trong mã ML mà có dãy khai báo, xử lý khai báo khối riêng biệt Chẳng hạn, đoạn code sau Chúng ta coi khai báo f khối khai báo g khối khác bên khối bên Nếu đoạn code không nằm cấu trúc khác, khối hai kết thúc điểm kết thúc chương trình oạAn toàn bảo mật thông itn 19 Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Khi biểu thức ML chứa khai báo phần cấu trúc let-in-end, coi khai báo phần khối Chẳng hạn, xét biểu thức ví dụ sau Biểu thức chứa khối, bắt đầu với let kết thúc end Khối chứa hai khai báo, hàm g h, biểu thức h(x), gọi hàm Cấu trúc let … in … end gần tương đương với {…;…} C Khác biệt cú pháp khai báo mà xuất từ khóa let in, biểu thức sử dụng khai báo xuất từ khóa in end Vì khai báo hàm g h xuất khối, tên g h cho giá trị ghi kích hoạt 2.2.2 Các biến tổng thể liên kết điều khiển Vì ghi khác có kích thước khác nhau, thao tác đẩy vào ghi kích hoạt từ ngăn xếp thời gian chạy, lưu trỏ ghi kích hoạt đến đỉnh ghi trước Con trỏ đến đỉnh ghi trước gọi liên kết điều khiển control link, liên kết mà theo đó, điều khiển trả đến lệnh khối trước Điều cho ta cấu trúc nêu Hình 4.3 Một số tác giả gọi liên kết điều khiển liên kết động, liên kết điều đánh dấu dãy động lời gọi hàm tạo thực chương trình 20 An toàn bảo mật thông tin Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Hình 4.3 Bản ghi kích hoạt với liên kết điều khiển Khi ghi kích hoạt bổ sung vào ngăn xếp, liên kết điều khiển ghi kích hoạt gán cho giá trị trước biến môi trường, biến môi trường cập nhật để trỏ đến ghi kích hoạt Khi ghi kích hoạt lấy khỏi ngăn xếp, biến môi trường khởi tạo lại dựa theo liên kết điều khiển từ ghi kích hoạt Đoạn mã đẩy vào lấy ghi kích hoạt từ ngăn xếp sinh chương trình dịch thời gian dịch trở thành phần mã dịch chương oạAn toàn bảo mật thông itn 21 Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại trình Vì kích thước ghi kích hoạt xác định từ văn khối, chương trình dịch sinh mã tính toán kích thước ghi kích hoạt cho khối Khi biến tổng thể xuất biểu thức, chương trình dịch cần sinh mã tìm vị trí biến thời gian chạy Tuy nhiên, chương trình dịch cần tính số khối khối khối khối mà biến khai báo Điều dễ dàng xác định từ văn chương trình Thêm vào đó, vị trí tương đối biến bên khối biết thời gian dịch Vì chương trình dịch sinh mã tìm kiếm mà suy số liên kết xác định trước Ví dụ 7.1 Khi biểu thức x+y x-y tính toán thực đoạn mã này, ngăn xếp thời gian thực có ghi kích hoạt cho khối bên bên Hình vẽ sau: 22 An toàn bảo mật thông tin Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Hình 4.6 Ngăn xếp thời gian thực sau gọi g bên f 38 An toàn bảo mật thông tin Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Các liên kết điều khiển bên trái để giành không gian cho liên kết truy cập bên phải Liên kết truy cập khối trỏ đến ghi kích hoạt khối bao gần văn chương trình Ở có số điểm quan trọng hình vẽ minh họa này, mà theo qui ước bắt đầu khối cho khai báo ML • Khai báo g xảy bên phạm vi khai báo x Do liên kết truy cập cho khai báo g trỏ đến ghi kích hoạt cho khai báo x • Khai báo f tương tự bên khai báo g Do đó, liên kết truy cập cho khai báo f trỏ đến ghi kích hoạt cho khai báo g • Lời gọi f(3) buộc cho ghi kích hoạt cấp cho phạm vi liên kết với thân f Thân f xảy bên phạm vi khai báo f Do liên kết truy cập cho f(3) trỏ đến ghi kích hoạt cho khai báo f • Lời gọi g(12) tương tự buộc cho ghi kích hoạt cấp cho phạm vi liên kết với thân g Thân g xảy bên phạm vi khai báo g Do liên kết truy cập cho g(12) trỏ đến ghi kích hoạt cho khai báo g • Chúng ta tính toán giá trị biểu thức x+z cách cộng giá trị tham số z , lưu cục ghi kích hoạt g, với giá trị biến tổng thể x Chúng ta tìm vị trí biến tổng thể x cách lần theo liên kết truy cập ghi cho g đến ghi kích hoạt liên kết với khai báo g Do ta theo liên kết kích hoạt ghi để tìm ghi kích hoạt chứa biến x Như khối trực tiếp, chương trình dịch xác định cần lần theo liên kết truy cập tìm đâu biến bên ghi kích hoạt thời điểm dịch Các tính chất dễ dàng xác định từ cấu trúc mã nguồn Tóm lại, liên kết điều khiển liên kết đến ghi kích hoạt khối trước (gọi) Liên kết truy cập liên kết đến ghi kích hoạt khối bao gần nhât văn chương trình Liên kết điều khiển phụ thuộc vào hành vi động chương trình, liên kết truy cập phụ thuộc vào dạng tĩnh văn chương trình Liên kết truy cập dùng để tìm vị trí biến tổng thể ngôn ngữ phạm vi tĩnh với khối lồng thời gian chạy Các liên kết truy cập cần ngôn ngữ lập trình mà hàm khái báo bên hàm khối lồng khác Trong C, hàm khai báo phạm vi tổng thể nhất, liên kết truy cập không cần thiết 2.3.4 Đệ qui đuôi (Trường hợp bậc nhất) Trong mục này, xét tối ưu chương trình dịch có ích gọi khử đệ qui Đối với hàm đệ qui đuôi, mà mô tả sau đây, tái sử dụng ghi kích hoạt cho lời oạAn toàn bảo mật thông itn 39 Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại gọi đệ qui hàm Điều làm giảm kích thước không gian dùng hàm đệ qui Khái niệm ngôn ngữ lập trình mà cần, khái niệm lời gọi đuôi Giả sử hàm f gọi hàm g Hàm f g hàm khác f g hàm Lời gọi hàm f thân hàm g gọi gọi đuôi (tail call) g trả kết lời gọi f mà không cần tính toán Chẳng hạn, hàm Lời gọi thứ f g lời gọi đuôi, trả giá trị g giá trị lời gọi f Lời gọi thứ hai đến f thân g lời gọi đuôi, g thực tính toán gồm giá trị trả f trước g trả kết Hàm f gọi đệ qui đuôi, lời gọi đệ qui thân hàm f lời gọi đuôi đến f Ví dụ 4.7 Sau hàm đệ qui đuôi tính toán giai thừa: Cụ thể hơn, số nguyên n, tlfact(n,1) trả n! Chúng ta thấy tlfact hàm đệ qui đuôi, lời gọi thân hàm tlfact lời gọi đuôi Ưu điểm đệ qui đuôi sử dụng ghi kích hoạt cho lời gọi đệ qui Xét lời gọi tlfact(3,1) Hình 4.7 phần liên quan đén tính toán nói bên trên: 40 An toàn bảo mật thông tin Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Hình 4.7 Ba lời gọi đệ qui đuôi đến tlfact chưa tối ưu Sau lời gọi thứ ba kết thúc, truyền kết trả lại lời gọi thứ hai, mà sau truyền kết trả lại lời gọi thứ Chúng ta đơn giản hóa trình cách cho lời gọi thứ ba trả kết ghi kích hoạt mà tạo nên lời gọi từ đầu, tlfact(3,1) Khi thực phương án này, lời gọi thứ ba kết thúc, ta gỡ ghi kích hoạt cho lời gọi thứ hai, ta không cần Trên thực tế ghi kích hoạt cho lời gọi thứ không cần lời gọi thứ hai bắt đầu, ta gỡ bỏ ghi kích hoạt thư khỏi ngăn xếp trước cấp ghi thứ hai Sẽ tốt hơn, thay thu hồi ghi thứ sau cấp ghi thứ hai đồng với ghi thứ nhất, ta sử dụng ghi kích hoạt cho ba lời gọi Hình 4.8 ghi kích hoạt sử dụng ba lần cho ba lời gọi liên tiếp đến tlfact đệ qui đuôi Hình vẽ nội dung ghi kích hoạt cho lời gọi Khi lời gọi thứ nhất, tlfact(3,1) bắt đầu, ghi kích hoạt với tham số (1,3) tạo Khi lời gọi thứ hai tlfact(2,3) bắt đầu, giá trị tham số thay đổi sang (2,3) Khử đệ qui đuôi tái sử dụng ghi kích hoạt cho lời gọi hàm, sử dụng phép gán thay đổi giá trị tham số hàm cho lời gọi oạAn toàn bảo mật thông itn 41 Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Hình 4.8 Ba lời gọi đến tlfact đệ qui đuôi có tối ưu 2.3.5 Đệ qui đuôi Khi hàm đệ qui đuôi dịch, sinh mã mà tính toán giá trị hàm việc sử dụng vòng lặp Khi tối ưu sử dụng, hàm đệ qui đuôi tính toán ghi kích hoạt cho lời gọi ghi kết lời gọi đệ qui, không cần ghi kích hoạt bổ sung cho lời gọi đệ qui Chẳng hạn, hàm giai thừa đệ qui đuôi trước dịch sang mã mục đích hàm lặp sau: Bản ghi kích hoạt cho itfact trông giống ghi kích hoạt cho tlfact Nếu ta xem giá trị n a lần lặp, ta thấy chúng thay đổi xác lời gọi đệ qui đuôi tới tlfact Hai hàm tính kết việc thực dãy lệnh Như khử đệ qui đuôi dịch hàm đệ qui đuôi thành vòng lặp 2.4 Các hàm bậc cao 2.4.1 Các hàm … bậc Một ngôn ngữ có hàm … bậc hàm • • • 42 Được khai báo phạm vi Được truyền tham số đến hàm khác Được trả kết hàm An toàn bảo mật thông tin Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Trong ngôn ngữ tập trung xử lý hàm phạm vi tĩnh, giá trị hàm nói chung thể bao đóng, mà cặp gồm trỏ đến mã hàm trỏ đến ghi kích hoạt Đây ví dụ hàm ML mà yêu cầu đối số hàm: Hàm map nhận hàm f danh sách m đối số, áp dụng f cho phần tử m Kết map(f, m) danh sách kết f(x) cho phần tử x danh sách m Hàm sử dụng nhiều tình lập trình danh sách sử dụng Chẳng hạn, ta có danh sách thời gian hết hạn sựu kiện ta muốn tăng thời gian hết hạn, áp dụng hàm tăng cho map Chúng ta thấy bao đóng cần thiết cách xét tương tác phạm vi tĩnh đối số hàm giá trị trả C C++ không hỗ trợ bao đóng kèm theo trả giá cài đặt Tuy nhiên, việc cài đặt đối tượng C++ ngôn ngữ khác liên quan đến cài đặt giá trị hàm bàn chương Lý bao đóng đối tượng hai kết hợp liệu với mã hàm Mặc dù số lập trình C kinh nghiệm với việc truyền hàm tham số đến hàm khác, có nhiều tình mà việc phương pháp lập trình có ích Công nhận sử dụng hàm đối số hàm số đến từ khái niệm tổ chức phần mềm có ảnh hưởng Trong lập trình hệ thống, thuật ngữ upcall muốn đến lời gọi hàm ngăn xếp Trong báo quan trọng có tên “The Structuring of Systems Using upcalls” (ACM Symp, Operating Systems principles, 1985) David Clark mô tả phương pháp xếp hàm hệ thống thành lớp (layers) Phương pháp làm cho dễ code, modun hóa suy luận hệ thống Như ngăn xếp giao thức mạng, lớp cao clients dịch vụ cung cấp lớp Trong hệ thống file phân lớp, lớp phân cấp file xây dựng vnode, mà lại xây dựng inode lớp khối đĩa Trong phương pháp Clark, mà đưa vào sử dụng rộng rãi, mức cao truyền hàm điều khiển đến mức thấp Các hàm điều khiển gọi, lớp cần cần nhắc lớp việc Các lời gọi đến lớp gọi upcalls Phương pháp thiết kế có ảnh hưởng lớn giá trị việc hỗ trợ ngôn ngữ cho việc truyền hàm tham số 2.4.2 Truyền hàm đến hàm Chúng ta thấy hàm f truyền cho hàm g, cần truyền bao đóng f, mà chứa trỏ đến ghi Khi f gọi thân g, trỏ môi trường bao đóng sử dụng để đặt liên kết truy cập ghi kích hoạt cho lời gọi đến f cho Sự cần thiết bao đóng tình đôi oạAn toàn bảo mật thông itn 43 Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại gọi downward funarg problem, cho kết từ việc truyền hàm đối số xuống cho phạm vi lặp Ví dụ 4.8 Chương trình ví dụ, với hai khai báo biến x hàm f truyền cho hàm khác g, sử dụng để thể vấn đề sau: Trong chương trình này, thân hàm f chứa biến cục x mà khai báo bên hàm f Khi f gọi bên g, giá trị x cần phải lấy từ ghi kích hoạt gắn kết với khối bên Tuy nhiên thân f cần tính với biến cục x khai báo bên hàm g, mà vi phạm phạm vi tĩnh Đây chương trình mục đích viết cú pháp giống C (ngoại trừ cho biểu thức kiểu int -> int) dành cho cảm thấy dễ đọc hơn: Phiên tựa C đoạn mã phản ánh định dùng để đơn giản hóa suốt sách xử lý khai báo mức cao ML bắt đầu khối riêng Chúng ta thấy vấn đề tìm kiếm biến cách xem ngăn xếp thời gian thực sau lời gọi đến f từ việc khởi tạo g 44 An toàn bảo mật thông tin Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Thể đơn giản đưa liệu chứa ghi kích hoạt Trong hình vẽ trên, biểu thức x*y từ thân hàm f đáy, ghi kích hoạt gắn kết với khởi tạo f (qua tham số hình thức h g) Như hình vẽ, biến y cục hàm cần phải tìm ghi kích hoạt thời Tuy nhiên biến x tổng thể, đặt vài ghi kích hoạt so với ghi thời Vì tìm biến tổng thể theo liên kết truy cập, liên kết truy cập ghi kích hoạt đáy cần phải cho phép ta tìm đến ghi kích hoạt đỉnh hình vẽ Khi hàm truyền cho hàm, cần đặt liên kết truy cập cho ghi hàm cho tìm biến tổng thể hàm cách đắn Chúng ta giải vấn đề cách dễ dàng mà không mở rộng cấu trúc liệu thời gian chạy theo cách Sử dụng bao đóng Giải pháp chuẩn để bảo trì phạm vi tĩnh hàm truyền cho hàm trả kết sử dụng cấu trúc liệu gọi bao đóng Bao đóng cặp gồm trỏ đến mã hàm trỏ đến ghi kích hoạt Vì ghi kích hoạt chứa liên kết truy cập trỏ đến ghi cho bao đóng phạm vi gần nhất, trỏ đến phạm vi mà hàm khai báo cung cấp liên kết đến ghi cho khối bao oạAn toàn bảo mật thông itn 45 Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Khi hàm truyền cho hàm khác, giá trị thực tế mà truyền trỏ đến bao đóng Các bước sau sử dụng để gọi hàm, cho trước bao đóng • Cấp ghi kích hoạt cho hàm gọi thông thường • Đặt liên kết truy cập ghi kích hoạt việc trỏ ghi kịch hoạt từ bao đóng Chúng ta thấy giải vấn đế truy cập biến cho hàm truyền đến hàm hình vẽ ghi kích hoạt ngăn xếp thời gian chạy chương trình Hình 4.8 thực Các điều vẽ Hình 4.9 Hình 4.9 Đặt liên kết truy cập từ bao đóng Chúng ta hiểu Hình vẽ 4.9 duyệt qua bước thời gian chạy mà dẫn đến cấu hình cấu Hình vẽ 46 An toàn bảo mật thông tin Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Khai báo x Một ghi kích hoạt cho khối mà x khai báo đẩy vào ngăn xếp Bản ghi kích hoạt chứa giá trị x liên kết điều khiển (mà chưa nêu) Khai báo f Một ghi kích hoạt cho khối mà f khai báo đẩy vào ngăn xếp Bản ghi kích hoạt chứa trỏ đến biểu diến thời gian chạy f, mà bao đóng với hai trỏ Con trỏ thứ bao đóng trỏ đến ghi kích hoạt cho phạm vi tĩnh f, mà ghi cho khai báo f Con trỏ thứ hai bao đóng trỏ đến mã f, mà tạo dịch đặt vị trí mà chương trình dịch biết, mã dịch chương trình sinh Khai báo g Như với khai báo f, ghi kích hoạt cho khối mà g khai báo đẩy vào ngăn xếp Bản ghi kích hoạt chứa trỏ đến biểu diến thời gian chạy g, mà bao đóng Lời gọi tới g(f): Lời gọi tạo ghi kích hoạt cho hàm g cấp ngăn xếp kích thước thể ghi xác định mã g Liên kết truy cập đặt vào ghi kích hoạt cho phạm vi mà g khai báo; liên kết truy cập trỏ đến ghi kích hoạt ghi kích hoạt bao đóng cho g Bản ghi kích hoạt chứa không gian ch tham số h biến cục x Vì tham số thực tế bao đóng cho f, giá trị tham số cho h trỏ tới bao đóng cho f Biến cục x có giá trị 7, cho mã nguồn Lời gọi tới h(3): Cơ chế để thực thi lời gọi điểm ví dụ Vì h tham số hình thức đến g, mã g dịch mà không cần biết hàm h khai báo đâu Như kết quả, chương trình dịch chèn lệnh nói việc đặt liên kết truy cập cho ghi kích hoạt lời gọi h(3) Tuy nhiên, việc sử dụng bao đóng cung cấp giá trị cho liên kết truy cập – liên kết truy cập đến ghi đặt trỏ đến ghi từ bao đóng h Vì tham số thực tế f, liên kết truy cập trỏ đến ghi kích hoạt cho phạm vị mà f khai báo Khi mã f thực hiện, liên kết truy cập sử dụng để tìm x Đặc biệt, mã lần theo liên kết truy cập lên tới ghi kích hoạt thứ hai minh họa trên, theo liên kết truy cập chương trình biết sinh mã cho f khai báo x nằm phạm vi bên khai báo f, tìm giá trị cho x tổng thể thân hàm f Như mô tả bước 5, bao đóng f cho phép mã thực thời gian chạy để tìm ghi kích hoạt chứa khai báo tổng thể x Khi ta truyền hàm tham số, liên kết truy cập bên ngăn xếp tạo thành Cấu trúc không tuyến tính, ghi kích hoạt tương ứng với lời gọi hàm h(3) cần bỏ qua ghi kích hoạt g(f) để tìm x cần thiết Tuy nhiên, liên kết truy cập trỏ lên Do khả cấp thu hồi ghi kích hoạt việc sử dụng nguyên lý ngăn xếp (cấp sau cùng, thu hồi trước) 2.4.3 Trả hàm từ phạm vi lồng oạAn toàn bảo mật thông itn 47 Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Một vấn đề liên quan phức tạp gọi upward funnarg problem, gọi xác vấn đề kết - hàm phía trên, xảy trả giá trị hàm từ phạm vi lồng nhau, nói chung giá trị trả hàm số Ví dụ đơn giản hàm mà trả hàm mã ML sau cho việc hợp hàm: Cho hai đối số hàm số f g, phép hợp hàm trả hàm hợp f g Thân phép hợp mã yêu cầu tham số hàm x sau tính toán g(f(x)) Mã có ích gắn kết với chế để tìm giá trị f g Do đó, bao đóng sử dụng để thể phép hợp hàm (f,g) Con trỏ mã bao đóng trỏ tới mã dịch “để nhận tham số x hàm sau tính toán g(f(x))” trỏ ghi kích hoạt bao đóng trỏ đến ghi kích hoạt phép hợp lời gọi (f,g) ghi kích hoạt cho mã để tìm hàm thực tế f g cần thiết để tính hợp hàm chúng Chúng ta sử dụng ví dụ hàm gây ngạc nhiên chút để thấy bao đóng giải vấn đề tìm kiếm biến hàm trả từ phạm vi lồng Ví dụ sau cho cảm giác tương tự bao đóng đối tượng Ví dụ 7.9 Trong mã ví dụ này, counter hàm mà có giá trị nguyên lưu trữ Khi gọi, counter tăng giá trị bên trả gía trị Giá trị trở thành giá trị riêng lưu trữ cho lời gọi Hàm ML make_counter sau, nhận đối số nguyên trả counter khởi tạo giá trị nguyên này: Hàm make_counter cấp nhớ cho biến cục count, khởi tạo giá trị tham số nguyên init Hàm make_counter sau trả hàm, mà gọi, tăng thêm giá trị count tham số inc, sau trả giá trị count Các kiểu giá trị gắn kết với khai báo này, in bới chương trình dịch 48 An toàn bảo mật thông tin Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Sau là chương trình viết cú pháp tựa C cho thích dùng hơn: Nếu ta lần theo việc cấp nhớ gắn kết với trinh dịch thực thi, ta thấy nguyên lý ngăn xếp không Cụ thể, cần thiết lưu ghi kích hoạt mà lấy từ ngăn xếp, ta tuân theo nguyên lý chuẩn cấp sau-giải phóng trước Hình 4-10 rằng, ghi cấp giải phóng thực thi mã từ ví dụ 49 Sau dãy bước để tạo ghi Hình 4-10 Khai báo make_counter Một ghi kích hoạt cho khối bao gồm việc khai báo hàm make_counter cấp ngăn xếp thời gian chạy Tên hàm dùng cho counter đươc viết ngắn make_c để tên trùng với hình vẽ Giá trị make_c bao đóng Con trỏ ghi kích hoạt bao đóng trỏ trỏ đến ghi kích hoạt make_counter Con trỏ mã bao đóng trỏ đến trỏ đến mã make_counter tạo thời gian dịch Khai báo c: Bản ghi kích hoạt khối gồm khai báo hàm c cấp ngăn xếp thời gian chạy Con trỏ truy cập ghi kích hoạt trỏ ghi kích hoạt dầu tiên , khai báo make_counter khối trước Giá trị c hàm biểu diễn bao đóng Tuy nhiên, biểu thức định nghĩa hàm c khai báo hàm Đây biểu thức mà gửi mà lời gọi yêu cầu đến hàm make_counter Do đó, sau ghi kích hoạt thiết lập, chương trình thực cần phải gọi đến make_counter Lời gọi đến make_counter: Một ghi kích hoạt cấp để thực thi hàm make_counter Bản ghi kích hoạt chứa không gian cho tham số mà kết trả lời gọi Con trỏ mã bao đóng cho counter trỏ đến mã mà sinh lưu thời gian dịch Con trỏ ghi oạAn toàn bảo mật thông itn 49 Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại kích hoạt trỏ đến ghi kích hoạt thứ ba, biến cục hàm thường trú Chương trình cần ghi kích hoạt ba sau lời gọi đến make_counter trả về, counter hàm trả từ lời gọi đến make_counter tham chiếu đến biến init count mà lưu (hoặc đạt thông qua) ghi kích hoạt cho make_counter Nếu ghi kích hoạt ba (sử dụng để gọi đến make_counter lấy từ ngăn xếp), hàm counter làm việc không đắn Lời gọi đầu tới c(2): Khi biểu thức đầu c(2) tính toán, ghi kích hoạt tạo cho lời gọi hàm Bản ghi kích hoạt có trỏ truy cập thiết lập từ bao đóng cho c Vì bao đóng trỏ đến ghi kích hoạt ba, nên trỏ truy cập cho ghi kích hoạt Điều quan trọng mã cho counter tham chiếu đến biến count count cấp theo trỏ ghi kích hoạt ba Hình 4.10: Các ghi kích hoạt cho bao đóng hàm trả từ hàm Ở có hai điểm cần nhớ ví dụ này: • Bao đóng dùng để thiết lập trỏ truy cập hàm trả từ phạm vi lồng gọi • Khi hàm trả từ phạm vi lồng nhau, ghi kích hoạt không cần tuân theo nguyên lý ngăn xếp Bản ghi kích hoạt cấp với lời gọi hàm giải phóng hàm trả về, giá trị trả hàm hàm khác mà đòi hỏi ghi kích hoạt 50 An toàn bảo mật thông tin Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối đại Giải pháp cho vấn đề quản trị nhớ Bạn nhận thấy rằng, sau mã Ví dụ 4.9 thực hiện, theo bước mô tả, số ghi kích hoạt lại ngăn xếp mà sử dụng phần lại chương trình Cụ thể hàm c gọi biểu thức khác, cần ghi kích hoạt mà trì phạm vi tĩnh Tuy nhiên, hàm c không sử dụng nữa, không cần ghi kích hoạt Ta hỏi, chương trình dịch hệ thống thời gian chạy xác định việc ghi kích hoạt giải phóng Có số phương pháp giải vấn đề Tuy nhiên, việc bàn luận đầy đủ phức tạp không cần thiết để hiểu cân nhắc thiết kế ngôn ngữ mà đối tượng chương Một giải pháp mà tương đối trực tiếp không hiệu đơn giản sử dụng thuật toán thu gom rác để tìm ghi mà không cần Trong cách tiếp cận này, thu gom rác lần theo trỏ đến ghi kích hoạt thu gom ghi không đạt mà trỏ bao đóng trỏ đến chúng 2.5 Tóm tắt chương Một khối vùng văn chương trình, xác định dấu bắt đầu kết thúc, mà chứa khai báo cục vùng Các khối xuất bên khối khác thân hàm hay thủ tục Các ngôn ngữ cấu trúc khối cài đặt ghi kích hoạt mà chứa không gian cho biến cục thông tin liên quan đến khối khác Vì có cách khối chồng chéo lên khối khác khối chứa trọn vẹn khối Các ghi kích hoạt nói chung quản lý ngăn xếp thời gian chạy với sách ghi kích hoạt cấp giải phóng trước tiên (last allocated – first deallocated) Các tham số truyền cho hàm thủ tục lưu ghi kích hoạt, biến cục Bản ghi kích hoạt chứa giá trị tham số thực tế (truyền theo giá trị) địa (truyền theo tham chiếu) Lời gọi đuôi có thể tối ưu để tránh trả thủ tục gọi Trong trường hợp hàm đệ qui đuôi mà không truyền đối số hàm, điều có nghĩa ghi kích hoạt dùng cho lời gọi đệ qui, loại bỏ việc cần thiết phải cấp, khởi tạo, sau giải phóng ghi kích hoạt cho lời gọi Kết hàm đệ qui đuôi thực hiệu vòng lặp Truy cập đến biến tổng thể phạm vi tĩnh bao gồm ba khái niệm cài đặt sau: • Các ghi kích hoạt hàm thủ tục chứa liên kết truy cập (phạm vi tĩnh) mà trỏ đến ghi kích hoạt liên kết với khối bao trung gian oạAn toàn bảo mật thông itn 51 Trần Văn Dũng BM Khoa học máy tính • • Bài 4: Mã khối đại Các hàm truyền tham số trả kết cần biểu diễn dạng bao đóng (closures) gồm mã hàm với trỏ đến môi trường từ vựng Khi hàm trả hàm mà dựa biến khai báo phạm vi lồng nhau, phạm vi tĩnh đòi hòi suy diễn từ nguyên lý ngăn xếp: Bản ghi kích hoạt cần trì giá trị hàm (bao đóng) không cần sử dụng chương trình Mỗi khái niệm đặt bàn chương này, gắn chặt với tính chất ngôn ngữ cụ thể, tổng kết bảng sau: Các tập việc ghi kích hoạt cho khối mà x khai báo đẩy vào trên, ngăn xếp 52 An toàn bảo mật thông tin [...]... (không thay đổi) giữa các khối trong văn bản chương trình Ngược lại, phạm vi động sử dụng dãy thực tế các lời gọi mà được thực thi trong quá trình thực hiện động (thay đổi) của chương trình Mặc dù hầu hết các ngôn ngữ lập trình đa năng sử dụng phạm vi tĩnh cho khai báo các biến và các hàm, phạm vi động là khái niệm quan trọng mà được sử dụng trong các ngôn ngữ chuyên dụng và cho các cấu trúc chuyên dụng... Văn Dũng BM Khoa học máy tính Bài 4: Mã khối hiện đại Cách mà các tham số thực tế được tính toán và truyền cho hàm phụ thuộc vào ngôn ngữ lập trình và cơ chế truyền tham số mà nó sử dụng Sự khác biệt chính giữa các cơ chế truyền tham số là • Thời điểm mà tham số thực tế được tính toán • Vị trí được sử dụng để lưu giá trị tham số Hầu hết các ngôn ngữ lập trình tính toán các tham số thực tế trước khi... chương trình Liên kết truy cập được dùng để tìm vị trí các biến tổng thể trong ngôn ngữ phạm vi tĩnh với các khối lồng nhau trong thời gian chạy Các liên kết truy cập chỉ cần trong các ngôn ngữ lập trình mà ở đó các hàm có thể được khái báo bên trong hàm hoặc các khối lồng nhau khác Trong C, ở đó các hàm đều được khai báo ở phạm vi tổng thể ngoài nhất, các liên kết truy cập là không cần thiết 2.3.4 Đệ qui... nhau từ chương trình dịch này đến chương trình dịch khác, nhưng điểm chính là chương trình dịch có thể xác định số liên kết điều khiển cần lần theo và vị trí tương đối của biến trong khối chứa nó từ mã nguồn Đặc biệt không cần thiết phải lưu tên biến trong các bản ghi kích hoạt 2.3 Các hàm và các thủ tục Hầu hết các ngôn ngữ cấu trúc khối có các thủ tục hoặc các hàm mà chứa các tham số, các biến cục... luận có thể bàn về các tính chất của hàm, và sau đó ví dụ code có thể thể hiện các tính chất với một thủ tục nào đó Cũng cần phải nhắc bạn rằng việc bàn luận này áp dụng cho cả các hàm và thủ tục trong nhiều ngôn ngữ lập trình, cho dù ngôn ngữ đó có xử lý thủ tục khác với hàm không 2.3.1 Bản ghi kích hoạt cho các hàm Bản ghi kích hoạt của khối hàm hoặc thủ tục cần phải có không gian cho các tham số và... tạm thời cho các kết quả trung gian được tính toán với việc thực hiện hàm oạAn toàn và bảo mật thông itn 25 Trần Văn Dũng BM Khoa học máy tính Bài 4: Mã khối hiện đại Hình 7.4: Bản ghi kích hoạt gắn kết với lời gọi hàm Thông tin này có thể được lưu theo thứ tự khác nhau và theo các cách khác nhau trong việc cài đặt các ngôn ngữ lập trình khác nhau Cũng như đã lưu ý trước đây, nhiều chương trình dịch... là cần thiết bằng cách xét tương tác giữa phạm vi tĩnh và các đối số của hàm và giá trị trả về C và C++ không hỗ trợ bao đóng vì nó kèm theo trả giá cài đặt Tuy nhiên, việc cài đặt các đối tượng trong C++ và các ngôn ngữ khác liên quan đến cài đặt các giá trị hàm sẽ được bàn trong chương này Lý do là bao đóng và đối tượng cả hai đều kết hợp dữ liệu với mã của hàm Mặc dù một số lập trình C có thể không... cho tlfact Nếu ta xem các giá trị của n và a trên mỗi lần lặp, ta sẽ thấy chúng thay đổi chính xác như đối với các lời gọi đệ qui đuôi tới tlfact Hai hàm này tính ra cùng một kết quả bằng việc thực hiện cùng dãy chỉ lệnh như nhau Như vậy khử đệ qui đuôi dịch hàm đệ qui đuôi thành các vòng lặp 2.4 Các hàm bậc cao 2.4.1 Các hàm … bậc nhất Một ngôn ngữ có các hàm … bậc nhất nếu các hàm đó có thể • • •... dãy các câu lệnh Chẳng hạn, sau đây là một số dạng giống C và Algol: Sự khác biệt giữa thủ tục và hàm là hàm có trả giá trị về, còn thủ tục thì không Trong hầu hết các ngôn ngữ, các hàm và thủ tục có thể có một số tác động phụ Tuy nhiên, thủ tục chỉ có tác động phụ là lời gọi thủ tục là lệnh chứ không phải là biểu thức Vì các hàm và các thủ tục có nhiều tính chất chung, chúng ta sử dụng thuật ngữ hầu... phương pháp lập trình có ích Công nhận sử dụng một hàm như đối số hàm số đến từ khái niệm tổ chức phần mềm có ảnh hưởng Trong lập trình hệ thống, thuật ngữ upcall muốn chỉ đến lời gọi hàm trên ngăn xếp Trong bài báo quan trọng có tên là “The Structuring of Systems Using upcalls” (ACM Symp, Operating Systems principles, 1985) David Clark mô tả phương pháp sắp xếp các hàm của hệ thống thành các lớp (layers)

Ngày đăng: 03/04/2016, 20:35

Mục lục

  • Trong chương này quản lý bộ nhớ đối với ngôn ngữ cấu trúc khối sẽ được mô tả bằng cấu trúc dữ liệu thời gian thực mà được sử dụng trong cài đặt tham chiếu đơn giản. Các đặc trưng của ngôn ngữ lập trình mà tạo nên liên kết giữa các tên trong chương trình với các vị trí bộ nhớ quan tâm là phạm vi, mà cho phép hai tên cú pháp khác nhau tham chiếu đến hai vị trí khác nhau, và các lời gọi hàm, mà mỗi lời gọi yêu cầu một vùng nhớ mới ở đó lưu trữ các tham số của hàm và các biến cục bộ. Một số chủ đề quan trọng trong chương này là truyền tham số, truy cập biến tổng thể và tối ưu bộ nhớ gắn kết với kiểu gọi hàm chuyên biệt gọi là tail call. Chúng ta sẽ thấy quản lý bộ nhớ trở nên phức tạp trong các ngôn ngữ có các khai báo hàm lồng nhau mà cho phép hàm được truyền như các tham số hoặc trả về như kết quả của lời gọi hàm.

  • 2.1. Ngôn ngữ cấu trúc khối

  • Trong đoạn code này có hai khối. Mỗi khối bắt đầu bằng mở ngoặc trái { và kết thúc bằng đóng ngoặc phải }. Khối ngoài được bắt đầu bằng mở ngoặc móc thứ nhất và đóng ngoặc móc phải sau cùng. Khối trong được lồng trong khối ngoài. Nó bắt đầu bằng mở ngoặc móc thứ hai và đóng ngoặc móc phải thứ nhất. Biến x được khai báo trong block ngoài và biến y trong block trong. Một biến được khai báo bên trong một block được coi là cục bộ đối với block đó. Một biến được khai báo trong một block bao bọc một block đang xét được coi là tổng thể của block bên trong đó. Trong ví dụ này, x là cục bộ đối với block ngoài, y là cục bộ đối với block trong và x là tổng thể đối với block trong.

  • C, Pascal, ML là các ngôn ngữ cấu trúc khối. Các khối được xác định bởi {…} trong C, begin … end trong Pascal và let…in…end trong ML. Thân của các thủ tục hoặc hàm cũng là các khối trong các ngôn ngữ lập trình đó.

  • Cơ chế quản lý bộ nhớ liên kết với cấu trúc khối cho phép các hàm được gọi đệ qui.

  • Các phiên bản Fortran được sử dụng rộng rãi trong những năm 1960 và 1970 không là cấu trúc khối. Trong Fortran kinh điển, mỗi biến bao gồm các tham số của mỗi thủ tục (được gọi là subroutine trong Fortran) được gán với một vị trí bộ nhớ cố định. Điều đó làm cho không thể gọi thủ tục đệ qui, hoặc trực tiếp hoặc gián tiếp. Nếu trong Fortran, procedure P gọi Q và Q gọi R và sau đó R thử gọi P, thì lần gọi P thứ hai là không cho phép. Giả sử P được gọi lần hai, thì trong chuỗi gọi đó, lần gọi hai sẽ ghi đè lên các tham số và địa chỉ trả về của lần gọi thứ nhất. Điều này làm cho nó không thể gọi để trả về kết quả một cách đúng đắn.

  • Các ngôn ngữ cấu trúc khối được đặc trưng bởi các tính chất sau:

  • Các biến mới có thể được khai báo ở các vị trí khác nhau trong chương trình

  • Mỗi khai báo được nhìn thấy bên trong một vùng nào đó của chương trình được gọi là block. Block có thể lồng nhau, nhưng không được chồng cắt nhau từng phần. Nói cách khác, hai block chứa một biểu thức hoặc các lệnh chung nào đó, thì một block sẽ chứa chọn vẹn trong block kia.

  • Khi chương trình bắt đầu thực hiện các chỉ lệnh chứa trong một block trong thời gian thực, bộ nhớ được cấp cho các biến được khai báo trong block.

  • Khi chương trình thoát ra khỏi block, một số hoặc toàn bộ bộ nhớ cấp cho các biến khai báo trong block được thu hồi.

  • Định danh mà không khai báo trong block hiện thời được coi là tổng thể đối với block và được tham chiếu đến thực thể có tên đó được khai báo trong block bao bọc gần nhất.

  • Có vẻ ngạc nhiên là hầu hết các phức tạp liên quan đến việc truy cập các biến tổng thể. Tuy nhiên, điều này trên thực tế là kết quả của việc quản lý bộ nhớ dựa trên ngăn xếp. Ngăn xếp được sử dụng làm cho dễ dàng cấp và truy cập các biến cục bộ. Trong khi các biến cục bộ được đặt gần, thì các biến tổng thể được cất trong ngăn xếp dưới một số bản ghi kích hoạt.

  • Mô hình máy tính đơn giản

  • Chúng ta sử dụng mô hình máy tính đơn giản trên Hình sau để xem xét việc quản trị bộ nhớ trong các ngôn ngữ cấu trúc khối.

  • Mô hình máy trên Hình 4.1 tách bộ nhớ code khỏi bộ nhớ dữ liệu. Bộ đếm chương trình lưu trữ địa chỉ của chỉ lệnh hiện tại của chương trình và được tăng một cách bình thường sau mỗi chỉ lệnh. Khi chương trình vào một block mới, một bản ghi kích hoạt activation record chứa bộ nhớ cho các biến cục bộ khai báo trong block được bổ sung thêm vào ngăn xếp thời gian chạy (run-time stack – được vẽ trên đỉnh bộ nhớ dữ liệu), và con trỏ môi trường được thiết lập đến bản ghi mới này. Khi chương trình thoát khỏi khối, bản ghi kích hoạt đó được xóa khỏi ngăn xếp và con trỏ môi trường sẽ được đặt lại vị trí cũ. Chương trình có thể lưu lại dữ liệu, mà có thể tồn tại lâu hơn sau khi thực hiện khối hiện thời, trên đống heap. Trên thực tế, bản ghi kích hoạt được cấp mới nhất là cái đầu tiên sẽ bị thu hồi, thường được gọi là stack discipline. Mặc dù hầu hết các ngôn ngữ cấu trúc khối được cài đặt bởi ngăn xếp, các hàm bậc cao có thể làm cho stack discipline bị lỗi.

  • Tuy Hình 4.1 có một số thanh ghi, nói chung được dùng để lưu trữ địa chỉ và dữ liệu trong thời gian ngắn, chúng ta sẽ không bàn đến thanh ghi hoặc chỉ lệnh mà có thể lưu trữ trên đoạn code của bộ nhớ.

  • Cài đặt tham chiếu. Cài đặt tham chiếu là cài đặt ngôn ngữ mà được thiết kế để xác định hành vi của ngôn ngữ. Nó không cần phải là cài đặt hiệu quả. Mục đích của chương này là cho bạn thông tin về việc các khối được cài đặt như thế nào trong hầu hết các ngôn ngữ lập trình để bạn có thể hiểu khi nào bộ nhớ cần được cấp phát, kiểu dữ liệu nào được lưu trữ trên ngăn xếp thời gian chạy, làm thế nào để chương trình đang thực hiện truy cập đến các bộ nhớ dữ liệu khi cần thiết. Chúng ta sẽ làm điều đó bằng cách mô tả cài đặt tham chiếu. Vì mục đích của chúng ta là hiểu chương trình chứ không phải xây dựng chương trình dịch, chương trình tham chiếu này sẽ đơn giản và trực tiếp. Các phương pháp hiệu quả hơn để làm nhiều việc mà được mô tả trong chương này, tùy thuộc vào các ngôn ngữ cụ thể, có thể tìm trong các cuốn sách về chương trình dịch.

  • Ghi chú về C.

  • Ngôn ngữ lập trình C được thiết kế làm cho C dễ dịch và dễ thực hiện, tránh một số kỹ thuật phạm vi tổng quát và quản trị bộ nhớ mô tả trong chương này. Hiểu các trường hợp tổng quát xét ở đây sẽ cho các lập trình viên C hiểu một số cách mà ở đó C đơn giản hơn các ngôn ngữ khác. Thêm vào đó, các lập trình viên C, người mà muốn hiệu quả trong việc truyền hàm và môi trường của nó cho hàm khác, có thể sử dụng ý tưởng được mô tả trong chương này cho chương trình của họ.

Tài liệu cùng người dùng

Tài liệu liên quan