OOP (ngôn ngữ lập trình hướng đối tượng ) là ngôn ngữ hiện thực trong đó chương trình được tổ chức như tập hợp những đối tượng hợp tác với nhau, mỗi đối tượng đại diện cho một instance c[r]
(1)LẬP TRÌNH HỆ THỐNG Biên tập bởi:
(2)LẬP TRÌNH HỆ THỐNG Biên tập bởi:
Khoa CNTT ĐHSP KT Hưng Yên Các tác giả:
Khoa CNTT ĐHSP KT Hưng Yên
Phiên trực tuyến:
(3)MỤC LỤC
1 Bài 1: TỔNG QUAN VỀ LẬP TRÌNH HỆ THỐNG 1.1 Khái niệm lập trình hệ thống
1.2 Tổng quan lập trình hệ thống 1.3 Lịch sử lập trình hệ thống
1.4 Cấu trúc tổng quan lập trình hệ thống Bài 2: CƠNG CỤ LẬP TRÌNH HỆ THỐNG
2.1 Các ngơn ngữ lập trình 2.2 Giới thiệu C++
2.3 Giới thiệu Visual C++
3 Bài 3: THỰC HÀNH MỘT SỐ BÀI TẬP CƠ BẢN TRÊN C++ 3.1 Thực hành số tập C++
4 Bài 4: CƠ BẢN VÀ CẤU TRÚC VỀ DRIVER 4.1 Tóm lược lịch sử điều khiển thiết bị
4.2 Tổng quan Hệ điều hành (An Overview of the Operating Systems) 4.3 Các kiểu Driver
4.4 Tổng quan quản lý kiểm tra danh sách
5 Bài 5: THỰC HÀNH MỘT SỐ BÀI TẬP CƠ BẢN TRÊN VC++ 5.1 Thực hành số tập VC++
6 Bài 6: CÁC KỸ THUẬT LẬP TRÌNH CƠ BẢN 6.1 Mơi trường lập trình kiểu Kernel – Mode 6.2 Trình bày lỗi (Lỗi xử lý)
6.3 Quản lý nhớ (Memory Management ) 6.4 Trình bày chuỗi (String Handling)
6.5 Kỹ thuật lập trình hỗn hợp (Miscellaneous Programming Techniques ) Bài 7: THỰC HÀNH MỘT SỐ BÀI TẬP TRÊN VC++
(4)10.2 Cấu trúc cổng COM
11 Bài 11: THỰC HÀNH VỚI CÁC CHƯƠNG TRÌNH GIAO TIẾP QUA CỔNG COM
11.1 Thực hành với chương trình giao tiếp qua cổng COM 12 Bài 12: VẤN ĐỀ ĐỒNG BỘ
12.1 Vấn đề đồng hóa nguyên mẫu (An Archetypal Synchronization Problem ) 12.2 Mức yêu cầu Ngắt (Interrupt Request Level )
12.3 Khóa xoay vịng (Spin Locks )
12.4 Các đối tượng Kernel Dispatcher (Kernel Dispatcher Objects )
12.5 Một số phương pháp đồng khác (Other Kernel-Mode Synchronization Primitives )
13 Bài 13: THỰC HÀNH LẬP TRÌNH DRIVER CƠ BẢN 13.1 Thực hành lập trình driver
14 Bài 14: GÓI DỮ LIỆU VÀO RA
14.1 Các cấu trúc liệu (Data Structures )
14.2 Hàng đợi yêu cầu Vàora (Queuing IO Requests) 14.3 Hủy bỏ yêu cầu vàora (Cancelling IO Requests )
14.4 Tóm lược kịch xử lý (Summary—Eight IRP-Handling Scenarios) 15 Bài 15: THỰC HÀNH LẬP TRÌNH DRIVER CHO XỬ LÝ IRP
15.1 Thực hành số lập trình driver 16 Bài 16: ĐỌC VÀ GHI DỮ LIỆU
16.1 Cấu hình thiết bị bạn (Configuring Your Device ) 16.2 Địa Bộ đệm liệu (Addressing a Data Buffer ) 16.3 Các cổng ghi (Ports and Registers )
16.4 Phục vụ ngắt (Servicing an Interrupt )
16.5 Truy nhập nhớ trực tiếp (Direct Memory Access )
17 Bài 17: ĐIỀU KHIỂN VÀO/RA VÀ HÀM ĐIỀU KHIỂN PLUG AND PLAY 17.1 Hàm DeviceIoControl API (The DeviceIoControl API)
17.2 Điều khiển IRP MJ DEVICE CONTROL
17.3 Những thao tác bên điều khiển IO (Internal IO Control Operations) 18 Bài 18: THỰC HÀNH LẬP TRÌNH DRIVER CHO ĐIỂU KHIỂN VÀO/ RA
18.1 Thực hành lập trình driver cho điều khiển Vàora 19 Bài 19: TRÌNH ĐIỀU KHIỂN CHO USB
19.1 Giới thiệu cổng USB
20 Bài 20: THỰC HÀNH ĐIỀU KHIỂN QUA CỔNG USB
(5)21 Bài 21: TRÌNH ĐIỀU KHIỂN CHO HID
21.1 Những điều khiển cho thiết bị HID (Drivers for HID Devices )
21.2 Những mô tả báo cáo báo cáo (Reports and Report Descriptors ) 21.3 Những điều khiển nhỏ HIDCLASS (HIDCLASS Minidrivers)
22 Bài 22: THỰC HÀNH LẬP TRÌNH HID
22.1 Thực hành với chương trình ví dụ điều khiển cho HID
23 Bài 23: THỰC HÀNH LẬP TRÌNH DRIVER GIAO TIẾP CÁC CỔNG 23.1 Thực hành số tập tổng hợp
24 TÀI LIỆU THAM KHẢO
24.1 Lập trình hệ thống: Tài liệu tham khảo 25 MỤC LỤC
(6)Bài 1: TỔNG QUAN VỀ LẬP TRÌNH HỆ THỐNG
Khái niệm lập trình hệ thống
(7)Tổng quan lập trình hệ thống
Những điểm đặc biệt lập trình hệ thống:
• Những nhà lập trình tạo gánh vác phần cứng số thuộc tính khác chương trình chạy hệ thống đó, thường khai thác thuộc tính (cho ví dụ việc sử dụng giải thuật mà biết mà hiệu sử dụng với phần cứng đặc biệt)
• Thơng thường ngơn ngữ lập trình cấp thấp tiếng địa phương ngơn ngữ lập trình sử dụng là:
◦ hoạt động môi trường tài nguyên bắt buộc ◦ hiệu thực đầu
◦ có thư viện thực nhỏ, không thứ
◦ cho phép trực tiếp “thô” mà điều khiển qua truy cập nhớ điều khiển chảy tràn
◦ người lập trình viết phần chương trình tức khắc ngơn ngữ assembly
• Gỡ rối khó thật khơng để chạy chương trình chương trình gỡ rối ràng buộc tài ngun Chạy chương trình bên mơi trường giả sử dụng để giảm bớt vấn đề
Những nhà lập trình hệ thống cách đầy đủ khác với lập trình ứng dụng mà người lập trình hướng tới chuyên khác
Trong lập trình hệ thống, phương tiện lập trình có hạn thường sẵn có Sự sử dụng tập hợp rác tự động khơng phải phổ biến gỡ rối không đổi để làm Thư viện thực hiện, sẵn có nơi, mạnh nhiều thơng thường, làm sợ kiểm tra lỗi Bởi hạn chế đó, hình đăng ký thường sử dụng; hệ điều hành có vơ chi tiết hóa hệ thống đăng ký
(8)Lịch sử lập trình hệ thống
(9)Cấu trúc tổng quan lập trình hệ thống
Hình 1-1 biểu đồ thu gọn hệ điều hành Windows XP, quan trọng người lập trình driver Các hoạt động Windows XP hỗ trợ hai chế độ Đó User Mode Kernel mode
(10)Bài 2: CÔNG CỤ LẬP TRÌNH HỆ THỐNG
Các ngơn ngữ lập trình
Lập trình hệ thống khơng thiết phải sử dụng ngôn ngữ assembly Thật vậy, tuyệt đại đa số module chức cấu thành hệ điều hành Windows, Unix, Linux viết ngôn ngữ C Ưu điểm ngôn ngữ cấp cao rõ ràng, dễ đọc, dễ diễn đạt giải thuật, diễn đạt giải thuật cô đọng Như vậy, chưa thật cần thiết phải dùng assembly hay ngôn ngữ máy, bạn nên dùng ngôn ngữ cấp cao C, C++ để viết ứng dụng bạn
Ngược lại, ngôn ngữ Assembly hay ngôn ngữ máy không thiết để dùng cho lập trình hệ thống mà dùng để viết ứng dụng Tuy nhiên nhược điểm assembly ngôn ngữ máy yếu để diễn đạt giải thuật nên người dùng chúng trực tiếp Như nói, viết hệ điều hành hay hệ thống nhúng (chương trình điều khiển thiết bị ghi ROM thiết bị đó), người ta cố gắng dùng ngôn ngữ cấp cao C, trừ đoạn code đặc biệt dùng assembly hay mã máy
(11)Giới thiệu C++
C++ ngơn ngữ lập trình tiến tiến, mạnh ngơn ngữ lập trình nay, sử dụng hàng triệu lập trình viên giới Nó ngơn ngữ phổ biến để viết ứng dụng máy tính – ngơn ngữ thơng dụng để lập trình games Được sáng tạo Bjarne Stroustrup, C++ hệ sau ngôn ngữ C Thực tế, C++ giữ lại hầu hết đặc điểm C Như nữa, C++ đem đến cho thuận lợi việc lập trình
Dùng C++ cho Games:
C++ ngơn ngữ lập trình viên games lựa chọn Hầu hết games giới thiệu viết C++ Có nhiều lí khác để giải thích người lập trình games sử dụng C++ Đây vài lí do:
Nhanh:Nếu bạn rành C++ bạn lập trình nhanh Một mục tiêu C++ khả thực thi Và bạn cần thêm tính cho chương trình, C++ cho phép bạn dùng ngôn ngữ Assembly (Hợp ngữ) – Ngôn ngữ lập trình bậc thấp – để giao tiếp trực tiếp với phần cứng máy tính
Dễ điều khiển:C++ ngơn ngữ biến hóa, hỗ trợ phong cách lập trình khác nhau, bao gồm lập trình hướng đối tượng Không giống ngôn ngữ khác, C++ khơng ép buộc lập trình viên phải theo phong cách
(12)Tạo File thực thi: (.exe)
File mà bạn dùng để chạy chương trình – dù bạn nói đến game hay ứng dụng windows – gọi file thực thi (Executable File) Có nhiều bước để tạo file thực thi từ mã nguồn C++ (tập hợp lệnh ngơn ngữ C++) Q trình mơ tả hình 1.1
1 Đầu tiên, người lập trình dùng editor (trình soạn thảo) để viết mã nguồn C++, file thường có cpp Trình soạn thảo giống xử lý ngơn ngữ cho chương trình, cho phép lập trình viên tạo, chỉnh sửa, lưu trữ mã nguồn
(13)3 Tiếp theo, phận kết nối (Linker) kết nối file object đến file ngồi cần thiết, sau tạo file thực thi (executable file), thường có mở rộng exe Đến lúc này, người dùng chạy chương trình cách chạy file thực thi
Lưu ý:Q trình tơi miêu tả trường hợp đơn giản Để tạo nên ứng dụng phức tạp C++ thường liên quan đến nhiều file mã nguồn viết lập trình viên (hay nhóm lập trình viên)
Để tự động hóa q trình này, lập trình viên dùng cơng cụ tổng hợp, IDE (Integrated Development Environment – mơi trường tương thích khai triển) IDE thường bao gồm editor, compiler, linker số công cụ khác Phiên thương mại IDE cho Windows bao gồm Visual Studio.NET C++ Builder Studio Dev-C++ ngôn ngữ mà nguồn mở miễn phí cho Windows (hyutar: strong CD ROM kèm sách gốc có Dev-C++, sách đồ lậu nên hổng có, người tải từ net về, dùng C++ 6.0 hay Visual C++ được, nghĩ hầu hết người có thương mại C rồi)
Xử lý lỗi: (error)
Khi miêu tả trình tạo file thực thi từ mã nguồn C++, tơi bỏ qua chi tiết nhỏ: lỗi Lỗi chuyện hay gặp chương trình máy tính Lập trình viên người thường xun mắc lỗi Ngay lập trình viên giỏi mắc lỗi lần thứ (hoặc nhiều hơn) chạy chương trình Lập trình viên phải sửa lỗi chạy lại trình tạo file thực thi Sau vài loại lỗi bạn thường mắc phải chạy chương trình:
Lỗi biên dịch (Compile Errors):Nó xảy q trình biên dịch Kết quả, file object không tạo Lỗi thường lỗi cú pháp, có nghĩa trình biên dịch khơng hiểu Nó đơn giản gõ sai lệnh chẳng hạn, hay thiếu dấu “;” Trình biên dịch cịn đưa cảnh báo (warning) Mặc dù bạn thường không cần phải ý đến warning, bạn nên giải lỗi, sữa chửa, sau biên dịch lại, thói quen tốt ^^
(14)Trong thực tế:Như nhà tạo phần mềm, công ty game thường gặp rắc rối với sản phẩm bị lỗi Biện pháp khắc phục họ trước đem thị trường, họ thuê người chơi game thử (game testers) Những người chơi games, công việc họ không thú vị bạn tưởng đâu Họ phải chơi chơi lại phần game – lên đến hàng trăm – cố gắng tìm xem có lỗi khơng Và với công việc buồn tẻ này, lương họ bèo nhèo Nhưng trở thành game testers nấc thang để bạn vào làm việc cơng ty làm games
Ví dụ:
#include <stdio.h> #include <conio.h> void main()
{
printf(“chao cac ban”); getch();
(15)Giới thiệu Visual C++
Visual C++ mơt phần mềm lập trình hướng đối tượng phát triển sở ngôn ngữ lập trình C C++
Phương pháp thiết kế hướng đối tượng vừa phát triển nhằm giúp nhà phát triển khai thác sức mạnh đối tượng ngơn ngữ lập trình hướng đối tượng, dùng lớp đối tượng khối xây dựng sở
OOP (ngơn ngữ lập trình hướng đối tượng ) ngơn ngữ thực chương trình tổ chức tập hợp đối tượng hợp tác với nhau, đối tượng đại diện cho instance vài lớp lớp mà chúng thành viên lớp phân cấp thông qua quan hệ thừa kế
1 Abstraction ( tính trừu tượng) :
Sự trừu tượng thể đặc tính cốt yếu đối tượng mà đặc tính dùng để phân biệt đối tượng với tất loại đối tượng khác cung cấp cách rõ ràng giới hạn ý niệm ý nghĩa, liên quan đến viễn tượng người nhìn
Trừu tượng tập trung vào nhìn bề ngồi đối tượng thỏa mãn hành vi chủ yếu đối tượng riêng biệt từ thực
Ta có loại trừu tượng sau:
- Thực thể trừu tượng : đối tượng mà đại diện cho mơ hình hữu dụng miền vấn đề hay thực thể miền giải
(16)mà thực thi cho đối tượng khác Quan điểm buộc phải tập trung vào nhìn bề ngồi đối tượng
Chúng ta gọi toàn tập hợp hoạt động mà client thi hành cho đối tượng, với câu lệnh hợp lệ mà chúng gọi protocol Một protocol biểu thị cách thức mà đối tượng hành động phản ứng, cấu thành tổng thể bề tĩnh động trừu tượng
2 Encap sulation (sự đóng kín) :
Tính đóng kín q trình phân chia phần tử trừu tượng để cấu thành nên cấu trúc hành vi nó, đóng kín cho phép hoạt động giao tiếp trừu tượng thực
Sự đóng kín chế liên kết mã liệu mà thao tác, giữ cho an toàn khỏi can thiệp từ bên sử dụng sai Trong ngôn ngữ hướng đối tượng, mã liệu liên kết với để tạo thành “hộp đen” độc lập Trong hộp tất mã data cần thiết Khi mã data liên kết với đối tượng tạo Nói cách khác, đối tượng dụng cụ hỗ trợ cho đóng kín
Trong đối tượng , mã, data, private (riêng) đối tượng hay public (chung) Mã data riêng thuộc đối tượng truy cập với phận đối tượng Nghĩa mã data riêng truy cập phần khác chương trình tồn ngồi đối tượng Khi data chung, phận khác truy cập đến nó định nghĩa đối tượng Các phần chung đối tượng dùng để cung cấp giao diện có điều khiển cho phần riêng đối tượng
Nói chung, đối tượng biến thuộc kiểu người sử dụng định nghĩa Mỗi lần ta định nghĩa đối tượng mới, ta tạo loại data
Đặc biệt thành viên đặt vào public, private, hay protectedcủa lớp Thành viên khai báo public thấy client, thành viên khai báo private hồn tồn đóng kín, thành viên khai báo protected thấy với lớp lớp C++ cịn cho phép kí hiệu friend : lớp hợp tác phép thấy phần privated
3 Modularity (modun hóa) :
(17)Việc phân chia chương trình thành phần riêng lẻ làm giảm độ phức tạp Ở ngôn ngữ lớp, đối tượng hình thành cấu trúc luận lý hệ thống Chúng ta đặt trừu tượng modun để tạo kiến trúc vật lý hệ thống
Đối với vấn đề nhỏ, nhà phát triển định vấn đề khai báo tất lớp đối tượng gói Ta thường nhóm lớp vàø đối tượng có quan hệ modun, phơi bày phần tử mà modun khác cần thấy Trong hệ thống lớn, có q nhiều modun thật khó cho người sử dụng tìm thấy lớp mà họ cần Hơn , định thay đổi hàng trăm modun phải hiệu chỉnh biên dịch lại Như vậy, modun hóa đơi không tốt
Modun phục vụ phần tử đơn vị phân chia phần mềm mà sử dụng lại qua ứng dụng Nhà phát triển chọn cách đóng gói đối tượng thành modun cho chúng thuận tiện để sử dụng lại
4 Hierachy (hệ thống phân cấp) :
Hệ thống phân cấp xếp theo thứ bậc hay đặt trừu tượng Có hai phân cấp quan trọng hệ thống phức tạp : cấu trúc lớp nó(phân cấp “is a”), cấu trúc đối tượng ( phân cấp “part of “)
Thừa kế đơn giản:thừa kế mối quan hệ “ is a “ thừa kế định nghĩa mối quan hệ lớp, lớp chia sẻ cấu trúc hành vi định nghĩa lớp hay nhiều lớp ( tương ứng với thừa kế đơn giản đa thừa kế ) Do thừa kế phân cấp trừu tượng, lớp thừa kế hay nhiều lớp cha Đa thừa kế đưa đến số vấn đề phức tạp cho ngơn ngữ lập trình Những ngôn ngữ phải đưa hai vấn đề: xung đột tên lớp cha khác nhau, thừa kế lập lại nhiều lần Sự xung đột xảy hai hay nhiều lớp cha cấp chia sẻ lớp cha chung Và trường hợp vậy, lớp có nhiều cấu trúc lớp cha dùng chung Một số ngơn ngữ khơng cho phép thừa kế lập lại, số khác chọn hướng khác C++ cho phép người lập trình định: virtual base class (lớp sở ảo ) dùng để dùng chung cấu trúc lập lại, nonvirtual base class có kết trùng lớp
(18)Là tính chất cho phép tên dùng cho hai nhiều mục đích khác có quan hệ phương diện kỹ thuật Mục đích tính đa dạng áp dụng cho OOP cho phép tên dùng để rõ lớp tác động tổng quát, tác động cụ thể xác định loại data Ví dụ, C, khơng có hỗ trợ tính đa dạng nên tác động giá trị tuyệt đối cần phải có ba hàm khác nhau: abs(), labs(), fabs() Các hàm tính tốn trả giá trị tuyệt đối số nguyên, số nguyên dài, giá trị dấu phẩy động Tuy nhiên, C++ có đặc tính đa dạng nên có hàm abs() Loại data dùng để gọi hàm xác định loại hàm thực dùng Trong C++ sử dụng tên hàm cho nhiều mục đích khác Điều gọi tải hàm(function overloading)
Tổng quan khái niệm tính đa dạng ý tưởng “một giao diện, nhiều phương pháp” Điều có nghĩa thiết kế giao diện chung cho nhóm tác động có liên quan Tuy nhiên, tác động cụ thể thi hành phụ thuộc vào data Ưu điểm tính đa dạng chúng làm giảm tính phức tạp cách cho phép giao diện sử dụng để ghi rõ lớp tác động tổng qt, trình biên dịch lựa chọn tác động cụ thể áp dụng cho trường hợp Là người lập trình ta thực lựa chọn tay Ta cần nhớ sử dụng giao diện chung
Liên kết tĩnh kiên kết động (Static and Dynamic Binding):
Khái niệm typing static typing liên kết tĩnh hoàn toàn khác Strong typing đề cập tới quán kiểu Stactic binding có nghĩa kiểu biến biểu thức cố định vào lúc biên dịch Dynamic binding nghĩa kiểu biến biểu thức khơng cho biết chạy chương trình Bởi Strong typing Dynamic binding khái niệm độc lập ngơn ngữ vừa Strong Static typing
6 Bản chất đối tượng:
Một đối tượng có trạng thái, hành vi, đặc tính nhân dạng; cấu trúc hành vi đối tượng giống định nghĩa lớp chung chúng, thuật ngữ instance đối tượng thay lẫn
Trạng thái (state): đối tượng bao gồm tất đặc tính (thường tĩnh) đối tượng trừ giá trị ( thường động ) đặc tính
Hành vi (behavior ): đối tượng hoạt động phản ứng theo điều kiện trạng thái thay đổi message truyền đến
(19)• Modifier : operation thay đổi trạng thái đối tượng Selector: Operation truy xuất trạng thái đối tượng khơng làm thay đổi trạng thái
• Iterrator : operation cho phép tất phần đối tượng truy xuất theo thứ tự định nghĩa trước Hai loại operation thông dụng khác cần thiết để tạo hủy instance lớp :
• Constructor: operation tạo đối tượng (hoặc) khởi động trạng thái
• Destructor operation giải phóng trạng thái đối tượng (hoặc) hủy đối tượng
• Indentify: (đặc điểm nhận dạng) : indentify đặc tính đối tượng để phân biệt với đối tượng khác
7 Mối quan hệ đối tượng:
Links( liên kết): Link nối kết vật lý hay ý niệm đối tượng Một đối tượng cộng tác với đối tượng khác thơng qua link tới đối tượng Hay nói cách khác, link vó nghĩa hợp tác cụ thể qua đối tượng ( client) áp dụng dịch vụ đối tượng khác (nhà cung cấp) qua đối tượng điều khiển đối tượng khác.Một đối tượng đóng vai trị sau:
• Actor : đối tượng làm việc đối tượng khác khơng cho đối tượng khác làm việc nó, thuật ngữ actor active object thay lẫn
• Server: đối tượng không làm việc đối tượng khác, cho đối tượng khác làm việc
• Agent : đối tượng vừa làm việc đối tượng khác vừa cho đối tượng khác làm việc nó, đại lý thường tạo để làm công việc cho actor hay agent khác
(20)Khi có multiple thread control, việc truyền thơng tin đối tượng cần xử lý vấn đề multual exclusion hệ thống xử lý đồng thời Vấn đề đồng hóa phải xem xét
Aggregation: Aggregation có nghĩa phân cấp tổng thể / phận, với khả điều khiển từ tổng thể ( gọi aggregate ) tới phận (được hiểu thuộc tính nó)
8 Bản chất lớp:
Class (lớp) : tập hợp đối tượng có cấu trúc chung hay hành vi chung Một đối tượng đơn giản instance lớp
Interface: lớp cho thấy bên ngồi đối tượng nhấn mạnh đến vấn đề trừu tượng che dấu cấu trúc hành vi bên
Implemention : mơt lớp nhìn bên Implemention lớp bao gồm tât operation định nghĩa interface Chúng ta chia interface lớp thành ba phần:
• Public : khai báo truy xuất đến client
• Protected : khai báo truy xuất lớp đó, lớp nó, lớp friend • Private: khai báo truy xuất lớp lớp friend
9 Mối quan hệ lớp:
Phần lớn ngôn ngữ hướng đối tượng hỗ trợ trực tiếp vài kết hợp quan hệ sau đây:
• Association : gồm có quan hệ một-một, một-nhiều, nhiều-nhiều
• Inheritance (thừa kế) : lớp chia cấu trúc (hoặc) hành vi định nghĩa lớp (đơn thừa kế) nhiều lớp (đa thừa kế)
• Aggregation (kết tập) : quan hệ kết tập lớp giống quan hệ kết tập đối tượng tượng lớp Đa thừa kế thường bị lẫn lộn với kết tập Trong C++ thừa kế protected hay private dễ dàng bị thay kết tập protected hay private instace lớp cha, mà không tính ngữ nghĩa
http://voer.edu.vn/c/92c88426 BLISS BCPL,