Bài giảng môn Kỹ thuật Vi xử lý

pdf 85 trang vanle 2210
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng môn Kỹ thuật Vi xử lý", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfbai_giang_mon_ky_thuat_vi_xu_ly.pdf

Nội dung text: Bài giảng môn Kỹ thuật Vi xử lý

  1. BM.05-QT.DT.04 TRƯỜNG ĐẠI HỌC HÀNG HẢI VIỆT NAM 15/3/12-REV:0 KHOA CÔNG NGHỆ THÔNG TIN BÀI GIẢNG TÊN HỌC PHẦN : KỸ THUẬT VI XỬ LÝ MÃ HỌC PHẦN : 17301 HỆ ĐÀO TẠO : ĐẠI HỌC CHÍNH QUY Hải Phòng, ngày / / 20 Hải Phòng, ngày / / 20 Hải Phòng, ngày 12/12/2013 TRƯỞNG KHOA TRƯỞNG BỘ MÔN NGƯỜI BIÊN SOẠN (hoặc Trưởng đơn vị) (hoặc Trưởng bộ phận) Ts. Lê Quốc Định Ths. Ngô Quốc Vinh Ths. Phạm Trung Minh HẢI PHÒNG, 12/2013
  2. MỤC LỤC Chƣơng 1 : TỔNG QUAN 1 1.2. Tổng quan về Bộ và Hệ vi xử lý 1 1.2. Bộ vi xử lý 1 1.3. Hệ vi xử lý 1 1.2. Những đặc điểm cấu trúc của bộ vi xử lý 2 1.2.1. Công suất của bộ vi xử lý 2 1.2.2. Những đặc tính nâng cao tốc độ của bộ vi xử lý 3 1.3. Tập lệnh của bộ vi xử lý 5 Chƣơng 2 : CẤU TRÚC CÁC BỘ VI XỬ LÝ 6 2.1. Sơ đồ khối cấu trúc bộ VXL cấp thấp (8bit) 6 2.1.1. Đơn vị số học – logic ALU 6 2.1.2. Các thanh ghi (Registers) 6 2.1.3. Khối logic điều khiển CL ( Control Logic) 7 2.2. Sơ đồ khối cấu trúc bộ VXL công nghệ cao 8 Chƣơng 3: BỘ VI XỬ LÝ INTEL 8088 9 3.1. Cấu trúc bên của bộ vi xử lý 8088. 9 3.2. Tập các thanh ghi. 11 3.3. Phương pháp quản lý bộ nhớ 16 3.4. Ngắt 17 3.4.1. Khái niệm ngắt 17 3.4.2. Các loại ngắt và bảng vector ngắt 18 3.4.3. Gọi ngắt 21 3.5. Mã hoá lệnh của bộ vi xử lý 8088 21 Chƣơng 4 : LẬP TRÌNH BẰNG HỢP NGỮ VỚI 8088 24 4.1. Tổng quan, cấu trúc hợp ngữ (Assembly) 24 4.1.1. Cú pháp của chương trình hợp ngữ 24 4.1.2. Khung của một chương trình hợp ngữ 25 4.2. Dữ liệu trong Assembly 29 4.2.1. Dữ liệu cho chương trình 29 4.2.2. Biến và hằng 29 4.2. Vào/ra trong Assembly 31 4.3. Nhóm lệnh dịch chuyển dữ liệu 32 4.3.1. Lệnh Mov (Move) 32 4.3.2. Lệnh LEA (LoadEffectiveAddress) 33 4.3.3. Lệnh chuyển dữ liệu qua cổng: IN và OUT 34 4.4. Nhóm lệnh tính toán số học 35 4.4.1. Lệnh cộng 35
  3. 4.4.1. Lệnh trừ 35 4.4.3. Lệnh nhân 35 4.4.4. Lệnh chia 36 4.5. Nhóm lệnh chuyển điều khiển 36 4.5.1. Lệnh nhẩy không có điều kiện 36 4.5.2. Lệnh so sánh 37 4.5.3. Lệnh nhẩy có điều kiện 38 4.5.4. Lệnh lặp 38 4.6. Nhóm lệnh Logic 38 4.6.1. Lệnh And 38 4.6.2. Lệnh OR 39 4.6.3. Lệnh XOR 39 4.6.4. Lệnh NOT 39 4.7. Nhóm lệnh dịch và quay 40 4.7.1. Lệnh dịch 40 4.7.2. Lệnh quay 41 Chƣơng 5 : PHỐI GHÉP 8088 VỚI BỘ NHỚ VÀ TỔ CHỨC VÀO/RA DỮ LIỆU 43 5.1. Các chân tín hiệu của 8088 và các mạch phụ trợ 43 5.1.1. Các tín hiệu của 8088 43 5.1.2. Phân kênh để tách thông tin và việc đệm cho các bus 46 5.1.3. Mạch tạo xung nhịp 8284 47 5.1.4. Mạch điều khiển bus 8288 49 5.1.5. Biểu đồ thời gian của các lệnh ghi/đọc 50 5.2. Phối ghép 8088 với bộ nhớ 53 5.2.1. Bộ nhớ bán dẫn 53 5.2.2. Giải mã địa chỉ cho bộ nhớ 56 5.2.3. Phối ghép CPU 8088 - 5MHz với bộ nhớ 60 5.3. Phối ghép 8088 với thiết bị ngoại vi 61 5.3.1. Các kiểu phối ghép vào/ra 61 5.3.2. Giải mã địa chỉ cho thiết bị vào/ra 62 5.3.3. Các lệnh vào/ra dữ liệu 63 5.3.4. Mạch phối ghép vào/ra song song lập trình được 8255A 64 5.4. Một số phối ghép cơ bản 69 5.4.1. Phối ghép với bàn phím 70 5.4.2. Phối ghép với đèn Led 77
  4. Kỹ thuật vi xử lý Mã HP: 17301 a. Số tín chỉ: 3 TC BTL ĐAMH b. Đơn vị giảng dạy: Bộ môn Kỹ thuật Máy tính c. Phân bổ thời gian: - Tổng số (TS): 60 tiết. - Lý thuyết (LT): 28 tiết. - Thực hành (TH): 30 tiết. - Bài tập (BT): 0 tiết. - Hướng dẫn BTL/ĐAMH (HD): 0 tiết. - Kiểm tra (KT): 2 tiết. d. Điều kiện đăng ký học phần: Học phần học trước: Kiến trúc máy tính và TBNV, Kỹ thuật lập trình (C) e. Mục đích, yêu cầu của học phần: Kiến thức : - Nắm bắt các kiến thức cơ bản, cấu tạo, nguyên lý của bộ vi xử lý, hệ vi xử lý cùng các vấn đề liên quan. - Tìm hiểu cấu trúc nguyên lý thực hiện của các bộ vi xử lý cấp thấp, cấp cao. - Tìm hiểu cấu trúc, các thành phần, nguyên lý thực thi, tập lệnh của bộ VXL 8086/8088. - Sử dụng thành thạo ngôn ngữ lập trình hệ thống (Assembly), ứng dụng trong các bài toán lập trình điều khiển hệ thống. - Hiểu được cơ chế phối ghép giữa bộ VXL với các thành phần quan trọng khác trong hệ thống nhằm tạo thành 1 hệ VXL hoàn chỉnh, ổn định. Kỹ năng : - Thành thạo trong việc xác định đặc điểm, thông số, tính chất của các bộ, dòng vi xử lý, hệ vi xử lý. - Thành thạo ngôn ngữ lập trình hệ thống, áp dụng cho việc lập trình mức hệ thống. - Hiểu và thực hiện tốt các cơ chế giải mã lệnh. - Xác định chính xác các cơ chế giải mã địa chỉ cho bộ nhớ, thiết bị. - Hiểu và thành thạo việc xác định các chân tin hiệu của bộ vi xử lý trong việc việc ghép nối với các thành phần khác trong hệ thống. Thái độ nghề nghiệp: - Có thái độ ứng xử đúng trong vận hành, khai thác hiệu quả các bộ - hệ vi xử lý. - Hình thành nhận thức về phân tích, giải quyết các bài toán với các hệ vi xử lý. f. Mô tả nội dung học phần: Học phần trang bị các kiến thức về: Các vấn đề cơ bản của các bộ – hệ vi xử lý; Tập lệnh, các chế độ địa chỉ, lập trình điều khiển hệ thống; Các thành phần phụ trợ và ghép nối vi xử lý với khối vào ra cơ bản. g. Người biên soạn: Phạm Trung Minh – Bộ môn Kỹ thuật Máy tính h. Nội dung chi tiết học phần: PHÂN PHỐI SỐ TIẾT TÊN CHƢƠNG MỤC TS LT BT TH HD KT Chƣơng 1. Tổng quan 5 5
  5. PHÂN PHỐI SỐ TIẾT TÊN CHƢƠNG MỤC TS LT BT TH HD KT 1.1. Tổng quan về Bộ và Hệ Vi xử lý 1.5 1.2. Các đặc điểm cấu trúc của hệ Vi xử lý 2.5 1.3. Tập lệnh của bộ vi xử lý 1 Nội dung tự học (10t): - Tự nghiên cứu bài giảng, tài liệu khác về các vấn đề : • Lịch sử phát triển, đặc tính của các thế hệ bộ vi xử lý. • Các vi mạch hỗ trợ cho bộ vi xử lý. - Sử dụng Internet để tìm đọc tài liệu và tóm tắt bằng tiếng Việt các hệ vi xử lý dòng Pentium và Core của hãng Intel. - Đọc và tìm hiểu Chương 2 :Cấu trúc của bộ vi xử lý. Chƣơng 2. Cấu trúc của bộ vi xử lý 2 2 2.1.Bộ vi xử lý cấp thấp (8 bit) 1 2.2. Bộ vi xử lý cấp cao (16 bit) 1 Nội dung tự học (4t): - Tự nghiên cứu bài giảng, tài liệu khác về các vấn đề : • Cấu trúc một số bộ vi xử lý cấp thấp (thế hệ 1 và 2). • Cấu trúc một số bộ vi xử lý cấp cao. • Xác định cấu tạo, nguyên lý hoạt động của các thành phần trong các bộ vi xử lý cấp cao (PUIQ, BTC, CU, MMU, SFU, IU, FPU). Chƣơng 3. Bộ vi xử lý 8088 7 6 1 3.1. Cấu trúc bộ vi xử lý 8088 1 3.2. Tập các thanh ghi 1 3.3. Ghép nối vào ra 1 3.4. Ngắt 1 3.5. Mã hóa lệnh 2 Nội dung tự học (10t): - Tự nghiên cứu bài giảng, tài liệu khác về các vấn đề : • Cơ chế, nguyên lý của chu kỳ lệnh trong bộ vi xử lý 8088. • Cấu tạo, các thức tổ chức quản lý địa chỉ bộ nhớ. Cơ chế xử lý địa chỉ vật lý và địa chỉ logic. • Các loại, số hiệu ngắt được sử dụng cho bộ vi xử lý 8088. -Làm 02 bài tập về giải mã lệnh. Chƣơng 4. Lập trình hợp ngữ 34 4 30 4.1. Tổng quan, cấu trúc hợp ngữ (Assembly) 0.5 4.2. Dữ liệu trong Assembly 0.5 4.3. Vào/ra trong Assembly 0.5 4.4. Nhóm lệnh dịch chuyển dữ liệu 0.5
  6. PHÂN PHỐI SỐ TIẾT TÊN CHƢƠNG MỤC TS LT BT TH HD KT 4.5. Nhóm lệnh tính toán số học 0.5 4.6. Nhóm lệnh chuyển điều khiển 0.5 4.7. Nhóm lệnh lặp 0.5 4.8. Nhóm lệnh dịch chuyển và quay 0.5 Nội dung tự học (8t): - Tự nghiên cứu bài giảng, tài liệu khác về các vấn đề : • Cấu trúc, cách thức hoạt động của chương trình hệ thống. • Các bài toán lập trình bằng ngôn ngữ Assembly (theo chủ đề giảng viên đề ra). • Cơ chế lập trình hệ thống với Assembly. -Đọc và tìm hiểu Chương 5: tổ chức vào ra dữ liệu. Chƣơng 5. Tổ chức vào/ra dữ liệu 13 11 1 5.1. Các chân tín hiệu của 8088 và các mạch phụ trợ 4 5.2. Phối ghép 8088 với bộ nhớ 2 5.3. Phối ghép 8088 với thiết bị ngoại vi 3 5.4. Một số phối ghép cơ bản 2 Nội dung tự học (22t): - Tự nghiên cứu bài giảng, tài liệu khác về các vấn đề : • Mạch điều khiển bus 8288, mạch điều khiển ngắt 8259, mạch DMAC 8237A. • Lập trình điểu khiển vào ra với 8255A -Làm 04 bài tập. - Download trên Internet các sơ đồ mạch phối phép giữa vi xử lý với các thiết bị (mỗi loại 2 sơ đồ), phân tích và tìm hiểu cơ chế hoạt động của các mạch đó. i. Mô tả cách đánh giá học phần: - Thời gian học tập trên lớp phải ≥75% số tiết quy định của học phần. - Thực hiện 02 bài kiểm tra trên lớp: X1=(KT1+KT2)/2 với điều kiện dự thi X≥4, và điểm đánh giá thực hành do giảng viên chấm: X = (X1+TH)/2. - Hình thức đánh giá học phần : Thi viết, rọc phách. - Điểm đánh giá học phần: Z = 0,3X + 0,7Y (với Y là điểm thi kết thúc học phần). - Thang điểm: Thang điểm chữ A+, A, B+, B, C+, C, D+, D, F. k. Giáo trình: 1. Văn Thế Minh, Kỹ thuật vi xử lý, NXB Giáo dục 1997. l. Tài liệu tham khảo: 1. Đỗ Xuân Thụ & Hồ Khánh Lâm, Kỹ thuật Vi xử lý và máy vi tính, NXB Giáo dục 2000.
  7. 2. Nguyễn Tăng Cường & Phan Quốc Thắng, Cấu trúc và lập trình họ vi điều khiển 8051, NXB Khoa học Kỹ thuật, 2004. 3. Charles M.Gilmore McGraw, Microprocessors Principles and Application, Hill International Edition 1995. Ngày phê duyệt: / / 2014 Bộ phận biên soạn Trƣởng Bộ môn Trƣởng đơn vị (Ký, ghi rõ họ tên) (Ký, ghi rõ họ tên) (Ký, ghi rõ họ tên)
  8. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Chƣơng 1 : TỔNG QUAN 1.2. Tổng quan về Bộ và Hệ vi xử lý 1.2. Bộ vi xử lý Trong các thế hệ máy tính số, khối xử lý trung tâm CPU (Central processing unit) thực hiện các chức năng chính quyết định tên gọi của máy tính : đó là thực hiện các phép xử lý dữ liệu như các phép tính số học, logic các trao đổi dữ liệu bộ nhớ, với các ngoại vi Khối CPU là tập hợp các logic điều khiển và các thanh ghi gồm nhiều vi mạch với mực độ tích hợp khác nhau. Cũng giống như CPU, bộ vi xử lý có các mạch số thực hiện xử lý và tính toán dữ liệu dưới sự điều khiển của chương trình. Nhưng điều khác cơ bản đối với CPU bình thường ở chỗ là toàn bộ các mạch số của bộ vi xử lý được tích hợp trong một chip vi mạch tích hợp mật độ cao LSI hoặc VLSI, điều này làm tăng tốc độ xử lý lên rất nhiều vì sự trễ tín hiệu do liên kết giữa các mạch số không đáng kể nữa. Cũng như CPU của các máy tính số, chức năng chính của bộ vi xử lý là xử lý dữ liệu, bao gồm tính toán (computing) và thao tác với dữ liệu (handling). Quá trình tính toán được tập hợp các vi mạch logic, thường gọi là ALU(đơn vị số học và logic) thực hiện. Đó là các lệnh số học căn bản như : ADD, SUB, MUL, DIV, các phép Logic, các phép so sánh Để xử lý dữ liệu, bộ vi xử lý cần phải có đơn vị logic điều khiển CU để chỉ bảo bộ vi xử lý phải giải mã và thực hiện lệnh theo chương trình như thế nào. Chương trình là tập hợp các lệnh máy (instruction set) mà bộ vi xử lý có thể thực hiện được. Chương trình được lưu trong bộ nhớ chính của máy tính nằm bên ngoài chip vi xử lý. Điều này có nghĩa là phải đọc các lệnh (instruction fetch) của chương trình vào bộ vi xử lý để thực hiện. Lệch đọc vào bộ vi xử lý được giải mã (decode) để tạo ra những chuỗi những tín hiệu điều khiển từ CU theo thời gian để thực hiện các phép xử lý dữ liệu do lệnh yêu cầu. Như vậy, xử lý dữ liệu của bộ vi xử lý đòi hỏi 3 bước :  Bước thứ nhất : đọc lệnh (instruction fetch).  Bước thứ hai : CU giải mã lệnh (instruction decode).  Bước thứ ba : ALU thực hiện lệnh Toàn bộ các bước này hoàn thành một chu kỳ đọc và thực hiện lệnh (Fetch and execute cycle). Đơn vị CU của bộ vi xử lý còn phải thực hiện điều khiển giao tiếp với ccs hệ thống bên ngoài của bộ vi xử lý : bộ nhớ, các thiết bị vào ra. Sự trao đổi dữ liệu giữa bộ vi xử lý và các thiết bị bên ngoài cũng cần phải có các mạch Input/Output (I/O circuit). Trong bộ vi xử lý, các đơn vị liên kết dữ liệu với nhau thông qua bus bên trong (internal bus), và sự liên kết với thế giới bên ngoài thực hiện bằng các bus bên ngoài (system bus). 1.3. Hệ vi xử lý Hệ vi xử lý và bộ vi xử lý là hai khái niệm khác nhau. Bộ vi xử lý là một hay vài vi mạch tổ hợp lớn với chức năng chủ yếu là xử lý dữ liệu và điều khiển. Hệ vi xử lý là một hệ thống tính toán với đơn vị xử lý trung tâm là bộ vi xử lý và các đơn vị ngoài kết nối với nó. Phạm Trung Minh – Khoa CNTT 1
  9. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Data BUS Control BUS CPU Memory I/O Address BUS Thanh ghi trong Thanh ghi ngoài Một hệ thống máy tính bao gồm các thành phần như hình vẽ trên (theo nguyên lý Von Newman cổ điển). Các thành phần trên không thể đứng rời rạc với nhau, cần có sự liên kết giữa các thành phần để tạo thành 1 khối thống nhất hoàn chỉnh. Hệ vi xử lý thực tế chính là một hệ thống máy tính được xét theo góc độ kỹ thuật ghép nối các thành phần lại với nhau để đạt được sự đồng bộ, ổn định và công suất cao. Trong 1 hệ vi xử lý, bộ vi xử lý đóng vai trò quan trọng nhất, các thành phần còn lại phải có khả năng hoạt động tương thích với bộ vi xử lý. Vì vậy tên của hệ vi xử lý thường được lấy theo tên của dòng vi xử lý. Các thành phần khác trong hệ vi xử lý (Ram, Rom, HDD, MainBoard ) đều phải các thành phần có thể hoạt động ổn định có hiệu suất cao khi được phối ghép vào cùng 1 hệ thống với bộ vi xử lý. 1.2. Những đặc điểm cấu trúc của bộ vi xử lý 1.2.1. Công suất của bộ vi xử lý Công suất của bộ vi xử lý là khả năng xử lý dữ liệu, nó gồm có những đặc điểm sau đây : độ dài từ của bộ vi xử lý (data word length), tính bằng số byte; dung lượng nhớ vật lý có thể đánh địa chỉ (addressing capacity); tốc độ xử lý lệnh của bộ vi xử lý (instruction exectue speed). Công suất của hệ vi xử lý, hay nói cách khác, tốc độ xử lý thông tin, khả năng lưu trữ thông tin, khả năng kết nối nhiều loại thiết bị ngoại vi . . . phụ thuộc vào công suất của bộ vi xử lý.  Độ dài từ o VXL chỉ có thể xử lý dữ liệu với độ dài từ cố định, phụ thuộc và từng thế hệ vi xử lý và mức độ phát triển của công nghệ vi xử lý. o Tùy theo công nghệ, thế hệ VXL : 4 ,8,16,32,64 bit o Quyết định độ dài của các thanh ghi, ALU, bus dữ liệu bên trong o Độ dài từ càng lớn càng tạo ra nhiều khả năng tính toán của bộ vi xử lý : khoảng biểu diễn số rộng hơn, tốc độ tính toán nhanh hơn  Khả năng đánh địa chỉ Các từ dữ liệu và lệnh máy cất trong bộ nhớ tại các ngăn nhớ khác nhau. Mỗi ngăn nhớ phải có địa chỉ nhận biết. o Dải đánh địa chỉ càng lớn thì dung lượng nhớ càng nhiều. Phạm Trung Minh – Khoa CNTT 2
  10. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam o Để đánh địa chỉ, bộ vi xử lý có thanh ghi địa chỉ (address register). o Độ rộng của thanh ghi địa chỉ quyết định giải địa chỉ của vùng nhớ vật lý mà bộ vi xử lý thỏa mãn. o Khả năng đánh địa chỉ càng lớn thì càng cho phép tạo ra một hệ thống máy tính có cấu hình mạnh với nhiều loại thiết bị ngoại vi, bộ nhớ chính có dung lượng lớn và khả năng xử lý nhanh.  Tốc độ thực hiện lệnh Tốc độ thực thực hiện lệnh của bộ vi xử lý có thể đo bằng tốc thực hiện các lện dấu phẩy động FLOPS (Floating Point Operations per Second) hoặc ính bằng triệu lệnh/giây (MIPS – Millions of instructions per second). f * N MIPS M T o f : tần số làm việc của bộ VXL o N : Số lượng các đơn vị xử lý số học và logic (ALU) không phụ thuộc vào nhau bên trong bộ vi xử lý. o M : Số lượng vi lệnh ( microinstruction) trung bình của 1 lệnh trong bộ vi xử lý (thường cần từ 4-7 vi lệnh ). o T : Hệ số thời gian truy nhập bộ nhớ (chu trình chờ đợi trong khi truy nhập bộ nhớ). 1.2.2. Những đặc tính nâng cao tốc độ của bộ vi xử lý  Xử lý song song (parallel processing) Xử lý song song có nghĩa là hai hay nhiều quá trình tính toán cùng xảy ra đồng thời. Trong kiến trúc máy tính, sự kết hợp 2 bộ vi xử lý trong khối xử lý trung tâm (CPU) tạo ra khả năng xử lý song song trong cùng một không gian. Bộ xử lý 1 Dữ liệu vào Dữ liệu ra Bộ xử lý 2 Kiểu kiến trúc này có thể tạo ra tốc độ xử lý dữ liệu lên gấp đôi so với kiến trúc chỉ dùng mộ bộ vi xử lý. Cũng có thể thực hiện xử lý song song ngay bên trong cấu trúc của bộ vi xử lý, bằng cách thiết kế saocho quá trình xử lý dữ liệu bên trong chip vi xử lý chia thành các phiên khác nhau và thực hiện song song nhờ sự phân chia khối logic điều khiển (CU) bên trong thành 2 phần riêng. Kiến trúc của bộ vi xử lý có các khôi chức năng xử lý song song bên trong gọi là kiến trúc siêu hướng ( superscalar architechture), nghĩa là cùng một lúc có nhiều hướng xử lý khác nhau bên trong bộ vi xử lý. Kiến trúc siêu hướng không những nâng cao tốc độ xử lý mà còn nâng cao độ tin cậy của CPU, bởi vì khi có sự cố ở 1 chip vi xử lý (hay một đơn vị xử lý bên trong một chip) thì chip còn lại (hay đơn vị xử lý còn lại bên trong một chip) vẫn đảm nhiệm chức năng được bình thường.  Đồng xử lý (coprocessing) Phạm Trung Minh – Khoa CNTT 3
  11. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Bộ xử Bộ Bộ Các lý đồng nhớ cổng 8038 xử lý vào/ra 6 80387 chín h Bus hệ thống Bộ đồng xử lý là một bộ vi xử lý riêng biệt kết nối với bộ vi xử lý chính thông qua bus hệ thống. Ví dụ như trong họ vi xử lý Intel 80XXX, có bộ đồng vi xử lý 80387 làm việc với 80386 hoặc 80486. Bộ đồng xử lý chỉ thực hiện một số chức năng đặc biệt, ví dụ như các phép toán đòi hỏi sự chính xác sử dụng dấu phẩy động. Tốc độ của bộ đồng xử lý những phép tính này sẽ nhanh hơn rất nhiều so với bộ vi xử lý chính.  Bộ nhớ lưu trữ ( cache memory) Theo công thức MIPS, tốc độ của bộ vi xử lý sẽ tăng đáng kể nếu tổng M + T tiến tới 1. Thời gian truy nhập bộ nhớ T có thể giảm tối thiểu nhờ giảm tối thiểu số lượng lệnh đặt trong bộ vi xử lý và từng giai đoạn trong khi thực hiện lệnh và truy nhập bộ nhớ ngoài chồng lên nhau về thời gian. Bộ Bộ nhớ Bộ Bộ xử lý nhớ Các cổng dự trữ nhớ 80386 vào/ra trong dự trữ chính ngoài Bus hệ thống Một biện pháp giảm T nữa là áp dụng kỹ thuật bộ nhớ dự trữ. Bộ nhớ cache là bộ nhớ có tốc độ cao, nó có thể nằm ngay bên trong bộ vi xử lý với dung lượng hạn chế (internal cache), hoặc nằm kề ngay bên cạnh bộ vi xử lý và kết nối trực tiếp với chip vi xử lý với dung lượng đủ lớn (external cache). Trong khi đó bộ nhớ chính ( main memory ) kết nối với bộ vi xử lý qua bus hệ thống. Sự trao đổi dữ liệu giữa bộ nhớ chính và bộ vi xử lý bị hạn chế về tốc độ, vì vậy để tăng tốc độ xử lý, phải tổ chức làm sao khi thực hiện chương trình, bộ vi xử lý trước hết tìm kiếm lệnh ở bộ nhớ dự trữ trước, nếu không có lệnh chứa trong bộ nhớ dự trữ thì mới phải tìm đến bộ nhớ chính. Điều này có nghĩa là nếu đa số lệnh khong có trong bộ nhớ dự trữ thì tốc độ xử lý chậm hơn gần gấp đôi so với vơi truy nhập thẳng vào bộ nhớ chính. Vì vậy phải tổ chức làm sao đa số các lệnh của chương trình nằm trong bộ nhớ dự trữ.  Kỹ thuật đường ống ( pipelining technique) Mô phỏng dây chuyền lắp ráp máy móc, hệ thống đường ống dẫn, trong các bộ vi xử lý hiện nay có chức năng thực hiện các lệnh máy liên tục thành một dây chuyền với 5 công đoạn : nhạp dữ liệu của lệnh từ bộ nhớ, giải mã lệnh, thực hiện các lệnh, ghi kết quả thực hiện lệnh vào bộ nhớ. Khi lệnh thứ nhất bắt đầu thực hiện ở giai đoạn hai thì mã lệnh của lệnh kế tiếp Phạm Trung Minh – Khoa CNTT 4
  12. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam theo được đọc từ bộ nhớ ra để thực hiện bước một ( giải mã lệnh ). Cứ như vậy các lệnh được thực hiện theo một dây chuyền liên tục như là dòng nước đi trong đường ống. Tốc độ xử lý lệnh vì thế được tăng lên rất cao. 1.3. Tập lệnh của bộ vi xử lý Tập lệnh là một đặc tín then chốt của kiến trúc bộ vi xử lý. Các bộ vi xử lý hoạt động theo sự chỉ dẫn của tập lệnh riêng của chúng. Người lập trình hay nhà thiết kế hệ thống dựa vào tập lệnh để soạn thảo các chương trình điều khiển hoạt động của bộ vi xử lý theo một trình tự nào đó. Một bộ vi xử lý của một tập lệnh riêng và thường có tính kế thừa, tức là tập lệnh của những bộ vi xử lý ra đời sau thường bao hàm các lệnh của các bộ vi xử lý cùng họ đã được sản xuất trước đó. Tập lệnh thường được chia thành 8 hoặc 9 nhóm khác nhau, và được biểu diễn ở dạng mã ngữ ( Memonic code) gợi nhớ của tiếng Anh đời thường : - Các lệnh chuyển dữ liệu. - Các lệnh số học với các nguyên và các lệnh logic. - Các lệnh dịch và quay vòng. - Các lệnh chuyển điều khiển. - Các lệnh xử lý bit. - Các lệnh điều khiển hệ thống. - Các lệnh với dấu phảy động. - Các lệnh của các khối chức năng đặc biệt. Sự phân chia này phù hợp với các bộ vi xử lý công nghệ cao hiện nay, vì cấu trúc bên trong của chúng tập trung các khối chức năng đặc biệt Phạm Trung Minh – Khoa CNTT 5
  13. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Chƣơng 2 : CẤU TRÚC CÁC BỘ VI XỬ LÝ 2.1. Sơ đồ khối cấu trúc bộ VXL cấp thấp (8bit) Sơ đồ khối cấu trúc và mô hình lập trình của bộ vi xử lý là tổ chức các thanh ghi mà người sử dụng có thể lập trình và truy nhập tới được bên trong bộ vi xử lý. Cấu trúc cơ bản của bộ vi xử lý cấp thấp có 3 thành phần chính : - Đơn vị logic – số học ALU ( Arithmetic logic unit). - Khối các thanh ghi - Registers. - Khối logic điều khiển - CU. Bus Đường đ/khiển vào ra bên ngoài đ/chỉ 16bit Th/ghi địa chỉ bộ nhớ Reg A Th/ghi trạng thái Reg B Reg C SP Reg D Reg E PC Reg H Reg L Khối Bus dữ liệu trong 8 bit logic điều Bus dữ liệu khiển 8bit Th/ghi lệnh Temp1 Temp2 In In Giải mã lệnh ALU Out 2.1.1. Đơn vị số học – logic ALU Đơn vị ALU là một trong những thành phần chính bên trong bộ vi xử lý. ALU chứa khối loggic thực hiện xử lý dữ liệu. ALU có 2 cổng vào và một cổng ra. Cổng vào để nhận dữ liệu vào ALU, cổng ra để lấy kết quả xử lý dữ liệu của ALU ra bên ngoài. Các thanh ghi Temp1 và Temp2 làm nhiệm vụ nhận dữ liệu từ các nơi khác nhau bên trong bộ vi xử lý và lưu trữ trung gian dữ liệu trong quá trình xử lý dữ liệu trong ALU. Tương tự cổng ra kết nối với bus dữ liệu bên trong, do đó kết quả phép toán có thể đưa tới các nơi khác nhau. Các lệnh máy được ALU xử lý có thể là một hay hai toán hạng. Lệnh máy được đọc từ bộ nhớ vào bộ vi xử lý, được giải mã nhờ bộ giải mã lệnh để tạo ra chuỗi các tín hiệu đi tới ALU điều khiển quá trình xử lý dữ liệu trong ALU. 2.1.2. Các thanh ghi (Registers) Các thanh ghi bên trong bộ vi xử lý được chia thành cá nhóm theo mục đích sử dụng : Phạm Trung Minh – Khoa CNTT 6
  14. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam - Nhóm thanh ghi dùng chung : thanh ghi A (bộ cộng), B, C, D, E, H và L. Đây là các thanh ghi 8 bit. Để xử lý 16 bit, có các lệnh thực hiện với các cặp thanh ghi BC, DE và HL - Các thanh ghi khác : thanh ghi trạng thái (SR), con trỏ ngăn xếp (SP), thanh ghi đếm lệnh (PC), thanh ghi địa chỉ ngăn nhớ, thanh ghi tạm thời Temp1, Temp2, thanh ghi lệnh  Thanh ghi tổng A (Accumulator) Thanh ghi này tham gia vào phần lớn các phép tính, độ dài bằng độ dài từ của bộ vi xử lý. Ở một số loại vi xử lý có thể có thanh tổng có độ dài gấp đôi độ dài từ xử lý của bộ vi xử lý hay còn gọi là thanh tổng độ dài kép.  Thanh ghi đếm chương trình PC (Program counter) Chứa địa chỉ của lệnh trong bộ nhớ và chỉ ra cho bộ VXL biết lệnh tiếp theo nằm ở ngăn nhớ nào để lấy ra thực hiện. Như vậy độ dài của PC chính là khả năng đánh địa chỉ bộ nhớ chính có thể đạt được của bộ vi xử lý. PC luôn được nạp địa chỉ lệnh (địa chỉ ngăn nhớ chứa lệnh máy) tiếp theo trong quá trình thực hiện bất kỳ một chương trình nào. Trong các bộ vi xử lý công nghệ cao có cơ chế quản lý bộ nhớ ảo ( Virtual Memory) bao gồm bộ nhớ chính và bộ nhớ ngoài, cơ chế dânh địa chỉ ảo có sự biến đổi địa chỉ ảo thành địa chỉ vật lý.  Thanh ghi trạng thái SR (Status register) Lưu kết quả của các lệnh kiểm tra, so sánh và một số lệnh tính toán với các thanh ghi. Đôi khi thanh ghi trạng thái còn được gọi là thanh ghi cờ ( Flag Register). Sử dụng các bit của thanh ghi trạng thái (bit cờ) có thể thực hiện rẽ nhánh chương trình bằng các lệnh nhảy và rẽ nhánh có điều kiện. Mỗi bit của thanh ghi trạng thái có một ý nghĩa và bị tác động tùy theo lệnh.  Con trỏ ngăn xếp SP (Stack pointer) Ngăn xếp có thể là một vùng nào đó của bộ nhớ chính, hay là một mảng thanh ghi riêng biệt. Thanh ghi SP chứa địa chỉ của đỉnh ngăn xếp và nội dung của SP sẽ thay đổi mỗi khi thực hiện các lệnh – luôn trỏ tới vùng nhớ tiếp theo. Khi khởi động hệ thống máy tính, con trỏ ngăn xếp luôn được khởi tạo về địa chỉ đỉnh của ngăn xếp.  Thanh ghi địa chỉ bộ nhớ và logic Các đầu ra của thanh ghi này được điều khiển nối ra bus địa chỉ của hệ thống máy tính để thực hiện việc chọn ngăn nhớ, hoặc để chọn cổng ngoại vi nào đó. Trong chu kỳ đọc lệnh, một lệnh máy được đọc từ bộ nhớ, nội dung của thanh ghi địa chỉ ngăn nhớ và nội dung của thanh đếm lệnh PC lúc này là như nhau. Nghĩa là thanh ghi địa chỉ bộ nhớ trỏ tới từ lệnh đang được đọc từ bộ nhớ. Thanh ghi địa chỉ bộ nhớ không thể tự động tưng hay giảm nội dung mà nó nhận địa chỉ lệnh từ PC, SP và các thanh ghi chỉ số.  Thanh ghi lệnh IR ( Instruction register) IR chứa lệnh đang thực hiện. Trong chu kỳ đọc mã lệnh (instruction cycle) từ bộ nhớ, mã lệnh được nạp vào IR thông qua bus dữ liệu nội bộ. IR như là bộ đệm duy trì nội dung mẽ lệnh và đầu ra của IR đưa tới bộ giải mã lệnh để tạo ra chuỗi các tín hiệu điều khiển thực hiện lệnh. Độ dài của IR tùy thuộc vào từng bộ vi xử lý.  Các thanh ghi dữ liệu tạm thời Temp (temporaty data registers) Do ALU không có bộ đệm, do đó khi tính toán các dữ liệu phải được lấy từ hoặc đưa trở lại bus dữ liệu bên trong theo thời điểm nhịp nào đó. Những việc này phải được thực hiện thông qua các thanh ghi tạm thời. Ngoài ra, trong quá trình xử lý cần sự ổn định dữ liệu ở đầu vào ALU, do đó cần thanh ghi đệm tạm thời để lưu trữ dữ liệu trong thời gian ngắn đủ để cho ALU thực hiện xong phép tính. 2.1.3. Khối logic điều khiển CL ( Control Logic) Khối CL liên hệ thông tin với tất cả các đơn vị trong bộ vi xử lý, bởi vì nó điều khiển toàn bộ hoạt động xử lý thông tin bên trong bộ vi xử lý. Kết quả giải mã lệnh được đưa đến khối logic Phạm Trung Minh – Khoa CNTT 7
  15. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam điều khiển tạo ra các chuỗi tín hiệu để điều khiển quá trình ghi, đọc với các thanh ghi bên trong, tính toán trong ALU. Từ CL, các xung tín hiệu điều khiển đi ra bus điều khiển của hệ thống tác động đến bộ nhớ, các đơn vị I/O để thực hiện trao đổi dữ liệu. Cũng có thể CL nhận các tín hiệu điều khiển từ bên ngoài thông qua bus điều khiển của hệ thống để tiếp tục điều khiển quá trình xử lý bên trong bộ vi xử lý. Thông thường CL là một khối được vi chương trình hóa (Microprogrammed logic unit), tức là kiến trúc của CL giống như kiển trúc của vi xử lý nhỏ. Một tín hiệu quan trọng quyết định trình tự sản sinh các chuỗi tín hiệu của CL là nhịp đồng hồ của bộ vi xử lý. Nhịp đồng hồ tác động đến CL, và CL từ đây tạo ra các xung tín hiệu điều khiển có các chu kỳ khác nhau. CL quyết định thứ tự làm việc của từng đơn vị trong bộ vi xử lý và sự trao đổi thông tin với thế giới bên ngoài chip vi xử lý. CL là trung tâm điều khiển của bộ vi xử lý. 2.2. Sơ đồ khối cấu trúc bộ VXL công nghệ cao Các bộ vi xử lý công nghệ cao gọi chung cho các bộ vi xử lý được sản xuất từ giữa những năm 1990 của nhiều hãng chế tạo hàng đầu thế giới như Intel, Motorola, Sun, IBM, AMD . . . Nó chứa đựng các đặc điểm của đa số các loại vi xử lý hiện nay. Đơn vị tiền đọc lệnh và hàng lệnh Đơn vị giải mã S 32k (Prefetch Unit and Instruction Queue) (Decoding Unit) Data Bus Đơn vị y PUIQ DU S giao tiếp Bus và T 32+j Data Cache chốt BIU E Add Bus (Dcache) (Bus Branch Target Control Đơn vị điều khiển M B Interface cache Unit (Control Unit) unit) Instruction (BTC) U Control CU S Cache Bus (Icache) Memory Management Unit (MMU) Internal Bus 32n Interger Unit (IU) Floating Point Unit (FPU) Special Interger Floating Point Function Register File Register File Units (IRF) (FRF) SFU Interger Floating Point Operation Operation Units Units (IOU) (FPOU) Phạm Trung Minh – Khoa CNTT 8
  16. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Chƣơng 3: BỘ VI XỬ LÝ INTEL 8088 Sau khi đã tìm hiểu qua về cấu trúc của hệ vi xử lý. Trong chương này ta sẽ đi sâu tìm hiểu mọt bộvi xử lý cụ thể và rất điển hình: bộ vi xử lý của Intel. Trước hết cần nói rỏ lý do tại sao ở đây ta lại chọn đích danh bộ vi xử lý 8088 để tìm hiểu mà không phải là bộ vi xử lý nào khác ( điều mà nhiều người khác phải làm ). Thứ nhất, đây là bộ vi xử lý nổi tiếng một thời thuộc họ 80x86 của Intel, nó được sử dụng trong nhiều lĩnh vực khác nhau, nhất là trong các máy IBM PC /XT. Các bộ vi xử lý thuộc họ này sẽ còn được sử dụng rộng rãi trong hàng chục năm nữa, và vi tính kế thừa của các sản phẩm trong họ 80x86, các chương trình viết cho 8088 vẫn có thể chạy trên các hệ thống tiên tiến sau này. Thứ hai, về góc độ sư phạm thì đây là bộ vi xử lý khá đơn giản và vì việc dạy hiểu nó là tương đối dể đối với những người mới bắt đầu thâm nhập vào lĩnh vực này. Thứ ba, các họ vi xử lý tuy có khác nhau nhưng xét cho cùng cũng có khá nhiều điểm chủ yếu rất giống nhau. Do đó một khi đã nắm được các vấn đề kỷ thuật của8088, ta sẽ có cơ sở để nắm bắt các kỹ thuật của các bộ vi xử lý khác cùng trong họ Intel 80x86 hoặc của các họ khác. 3.1. Cấu trúc bên của bộ vi xử lý 8088. Trước khi giới thiệu tập lệnh và cách thức lập trình cho bộvi xử lý8088 hoạt động ta cần phải tìm hiểu kỹ cấu trúc bên trong của nó.                            BIU Và EU Theo sơ đồ khối, ta thấy bên trong CPU 8088 có 2 khối chính: khối phối ghép ( bus interface unit, BIU ) vàkhối thực hiện lệnh ( execution unit, EU ). Việc chia CPU ra thành 2 phần làm việc đồng thời có liên hệ với nhau qua đệm lệnh làm tăng đáng kể tốc độ xử lý của CPU. Các bus bên trong CPU có nhiệm vụ chuyển tải tín hiệu của các khối khác. Trong số các bus đó có bus dữ liệu 16 bit của ALU, bus các tín hiệu điều khiển ở EU và bus trong của hệ Phạm Trung Minh – Khoa CNTT 9
  17. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam thống ở BIU. Trước khi đi ra bus ngoài hoặc đivào bus trong của bộ vi xử lý, các tín hiệu truyền trên bus thường được cho đi qua các bộ đệm để nâng cao tính tương thích cho nối ghép hoặc nâng cao phối ghép. BIU đưa ra địa chỉ, đọc mã lệnh từ bộ nhớ, đọc / ghi dữ liệu từ vào cổng hoặc bộ nhớ. Nói cách khác BIU chịu trách nhiệm đưa địa chỉ ra bus và trao đổi dữ liệu với bus. Trong EU ta thấy có một khối điều khiển ( control unit, CU ). Chính tại bên trong khối điều khiển này có mạch giải mã lệnh. Mã lệnh đọc vào từ bộ nhớ được đưa đến đầu vào của bộ giải mã, các thông tin thu được từ đầu ra của nó sẽ được đưa đến mạch tạo xung điều khiển, kết quả là tu thu được các dãy xung khác nhau ( tuỳ theo mã lệnh ) để điều khiển hoạt động của các bộ phận bên trong và bên ngoài CPU. Trong khối EU còn có khối số học và lôgic ( arithmetic anh logic unit. ALU ) dùng để thực hiện các thao tác khác nhau với các toán hạng của lệnh. Tóm lại, khi CPU hoạt động EU sẽ cung cấp thông tin về địa chỉ cho BIU để khối này đọc lệnh và dữ liệu, còn bản thân nó thì đọc lệnh và giải mã lệnh. Trong BIU còn có một bộ nhớ đệm lệnh với dung lượng 4 byte dùng để chứa các mã lệnh đọc được nằm sẵn để chờ EU xử lý ( trong tài liệu của Intel bộ đệm lệnh này còn được gọi là hàng đợi lệnh ). Đây là một cấu trúc mới được cấy vào bộ vi xử lý 8086x88 do việc Intel đưa cơ chế xử lý xen kẻ liên tục, dòng mã lệnh ( instruction pipelining ) vào ứng dụng trong các bộ vi xử lý thế hệ mới. Pipeline là một cơ chế đã được ứng dụng từ những năm 60 từ các máy lớn. Nhân đây ta sẽ giới thiệu sơ qua một chút về cơ chế này. Trong các bộ vi xử lý ở các thế hệ trước ( như ở 8085 chẳng hạn ), thông thường hoạt động của CPU gồm 3 giai đoạn: đọc mã lệnh ( opcode fetch ), giải mã lệnh ( decode ) và thực hiện lệnh ( execution ). Trong một thời điểm nhất định, CPU thế hệ này chỉ có thể thực hiện một trong ba công việc nói trên và vì vậy tuỳ theo từng giai đoạn sẽ có những bộ phận nhất định của CPU ở trạng thái nhàn rỗi. Chẳng hạn, khi CPU giải mã lệnh hoặc khi nó đang thực hiện những lệnh không liên quan đến bus ( thao tác nội bộ ) thì các bus không được dùng vào việc gì dẫn đến tình trạng lãng phí khả năng của chúng . Trong khi đó từ bộ vi xử lý 8086/88, Intel sử dụng cơ chế xử lý xen kẽ liên tục dòng mã lệnh thì CPU được chia thành 2 khối và có sự phân chia công việc cho từng khối: việc đọc mã lệnh là do khối BIU thực hiện, việc giải mã lệnh và thực hiện lệnh là do khối EU đảm nhiệm. Các khối chức năng này có khả năng làm việc đồng thời và các bus sẽ liên tục sử dụng: trong khi EU lấy mã lệnh từ bộ đệm 4 byte để giải mã hoặc thực hiện các thao tác nội bộ thì BIU vẫn có thể đọc mã lệnh từ bộ nhớ chính rồi đặt chúng vào bộ nhớ đệm lệnh đã nói. Bộ đệm lệnh này làm việc theo kiểu “ vào trước – ra trước “ (first in-first out, FIFO ), nghĩa là byte nào được cất vào đệm trước sẽ được lấy ra xử lý trước. Nếu có sự vào/ra liên tục của dòng mã lệnh trong bộ đệm này thì có nghĩa là có sự phối hợp hoạt động hiệu quả giữa hai khối EU và BIU theo cơ chế xử lý xen kẽ liên tục dòng mã lệnh để làm tăng tốc độ xử lý tổng thể. Kỹ thuật xử lý xen kẽ liên tục dòng mã lệnh sẽ không còn tác dụng tăng tốc độ xử lý chung của CPU nữa nếu như trong đệm lệnh có chứa các mã lệnh của các lệnh CALL ( gọi chương trình con ) hoăc JMP ( nhảy ), bởi vì lúc các lệnh này nội dung của bộ đệm sẽ bị xoá và thay thế vào đó là nội dung mới được nạp bởi các mã lệnh mới do lệnh nhảy hoặc gọi quyết định. Việc này tiêu tốn nhiều thời gian hơn so với trường hợp trong đệm chỉ có mã lệnh của các lệnh tuần tự Không có pipelining F1 D1 E1 F2 D2 E2 F3 D3 E3 Có pipelining F1 D1 E1 F1 D1 E1 F1 D1 E1 (F : Đọc lệnh , D :Giải mả lệnh, E : Thực hiện lệnh) Dòng lệnh thường và dòng lệnh xen kẽ liên tục Phạm Trung Minh – Khoa CNTT 10
  18. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Trong bộ vi xử lý 8088 ta còn thắy c các thanh ghi 16 bit nằm trong cả hai khối BIU và EU, ngoài ra cũng có một số thanh ghi 8 hoặc 16 bit tại EU. Ta sẽ lần lượt giới thiệu các thanh ghi nói trên cùng chức năng chính của chúng. 3.2. Tập các thanh ghi.  Các thanh ghi đoạn Khối BIU đưa ra trên bus địa chỉ 20 bit địa chỉ, như vậy 8088 có khả năng phân biệt ra được 220 = 1.048.576 = 1M ô nhớ hay 1Mbyte, vì các bộ nhớ nói chung tổ chức theo byte. Nói cách khác: không gian địa chỉ của 8088 là 1Mbyte. Trong không gian 1Mbyte bộ nhớ cần được chia thành các vùng khác nhau ( điều này rất có lợi khi làm việc ở chế độ nhiều người sử dụng hoặc đa nhiệm ) dành riêng để: Chứa mã chương trình. Chứa dữ liệu và kết quả không gian của chương trình. Tạo ra một vùng nhớ đặc biệt gọi là ngăn xếp ( stack ) dùng vào việc quản lý các thông số của bộ vi xử lý khi gọi chương trình con hoặc trở về từ chương trình con. Trong thực tế bộ vi xử lý 8088 có các thanh ghi 16 bit liên quan đến địa chỉ đầu của các vùng ( các đoạn ) kể trên và chúng được gọi là các thanh ghi đoạn ( Segment Registers ). Đó là thanh ghi đoạn mã CS ( Code-Segment ), thanh ghi đoạn dữ liệu DS ( Data segment ). Thanh ghi đoạn ngăn xếp SS ( Stack segment ) và thanh ghi đoạn dữ liệu phụ ES ( Extra segment ). Các thanh ghi đoạn 16 bit này chỉ ra địa chỉ đầu của bốn đoạn trong bộ nhớ, dung lượng lớn nhất của mỗi đoạn nhớ này là 64 Kbyte và tại một thời điểm nhất định bộ vi xử lý chỉ làm việc được với bốn đoạn nhớ 64 Kbyte này. Việc thay đổi giá trị của các thanh ghi đoạn làm cho các đoạn có thể dịch chuyển linh hoạt trong phạm vi không gian 1 Mbyte, vì vậy các đoạn này có thể nằm cách nhau khi thông tin cần lưu trong chúng đòi hỏi dung lượng đủ 64 Kbyte hoặc cũng có thể nằm trùm nhau do có những đoạn không cần dùng hết đoạn dài 64 Kbyte và vì vậy những đoạn khác có thể bắt đầu nối tiếp ngay sau đó. Điều này cũng cho phép ta truy nhập vào bất kỳ đoạn nhớ ( 64 Kbyte ) nào nằm trong toàn bộ không gian 1 Kbyte. Nội dung các thanh ghi đoạn sẽ xác định địa chỉ của ô nhớ nằm ở đầu đoạn. Địa chỉ này còn gọi là địa chỉ cơ sở. Địa chỉ của các ô nhớ khác nằm trong đoạn tính được bằng cách cộng thêm vào địa chỉ cơ sở một giá trị gọi là địa chỉ lệch hay độ lệch ( Offset ), gọi như thế vì nó ứng với khoảng lệch của toạ độ một ô nhớ cụ thể nào đó so với ô đầu đoạn. Độ lệch này được xác định bởi các thanh ghi 16 bit khác đóng vai trò thanh ghi lệch ( Offset register ) mà ta sẽ nói đến sau. Cụ thể, để xác định địa chỉ vật lý 20 bit của một ô nhớ nào đó trong một đoạn bất kỳ. CPU 8088 phải dùng đến 2 thanh ghi 16 bit ( một thanh ghi để chứa địa chỉ cơ sở, còn thanh kia chứa độ lệch ) và từ nội dung của cặp thanh ghi đó tạo ra địa chỉ vật lý theo công thức sau: Địachỉvậtlý=Thanhghiđoanx16+Thanhghilệch Việc dùng 2 thanh ghi để ghi nhớ thông tin về địa chỉ thực chất để tạo ra một loại địa chỉ gọi là địa chỉ logic và được ký hiệu như sau: Thanhghiđoạn: Thanhghilệch hay segment: offset Địa chỉ kiểu segment: offset là logic vì nó tồn tại dưới dạng giá trị của các thanh ghi cụ thể bên trong CPU và ghi cần thiết truy cập ô nhớ nào đó thì nó phải được đổi ra địa chỉ vật lý để rồi được đưa lên bus địa chỉ. Việc chuyển đổi này do một bộ tạo địa chỉ thực hiện (phần tử  ). Ví dụ: cặp CS:IP sẽ chỉ ra địa chỉ của lệnh sắp thực hiện trong đoạn mã. Tại một thời điểm nào đó ta có CS = F00H và IP = FFFOH thì CS:IP~FOOOHx16 + FFFOH = FOOOOH + FFFOH = FFFFOH Phạm Trung Minh – Khoa CNTT 11
  19. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Địa chỉ FFFFOH chính là địa chỉ khởi động của 8088 dấu ~ ở đây là để chỉ sự tương ứng. Địa chỉ các ô nhớ thuộc các đoạn khác cũng có thể tính được theo cách tương tự như vậy. Từ nay khi cần nói đến đến địa chỉ của một ô nhớ ta có thể sử dụng cả địa chỉ logic lẫn địa chỉ vật lý vì bao giờ cũng tồn tại sự tương ứng giữa hai loại địa chỉ này ( thông qua bộ tạo địa chỉ  ). Trước khi nói đến các thanh ghi khác ta nói thêm chút ít về tính đa trị của các thanh ghi đoạn và thanh ghi lệch trong địa chỉ logic ứng với một địa chỉ vật lý. Điều này cũng nói lên tính linh hoạt của cơ chế segment offset trong việc định địa chỉ của 8086/ 88. Nhìn vào giá trị cuối cùng của địa chỉ vật lý ta thấy có thể tạo ra địa chỉ đó từ nhiều giá trị khác nhau của thanh ghi đoạn và thanh ghi lệch Ví dụ: Địa chỉ vật lý 12345H có thể được tạo ra từ các giá trị: Thanh ghi đoạn Thanh ghi lệch 1000H 2345H 1200H 0345H 1004H 2305H 0300H E345H  Các thanh ghi đa năng Trong khối EU có bốn thanh ghi đa năng 16 bit AX, BX, CX, DX. Điều đặc biệt là khi cần chứa các dữ liệu 8 bit thì mỗi thanh ghi có thể tách ra thành hai thanh ghi 8 bit cao và thấp để làm việc độc lập, đó là các tập thanh ghi AH và AL, BH và BL, CH và CL, DH và DL ( trong đó H chỉ phần cao, L chỉ phần thấp ). Mỗi thanh ghi có thể dùng một cách vạn năng để chứa các tập dữ liệu khác nhau nhưng cũng có công việc đặc biệt nhất định chỉ thao tác với một vài thanh ghi nào đó và chính vì vậy các thanh ghi thường được gan cho những cái tên đặc biệt rất có ý nghĩa. Cụ thể: o AX ( accumulator, acc ): thanh chứa. Các kết qủa của các thao tác thường được chứa ở đây ( kết quả của phép nhân, chia ). Nếu kết quả là 8 bit thì thanh ghi AL được coi là acc. o BX ( base ): thanh ghi cơ sở thường chứa địa chỉ cơ sở của một bảng dùng trong lệnh XLAT. o CX ( count ): bộ đếm. CX thường được dùng để chứa số lần lặp trong trường hợp các lệnh LOOP ( lặp ), còn CL thường cho ta số lần dịch hoặc quay trong các lệnh dịch hoặc quay thanh ghi. o DX ( data ): thanh ghi dữ liệu DX cùng BX tham gia các thao tác của phép nhân hoặc chia các số 16 bit. DX thường dùng để chứa địa chỉ của các cổng trong các lệnh vào/ ra dữ liệu trực tiếp.  Các thanh ghi con trỏ và chỉ số Trong 8088 còn có ba thanh ghi con trỏ và hai thanh ghi chỉ số 16 bit. Các thanh ghi này ( trừ IP ) đều có thể được dùng như các thanh ghi đa năng, nhưng ứng dụng chính của mỗi thanh ghi là chúng được ngầm định như là thanh ghi lệch cho các đoạn tương ứng. Cụ thể: o IP: con trỏ lệnh ( Instruction pointer ). IP luôn trỏ vào lệnh tiếp theo sẽ được thực hiện nằm trong đoạn mã CS. Địa chỉ đầy đủ của lệnh tiếp theo này ứng với CS:IP và được xác định theo cách đã nói ở trên. o BP: con trỏ cơ sở ( base pointer ). BP luôn trỏ vào một dữ liệu nằm trong đoạn ngăn xếp SS. Địa chỉ đầy đủ của một phần tử trong đoạn ngăn xếp ứng với SS:BP và được xác định theo cách đã nói ở trên. Phạm Trung Minh – Khoa CNTT 12
  20. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam o SP: con trỏ ngăn xếp ( stack pointer ). SP luôn trỏ vào đỉnh hiện thời của ngăn xếp nằm trong đoạn ngăn xếp SS. Địa chỉ đỉnh ngăn xếp ứng với SS:SP và được xác định theo cách đã nói ở trên. o SI: chỉ số gốc hay nguồn ( source index ). SI chỉ vào dữ liệu trong đoạn dữ liệu DS mà địa chỉ cụ thể đầy đủ ứng với DS:SI và được xác định theo cách đã nói ở trên. o DI: chỉ số đích ( destination index ). DI chỉ vào dữ liệu trong đoạn dữ liệu DS mà địa chỉ cụ thể đầy đủ ứng với DS:DI và được xác định theo cách đã nói ở trên. Riêng trong các lệnh thoa tác với dữ liệu kiểu chuổi thì cặp ES:DI luôn ứng với địa chỉ của phần tử thuộc chuỗi đích còn cặp DS:SI ứng với địa chỉ của phần tử thuộc chuỗi gốc.  Thanh ghi cờ FR ( flag register ) Đây là thanh ghi khá đặc biệt trong CPU, mỗi bit của nó được dùng để phản ánh một trạng thái nhất định của kết quả phép toán do ALU thực hiện hoặc một trạng thái hoạt động của EU. Dựa vào các cờ này người lập trình có thể có các lệnh thích hợp tiếp theo cho bộ vi xử lý ( các lệnh nhảy có điều kiện ). Thanh ghi cờ gồm 16 bit nhưng người ta chỉ dùng hết 9 bit của nó để làm các bit cờ . Các cờ của bộ vi xử lý 8086 x x x x O D I T S Z x A x P x C X : Không được định nghĩa Sơ đồ thanh ghi cờ của bộ vi xử lý 8086/88 Các cờ cụ thể o C hoặc CF ( carry flag ): cờ nhớ. CF = 1 khi có nhớ hoặc muợn từ MSSP. o P hoặc PF ( parity flag ): cờ parity. PF phản ánh tính chẵn lẻ ( parity ) của tổng số bit 1 có trong kết quả. Cờ PF =1 khi tổng số bit trong kết quả là chẵn ( even parity, parity chẵn ). Ở đây ta tạm dùng parity dạng nguyên gốc để tránh sự lủng củng khi phải dịch cụm từ “ even parity “ thành tính chẵn lẻ chẵn hoặc “ odd party “ thành tính chẵn lẻ lẻ. o A hoặc AF ( auxilialyry carry flag ): cờ nhớ phụ rất có ý nghĩa khi ta làm việc với các số BCD.AF = 1 khi có nhớ hoặc muợn từ một số BCD thấp ( 4 bit thấp ) sang một số BCD cao ( 4 bit cao ). o Z hoặc ZF ( zero flag ): cờ rỗng. ZF =1 khi kết quả = 0. o S hoặc SF ( sign flag ): cờ dấu. SF = 1 khi kết quả âm. o O hoặc OF ( over flow flag ): cò tràn. OF = 1 khi kết quả là một số bù 2 vượt qua ngoài giới hạn biểu diễn dành cho nó. Trên đây là 6 bit cờ trạng thái phản ánh các trạng thái khác nhau của kết sau một thao tác nào đó, trong đó 5 bit cờ đầu thuộc byte thấp của thanh cờ là các cờ giống như của bộ vi xử lý 8 bit 8085 của Intel. Chúng được lặp hoặc xoá tuỳ theo các điều kiện cụ thể sau các thao tác của ALU. Ngoài ra, bộ vi xử lý 8088 còn có các cờ điều khiển sau đây ( các cờ này được lập hoặc xoá bằng các lệnh riêng ): o T hoặc TF ( trap flag ): cờ bẫy. TF = 1 thì CPU làm việc ở chế độ chạy từng lệnh ( chế độ này dùng khi cần tìm lỗi trong một chương trình ). o I hoặc IF ( interrupt enable flag ): cờ cho phép ngắt. IF = 1 thì CPU cho phép các yêu cầu ngắt ( che được ) được tác động. o D hoặc DF ( direction flag ): cờ hướng. DF = 1 khi CPU làm việc với chuổi ký tự theo thứ tự từ phải sang trái ( vì vậy D chính là cờ lùi ) Ý nghĩa của các cờ đã khá rõ ràng. Riêng cờ tràn cần phải làm rõ hơn để ta hiểu được bản chất và cơ chế làm việc của nó. Cờ tràn thường được dùng đến khi ta làm việc với số bù 2 có dấu. Phạm Trung Minh – Khoa CNTT 13
  21. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam  Các chế độ địa chỉ bộ nhớ của bộ vi xử lý 8088 Chế độ địa chỉ (addressing mode ) là cách để CPU tìm thấy toán hạng cho các lệnh của nó khi hoạt động. Một bộ vi xử lý có thể có nhiều chế độ địa chỉ. Các chế độ địa chỉ này được xác định ngay từ khi chế tạo ra bộ bi xử lý và sau này không thể thay đổi được. Bộ vi xử lý 8088 và cả họ 80x86 nói chung đều có 7 chế độ địa chỉ sau: 1. Chế độ địa chỉ thanh gi ( register addressing mode ). 2. Chế độ địa chỉ tức thì ( immediate addressing mode ). 3. Chế độ địa chỉ trực tiếp ( direct addressing mode ). 4. Chế độ địa chỉ gián tiếp qua thanh ghi ( register indirect addressing mode ). 5. Chế độ địa chỉ tương đối cơ sở ( based indexed relative addressing mode ). 6. Chế độ địa chỉ tương đối chỉ số ( indexed relative addressing mode ). 7. Chế độ địa chỉ tương đối chỉ số cơ sở ( based indexed relative addressing mode ). Các chế độ địa chỉ này sẽ được giải thích thông qua các chế độ địa chỉcủa lệnh MOV và lệnh ADD.  Chế độ địa chỉ thanh ghi Trong chế độ địa chỉ này người ta dùng các thanh ghi bên trong CPU như là các toán hạng để chứa dữ liệu cần thao tác. Vì vậy khi thực hiện lệnh có thể đạt tốc độ truy nhập cao hon so với các lệnh có truy nhập đên bộ nhớ. Ví dụ: MOV BX, DX ; chuyển nội dung DX vào BX. MOV DS,AX ; chuyển nội dung AX vào DX ADD AL,DL ; cộng nội dung AL và DL rồi đưa vào  Chế độ địa chỉ tức thì Trong chế độ địa chỉ này toán hạng đích là một thanh ghi hay một ô nhớ, còn toán hạng nguồn là một hằng số và ta có thể tìm thấy toán hạng này ở ngay sau mã lệnh ( chính vì vậy chế độ địa chỉ này có tên là chế độ địa chỉ tức thì ). Ta có thể dùng chế độ địa chỉ này để nạp dữ liệu cần thao tác vào bất kỳ thanh ghi nào ( trừ các thanh ghi đoạn và thanh cờ ) hoặc vào bất kỳ ô nhớ nào trong đoạn dữ liệu DS. Ví dụ: MOV CL, 100 ; chuyển 100 vào CL. MOV AX, OFFOH ; chuyển OFFOH vào AX để rồi đưa MOV DS, AX ; vào DS ( vì không thể chuyển ; trực tiếp vào thanh ghi đoạn ) MOV ( BX ), 10 ; chỉ DS:BX. Trong ví dụ cuối ta đã dùng chế độ địa chỉ gián tiếp qua thanh ghi để chỉ ra ô nhớ ( toán hạng đích ) sẽ nhận dữ liệu ở chế độ địa chỉ tức thì ( toán hạng nguồn ). Tại đây ( BX ) có nghĩa là ô nhớ có địa chỉ DS:BX.  Chế độ địa chỉ trực tiếp Trong chế độ địa chỉ này một toán hạng chứa địa chỉ lệnh của ô nhớ dùng chứa dữ liệu còn toán hạng kia chỉ có thể là thanh ghi mà không được là ô nhớ. Nếu so sánh với chế độ địa chỉ tức thì ta thấy ở đây ngay sau mã lệnh không phải là toán hạng mà là địa chỉ lệch của toán hạng. Xét về phương diện địa chỉ thì đó là địa chỉ trực tiếp. Ví dụ: MOV AL, ( 1234H ) ; chuuyển nội dung ô nhớ DS:1234 ; vào AL. MOV ( 4320H ), CX ; chuyển nội dung CX vào 2 ô nhớ Phạm Trung Minh – Khoa CNTT 14
  22. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam ; liên tiếp DS:4320 và DS:4321  Chế độ gián tiếp qua thanh ghi Trong chế độ địa chỉ này một toán hạng là một thanh ghi được sử dụng để chứa địa chỉ lệch của ô nhớ chứa dữ liệu, còn toán hạng kia chỉ có thể là thanh ghi mà không được là ô nhớ ( 8088 không cho phép quy chiếu bộ nhớ 2 lần đối với một lệnh ). Ví dụ: MOV AL, ( BX ) ; chuyển nội dung ô nhớ có địa ; chỉ DS:BX vào AL. MOV ( SI ), CL ; chuyển nội dung CL vào ô nhớ ; có địa chỉ DS:SI. MOV ( DI ), AX ; chuyển nội dung AX vào 2 ô nhớ ; liên tiếp có địa chỉ DS:DI và ; DS: ( DI + 1 ).  Chế độ địa chỉ tƣơng đối cơ sở Trong chế độ địa chỉ này các thanh ghi cơ sở như BX và BP và các hằng số biểu diễn các giá trị dịch chuyển ( displacement values ) được dùng để tính địa chỉ hiệu dụng của toán hạng trong các vùng nhớ DS và SS. Sự có mặt của các giá trị dịch chuyển xác định tính tương đối ( so với cơ sở ) của địa chỉ. Ví dụ: MOV CX, ( BX ) +10 ; chuyển nội dung 2 ô nhớ liên ; tiếp có địa chỉ DS: ( BX + 10 ) và ; DS: ( BX+10 ) vào CX. MOV CX, ( BX+10 ) ; một cách viết khác của lệnh trên . MOV CX, 10 ( BX ) ; một cách viết khác của lệnh đầu. MOV AL, ( BP ) +5 ; chuyển nội dung ô nhớ SS: ( BP+5 ) ; vào AL. ADD AL, Table ( BX ) ; cộng AL với nội dung ô nhớ do ; BX chỉ ra trong bảng table ; ( bảng này nằm trong DS ), kết ; quả dựa vào AL. Nhân đây cần làm rõ một số thuật ngữ hay dùng thông qua các ví dụ trên. o Table gọi là các dịch chuyển của các toán hạng tương ứng. 10 và 5 là các giá trị cụ thể. Table là tên mảng biểu diễn kiểu dịch chuyển của mảng ( phần tử đầu tiên ) so với địa chỉ đầu của đoạn dữ liệu DS. o ( BX+10) hoặc ( BJP+5 ) gọi là địa chỉ hiệu dụng (effective address. EA.theo cách gọi của Intel ). o DS: ( BX+10 ) hoặc SS: ( BP+5 ) chính là logic tương ứng với một địa chỉ vật lý. o Theo cách định nghĩa này thì địa chỉ hiệu dụng của một phần tử thứ BX nào đó ( kể từ 0 ) trong mảng Table ( BX ) thuộc đoạn DS là EA = Table+BX và của phần tử đầu tiên là EA = Table.  Chế độ địa chỉ tƣơng đối chỉ số cơ sở Kết hợp hai chế độ địa chỉ chỉ số và cơ sở ta có chế độ địa chỉ chỉ số cơ sở. Trong chế độ địa chỉ này ta dùng cả thanh ghi cơ sở lẫn thanh ghi chỉ số để tính địa chỉ của toán hạng. Nếu ta dùng thêm cả thành phần biểu diển sự dịch chuyển của địa chỉ thì ta có chế độ địa chỉ phức hợp nhất: chế độ địa chỉ tương đối chỉ số cơ sở. Ta có thể thấy chế độ địa chỉ này rất phù hợp cho việc dịa chỉ hoá các mảng hai chiều Phạm Trung Minh – Khoa CNTT 15
  23. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Ví dụ: MOV AX, [ BX ] [SI ]+8 ; chuyển nội dung 2 ô nhớ ; liên tiếp có địa chỉ ; DS:(BX+SI+8 ) và ; DS:(BX+SI+9 ) vào AX MOV AX, [BX+SI+8] ; một cách viết khác của lệnh trên MOV CL, [BP+DI+5] ; chuyển nội dung ô nhớ ; SS:( BP+DI+5 ) vào CL. 3.3. Phƣơng pháp quản lý bộ nhớ Trong hệ vi xử lý sử dụng bộ vi xử lý 8088, bộ nhớ chính được xem là một tập hợp các ô nhớ, mỗi ô nhớ có dung lượng 1 byte và được xác định bằng một địa chỉ vật lý duy nhất có độ dài 20 bit. Việc sử dụng 20 bit để địa chỉ hóa bộ nhớ cho phép 8088 quản lý được bộ nhớ có dung lượng tối đa là 220=1 Mb. Các ô nhớ sẽ được đánh địa chỉ từ 00000h đến FFFFFh. Khi một chương trình được nạp vào bộ nhớ, nó được nạp vào các vùng nhớ gọi là các đoạn(segment), mỗi đoạn có dung lượng 64Kb, các đoạn này được quản lý thông qua các thanh ghi đoạn (mỗi thanh ghi đoạn lưu địa chỉ của ô nhớ đầu tiên trong đoạn tương ứng)m hay còn gọi là địa chỉ đoạn(segment). Vị trí của ô nhớ trong đoạn được xác định bằng địa chỉ lệch(offset) : 0000h-FFFFh. Như vậy địa chỉ logic đầy đủ của một ô nhớ trong một đoạn được thể hiện bằng cặp địa chỉ Segment:Offset Phạm Trung Minh – Khoa CNTT 16
  24. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam 3.4. Ngắt 3.4.1. Khái niệm ngắt Ngắt (interrupt) là sự kiện sảy ra của một điều kiện làm cho chương trình đang thực hiện tạm ngưng trong khi điều kiên này được phục vụ bởi một chương trình khác. Các ngắt đóng vai trò quan trọng trong việc thiết kế và thực hiện các ứng dụng của bộ vi xử lý. Các ngắt cho phép hệ thống đáp ứng một sự kiện theo cách không đồng bộ và xử lý một sự kiện trong khi một chương trình khác đang thực thi. Một hệ thống được điều khiển bởi ngắt cho ta có cảm giác đang làm nhiều công việc đồng thời. CPU dĩ nhiên không thể thực hiện nhiều hơn một lệnh ở một thời điểm nhưng CPU có thể tạm ngưng việc thực thi một chương trình để thực thi một chương trình khác rồi sau đó quay trở về thực thi tiếp chương trình đang bị tạm ngưng. Điều này giống như CPU rời khỏi chương trình chính để thực hiện chương trình con bị gọi để rồi sau đó quay về chương trình chính. Chương trình xử lý một ngắt được gọi là chương trình phục vụ ngắt ISR (interrupt service routine). ISR được thực thi nhằm đáp ứng một ngắt và trong trường hợp tổng quát thực hiện việc xuất nhập với một thiết bị. Khi một ngắt xuất hiện, việc thực thi trương trình chính tạm thời bị dừng và CPU thực hiện rẽ nhánh đến trình phục vụ ngắt ISR. CPU thực thi ISR để thực hiện một công việc và kết thúc việc thực thi này khi gặp lệnh “quay về từ một trình phục vụ ngắt” RETI. Ta có thể nói chương trình chính được thực thi ở mức nền còn ISR được thực thi ở mức ngắt. Phạm Trung Minh – Khoa CNTT 17
  25. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Nói một cách đơn giản, ngắt như là một quá trình gọi chương trình con, nhưng các chương trình con này đã được tạo sẵn trong máy tính và quá trình gọi này có thể xảy ra tại thời điểm không xác định trước. 3.4.2. Các loại ngắt và bảng vector ngắt Yêu cầu ngắt Trong các quá trình ngắt, ta phân biệt thành 2 loại: ngắt cứng và ngắt mềm. Ngắt mềm là ngắt được gọi bằng một lệnh trong chương trình ngôn ngữ máy. Ngắt mềm được thục hiện trên hợp ngữ thông qua lệnh INT. Đối với các ngôn ngữ bậc cao hơn, vẫn cho phép thực hiện gọi ngắt nhưng phải được biên dịch thành lệnh INT trong hợp ngữ rồi mời thực hiện. Khác với ngắt mềm, ngắt cứng không được khởi động bên trong máy tính mà do các linh kiện điện tử tác đông lên hệ thống. Ngắt cứng cũng được chia thành 2 loại: ngắt che được và ngắt không che được. Ngắt che được là ngắt có thể cho phép hay không cho phép thực thi bằng phần mềm thông qua cờ ngắt IF (Interrupt Flag): lệnh CLI (Clear Interrupt Flag) sẽ cấm ngắt và lệnh STI (Set Interrupt Flag) sẽ cho phép các ngắt này hoạt động. Khi thực hiện lệnh gọi một ngắt nào đó, chương trình con phục vụ cho ngắt sẽ được gọi. Để thực hiện các ngắt tương ứng, địa chỉ thực hiện các chương trình con phục vụ ngắt được đặt trong một bảng, gọi là bảng vector ngắt. Bảng vector ngắt gồm có 256 phần tử, mỗi phần tử gồm 4 byte ứng với 256 ngắt (từ ngắt 0 đến ngắt 0FFh). Mỗi phần tử trong bảng vector ngắt chứa 2 địa chỉ: địa chỉ thanh ghi đoạn đưa vào CS và địa chỉ offset của chương trình phục vụ ngắt đưa vào IP. Bảng vector ngắt có thể mô tả như sau: Phạm Trung Minh – Khoa CNTT 18
  26. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Địa chỉ Địa chỉ ISR Số thứ tự ngắt 0000h:0000h CS 0 0000h:0002h IP 0000h:0004h CS 1 0000h:0006h IP 0000h:0008h CS 2 0000h:000Ah IP 0000h:03FCh CS 255 0000h:03FEh IP Khi có một quá trình ngắt xảy ra, CPU sẽ tìm địa chỉ bắt đầu của chương trình ngắt được chứa trong bảng vector ngắt theo số thự tự ngắt. Do một phần tử trong bảng vector ngắt chiếm 4 byte nên để tìm giá trị địa chỉ trong bảng vector ngắt, ta chỉ cần nhân số thứ tự ngắt với 4. Danh sách các ngắt mô tả như sau: STT Địa chỉ Chức năng 00h 0000h – 0003h CPU: chia cho 0 01h 0004h – 0007h CPU: thực hiện từng lệnh 02h 0008h – 000Bh CPU: Lỗi RAM 03h 000Ch – 000Fh CPU: thực hiện đến điểm dừng 04h 0010h – 0013h CPU: tràn số 05h 0014h – 0017h In trang màn hình (Print Screen) 06h, 07h 0018h – 001Fh Dành riêng 08h 0020h – 0023h IRQ0: ngắt đồng hồ (18.2 lần / giây) 09h 0024h – 0027h IRQ1: ngắt bàn phím 0Ah 0028h – 002Bh IRQ2: Dành riêng 0Bh 002Ch – 002Fh IRQ3: Giao tiếp nối tiếp 1 0Ch 0030h – 0033h IRQ4: Giao tiếp nối tiếp 2 0Dh 0034h – 0037h IRQ5: Đĩa cứng 0Eh 0038h – 003Bh IRQ6: Đĩa mềm 0Fh 003Ch – 003Fh IRQ7: Máy in 10h 0040h – 0043h BIOS: màn hình 11h 0044h – 0047h BIOS: xác định cấu hình máy tính 12h 0048h – 004Bh BIOS: xác định kích thước RAM 13h 004Ch – 004Fh BIOS: truy nhập đĩa cứng / đĩa mềm 14h 0050h – 0053h BIOS: truy nhập giao tiếp nối tiếp 15h 0054h – 0057h BIOS: truy nhập cassette hay mở rộng ngắt Phạm Trung Minh – Khoa CNTT 19
  27. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam 16h 0058h – 005Bh BIOS: kiểm tra bàn phím 17h 005Ch – 005Fh BIOS: truy nhập máy in 18h 0060h – 0063h Chương trình xâm nhập ROM BASIC 19h 0064h – 0067h BIOS: khởi động hệ thống (khi nhấn Ctrl-Alt-Del) 1Ah 0068h – 006Bh BIOS: đọc / ghi ngày / giờ 1Bh 006Ch – 006Fh Nhấn phím Break 1Ch 0070h – 0073h Gọi sau INT 08h 1Dh 0074h – 0077h Địa chỉ bảng tham số màn hình 1Eh 0078h – 007Bh Địa chỉ bảng tham số đĩa mềm 1Fh 007Ch – 007Fh Địa chỉ bảng font có ký tự mở rộng 20h 0080h – 0083h DOS: kết thúc chương trình 21h 0084h – 0087h DOS: gọi các hàm của DOS 22h 0088h – 008Bh Địa chỉ kết thúc chương trình 23h 008Ch – 008Fh Nhấn Ctrl-Break 24h 0090h – 0093h Địa chỉ chương trình xử lý lỗi 25h 0094h – 0097h DOS: đọc đĩa mềm / đĩa cứng 26h 0098h – 009Bh DOS: ghi đĩa mềm / đĩa cứng 27h 009Ch – 009Fh DOS: kết thúc chương trình và thường trú 28h – 3Fh 00A0h – 00FFh Dành riêng cho DOS 40h 0100h – 0103h BIOS: phục vụ đĩa mềm 41h 0104h – 0107h Địa chỉ bảng tham số đĩa cứng 1 42h – 45h 0108h – 0117h Dành riêng 46h 0118h – 011Bh Địa chỉ của bảng tham số đĩa cứng 2 47h – 49h 011Ch – 0127h Dành cho user 4Ah 0128h – 012Bh Hẹn giờ 4Bh – 67h 012Ch – 019Fh Dành cho user 68h – 6Fh 01A0h – 01BFh Không dùng 70h 01C0h – 01C3h IRQ8: đồng hồ thời gian thực 71h 01C4h – 01C7h IRQ9 72h 01C8h – 01CBh IRQ10 73h 01CCh – 01CFh IRQ11 74h 01D0h – 01D3h IRQ12 75h 01D4h – 01D7h IRQ13: từ 80x87 76h 01D8h – 01DBh IRQ14: đĩa cứng 77h 01DCh – 01DFh IRQ15 78h – 7Fh 01E0h – 01FFh Dành riêng Phạm Trung Minh – Khoa CNTT 20
  28. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam 80h – F0h 0200h – 03C3h Dùng cho bộ thông dịch BASIC F1h – FFh 03C4h – 03FFh Không sử dụng 3.4.3. Gọi ngắt Quá trình gọi ngắt từ hợp ngữ đơn giản là thực hiện lệnh INT STT_ngắt sau khi nạp các tham số cần thiết cho ngắt. Khi thực hiện lệnh gọi ngắt, CPU sẽ tìm kiếm trong bảng vector ngắt địa chỉ của chương trình phục vụ ngắt. Người sử dụng cũng có thể xây dựng môt chương trình cơ sở như các chương trình xử lý ngắt. Sau đó, các chương trình khác có thể gọi ngắt ra để sử dụng. Một chương trình có thể gọi chương trình con loại này mà không cần biết địa chỉ của nó. Như vậy, nếu muốn thay đổi ngắt, ta có thể thay đổi nội dung trong bảng vector ngắt để chỉ đến chương trình phục vụ do người sử dụng tự xây dựng và chương trình này sẽ được thực hiện khi ngắt được gọi. Để làm điều này, ta chỉ cần tìm vị trí của vector ngắt tương ứng trong bảng và thay đổi giá trị của nó. Điều này thực hiện được do bảng vector ngắt đặt trong RAM và được nạp mỗi khi khởi động hệ thống. Quá trình lấy và gán địa chỉ của chương trình con phục vụ ngắt có thể thực hiện thông qua ngắt 21h bằng các hàm sau: Hàm 35h: lấy địa chỉ của ngắt Vào: AL = số thứ tự ngắt Ra: ES:BX = địa chỉ của chương trình phục vụ ngắt Hàm 25h: gán địa chỉ của một chương trình phục vụ cho một ngắt Vào: AL = số thứ tự ngắt, DS:DX Ra: không có 3.5. Mã hoá lệnh của bộ vi xử lý 8088 Lệnh của bộ vi xử lý được ghi bằng các ký tự dưới dạng gợi nhớ (memonic ) để người sử dụng để nhận biết. Đối với bản thân bộ vi xử lý thì lệnh cho nó được mã hoá dưới dạng các số 0 và 1 (còn gọi là mã máy ) vì đó là dạng biểu diễn thông tin duy nhất mà máy hiểu được. Vì lệnh do bộ vi xử lý được cho dưới dạng mã nên sau khi nhận lệnh., bộ vi xử lý phải thực hiện việc giải mã lệnh rồi sau đó mới thực hiện lênh. Việc hiểu rõ bản chất cách ghi lệnh bằng số hệ 2 cho bộ vi xử lý sẽ có lợi khi ta cần dịch “ bằng tay “. Một lệnh gợi nhớ khi làm việc với các “ kit “ vi xử lý ( tuy rằng việc này ít khi xảy ra vì ta thường làm việc với các hệ được trang bị chương trình dịch hợp ngữ ). Một lệnh có thể có độ dài một vài byte tuỳ theo bộ vi xử lý. Giả thiết một bộ vi xử lý nào đó dùng 1 byte để chứa các mã lệnh ( opcode ) của nó. Ta có thể tính được số lệnh lớn nhất mà 1 byte này có thể mã hoá được là 256 lệnh. Trong thực tế việc ghi lệnh không phải hoàn toàn đơn giản như vậy. Việc mã hoá lệnh cho bộ vi xử lý là rất phức tạp và bị chi phối bởi nhiều yếu tố khác nữa. Đối với bộ vi xử lý 8088 một lệnh có thể có độ dài từ 1 đến 6 byte. Ta sẽ chỉ lấy trường hợp lệnh MOV để giải thích cách ghi lệnh nói chung của 8088. Lệnh MOV đích, gốc dùng để nguyển dữ liệu giữa 2 thanh ghi hoặc giữa 2 ô nhớ và thanh ghi. Chỉ nguyên với các thanh ghi của 8088, nếu ta lần lượt đặt các thanh ghi vào các vị trí toán hạng đích và toán hạng gốc ta thấy đã phải cần tới hàng trăm mà lệnh khác nhau để mã hoá tổ hợp các lệnh này. Hình dưới đây biểu diễn dạng thức các byte dùng để mã hoá lệnh MOV. Từ đây ta thấy rằng để mã hoá lệnh MOV ta phải cần ít nhất là 2 byte, trong đó 6 bit của byte đầu dùng để chứa mã lệnh. Đối với các lệnh MOV. Để chuyển dữ liệu kiểu: o Thanh ghi  thanh ghi ( trừ thanh ghi đoạn ) hoặc o Bộ nhớ  thanh ghi ( trừ thanh ghi đoạn ) thì 6 bit đầu này luôn là 100010. Đối với các thanh ghi đạon thì điều này lại khác. Bit W dùng để chỉ ra rằng 1 byte (W = 0 ) hoặc 1 từ ( W = 1 ) sẽ được chuyển. Phạm Trung Minh – Khoa CNTT 21
  29. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Byte Byte Byte Byte 1 2 3 4 1 0 0 0 1 0 Dis Dis mo RE M/ H Opcod D W p L p e d G R Hoặc Di chuyển trực tiếp Di chuyển trực tiếp phần thấp phần cao Dạng thức Byte mã lệnh của lệnh MOV Trong các thao tác chuyển dữ liệu, một toán hạng luôn bắt buộc phải là thanh ghi. Bộ vi xử lý dùng 2 hoặc 3 bit để mã hoá các thanh ghi trong CPU như sau: Thanh ghi Mã Thanh ghi đoạn Mã W = 1 W = 0 CS 01 AX AL 000 DS 11 BX BL 011 ES 00 CX CL 001 SS 10 DX DL 010 SP AH 100 DI BH 111 BP CH 101 SI DH 110 Bit D dùng để chỉ hướng đi của dữ liệu. D = 1 thì dữ liệu đi đến thanh ghi cho bởi b bit của REG. 2 bit MOD ( chế độ ) cùng với 3 bit R/M ( thanh ghi/bộ nhớ ) tạo ra 5 bit dùng để chỉ ra chế độ địa chỉ cho các toán hạng của lệnh ( có thể hiểu chế độ địa chỉ là cách tìm ra địa chỉ của toán hạng, xem thêm phần sau của chương này để rõ hơn về chế độ địa chỉ. Bảng Mod – R/M cho ta thấy cách mã hoá các chế độ địa chỉ ( cách tìm ra các toán hạng bằng các bit này ). MOD 00 01 10 11 R/M W=0 W=1 000 [BX]+[8] [BX]+[SI]+d8 [BX]+[SI]+d16 AL AX 001 [BX]+[DI] [BX]+[DI]+d8 [BX]+[DI]+d16 CL CX 010 [BP]+[SI] [BP]+[SI]+d8 [BP]+[SI]+d16 DL DX 011 [BP]+[DI] [BP]+[DI]+d8 [BP]+[DI]+d16 BL BX 100 [SI] [SI]+d8 [SI]+d16 AH SP 101 [DI] [DI]+d8 [DI] +d16 CH BP 110 d16 (Địa chỉ [BP]+d8 [BP]+d16 DH SI trực tiếp) 111 [BX] [BX]+d8 [BX]+d16 BH DI chế độ bộ nhớ chế độ thanh ghi Ghi chú : - disp , 8bit ,d16: disp , 16bit Phạm Trung Minh – Khoa CNTT 22
  30. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam - Các giá trị cho trong các cột 2,3,4 (ứng với MOD =00,01,10) là các địa chỉ hiệu dụng (EA) sẽ được cộng với DS để tạo ra địa chỉ vật lý (riêng BP phải được cộng với SP ) Trong các ví dụ sau đây ta sẽ dùng các kiến thức nêu trên để mã hoá một vài lệnh MOV. MOV CL ,[BX] 1 0 0 0 1 0 1 0 0 0 0 0 1 1 1 1 Opcode mã hoá CL Chuyển tới thanh ghi [ BX] Chuyển 1 byte MOV OF3H [SI] , CL 1 0 0 0 1 0 0 0 0 1 0 0 1 1 0 0 1 1 1 1 0 0 1 1 CL [SI] dS = F3H Chuyển từ thanh ghi 1 Byte Phạm Trung Minh – Khoa CNTT 23
  31. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Chƣơng 4 : LẬP TRÌNH BẰNG HỢP NGỮ VỚI 8088 4.1. Tổng quan, cấu trúc hợp ngữ (Assembly) 4.1.1. Cú pháp của chương trình hợp ngữ Trước khi trình bày cách lập trình bằng hợp ngữ ta phải tìm hiểu qua cú pháp của ngôn ngữ này, bởi vì như ta đã biết, để làm việc được với bất kỳ một ngôn ngữ lập trình nào ta cũng cần nắm được cú pháp của nó. Chương trình dưới dạng hợp ngữ mà ta viết ra, nếu đúng về cú pháp, sẽ được chương trình dịch hợp ngữ MASM dịch ra mã máy, từ chương trình mã máy này ta có thể tạo ra các chương trình chạy (thực hiện) được ngay bằng cách dịch tiếp ra các tệp có đuôi EXE hoặc COM. Do vậy khi viết một chương trình hợp ngữ ta phải tuân thủ những quy tắc cú pháp nhất định để chương trình MASM có thể hiểu và dịch được nó. Một chương trình hợp ngữ bao gồm các dòng lệnh, một dòng lệnh có thể là một lệnh thật dưới dạng ký hiệu (symbolic), mà đôi khi còn được gọi là dạng gợi nhớ (mnemonic) của bộ vi xử lý, hoặc một hướng dẫn cho chương trình dịch (assembler directive). Lệnh gợi nhớ sẽ được dịch ra mã máy còn hướng dẫn cho chương trình dịch thì không được dịch, vì nó chỉ có tác dụng chỉ dẫn riêng thực hiện công việc. Ta có thể viết các dòng lệnh này bằng chữ hoa hoặc chữ thường và chúng sẽ được coi là tương đương vì đối với dòng lệnh chương trình dịch không phân biệt kiểu chữ. Một dòng lệnh của chương trình hợp ngữ có thể có những trường sau (không nhất thiết phải có đủ hết tất cả các trường): Tên Mã lệnh Các toán dạng Chú giải Một ví dụ dòng lệnh gợi nhớ: TIEP : MOV AH, {BX} {SI} ; nạp vào AH nội dung ô ; nhớ có địa chỉ DS : (BX+SI) Trong ví dụ trên, tại trường tên ta có nhãn TIEP, tại trường mã lệnh ta có lệnh MOV, tại trường toán hạng ta có các thanh ghi AH, BX và SI và phần chú giải gồm có các dòng ; nạp vào AH nội dung ô ; nhớ có địa chỉ DS : (BX+SI) Một ví dụ khác là các dòng lệnh với các hướng dẫn cho chương trình dịch: MAIN PROC và MAIN ENDP Trong ví dụ này, ở trường tên ta có tên thủ tục là MAIN, ở trường mã lệnh ta có các lệnh giả PROC và ENDP. Đây là các lệnh giả dùng để bắt đầu và kết thúc một thủ tục có tên là MAIN. o Trường tên Trường tên chứa các nhãn, tên biến hoặc tên thủ tục. Các tên và nhãn này sẽ được chương trình dịch gán bằng các địa chỉ cụ thể của ô nhớ. Tên và nhẵn có thể có độ dài 1 31 ký tự, không được chứa dấu cách và không được bắt đầu bằng số. Các ký tự đặc biệt khác có thể dùng trong tên là ?.@_$%. Nếu dấu chấm ('.') được dùng thì nó phải được đặt ở vị trí đầu tiên của tên. Nói chung ta cứ đặt các tên bình thường và có ý nghĩa là sẽ ít khi bị sai. Một nhãn thường kết thúc bằng dấu hai chấm (:). o Trường mã lệnh Trong trường mã lệnh nói chung sẽ có các lệnh thật hoặc lệnh giả. Đối với các lệnh thật thì trường này chứa các mã lệnh gợi nhớ. Mã lệnh này sẽ được chương trình dịch dịch ra mã máy. Đối với các hướng dẫn chương trình dịch thì trường này chứa các lệnh giả và sẽ không được dịch ra mã máy. Phạm Trung Minh – Khoa CNTT 24
  32. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam o Trường toán hạng Đối với một lệnh thì trường này chứa các toán hạng của lệnh. Tùy theo từng loại lệnh mà ta có thể có 0,1 hoặc 2 toán hạng trong một lệnh. Trong trường hợp các lệnh với 1 toán hạng thông thường ta có toán hạng là đích hoặc gốc, còn trong trường hợp lệnh với 2 toán hạng thì ta có 1 toán hạng là đích và 1 toán hạng là gốc. Đối với hướng dẫn chương trình dịch thì trường này chứa các thông tin khác nhau liên quan đến các lệnh giả của hướng dẫn. o Trường chú giải Lời giải thích ở trường chú giải phải được bắt đầu bằng dấu chấm phẩy (;) Trường chú giải này được dành riêng cho người lập trình để ghi các lời giải thích cho các lệnh của chương trình với mục đích giúp cho người đọc chương trình dễ hiểu các thao tác của chương trình hơn. Lời chú giải cũng có lợi ngay cho chính tác giả của nó vì sau một thời gian không xem đến chương trình thì mọi việc lại như mới. Khi đọc thấy dấu chấm phẩy, chương trình dịch bỏ qua không dịch từ phần này trở đi. Chính vì vậy người ta cũng thường hay dùng dấu này để loại bỏ một dòng lệnh nào đó trong chương trình. Thông thường lời chú giải cần phải mang đủ thông tin để giải thích về thao tác của lệnh trong hoàn cảnh cụ thể và như thế thì mới có ích cho người đọc. Đối với những người mới lập trình bằng hợp ngữ còn thiếu kinh nghiệm thì lời chú giải còn phản ảnh sự hiểu biết về vấn đề phải giải quyết của họ, vì nếu không hiểu thấu đáo vấn đề thì không để đưa ra lời chú giải tốt được. Tóm lại là ta nên tránh việc đưa ra một lời chú giải vô bổ (không mang thông tin) kiểu như: MOV BX, 0 ; đưa 0 vào thanh ghi BX Vì tự thân lệnh gợi nhớ đó đã có ý nghĩa như lời giải thích rồi. Nếu trong bài toán cụ thể thanh ghi BX được chọn dùng làm tổng tích luỹ cho một tính toán nhất định ta có thể có lời chú giải hơn như sau: MOV BX, 0 ; tổng tích luỹ ở BX lúc đầu bằng 0. Ta cũng có thể dùng một vài dòng lệnh chỉ để làm chú giải cho một công việc nào đó. Cần lưu ý là mỗi dòng chú giải đó phải bắt đầu bằng dấu chấm phẩy. Ví dụ: ; khởi đầu thanh ghi DS và ES trong đoạn dữ liệu MOV AX, @DATA MOV DS, AX MOV ES, AX 4.1.2. Khung của một chƣơng trình hợp ngữ Một chương trình mã máy trong bộ nhớ thường bao gồm các vùng nhớ khác nhau để chứa mã lệnh, chứa dữ liệu của chương trình và một vùng nhớ khác được dùng làm ngăn xếp phục vụ hoạt động của chương trình. Chương trình viết bằng hợp ngữ cũng phải có cấu trúc tương tự để khi được dịch nó sẽ tạo ra mã tương ứng với chương trình mã máy nói trên. Để tạo ra sườn của một chương trình hợp ngữ chúng ta sẽ sử dụng cách định nghĩa đơn giản đối với mô hình bộ nhớ dành cho chương trình và đối với các thanh ghi đoạn, cách định nghĩa được phép từ phiên bản 5.0 của Microsoft Macro Aesembler,  Khai báo quy mô sử dụng bộ nhớ Kích thước của bộ nhớ dành cho đoạn mã và đoạn dữ liệu trong một chương trình được xác định nhờ hướng dẫn chương trình dịch MODEL như sau (hướng dẫn này phải được đặt trước các hướng dẫn khác trong chương trình hợp ngữ, nhưng sau hướng dẫn về loại CPU): .MODEL Kiểu_ kích_thước_bộ_nhớ Có nhiều Kiểu_ kích_thước_bộ_nhớ cho các chương trình với đòi hỏi dung lượng bộ nhớ khác nhau. Đối với ta thông thường các ứng dụng đòi hỏi mã chương trình dài nhất cũng chỉ cần chứa trong một đoạn (64KB), dữ liệu cho chương trình nhiều nhất cũng chỉ cần chứa Phạm Trung Minh – Khoa CNTT 25
  33. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam trong một đoạn, thích hợp nhất nên chọn Kiểu_ kích_thước_bộ_nhớ là Small (nhỏ) hoặc nếu như tất cả mã và dữ liệu có thể gói trọn được trong một đoạn thì có thể chọn Tiny(hẹp): .Model small hoặc .Model Tiny Ngoài Kiểu_ kích_thước_bộ_nhớ nhỏ hoặc hẹp nói trên, tuỳ theo nhu cầu cụ thể MASM còn cho phép sử dụng các Kiểu_ kích_thước_bộ_nhớ khác như liệt kê trong bảng 4.1 Các kiểu kích thước bộ nhớ cho chương trình hợp ngữ Kiểu kích thước Mô tả Tiny Mã lệnh và dữ liệu gói gọn trong một đoạn (Hẹp) Small Mã lệnh gói gọn trong một đoạn , dữ liệu nằm (Nhỏ) trong một đoạn. Medium Mã lệnh không gói gọn trong một đoạn , dữ liệu (Trung bình) nằm trong một đoạn. Compact Mã lệnh không gói gọn trong một đoạn , dữ liệu (Gọn) không gói gọn trong một đoạn. Large Mã lệnh không gói gọn trong một đoạn , dữ liệu (lớn) không gói gọn trong một đoạn. không có mảng nào lớn hơn 64KB. Huge Mã lệnh không gói gọn trong một đoạn , dữ liệu (Đồ sộ) không gói gọn trong một đoạn. các mảng có thể lớn hơn 64KB  Khai báo đoạn ngăn xếp Việc khai báo đoạn ngăn xếp là cốt để dành ra một vùng nhớ đủ lớn dùng làm ngăn xếp phục vụ cho hoạt động của chương trình khi có chương trình con. Việc khai báo được thực hiện nhờ hướng dẫn chương trình dịch như sau. .Stack Kích_thước Kích_thước sẽ quyết định số byte dành cho ngăn xếp. Nếu ta không khai Kích_thước thì chương trình dịch sẽ tự động gán cho Kích_thước giá trị 1 KB, đây là kích thước ngăn xếp quá lớn đối với một ứng dụng thông thường. Trong thực tế các bài toán của ta thông thường với 100-256 byte là đủ để làm ngăn xếp và ta có thể khai báo kích thước cho nó như sau: .Stack 100 Hoặc .Stack 100H  Khai báo đoạn dữ liệu Đoạn dữ liệu chứa toàn bộ các định nghĩa cho các biến của chương trình. Các hằng cũng nên được định nghĩa ở đây để đảm bảo tính hệ thống mặc dù ta có thể để chúng ở trong chương trình như đã nói ở phần trên. Việc khai báo đoạn dữ liệu được thực hiện nhờ hướng dẫn chương trình dịch DATA, việc khai báo và hằng được thực hiện tiếp ngay sau đó bằng các lệnh thích hợp. Điều này được minh hoạ trong các thí dụ đơn giản sau: .Data MSG DB 'helo!$' CR DB 13 LF EQU 10 Phạm Trung Minh – Khoa CNTT 26
  34. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam  Khai báo đoạn mã Đoạn mã chứa mã lệnh của chương trình. Việc khai báo đoạn mã được thực hiện nhờ hướng dẫn chương trình dịch .CODE như sau: .CODE Bên trong đoạn mã, các dòng lệnh phải được tổ chức một cách hợp lý, đúng ngữ pháp dưới dạng một chương trình chính (CTC) và nếu cần thiết thì kèm theo các chương trình con (ctc). Các chương trình con sẽ được gọi ra bằng các lệnh CALL có mặt bên trong chương trình chính. Một thủ tục được định nghĩa nhờ các lệnh giả PROC và ENDP. Lệnh giả PROC để bắt đầu một thủ tục còn lệnh giả ENDP được dùng để kết thúc nó. Như vậy một chương trình chính có thể được định nghĩa bằng các lệnh giả PROC và ENDP theo mẫu sau: Tên_CTC Proc ; Các lệnh của thân chương trình chính : CALL Tên_ ctc; gọi ctc : Tên_CTC Endp Giống như chương trình chính con cũng được định nghĩa dưới dạng một thủ tục nhờ các lệnh giả PROC và ENDP theo mẫu sau: Tên_ctc Proc ; các lệnh thân chương trình con : RET Tên_ctc Endp Trong các chương trình nói trên, ngoài các lệnh giả có tính nghi thức bắt buộc ta cần chú ý đến sự bố trí của lệnh gọi (CALL) trong chương trình chính và lệnh về (RET) trong chương trình con.  Khung của chƣơng trình hợp ngữ để dịch ra chƣơng trình .EXE Từ các khai báo các đoạn của chương trình đã nói ở trên ta có thể xây dựng một khung tổng quát cho các chương trình hợp ngữ với kiểu kích thước bộ nhớ nhỏ. Sau đây là một khung cho chương trình hợp ngữ để rồi sau khi được dịch (assembled) nối (linked) trên máy IBM PC sẽ tạo ra một tệp chương trình chạy được ngay (executable) với đuôi .EXE. . Model small .Stack 100 .Data ; các định nghĩa cho biến và hằng để tại đây .Code MAIN Proc ; Khởi đầu cho DS MOV AX, @Data MOV DS, AX ; Các lệnh của chương trình chính để tại đây ; Trở về DOS dùng hàm 4CH của INT 21H MOV AH, 4CH INT 21 H MAIN Endp Phạm Trung Minh – Khoa CNTT 27
  35. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam ; các chương trình con (nếu có ) để tại đây END MAIN Trong khung chương trình trên, tại dòng cuối cùng của chương trình ta dùng hướng dẫn chương trình dịch END và tiếp theo là MAIN để kết thúc toàn bộ chương trình. Ta có nhận xét rằng MAIN là tên của chương trình chính nhưng quan trọng hơn và về thực chất thì nó là nơi bắt đầu các lệnh của chương trình trong đoạn mã. Khi một chương .EXE được nạp vào bộ nhớ. DOS sẽ tạo ra một mảng gồm 256 byte của cái gọi là đoạn mào đầu chương trình (Programsegment prefix. PSP) dùng để chứa các thông tin liên quan đến chương trình và các thanh ghi DS và ES. Do vậy DS và ES không chứa giá trị địa chỉ của các đoạn dữ liệu cho chương trình của chúng ta. Để chương trình có thể chạy đúng ta phải có các lệnh sau để khởi đầu cho thanh ghi DS (hoặc caES nữa nếu cần): MOV AX, @Data MOV DS, AX ; nếu cần thì bỏ ';' trong đó @ Data là tên của đoạn dữ liệu. Data định nghĩa bởi hướng dẫn chương trình dịch sẽ dịch tên @ Data thành giá trị số của đoạn dữ liệu. Ta phải dùng thanh ghi AX làm trung gian cho việc khởi đầu DS như trên là do bộ vi xử lý 8086/88, Vì những lí do kỹ thuật, không cho phép chuyển giá trị số (chế độ địa chỉ tức thì) vào các thanh ghi đoạn. Thanh ghi AX cũng có thể được thay thế bằng các thanh ghi khác. Sau đây là ví dụ của một chương trình hợp ngữ được viết để dịch ra chương trình với đuôi .EXE. khi cho chạy, chương trình này sẽ hiện lên màn hình lời chào 'Hello' nằm giữa hai dòng trống cách đều các dòng mang dấu nhắc của DOS. Chƣơng trình 4.1 Chƣơng trình Hello.EXE . Model Small . Stack 100 . Data CRLF DB 13,10,' $ ' MSG DB ' Hello!$ ' . Code MAIN Proc ; khởi đầu thanh ghi DS MOV AX,@Data MOV DS, AX ; về đầu dòng mới dùng hàm 9 của INT 21H MOV AH, 9 LEA DX, CRLF INT 21H ; hiện thị lời chào dùng hàm 9 của INT 21H MOV AH, 9 LEA DX, MSG INT 21H ; về đầu dòng mới dùng hàm 9 của INT 21H MOV AH, 9 LEA DX, CFLF INT 21H ; trở về DOS dùng hàm 9 của INT 21H Phạm Trung Minh – Khoa CNTT 28
  36. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam MOV AH, 4CH INT 21H MAIN Endp END MAIN Trong ví dụ trên chúng ta đã sử dụng các dịch vụ có sẵn (các hàm 9 và 4CH) của ngắt INT 21H của DOS trên máy IBM PC để hiện thị xâu ký tự và trở về DOS một cách thuận lợi. 4.2. Dữ liệu trong Assembly 4.2.1. Dữ liệu cho chương trình Dữ liệu của một chương trình hợp ngữ là rất đa dạng. Các dữ liệu có thể được cho dưới dạng số hệ hai, hệ mười, hệ mười sáu hoặc dưới dạng ký tự (cần chú ý là trên các máy IBM PC trong chương trình DEBUG, một công cụ tìm lỗi rất thông dụng cho các chương trình hợp ngữ đơn giản, dữ liệu bằng số được ngầm định phải ở hệ mười sáu). Khi cung cấp số liệu cho chương trình, số cho ở hệ nào phải được kèm đuôi của hệ đó như ta đã nói rõ ở chương I (trừ hệ mười thì không cần vì là trường hợp ngầm định của assembler). Riêng đối với số hệ mười sáu nếu số đó bắt đầu bằng các chữ (a.f hoặc A F) thì ta phải thêm 0 ở trước để chương trình dịch có thể hiểu được đó là một số hệ mười sáu chứ không phải là một tên hoặc một nhãn. Ví dụ các số viết đúng: 0011B ; Số hệ hai. 1234 ; Số hệ mười 0ABBAH ; Số hệ mười sáu, không nhầm được với ; tên của một ban nhạc nổi tiếng ABBA. 1EF1H ; Số hệ mười sáu. Nếu dữ liệu là ký tự hoặc chuỗi ký tự thì chúng phải được đóng trong căpk dấu trích dẫn đơn hoặc kép, thí dụ 'A' hay "abcd". Chương trình dịch sẽ dịch ký tự ra mã ASCII tương ứng của nó, vì vậy trong khi cung cấp dữ liệu kiểu ký tự cho chương trình ta có thể dùng bản thân ký tự được đóng trong dấu trích dẫn hoặc mã ASCII của nó. Ví dụ, ta có thể sử dụng liệu ký tự là "0" hoặc mã ASCII tương ứng là 30H, ta cps thể dùng '$' hoặc 26H hoặc 34 4.2.2. Biến và hằng Biến trong chương trình hợp ngữ có vai trò như nó có ở ngôn ngữ bậc cao. Một biến phản được định kiểu dữ liệu là kiểu byte hay kiểu từ và sẽ được chương trình dịch gán cho một địa chỉ nhất định trong bộ nhớ. Để định nghĩa các kiểu dữ liệu khác nhau ta thường dùng các lệnh giả sau: DB (define byte) : định nghĩa biến kiểu byte DW (define word) : định nghĩa biến kiểu từ DD (define double word) : định nghĩa biến kiểu từ kép Biến byte Biến kiểu byte sẽ chiếm 1 byte trong bộ nhớ. Hướng dẫn chương trình dịch để định nghĩa biến kiểu byte có dạng tổng quát như sau: Tên DB giá_ trị_khởi_đầu Ví dụ: B1 DB 4 Ví dụ trên định nghĩa biến byte có tên là B1 và dành 1 byte trong bộ nhớ cho nó để chứa giá trị khởi đầu bằng 4. Phạm Trung Minh – Khoa CNTT 29
  37. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Nếu trong lệnh trên ta dùng dấu? thay vào vị trí của số 4 thì biến B1 sẽ được dành chỗ trong bộ nhớ nhưng không được gán giá trị khởi đầu. Cụ thể dòng lệnh giả: B2 DB ? chỉ định nghĩa 1 biến byte có tên là B2 và dành cho nó một byte trong bộ nhớ. Một trường hợp đặc biệt của biến byte là biến ký tự. Ta có thể có định nghĩa biến kỳ tự như sau: C1 DB ' $' C2 DB 34 o Biến từ Biến từ cũng được định nghĩa theo cách giống như biến byte. Hướng dẫn chương trình dịch để định nghĩa biến từ có dạng như sau: Tên DB giá_ trị_khởi_đầu Ví dụ: W1 DW 40 Ví dụ trên định nghĩa biến từ có tên là W1 và dành 2 byte trong bộ nhớ cho nó để chứa giá trị khởi đầu bằng 40. Chúng ta cũng có thể sử dụng dấu? chỉ để định nghĩa và dành 2 byte trong bộ nhớ cho biến từ W2 mà không gán giá trị đầu cho nó bằng dòng lệnh sau: W2 DW ?  Biến mảng Biến mảng là biến hình thành từ một dãy liên tiếp các phần tử cùng loại byte hoặc từ, khi định nghĩa biến mảng ta gán tên cho một dãy liên tiếp các byte hay từ trong bộ nhớ cùng với các giá trị ban đầu tương ứng. Ví dụ: M1 DB 4, 5, 6, 7, 8, 9 Ví dụ trên định nghĩa biến mảng có tên là M1 gồm 6 byte và dành chỗ cho nó trong bộ nhớ từ địa chỉ ứng với M1 để chứa các giá trị khởi đầu bằng 4, 5, 6, 7, 8, 9. Phần tử đầu tỏng mảng là 4 và có địa chỉ trùng với địa chỉ của M1, phần tử thứ hai là 5 và có địa chỉ M1+1 Khi chúng ta muốn khởi đầu các phần tử của mảng với cùng một giá trị chúng ta có thể dùng thêm toán tử DUP trong lệnh. Ví dụ: M2 DB 100 DUP (0) M3 DB 100 DUP (?) Ví dụ trên định nghĩa một biến mảng tên là M2 gồm 100 byte, dành chỗ trong bộ nhớ cho nó để chứa 100 giá trị khởi đầu bằng 0 và biến mảng khác tên là M3 gồm 100byte, dành sẵn chỗ cho nó trong bộ nhớ để chứa 100 giá trị nhưng chưa được khởi đầu. Toán tử DUP có thể lồng nhau để định nghĩa ra 1 mảng. Ví dụ: dòng lệnh M4 DB 4, 3, 2, 2 DUP(1,2 DUP(5),6) Sẽ định nghĩa ra một mảng M4 tương đương với lệnh sau: M4 DB 4,3,2,1,5,5,6,1,5,5,6 Một điều cần chú ý nữa là đối với các bộ vi xử lý của Intel, nếu ta có một từ để trong bộ nhớ thì byte thấp của nó sẽ được để ở ô nhớ có địa chỉ thấp, byte cao sẽ được để ở ô nhớ có địa chỉ cao. Cách lưu giữ số liệu kiểu này cũng còn có thể thấy ở các máy VAX của Digital hoặc của một số hãng khác và thường gọi là 'quy ước đầu bé' (little endian, byte thấp được cất tại địa chỉ thấp). Cũng nên nói thêm ở đây là các bộ vi xử lý của motorola lại có cách cất số liệu theo Phạm Trung Minh – Khoa CNTT 30
  38. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam thứ tự ngược lại hay còn được gọi là 'quy ước đầu to' (big endian byte cao được cất tại địa chỉ thấp) . Ví dụ: Sau khi định nghĩa biến từ có tên là WORDA như sau: WORDA DW OFFEEH Thì ở trong bộ nhớ thấp (EEH) sẽ được để tại địa chỉ WORDA còn byte cao (FFH) sẽ được để tại địa chỉ tiếp theo, tức là tại WORDA+1  Biến kiểu xâu kí tự Biến kiểu xâu kí tự là một trường hợp đặc biệt của biến mảng, trong đó các phần tử của mảng là các kí tự. Một xâu kí tự có thể được định nghĩa bằng các kí tự hoặc bằng mã ASCII của các kí tự đó. Các ví dụ sau đều là các lệnh đúng và đều định nghĩa cùng một xâu kí tự nhưng gắn nó cho các tên khác nhau: STR1 DB 'string' STR2 DB 73h, 74h, 72h, 69h, 6Eh, 67h STR3 DB 73h, 74h, 'x' 'i', 6Eh, 67h  Hằng có tên Các hằng trong chương trình hợp ngữ thường được gán tên để làm cho chương trình trở nên dễ đọc hơn. Hằng có thể là kiểu số hay kiểu ký tự. Việc gán tên cho hằng được thực hiện nhờ lệnh giả EQU (equate) như sau: CR EQU 0Dh ;CR là carriage return LE EQU 0Ah ;LF là line feed Trong ví dụ trên lệnh giả EQU gán giá trị số 13 (mã ASCII của kí tự trở về đầu dòng) cho tên CR và 10 (mã ASCII của ký tựu thêm dòng mới) cho tên LF. Hằng cũng có thể là một chuỗi ký tự. trong ví dụ dưới đây sau khi đã gán một chuỗi ký tự cho một tên: CHAO EQU 'Hello' ta có thể sử dụng hằng này để định nghĩa một biến mảng khác. MSG DB CHAO, '$' Vì lệnh giả EQU không dành chỗ của bộ nhớ cho tên của hằng nên ta có thể đặt nó khá tự do tại những chỗ thích hợp bên trong chương trình. Tuy nhiên trong thực tế người ta thường đặt các định nghĩa này trong đoạn dữ liệu. 4.2. Vào/ra trong Assembly Hàm 1 của ngắt INT 21H: đọc 1 ký tự từ bàn phím Vào: AH = 1 Ra: AL = mã ASCH của ký tự cần hiện thị Al = 0 khi ký tự gõ vào là từ các phím chức năng Hàm 2 của ngắt INT 21H: hiện 1 ký tự lên màn hình Vào: AH = 2 DL = mã ASCH của ký tự cần hiện thị. Hàm 9 của ngắt INT 21H: hiện chuỗi ký tự với $ ở cuối lên màn hình Vào: AH = 9 DX = địa chỉ lệch của chuỗi ký tự cần hiện thị. Hàm 4CH của ngắt INT 21H: kết thúc chương trình loại . EXE Vào: AH=4Ch Phạm Trung Minh – Khoa CNTT 31
  39. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam 4.3. Nhóm lệnh dịch chuyển dữ liệu 4.3.1. Lệnh Mov (Move) Cú pháp lệnh: Mov [Toán hạng đích], [Toán hạng nguồn] Trong đó: - [Toán hạng đích]: Có thể là thanh ghi (8 bít hay 16 bít), ô nhớ (chính xác hơn là địa chỉ của một ô nhớ) hay một biến nào đó. [Toán hạng đích] không thể là hằng số. - [Toán hạng nguồn]: Có thể là hằng số, biến, thanh ghi, ô nhớ (chính xác hơn là địa chỉ của một ô nhớ) nào đó. Tác dụng: Lấy nội dung (giá trị) của [Toán hạng nguồn] đặt vào [Toán hạng đích]. Nội dung của [Toán hạng nguồn] không bị thay đổi. Ví dụ 1: Mov Ax, 5 ; Ax ß 5: đặt giá trị 5 vào thành ghi Ax Mov Ax, 5*2 ; Ax ß 5*2: đặt giá trị 10 vào thành ghi Ax Mov Bx, (80*(Dong - 1) + (Cot - 1))*2 ; Dong, Cot là các biến Mov Dl, „A‟ ; Dl = 41h: đặt mã ASCII của „A‟ vào thanh ghi Dl Mov Cx, Var1 ; Cx = Var1: đặt giá trị của biến Var1 vào thanh ghi Cx Mov Ax, Bx ; Ax = Bx: đặt giá trị của thanh ghi Bx vào Ax Mov Ax, Dl ; Ax = Dl: đặt giá trị của Dl (8 bít) vào Ax (16 bít) Mov Bl, Dx ; Bl = Dx: không hợp lệ, vì: Dx (16 bít) mà Bl (8 bít) Mov Dl, 300 ; Dl = 300: không hợp lệ, vì 300 vượt giới hạn 1 byte Ví dụ 2: Giả sử DI = 100; Ô nhớ tại địa chỉ offset 100 trong đoạn nhớ Data (được chỉ bởi DS) chứa kí tự B. Thì : Mov Ax, DI ; (1) đặt giá trị thanh ghi DI vào thanh ghi Ax: Ax = 100 Mov Ax, [DI] ; (2) Ax = . Tức là, đặt nội dung của ; ô nhớ được chỉ bởi DI vào thanh ghi Ax: Ax = 41h Hãy phân biệt sự khác nhau giữa hai lệnh trên: Lệnh (1) sử dụng chế độ địa chỉ thanh ghi. Lệnh (2) sử dụng chế độ địa chỉ gián tiếp thanh ghi. Nhớ lại rằng: Trong chế độ địa chỉ gián tiếp thanh ghi, các thanh ghi chỉ có thể là BX, DI, SI (địa chỉ đoạn chứa trong DS) hay BP (địa chỉ đoạn chứa trong SS). Như vậy lệnh (2) tương đương với lệnh (3) nhưng khác lệnh (4): Mov Ax, DS:[DI] ; (3) Mov Ax, ES:[DI] ; (4) Ví dụ 3: Mov Ax, [SI] ; đặt nội dung ô nhớ được chỉ bởi SI vào thanh ghi Ax Mov [DI], Bx ; đặt giá trị của thanh ghi bx vào ô nhớ được chỉ bởi DI Mov [DI], [SI] ; [DI] ß [SI] : lệnh không hợp lệ, vì: không thể chuyển ; nội dung của ô nhớ vào một ô nhớ một cách trực tiếp Mov Var1, Ax ; Var1 ß Ax : đặt giá trị t/ghi Ax vào biến word Var1 Chú ý: Lệnh Mov không làm ảnh hưởng đến các cờ. Mov DS:[DI], ES:[SI] ; lệnh không hợp lệ, vì: không thể chuyển dữ liệu ; trực tiếp giữa hai toán hạng bộ nhớ với nhau Mov DS, ES ; DS ß ES: lệnh không hợp lệ, Mov ES, 0100 ; lệnh không hợp lệ, vì: không thể chuyển ; trực tiếp một hằng số vào thanh ghi đoạn. Để chuyển giá trị của hai thanh ghi đoạn hay nội dung của hai ô nhớ ta có thể mượn một thanh ghi đa năng làm trung gian: Mov Ax, ES ; hai lệnh này chuyển nội dung của thanh ghi đoạn ES Mov DS, Ax ; vào thanh ghi đoạn DS thông qua thanh ghi Ax Phạm Trung Minh – Khoa CNTT 32
  40. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Theo cách thông thường, để hoán đổi giá trị của hai thanh ghi đoạn hay nội dung của hai ô nhớ người ta thường sử dụng hai thanh ghi đa năng làm trung gian: Mov Ax, [DI] ; lưu tạm nội dung ô nhớ được chỉ bởi DI và Ax Mov Bx, [SI] ; lưu tạm nội dung ô nhớ được chỉ bởi SI và Bx Mov [DI], Bx ; chuyển giá trị của t/ghi Bx và ô nhớ được chỉ bởi DI Mov [SI], Ax ; chuyển giá trị của t/ghi Ax và ô nhớ được chỉ bởi SI Bốn lệnh trên có tác dụng hoán đổi nội dung của hai ô nhớ trong đoạn Data (DS) được chỉ bởi DI và SI (DI và SI chứa địa chỉ Offset của các ô nhớ). Không thể dùng thanh ghi đoạn CS làm [Toán hạng đích] trong lệnh Mov. 4.3.2. Lệnh LE (LoadEffective ddress) Cú pháp: LEA [Toán hạng đích],[Toán hạng nguồn] Trong đó: [Toán hạng đích]: Là các thanh ghi 16 bít. [Toán hạng nguồn]: Là địa chỉ của một vùng nhớ hay tên của một biến. Tác dụng: Lệnh LEA có tác dụng chuyển địa chỉ offset của [Toán hạng nguồn] vào [Toán hạng đích]. Lệnh này thường được sử dụng để lấy địa chỉ offset của một biến đã được khai báo trong chương trình. Thanh ghi được sử dụng trong trường hợp này là thanh ghi cơ sở (BX) và thanh ghi chỉ mục (SI và DI). Ví dụ 1: Lea Bx, DS:[0100] ; chuyển thành phần địa chỉ offset (0100) vào Bx Lea DI, XauKT ; chuyển địa chỉ offset của biến XauKT vào DI ; thao tác này thường được gọi là trỏ DI và đầu ; biến XauKT Khi chương trình được nạp vào bộ nhớ để hoạt động thì các biến được khai báo trong chương trình sẽ được định vị (cấp phát vùng nhớ) tại một địa chỉ xác định trong vùng nhớ Data. Từ đây, để thao tác đến dữ liệu trên các biến của chương trình thì chương trình phải xác định được địa chỉ segment vào offset (hai thành phần của địa chỉ logic) của biến. Lệnh LEA ở trên chỉ lấy được địa chỉ offset của biến, để lấy được địa chỉ segment của nó ta có thể sử dụng lệnh Mov với toán tử Seg (tương tự có thể sử dụng lệnh Mov với toán tử Offset để lấy địa chỉ offset của biến). Ví dụ: Các lệnh sau lấy địa chỉ Segment:Offset của biến XauKT (hay trỏ DS:SI về đầu biến XauKT): Mov Ax, Seg XauKT ; đưa địa chỉ Segment của biến XauKT Mov DS, Ax ; vào thanh ghi DS Mov SI, Offset XauKT ; đưa địa chỉ Offset của biến XauKT vào SI Ví dụ 2: Giả sử biến TenGom (là biến kiểu byte) đã được khai báo như sau: TenGom DB „Nguyen Kim Le Tuan’ Xem các lệnh sau đây (1): Mov Bx, 0 Mov Al, TenGom[Bx] ; Al =„N‟ Add Bx, 7 ; Mov Bl, TenGom[Bx] ; Bl =„K‟ Xem các lệnh sau đây (2): Lea DI, TenGom Mov Al, [DI] ; Al =„N‟ Mov Bl, [DI + 7] ; Bl =„K‟ Ta có thể thấy, nhóm các lệnh (1) và nhóm các lệnh (2) là tương đương nhau về tác dụng của nó, nhưng (1): sử dụng trực tiếp tên biến để truy xuất đến các phần tử của nó; (2): sử dụng thanh ghi chỉ mục DI để truy xuất đến các phần tử của biến. Trong trường hợp này địa chỉ segment mặc định được chỉ bởi DS, điều này phù hợp với việc sử dụng địa chỉ gián tiếp thanh ghi chỉ mục. Ví dụ 3: Giả sử tại địa chỉ 0100:0C00 trong bộ nhớ có chứa một xâu kí tự gồm 50 kí tự (tức là, gồm 50 ô nhớ, mỗi ô 1 byte). Hãy copy xâu kí tự này vào một biến trong chương trình. Phạm Trung Minh – Khoa CNTT 33
  41. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Với yêu cầu này chương trình phải khai báo một biến byte có độ lớn 50 byte: LuuTru DB 50 Dup („ „) Mov Ax, 0100 Mov DS, Ax ; trỏ cặp thanh ghi DS:SI về Mov SI, 0C00 ; đầu vùng nhớ chưa xâu cần copy (0100:0C00) ; Mov Ax, Seg LuuTru ; trỏ cặp thanh ghi ES:DI về Mov ES, Ax ; đầu biến LuuTru Lea DI, LuuTru ; Mov Cx, 50 Lap_Copy: Mov Bh, DS:[SI] ; mượn Bh để chuyển tường kí tự từ ô nhớ được Mov ES:[DI], Bh ; chỉ bởi DS:SI sang ô nhớ được chỉ bởi ES:DI Inc SI ; chuyển đến kí tự tiếp theo Inc DI Loop Lap_Copy ; lặp lại đủ 50 lần (để copy đủ 50 kí tự) Chú ý: Hợp ngữ còn cung cấp các lệnh LDS (Load Pointer use DS) để lấy nội dung toán hạng bộ nhớ 32 bít đưa vào các thanh ghi 16 bít (mặc định 16 bít cao vào thanh ghi đoạn dữ liệu DS); và lệnh LES (Load Pointer use DS) tương tự LDS nhưng mặc định 16 bít cao vào thanh ghi đoạn dữ liệu (thứ hai) ES [2 - 137]. 4.3.3. Lệnh chuy n dữ liệu qua c ng IN và OUT Cú pháp: IN AL, OUT , AL Trong đó: chính là số hiệu cổng (port) mà lệnh nhận nhiệm vụ trao đổi dữ liệu qua nó. Địa chỉ cổng có thể được ghi trực tiếp dưới dạng một hằng số hoặc được ghi thông qua thanh ghi Dx. Tác dụng: - LênhIn (Input): Đọc một lượng dữ liệu 8 bít từ cổng được chỉ ra ở đưa vào lưu trữ trong thanh ghi AL. Nếu địa chỉ cổng nằm trong giới hạn từ 0 đến FF (hệ thập lục phân) thì có thể viết trực tiếp trong câu lệnh, nếu địa chỉ cổng lớn hơn FF thì ta phải dùng thanh ghi Dx để chỉ định địa chỉ cổng. - LệnhOut (Output): Gởi một lượng dữ liệu 8 bít từ thanh ghi AL ra cổng được chỉ ra ở . Tương tự lệnh In, địa chỉ cổng có thể được viết trực tiếp trong câu lệnh hoặc thông qua thanh ghi Dx. Ví dụ 1: In Al, 40h ; Mov Dx, 3B0h ; In Al, Dx ; Ví dụ 2: Out 40h, Al ; Mov Dx, 3B0h ; Out Dx, Al ; Ví dụ 3: Các khai báo hằng: DAT EQU 13h ; POR EQU 7Ch ; Các lệnh: Mov Al, POR ; Mov Bl, DAT ; Phạm Trung Minh – Khoa CNTT 34
  42. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Out Bl, Al ; 4.4. Nhóm lệnh tính toán số học 4.4.1. Lệnh cộng ADD-Add ( cộng 2 toán hạng). Viết lệnh: ADD Đích, Gốc. Mô tả: Đích - Đích + Gốc. Tróng đó toán hạng đích và gốc có thể tìm được theo các chế độ địa chỉ khác nhau. Nhưng phải chứa dữ liệu có cùng độ dài và không được phép đồng thời là 2 ô nhó và cũng không được là thanh ghi đoạn. Có thể tham khảo các ví dụ của lệnh ADC. Cập nhật: AF, CF, PF, SF, ZP Inc-Increment Destination Register or Memory ( tăng toán hạng đích thêm 1 ). Viết lệnh : Inc-Đích Mô tả: Đích <- Đích+1. Trong đó toán hạng đích có thể tìm được theo các chế độ địa chỉ khác nhau. Lưu ý là nếu đích = FFH ( hoặc FFFFH ) thì Đích+1 = 00H (0000H ) mà không ảnh hưởng đến cờ CF. Lệnh này cho kết quả tương đương như lệnh ADD Đích.1.nhưng chạy nhanh hơn. Cập nhật: AF, OF, PF, SF, ZP. Không tác động: CF. 4.4.1. Lệnh trừ SUB - Substract ( trừ hau toán hạng) Viết lệnh : SUB Đích,Gốc. Mô tả : Đích  Đích - Gốc Trong đó toán hạng đích và gốc có thể tìm được theo các chế độ địa chỉ khác nhau, nhưng phải chứa dữ liệu có cùng độ dài và không được phép đồng thời là 2 ô nhớ và cũng không được là thanh ghi đoạn. Có thể tham khảo các ví dụ của lệnh SBB. Cập nhật : AF, CF, OF, PF, SF, ZP ( AF và PF chỉ liên quan đến 8 bit thấp). DEC – Decrement Destination Register or Memory ( Giảm toán hạng đi 1 ). Viết lệnh : DEC Destination Mô tả: Đích – Đích -1. Trong đó toán hạng đích có thể tìm đựoc thưo các chế độ địa chỉ khác nhau. Lưu ý là nếu Đích = 00H ( hoặc 0000H ) thì Đích -1 = FFH ( hoặc FFFFH ) mà không làm ảnh hưởng đến cờ CF. Lệnh này cho kết quả tương đương như lệnh SUB Đích nhưng chạy nhanh hơn. Cập nhật: AF, OF, PF, SF, ZP. Không tác động: CF/ 4.4.3. Lệnh nhân MUL - Multiply Unisigned Byte or Word (nhân số không dấu) Viết lệnh : MUL Gốc Trong đó toán hạng Gốc là số nhân và có thể tìm được theo các chế độ địa chỉ khác nhau. Mô tả : tuỳ theo độ dài của toán hạng Gốc ta có 2 trường hợp tổ chức phép nhân, chỗ để ngầm định cho số bị nhân và kết quả : o nếu Gốc là số 8 bit : AL Gốc, số bị nhân phải là số 8 bit để trong AL. sau khi nhân : AX  tích, Phạm Trung Minh – Khoa CNTT 35
  43. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam o nếu Gốc là số 16 bit : AX Gốc, số bị nhân phải là số 16 bit để trong AX. sau khi nhân : DXAX  tích. Nếu byte cao (hoặc 16 bit cao) của 16 (hoặc 32) bit kết quả chứa 0 thì CF=OF=0 Như vậy các cờ CF và OF sẽ báo cho ta biết có thể bỏ đi bao nhiêu số 0 trong kết quả. Ví dụ : Nếu ta cần nhân một số 8 bit với một số 16 bit , ta để số 16 bit tại Gốc và số 8 bit ở AL. Số 8 bit này ở AL cần phải được mở rộng sang AH bằng cách gán AH=0 để làm cho số bị nhân nằm trong AX. Sau cùng chỉ việc dùng lệnh MUL Gốc và kết qur có trong cặp DXAX. Cập nhật : CF, OF. Không xác định : AF, PF, SF, ZP. 4.4.4. Lệnh chia DIV – Unsingned Divide ( chia 2 số không có dấu ) Viết lệnh: DIV Gốc Trong đó toán hạng Gốc là số chia và có thể tìm được theo các chế độ địa chỉ khác nhau. Mô tả: tuỳ theo độ dài của toán hạng gốc ta có 2 trường hợp bố trí phép chia. Các chỗ để ngầm định cho số bị chia và kết quả: o Nếu Gốc là số 8 bit: AX/Gốc. Số bị chia phải là số không dấu 16 bit để trong AX. Kết quả phần thương lưu trong AL, phần dư lưu trong AH. o Nếu Gốc là số 16 bit: DXAX/Gốc. Số bị chia phải là số không dấu 32 bit để trong cặp thanh ghi DXAX. Kết quả phần thương lưu trong AX, phần dư lưu trong DX. Nếu thương không phải là số nguyên nó được làm tròn theo số nguyên sát đuôi. Nếu Gốc = 0 hoặc thương thu được lớn hơn FFH hoặc FFFFH ( tuỳ theo độ dài của toán hạng Gốc ) thì 8088 thực hiện lệnh ngắt INT 0. Không xác định: AF, CF, OF, PF, SF, ZP. 4.5. Nhóm lệnh chuyển điều khiển 4.5.1. Lệnh nhẩy không có điều kiện JMP - Unconditinal Jump to specified Destination (Nhảy không điều kiện đến một đích nào đó). Lệnh này khiến cho bộ vi xử lý 8088 bắt đầu thực hiện một lệnh mới tại địa chỉ được mô tả trong lệnh. Lệnh này có các chế độ địa chỉ giống như lệnh Call và nó cũng phân biệt nhảy xa và nhảy gần. Tuỳ thuộc vào độ dài của bước nhảy chúnh ta phân biệt 5 kiểu lệnh nhảy khác nhau : 3 kiểu nhảy gần và 2 kiểu nhảy xa với độ dài lệnh khác nhau. Mỗi ô trên các lệnh tương ứng một byte dùng để ghi lệnh. Như vậy lệnh nhảy có độ dài từ 2 đến 5 byte. Viết lệnh : sau đây là các dạng lệnh nhảy không điều kiện : JMP NHAN Lệnh mới bắt đầu tại địa chỉ ứng với nhãn NHAN. Chương trình dịch sẽ căn cứ vào khoảng dịch giữa nhãn và lệnh nhảy để xác định xem đó là : + nhảy ngắn (short jump) Trong trường hợp này nhãn NHAN phải nằm cách xa (dịch đi một khoảng nhiều nhất là -128 + 127 byte so với lệnh tiếp theosau lệnh JMP. Chương trình dịch sẽ căn cứ vào vị trí NHAN để xác định giá trị dịch chuyển mở rộng dấu cho nó. Sau đó IP  IP + Dịchchuyển Đây là lệnh nhảy trợc tiếp vì dịch chuyển được để trực tiếp trong mã lệnh. Phạm Trung Minh – Khoa CNTT 36
  44. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Để định hướng cho chương trình dịch làm việc nên viết lệnh dưới dạng : JMP SHORT NHAN + nhảy gần (near jump) Trong trường hợp này nhãn NHAN phải nằm cách xa (dịch đi một khoảng nhiều nhất là -32768 + 32767 byte so với lệnh tiếp theosau lệnh JMP. Chương trình dịch sẽ căn cứ vào vị trí NHAN để xác định giá trị dịch chuyển mở rộng dấu cho nó. Sau đó IP  IP + Dịchchuyển Đây là lệnh nhảy trợc tiếp vì dịch chuyển được để trực tiếp trong mã lệnh. Để định hướng cho chương trình dịch làm việc nên viết lệnh dưới dạng : JMP NEAR NHAN + nhảy xa (far jump) Trong trường hợp này NHAN nằm ở đoạn mã khác so với lệnh tiếp theo sau lệnh JMP. Chương trình dịch sẽ căn cứ vào vị trí NHAN để xác định giá trị địa chỉ nhảy đến (CS:IP của NHAN). Sau đó Nhảy ngắn : IP  IP của NHAN CS  CS của NHAN Đây là lệnh nhảy trực tiếp vì địa chỉ nhảy đến được để trực tiếp trong mã lệnh. Để định hướng cho chương trình dịch làm việc nên viết lệnh dưới dạng : JMP FAR NHAN NHAN trong trường hợp này phải được khai là NHAN LABEL FAR JMP BX Đây là lệnh nhảy gần ứng với trường hợp b) hình 3.8, trước đó BX phải chứa địa chỉ lệch của lệnh định nhảy đến trong đoạn CS. Khi thực hiện lệnh này : IP  BX Đây cũng là lệnh nhảy gián tiếp vì địa chỉ lệch nằm trong thanh ghi. Để định hướng cho chương trình dịch làm việc nên viết lệnh dưới dạng : JMP NEAR PTR BX JMP [BX] Đây là lệnh nhảy gần ứng với trường hợp e) hình 3.8, IP mới được lấy từ nội dung 2 ô nhớ do BX và BX+1 chỉ ra trong đoạn DS 4.5.2. Lệnh so sánh CMP-Compare Byte or Word *~( so sánh 2 byte hay 2 từ ). Viết lệnh: CMP Đích, Gốc. Mô tả: Đích – Gốc. Trong đó toán hạng đích và gốc có thể tìm được theo các chế độ địa chỉ khác nhau. Nhưng phải chứa dữ liệu có cùng độ dài và không được phép đồng thời là 2 ô nhớ. Lệnh này chỉ tạo các cờ, không lưu kết quả so sanh, sau khi so sanh các toán hạng không bị thay đổi. Lệnh này thường được dùng để tạo cờ cho các lệnh nhảy có điều kiện (nhảy theo cờ). Các cờ chính theo quan hệ đích và gốc khi so sánh 2 số không dấu: CF 2F Đích = Gốc 0 1 Đích > Gốc 0 1 Phạm Trung Minh – Khoa CNTT 37
  45. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Đích > Gốc 1 0 Cập nhật: AF, CF, OF, PF, SF, ZP. 4.5.3. Lệnh nhẩy có điều kiện Viết lệnh: J shortlabel Giải thích : Nếu thỏa điều kiện thì nhảy tương đối IP  địa chỉ lệnh kế + độ dời (mở rộng dấu 16 bit) ngược lại không làm gì cả (qua lệnh kế). Lệnh nhảy có điều kiện dùng trạng thái các cờ để làm điều kiện. Mã lệnh Giải thích Điều kiện JE/JZ Nhảy nếu bằng/không ZF = 1 JL/JNGE Nhảy nếu nhỏ hơn/không lớn hơn hoặc bằng SF xor OF = 1 JLE/JNG Nhảy nếu nhỏ hơn hoặc bằng /không lớn hơn SF xor OF or ZF = 1 JB/JNAE/JC Nhảy nếu dưới /không trên hoặc bằng/nhớ CF = 1 JBE/JNA Nhảy nếu dưới hoặc bằng /không trên CF or ZF = 1 JP/JPE Nhảy nếu kiểm tra / kiểm tra chẳn PF = 1 JO Nhảy nếu tràn OF = 1 JS Nhảy nếu dấu SF = 1 JNE/JNZ Nhảy nếu không bằng/khác không ZF = 0 JNL/JGE Nhảy nếu không nhỏ hơn/lớn hơn hoặc bằng SF xor OF = 0 JNLE/JG Nhảy nếu không nhỏ hơn hoặc bằng /lớn hơn SF xor OF or ZF = 0 JNB/JAE/JNC Nhảy nếu không dưới /trên hoặc bằng/không nhớ CF = 0 JNBE/JA Nhảy nếu không dưới hoặc bằng /trên CF or ZF = 0 JNP/JPO Nhảy nếu không kiểm tra / kiểm tra lẻ PF = 0 JNO Nhảy nếu không tràn OF = 0 JNS Nhảy nếu không dấu SF = 0 4.5.4. Lệnh lặp LOOP - Jump to Sspecified Label if CX 0 after Autodecrement (lặp lại đoạn chương trình do nhãn chỉ ra cho đến khi CX=0) Viết lệnh : LOOP NHAN Lệnh này dùng để lặp lại đoạn chương trình (gồm các lệnh nằm trong khoảng từ nhãn NHAN đến hết lệnh LOOP NHAN) cho đến khi số lần lặp CX=0. điều này có nghĩa là trước khi vào vòng lặp ta phải đưa số lần lặp mong muốn vào thanh ghi CX và sau mỗi lần thực hiện lệnh LOOP NHAN thì đồng thời CX tự động giảm đi một (CX CX-1). Nhãn NHAN phải nằm cách xa (dịch đi một khoảng) -128 byte so với lệnh tiếp theo sau lệnh LOOP. Lệnh này không tác động đến các cờ. Ví dụ : XOR AL, AL ; xoá AL MOV CX,16 ; số lần lặp để tại CX LAP: INC AL ; tăng AL thêm 1 LOOP LAP ; lặp lại 16 lần, AL = 16 4.6. Nhóm lệnh Logic 4.6.1. Lệnh nd AND-And Corresponding Bits of Two Operands ( Và 2 toán hạng ) Viết lệnh: AND Đích, Gốc Mô tả: Đích = and(Đích, Gốc) Phạm Trung Minh – Khoa CNTT 38
  46. Bài giảng Kỹ thuật Vi xử lý – Khoa CNTT – ĐHHH Việt Nam Trong đó toán hạng đích và gốc có thể tìm được ther các chế độ địa chỉ khác nhau. Nhưng phải chứa dữ liệu cùng độ dài và không được phép đồng thời là 2 ô nhớ và cũng không được là thanh ghi đoạn. Phép AND thường dùng để che đi/ giữ lại một vài bit nào đó của một toán hạng bằng cách nhân logic toán hạng đó với toán hạng tức thì có các bit 0/1 ở các chỗ cần che đi/giữ nguyên tương ứng ( toán hạng tức thì lúc này còn được gọi là mặt nạ ). Xoá: CF, OF. Cập nhật: PF, SF, ZP, PF chỉ có nghĩa khi toán hạng là 8 bit. Không xác định: À. Ví dụ: AND AL, BL ; AL , AL BL theo từng bit. AND OFH ; che 4 bit cao của BL. 4.6.2. Lệnh OR OR - Logically Or Corresponding Bits of Two Operands (hoặc hai toán hạng) Viết lệnh : OR Đích,Gốc Mô tả : Đích  Đích v Gốc Trong đó toán hạng đích và gốc có thể tìm được theo các địa chỉ khác nhau, nhưng phải chứa dữ liệu cùng độ dài và không được phép đồng thời là 2 ô nhớ và cũng không được là thanh ghi đoạn. Phép OR thường dùng để lập một vài bit nào đó của toán hạng bằng cách cộng loogic toán hạng đó với toán hạng tức thời có các bit 1 tại các vị trí tương ứng cần thiết lập. Xóa : CF,OF. Cập nhật : PF, SF, ZP,PF. Chỉ có nghĩa khi toán hạng là 8 bit. Không xác định : AF. Ví dụ : OR AL, BL ; AL  AL v BL theo từng bit OR BL, 30H ; lập bit b4 và b5 của BL lên 1. 4.6.3. Lệnh XOR XOR - Exclusive Or Corresponding Bits of two Operands ( hoặc loại trừ hai toán hạng) Viết lệnh : XOR Đích,Gốc Mô tả : Đích  Đích  Gốc Trong đó toán hạng đích và gốc có thể tìm được theo các chế độ địa chỉ khác nhau, nhưng phải chứa dữ liệu có cùng độ dài và không được phép đồng thời là 2 ô nhớ và cũng không được là thanh ghi đoạn. Từ tính chất của phép hoặc loại trừ ta thấy nếu toán hạng đích trùng với toán hạng gốc thì kết quả bằng 0, do đó lệnh này còn được dùng để xoá về 0 một thanh ghi nào đó và kèm theo các cờ CF và OF cũng bị xoá. Cập nhật : PF, SF, ZP, PF chỉ có nghĩa khi toán hạng là 8 biit. Không xác định : AF. Ví dụ : XOR AL,BL ; AL  AL  BL theo từng bit một XOR BH,BH ; xoá BH, xoá CF và OF. 4.6.4. Lệnh NOT NOT - Invert Each Bit of an Operand (Form its 1’s complement) (lấy bù của một toán hạng, đảo bit của một toán hạng). Viết lệnh : NOT Đích Phạm Trung Minh – Khoa CNTT 39