Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 43 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
43
Dung lượng
242,92 KB
Nội dung
Chương : CƠ BẢN VỀ HỢP NGỮ Trong chương giới thiệu nguyên tắc chung để tạo , dịch chạy chương trình hợp ngữ máy tính Cấu trúc ngữ pháp lệnh hợp ngữ giáo trình trình bày theo Macro Assembler ( MASM) dựa CPU 8086 1.1 Cú pháp lệnh hợp ngữ • • Một chương trình hợp ngữ bao gồm loạt mệnh đề ( statement) viết liên tiếp , mệnh đề viết dịng Một mệnh đề : lệnh ( instruction) : trình biên dịch ( Assembler =ASM) chuyển thành mã máy dẫn Assembler ( Assembler directive) : ASM không chuyển thành mã máy Các mệnh đề ASM gồm trường : Name Operation Operand(s) Comment trường cách ký tự trống ký tự TAB ví dụ lệnh đề sau : START : MOV CX,5 ; khơỉ tạo ghi CX Sau dẫn ASM : MAIN PROC ; tạo thủ tục có tên MAIN 1.1.1 Trường Tên ( Name Field) Trường tên dùng cho nhãn lệnh , tên thủ tục tên biến ASM chuyển tên thành địa nhớ Tên dài từ đến 31 ký tự Trong tên chứa ký tự từ a-z , số ký tự đặc biệt sau : ? ,@ , _ , $ dấu Không phép có ký tự trống phần tên Nếu tên có ký tự phải ký tự Tên không bắt đầu số ASM không phân biệt ký tự viết thường viết hoa Sau ví dụ tên hợp lệ khơng hợp lệ ASM Tên hộp lệ Tên không hợp lệ COUNTER1 TWO WORDS @CHARACTER 2ABC SUM_OF_DIGITS A45.28 DONE? YOU&ME TEST ADD-REPEAT 1.1.2 Trường toán tử ( operation field) Đối với lệnh trường toán tử chưá ký hiệu ( sumbol) mã phép toán ( operation code = OPCODE) ASM chuyển ký hiệu mã phép toán thành mã máy Thơng thường ký hiệu mã phép tốn mơ tả chức phép tốn , ví dụ ADD , SUB , INC , DEC , INT Đối với dẫn ASM , trường toán tử chưá opcode giả (pseudo operation code = pseudo-op) ASM không chuyển pseudo-op thành mã máy mà hướng dẫn ASM thực việc ví dụ tạo thủ tục , định nghĩa biến 1.1.3 Trường toán hạng ( operand(s) field) Trong lệnh trường toán hạng số liệu tham gia lệnh Một lệnh khơng có tốn hạng , có tốn hạng Ví dụ : NOP ; khơng có tốn hạng INC AX ; toán hạng ADD WORD1,2 ; toán hạng cộng với nội dung từ nhớ WORD1 Trong lệnh toán hạng toán hạng đầu tốn hạng đích ( destination operand) Tốn hạng đích thường làthanh ghi vị trí nhớ dùng để lưu trữ kết Toán hạng thứ hai toán hạng nguồn Tốn hạng nguồn thường khơng bị thay đổi sau thực lệnh Đối với dẫn ASM , trường toán hạng chứa nhiều thông tin mà ASM dùng để thực thi dẫn 1.1.4 Trường thích ( comment field) Trường thích tuỳ chọn mệnh đề ngơn ngữ ASM Lập trình viên dùng trường thích để thuyết minh câu lệnh Điều cần thiết ngơn ngữ ASM ngơn ngữ cấp thấp ( low level) khó hiểu chương trình khơng thích cách đầy đủ rỏ ràng Tuy nhiên khơng nên có thích dịng chương trình , kể nnhững lệnh mà ý nghĩa rỏ ràng : NOP ; không làm chi Người ta dùng dấu chấm phẩy (;) để bắt đầu trường thích ASM cho phép dùng tồn dịng cho thích để tạo khoảng trống ngăn cách phần khác cuả chương trình ,ví dụ : ; ; khởi tạo ghi ; MOV AX,0 MOV BX,0 1.2 Các kiểu số liệu chương trình hợp ngữ CPU làm việc với số nhị phân Vì ASM phải chuyển tất loại số liệu thành số nhị phân Trong chương trình hợp ngữ cho phép biểu diễn số liệu dạng nhị phân , thập phân thập lục phân chí ký tự nửa 1.2.1 Các số Một số nhị phân dãy bit va 2phải kết thúc h H Một số thập phân dãy chữ só thập phân kết thúc d D ( khơng cần) Một số hex phải bắt đầu chữ số thập phân phải kết thúc h H Sau biểu diễn số hợp lệ không hợp lệ ASM : Số Loại 10111 thập phân 10111b nhị phân 64223 thập phân -2183D thập phân 1B4DH hex 1B4D số hex không hợp lệ FFFFH số hex không hợp lệ 0FFFFH số hex 1.2.2 Các ký tự Ký tự chuỗi ký tự phải đóng hai dấu ngoặc đơn hai dấu ngoặc kép Ví dụ ‘A’ “HELLO” Các ký tự chuyển thành mã ASCII ASM Do chương trình ASM xem khai báo ‘A’ 41h ( mã ASCII A) giống 1.3 Các biến ( variables) Trong ASM biến đóng vai trị ngơn ngữ cấp cao Mỗi biến có loại liệu gán địa nhớ sau dịch chương trình Bảng sau liệt kê toán tử giả dùng để định nghĩa loại số liệu PSEUDO-OP STANDS FOR DB define byte DW define word ( doublebyte) DD define doubeword ( từ liên tiếp) DQ define quadword ( từ liên tiếp ) DT define tenbytes ( 10 bytes liên tiếp) 1.3.1 Biến byte Chỉ dẫn ASM để định nghĩa biến byte có dạng sau : NAME DB initial_value Ví dụ : ALPHA DB Chỉ dẫn gán tên ALPHA cho byte nhớ nhớ mà giá trị ban đầu Nếu giá trị byte không xác định đặt dấu chấm hỏi ( ?) vào giá trị ban đầu Ví dụ : BYT DB ? Đối với biến byte vùng giá trị mà lưu trữ -128 đến 127 số có dấu đến 255 số không dấu 1.3.2 Biến từ Chỉ dẫn ASM để định nghĩa biến từ sau : NAME DW initial_value Ví dụ : WRD DW -2 Cũng dùng dấu ? để thay cho biến từ có giá trị khơng xác định Vùng giá trị biến từ -32768 đến 32767 số có dấu đến 56535 số không dấu 1.3.3 Mảng ( arrays) Trong ASM mảng loạt byte nhớ từ nhớ liên tiếp Ví dụ để định nghĩa mảng byte gọi B_ARRAY mà giá trị ban đầu 10h,20h 30h viết : B_ARRAY DB 10h,20h,30h B_ARRAY tên gán cho byte B_ARRAY+1 tên byte thứ hai B_ARRAY+2 tên byte thứ ba Nếu ASM gán địa offset 0200h cho mảng B_ARRAY nội dung nhớ sau : SYMBOL ADDRESS CONTENTS B_ARRAY 200h 10h B_ARRAY+1 201h 20h B_ARRAY+2 202h 30h Chỉ dẫn sau định nghĩa mảng phần tử có tên W_ARRAY: W_ARRAY DW 1000,40,29887,329 Giả sử mảng bắt đầu 0300h nhớ sau: SYMBOL ADDRESS CONTENTS W_ARRAY 300h 1000d W_ARRAY+2 302h 40d W_ARRAY+4 304h 29887d W_ARRAY+6 306h 329d Byte thấp byte cao từ Đôi cần truy xuất tới byte thấp byte cao biến từ Giả sử định nghĩa : WORD1 DW 1234h Byte thấp WORD1 chứa 34h , byte cao WORD1 chứa 12h Ký hiệu địa byte thấp WORD1 ký hiệu địa byte cao WORD1+1 Chuỗi ký tự ( character strings) Một mảng mã ASCII định nghĩa chuỗi ký tự Ví dụ : LETTERS DW 41h,42h,43h tương đương với LETTERS DW ‘ABC ’ Bên chuỗi , ASM phân biệt chữ hoa chữ thường Vì chuỗi ‘abc’ chuyển thành bytes : 61h ,62h 63h Trong ASM tổ hợp ký tự số định nghĩa Ví dụ : MSG DB ‘HELLO’, 0AH, 0DH, ‘$’ tương đương với MSG DB 48H,45H,4CH,4Ch,4FH,0AH,0DH,24H 1.4 Các ( constants) Trong chương trình đặt tên nhờ dẫn EQU (equates) Cú pháp EQU : NAME EQU constant ví dụ : LF EQU 0AH sau có khai báo LF dùng thay cho 0Ah chương trình Vì ASM chuyễn lệnh : MOV DL,0Ah MOV DL,LF thành mã máy Cũng dùng EQU để định nghĩa chuỗi , ví dụ: PROMPT EQU ‘TYPE YOUR NAME ’ Sau có khai báo , thay cho MSG DB ‘TYPE YOUR NAME ’ viết MSG DB PROMPT 1.5 Các lệnh CPU 8086 có hàng trăm lệnh , chương ,chúng ta xem xét lệnh đơn giản 8086 mà chúng thường dùng với thao tác di chuyển số liệu thực phép toán số học Trong phần sau , WORD1 WORD2 biến từ , BYTE1 BYTE2 biến byte 1.5.1 Lệnh MOV XCHG Lệnh MOV dùng để chuyển số liệu ghi , ghi vị trí nhớ để di chuyển trực tiếp số đến ghi vị trí nhớ Cú pháp lệnh MOV : MOV Destination , Source Sau vài ví dụ : MOV AX,WORD1 ; lấy nội dung từ nhớ WORD1 đưa vào ghi AX MOV AX,BX ; AX lấy nội dung BX , BX không thay đổi MOV AH,’A’ ; AX lấy giá trị 41h Bảng sau cho thấy trường hợp cho phép cấm lệnh MOV Destination operand source operand General Reg Segment Reg Memory Location Constant General Reg Segment Reg MemoryLocation Constant Y Y Y Y Y NO Y NO Y Y NO Y NO NO NO NO Lệnh XCHG ( Exchange) dùng để trao đổi nội dung ghi ghi vị trí nhớ Ví dụ : XCHG AH,BL XCHG AX,WORD1 ; trao đổi nội dung ghi AX từ nhớ WORD1 Cũng lệnh MOV có số hạn chế lệnh XCHG bảng sau : Destination operand Source operand General Register Memory Locatin General Memory Memory Location Y Y Y No 1.5.2 Lệnh ADD, SUB, INC , DEC Lệnh ADD SUB dùng để cộng trừ nội dung ghi , ghi vị trí nhớ , cộng ( trừ) số với (khỏi) ghi vị trí nhớ Cú pháp : ADD Destination , Source SUB Destination , Source Ví dụ : ADD WORD1, AX ADD BL , SUB AX,DX ; AX=AX-DX Vì lý kỹ thuật , lệnh ADD SUB bị số hạn chế bảng sau: Destination operand Source operand General Reg Memory Loacation Gen Memory Memory Location Constant Y Y Y Y NO Y Việc cộng trừ trực tiếp vị trí nhớ không phép Để giải vấn đề người ta phải di chuyển byte ( từ ) nhớ đến ghi sau cộng trừ ghi với byte ( từ ) nhớ khác Ví dụ: MOV AL, BYTE2 ADD BYTE1, AL Lệnh INC ( incremrent) để cộng thêm vào nội dung ghi vị trí nhớ Lệnh DEC ( decrement) để giảm bớt khỏi ghi vị trí nhớ Cú pháp chúng : INC Destination DEC Destination Ví dụ : INC WORD1 INC AX DEC BL 1.5.3 Lệnh NEG ( negative) Lệnh NEG để đổi dấu ( lấy bù ) ghi vị trí nhớ Cú pháp : NEG destination Ví dụ : NEG AX ; Giả sử AX=0002h sau thực lệnh NEG AX AX=FFFEh LƯU Ý : toán hạng lệnh phải loại ( byte từ ) 1.6 Chuyển ngôn ngữ cấp cao thành ngôn ngữ ASM Giả sử A B biến từ Chúng ta chuyển mệnh đề sau ngôn ngữ cấp cao ngôn ngữ ASM 1.6.1 Mệnh đề B=A MOV AX,A ; đưa A vào AX MOV B,AX ; đưa AX vào B 1.6.2 Mệnh đề A=5-A MOV AX,5 ; đưa vào AX SUB AX,A ; AX=5-A MOV A,AX ; A=5-A cách khác : NEG A ;A=-A ADD A,5 ;A=5-A 1.6.3 Mệnh đề A=B-2*A MOV AX,B ;Ax=B SUB AX,A ;AX=B-A SUB AX,A ;AX=B-2*A MOV A,AX ;A=B-2*A 1.7 Cấu trúc chương trình hợp ngữ Một chương trình ngơn ngữ máy bao gồm mã ( code) , số liệu ( data) ngăn xếp (stack ) Mỗi phần chiếm đoạn nhớ Mỗi đoạn chương trình chuyển thành đoạn nhớ ASM 1.7.1 Các kiểu nhớ ( memory models) Độ lớn mã số liệu chương trình quy định dẫn MODEL nhằm xác định kiểu nhớ dùng với chương trình Cú pháp dẫn MODEL sau : MODEL memory_model Bảng sau cho thấy kiểu nhớ : MODEL DESCRITION SMALL MEDIUM COMPACT LARGE HUGE code data nằm đoạn code nhiều đoạn , data đoạn data nhiều đọan , code đoạn code dayta lớn đoạn , array không qúa 64KB code ,data lớn hớn đoạn , array lớn 64KB 1.7.2 Đoạn số liệu Đoạn số liệu chương trình chưá khai báo biến , khai báo Để bắt đầu đoạn số liệu dùng dẫn DATA với cú pháp sau : DATA ;khai báo tên biến , mãng ví dụ : DATA WORD1 DW WORD2 DW MSG DB ‘THIS IS A MESSAGE ’ MASK EQU 10010010B 1.7.3 Đoạn ngăn xếp Mục đích việc khai báo đoạn ngăn xếp dành vùng nhớ ( vùng satck) để lưu trữ cho stack Cú pháp lệnh sau : STACK size khơng khai báo size 1KB dành cho vùng stack STACK 100h ; dành 256 bytes cho vùng stack 1.7.4 Đọan mã Đoạn mã chưá lệnh chương trình Bắt đầu đoạn mã dẫn CODE sau : CODE Bên đoạn mã lệnh thường tổ chức thành thủ tục (procedure) mà cấu trúc thủ tục sau : name PROC ; body of the procedure name ENDP Sau câú trúc chương trình hợp ngữ mà phần CODE thủ tục có tên MAIN MODEL SMALL STACK 100h DATA ; định nghĩa số liệu CODE MAIN PROC ;thân thủ tục MAIN MAIN ENDP ; thủ tục khác có END MAIN 1.8 Các lệnh vào CPU thông tin với ngoại vi thông qua cổng IO Lệnh IN OUT CPU cho phép truy xuất đến cổng Tuy nhiên hầu hết ứng dụng không dùng lệnh IN OUT lý do: • địa cổng thay đổi tuỳ theo loại máy tính • lập trình cho IO dễ dàng nhờ chương trình ( routine) cung cấp hãng chế tạo máy tính Có loại chương trình phục vụ IO : routine BIOS ( Basic Input Output System) routine DOS Lệnh INT ( interrupt) Để gọi chương trình BIOS DOS dùng lệnh INT với cú pháp sau : INT interrupt_number interrupt_number số mà định routine Ví dụ INT 16h gọi routine thực việc nhập số liệu từ Keyboard 1.8.1 Lệnh INT 21h INT 21h dùng để gọi số lớn các hàm ( function) DOS Tuỳ theo giá trị mà đặt vào ghi AH , INT 21h gọi chạy routine tương ứng Trong phần quan tâm đến hàm sau : FUNCTION NUMBER ROUTINE Single key input Single character output FUNTION : Single key input Input : AH=1 Output:AL= ASCII code if character key is pressed AL=0 if non character key is pressed Để gọi routine thực lệnh sau : MOV AH,1 ; input key function INT 21h ; ASCII code in AL and display character on the screen FUNTION : Display a character or execute a control function Input : AH=2 DL=ASCII code of the the display character or control character Output:AL= ASCII code of the the display character or control character Các lệnh sau in lên hình dấu ? MOV AH,2 MOV DL,’?’ ; character is ‘?’ INT 21H ; display character Hàm dùng để thực chức điều khiển Nếu DL chưá ký tự điều khiển gọi INT 21h , ký tự điều khiển thực Các ký tự điều khiển thường dùng : ASCII code (Hex) SYMBOL FUNCTION BEL beep BS backspace HT tab A LF line feed D CR carriage return 1.9 Chương trình Chúng ta viết chương trình hợp ngữ nhằm đọc ký tự từ bàn phím in đầu dịng TITLE PGM1: ECHO PROGRAM MODEL SMALL STACK 100H CODE MAIN PROC ; display dấu nhắc MOV AH,2 MOV DL,’?’ INT 21H ; nhập ký tự MOV AH,1 ; hàm đọc ký tự INT 21H ; ký tự đưa vào AL MOV BL,AL ; cất ký tự BL ; nhảy đến dòng MOV AH,2 ; hàm xuất ký tự MOV DL,0DH ; ký tự carriage return INT 21H , thực carriage return MOV DL,0AH ; ký tự line feed INT 21H ; thực line feed ; xuất ký tự MOV DL,BL ; đưa ký tự vào DL INT 21H ; xuất ký tự ; trở DOS MOV AH,4CH ; hàm thoát DOS INT 21H ; exit to DOS MAIN ENDP END MAIN • • • • 1.10 Tạo chạy chương trình hợp ngữ Có bước để tạo chạy chương trình hợp ngữ : Dùng trình soạn thảo văn để tạo tập tin chương trình nguồn ( source program file ) Dùng trình biên dịch (Assembler ) để tạo tập tin đối tượng (object file) ngôn ngữ máy Dùng trình LINK để liên kết nhiều tập tin đối tượng tạo file thực thi Cho thực tập tin EXE COM Bước : Tạo chương trình nguồn Dùng trình soạn thảo văn (NC chẳng hạn) để tạo chương trình nguồn Ví dụ lất tên PGM1.ASM Phần mở rộng ASM phần mở rộng quy ước để Assembler nhận chương trình nguồn Bước :Biên dịch chương trình Chúng ta dùng MASM ( Microsoft Macro Assembler ) để chuyển tập tin nguồn PGM1.ASM thành tập tin đối tượng ngôn ngữ máy goị PGM1.OBJ lệnh sau : MASM PGM1; Sau in thông tin quyền MASM kiểm tra file nguồn để tìm lỗi cú pháp Nếu có lỗi MASM inra số dòng bị lỗi mộ tả ngắn lỗi Nếu khơng có lỗi MASM chuyển PGM1.ASM thành tậo tin đối tượng ngôn ngữ máy gọi PGM1.OBJ Dấu chấm phẩy sau lệnh MASM PGM1 có nghĩa khơng muốn tạo tập tin đối tượng có tên khác với PGM1 Nếu khơng có dấu chấm phẩy sau lệnh MASM yêu cầu gõ vào tên số tập tin mà tạo hình : Object file name [ PGM1.OBJ]: Source listing [NUL.LIST] : PGM1 Cross-reference [NUL.CRF] : PGM1 Tên NUL có nghĩa khơng tạo file tương ứng trừ lập trình viên gõ vào tên tập tin Tập tin danh sách nguồn ( source listing file) : tập tin Text có đánh số dịng , mã hợp ngữ mã nguồn nằm cạnh Tập tin thường dùng để gỡ rối chương trình nguồn MASM thơng báo lỗi theo số dịng Tập tin tham chiếu chéo ( Cross -Reference File ) : tập tin chứa danh sách tên mà chúng xuất chương trình kèm theo số dịng mà tên xuất Tập tin đưọc dùng để tìm biến nhãn chương trình lớn Bước : Liên kết chương trình Tập tin đối tượng tạo bước tập tin ngơn ngữ máy khơng chạy chưa có dạng thích hợp file chạy Hơn chưa biết chương trình nạp vào vị trí nhớ để chạy Một số địa dạng mã máy bị thiếu Trình LINK liên kết nhiều file đói tượng thành file chạy ( *.EXE ) Tập tin nạp vào nhớ thi hành Để liên kết chương trình ta gõ : LINK PGM1; Nếu khơng có dấu chấm phẩy ASM yêu câù gõ vào tên tập tin thực thi Bước : Chạy chương trình Từ dấu nhắc lệnh chạy chương trình cách gõ tên nhấn ENTER 1.11 Xuất chuỗi ký tự Trong chương trình PGM1 dùng INT 21H hàm để đọc xuất ký tự Hàm ngắt 21H dùng để xuất chuỗi ký tự INT 21H , Function : Display a string Input : DX=offset address of string The string must end with a ‘$’ character Ký tự $ cuối chuỗi không in lên hình Nếu chuỗi có chứa ký tự điều khiển chức điều khiển tương ứng thực Chúng ta viết chương trình in lên hình chuỗi “HELLO!” Thơng điệp HELLO định nghĩa sau đoạn số liệu : MSG DB ‘HELLO!$’ Lệnh LEA ( Load Effective Address ) LEA destnation , source Ngắt 21h , hàm số xuất chuỗi ký tự hình với điều kiện địa hiệu dụng biến chuỗi phải DX Có thể thực điều lệnh : LEA DX,MSG ; đưa địa offset biến MSG vào DX Program Segment Prefix ( PSP ) : Phần đầu đoạn chương trình Khi chương trình nạp vào nhớ máy tính , DOS dành 256 byte cho gọi PSP PSP chưá số thơng tin chương trình nạp nhớ Để cho chương trình truy xuất tới PSP , DOS đặt số phân đoạn (PSP) DS ES trước thực thi chương trình Kết qủa ghi DS không chứa số đoạn đoạn số liệu chương trình Để khắc phục điều , chương trình có chứa đoạn số liệu phải bắt đầu lệnh sau : MOV AX,@DATA MOV DS,AX Ở @DATA tên đoạn số liệu định nghĩa DATA Assembler chuyển @DATA thành số đoạn Sau chương trình hồn chỉnh để xuất chuỗi ký tự HELLO! TITLE PGM2: PRINT STRING PROGRAM MODEL SMALL STACK 100H DATA MSG DB ‘HELLO!$’ CODE MAIN PROC ; initialize DS MOV AX,@DATA MOV DS,AX ; display message LEA DX,MSG MOV AH,9 INT 21H ; return to DOS MOV AH,4CH INT 21H MAIN ENDP END MAIN 1.12 Chương trình đổi chữ thường sang chữ hoa Chúng ta viết chương trình yêu cầu người dùng gõ vào ký tự chữ thường Chương trình đổi sang dạng chữ hoa in dòng TITLE PGM3: CASE COVERT PROGRAM MODEL SMALL STACK 100H DATA CR EQU 0DH LF EQU 0AH MSG1 DB ‘ENTER A LOWER CASE LETTER:$’ MSG2 DB 0DH,0AH,’IN UPPER CASE IT IS :’ CHAR DB ?,’$’ ; định nghĩa biến CHAR có giá trị ban đầu chưa ;xác định CODE MAIN PROC ; INITIALIZE DS MOV AX,@DATA MOV DS,AX ;PRINT PROMPT USER LEA DX,MSG1 ; lấy thông điệp số MOV AH,9 INT 21H ; xuất hình ;nhập vào ký tự thường đổi thành ký tự hoa MOV AH,1 ; nhập vào ký tự INT 21H ; cất AL SUB AL,20H ; đổi thành chữ hoa cất AL MOV CHAR, AL ; cất ký tự biến CHAR ; xuất ký tự dòng LEA DX, MSG2 ; lấy thông điệp thứ MOV AH,9 INT 21H ; xuất chuỗi ký tự thứ hai , MSG2 khơng kết ;thúc ký tự $ nên tiếp tục xuất ký tự có biến CHAR ;dos exit MOV AH,4CH INT 21H ; dos exit MAIN ENDP END MAIN Chương : Trạng thái vi xử lý ghi cờ Trong chương xem xét ghi cờ vi xử lý ảnh hưởng lệnh máy đến ghi cờ Trạng thái ghi để chương trình thực lệnh nhảy , rẻ nhánh lặp Một phần chương giới thiệu chương trình DEBUG DOS 2.1 Các ghi cờ ( Flags register) Điểm khác biệt quan trọng máy tính so với thiết bị điện tử khác khả cho định Một mạch đặc biệt CPU làm định cách vào trạng thái hành CPU Có ghi đặc biệt cho biết trạng thái CPU ghi cờ Bảng 2.1 cho thấy ghi cờ 16 bit 8086 11 10 OF DF IF TF SF ZF AF PF CF Bảng 2.1 :Thanh ghi cờ 8086 Mục đích ghi cờ trạng thái CPU Có hai loại cờ cờ trạng thái ( status flags) cờ điều khiển (control flags) Cờ trạng thái phản ánh kết qủa thực lệnh CPU Bảng 2.2 tên ký hiệu ghi cờ 8086 Bit Name Symbol Carry flag CF Parity flag PF Auxiliary carry flag AF Zero flag ZF Sign flag SF 11 Overflow flag OF Trap flag TF Interrrupt flag IF 10 Direction flag DF Bảng 2.2 : Các cờ 8086 Mỗi bit ghi cờ phản ánh trạng thái CPU Các cờ trạng thái ( status flags) phép toán Cờ nhớ ( Carry Flag - CF) : CF=1 xuất bit nhớ (carry) từ vị trí MSB thực phép cộng có bit mượn ( borrow ) MSB thực phép trừ Trong trường hợp khác CF=0 Cờ CF bị ảnh hưởng lệnh dịch ( Shift) quay ( Rotate) số liệu Cờ chẳn lẻ ( Parity Flag - PF) : PF=1 byte thấp kết qủa có tổng số số số chẳn ( even parity) PF=0 byte thấp chẳn lẻ lẻ (old parity ) Ví dụ kết qủa FFFEh PF=0 Cờ nhớ phụ ( Auxiliary Carry Flag - AF ) :AF =1 có nhớ ( mượn) từ bit thứ phép cộng ( trừ) Cờ Zero ( Zero Flag -ZF) : ZF=1 kết qủa số Cờ dấu ( Sign Flag - SF ) : SF=1 MSB kết qủa ( kết qủa số âm ) SF=0 MSB=0 Cờ tràn ( Overflow Flag - OF ) : OF=1 xảy tràn số thực phép toán Sau phân tích trường hợp xảy tràn thực tính tốn Hiện tượng tràn số liên quan đến việc biễu diễn số máy tính với số hữu hạn bit Các số thập phân có dấu biễu diễn byte -128 đến +127 Nếu biễu diễn từ (16 bit) số thập phân biễu diễn -32768 đến +32767 Đối với số không dấu , dải số biễu diễn từ đến 65535 , byte đến 255 Nếu kết qủa phép tốn vượt ngồi dãi số biễu diễn xảy tràn số Khi có tràn số kết qủa thu bị sai 2.2 Tràn ( overflow) Có loại tràn số : Tràn có dấu ( signed overflow) tràn không dấu ( unsigned overflow) Khi thực phép cộng số học chẳng hạn phép cộng , xảy khả sau : 1) không tràn 2) tràn dấu 3) tràn không dấu 4) tràn dấu không dấu Ví dụ tràn khơng dấu phép cộng ADD AX,BX với AX=0FFFFh , BX=0001h Kết qủa dạng nhị phân : 1111 1111 1111 1111 0000 0000 0000 0001 10000 0000 0000 0000 Nếu diễn giải kết qủa dạng khơng dấu kết qủa ( 10000h=65536) Nhưng kết qủa vượt độ lớn từ nhớ Bit ( bit nhớ từ vị trí MSB ) xảy kết qủa AX =0000h sai Sự tràn tràn không dấu Nếu xem phép cộng phép cộng hai số có dấu kết qủa AX = 0000h , FFFFh = -1 , 0001h = +1 , kết qủa phép cộng Vậy trường hợp tràn dấu không xảy Ví dụ tràn dấu : giả sử AX = BX = 7FFFh , lệnh ADD AX,BX cho kết qủa sau : 0111 1111 1111 1111 0111 1111 1111 1111 1111 1111 1111 1110 = FFFE h Biễu diễn có dấu khơng dấu 7FFFh 3276710 Như phép cộng có dấu khơng dấu kết qủa 32767 + 32767 = 65534 Số này(65534) vượt ngồi dãi giá trị mà số 16 bit có dấu biễu diễn Hơn nửa FFFEh = -2 Do tràn dấu xảy Trong trường hợp xảy tràn , CPU biểu thị tràn sau : • CPU set OF =1 xảy tràn dấu • CPU set CF = xảy tràn không dấu Sau có tràn , chương trình hợp lý thực để sửa sai kết qủa Các lập trình viên phải quan tâm tới cờ OF CF biễu diễn số họ có dấu hay khơng dấu cách tương ứng Vậy làm để CPU biết có tràn ? • Tràn khơng dấu xảy có bit nhớ ( mượn ) từ MSB • Tràn dấu xảy trường hợp sau : a) Khi cộng hai số dấu , tràn dấu xảy tổng có dấu khác với hai tốn hạng ban đầu Trong ví dụ , cộng hai số 7FFFh +7FFFh ( hai số dương ) kết qủa FFFFh ( số âm) b) Khi trừ hai số khác dấu ( giống cộng hai số dấu) kết qủa phải có dấu hợp lý Nếu kết qủa cho dấu khơng mong đợi có nghĩa xảy tràn dấu Ví dụ 8000h - 0001h = 7FFFh ( số dương ) Do OF=1 Vậy làm để CPU có tràn ? • OF=1 tràn dấu • CF=1 tràn không dấu Làm để CPU biết có tràn ? • Tràn khơng dấu xảy có số nhớ ( carry) mượn ( borrow) từ MSB • Tràn dấu xảy cộng hai số dấu ( trừ số khác dấu ) mà kết qủa với dấu khác với dấu mong đợi Phép cộng hai số có dấu khác xảy tràn Trên thực tế CPU dùng phương pháp sau : cờ OF=1 số nhớ vào số nhớ từ MSB khơng phù hợp : nghĩa có nhớ vào khơng có nhớ có nhớ khơng có nhớ vào Cờ điều khiển ( control flags) Có cở điều khiển CPU , : • Cờ hướng ( Direction Flag = DF) • Cờ bẫy ( Trap flag = TF) • Cờ ngắt ( Interrupt Flag = IF) Các cờ điều khiển dùng để điều khiển hoạt động CPU Cờ hướng (DF) dùng lệnh xử lý chuỗi CPU Mục đích DF dùng để điều khiển hướng mà chuỗi xử lý Trong lệnh xử lý chuỗi hai ghi DI SI dùng để địa nhớ chứa chuỗi Nếu DF=0 lệnh xử lý chuỗi tăng địa nhớ cho chuỗi xử lý từ trái sang phải Nếu DF=1 địa nhớ xử lý theo hướng từ phải sang trái 2.3 Các lệnh ảnh hưởng đế cờ Tại thời điểm , CPU thực lệnh , cờ phản ánh kết qủa thực lệnh Dĩ nhiên có số lệnh không làm thay đổi cờ thay đổi vài cờ làm cho vài cờ có trạng thái khơng xác định Trong phần xét ảnh hưởng lệnh ( nghiên cứu chương trước ) lên cờ Bảng sau cho thấy ảnh hưởng lệnh đến cờ : INSTRUCTION AFFECTS FLAGS MOV/XCHG NONE ADD/SUB ALL INC/DEC ALL trừ CF NEG ALL (CF=1 trừ kết qủa , OF=1 kết qủa 8000H ) Để thấy rỏ ảnh hưởng lệnh lên cờ lấy vài ví dụ Ví dụ : ADD AX,AX AX=BX=FFFFh FFFFh + FFFFh 1FFFEh Kết qủa chứa AX FFFEh = 1111 1111 1111 1110 SF=1 MSB=1 PF=0 có ( lẻ) số byte thấp kết qủa ZF=0 kết qủa khác CF=1 có nhớ từ MSB OF=0 dấu kết qủa giống dấu số hạng ban đầu Ví dụ : ADD AL,BL AL= BL= 80h 80h + 80h 100h Kết qủa AL = 00h SF=0 MSB=0 PF=1 tất bit ZF=1 kết qủa CF=1 có nhớ từ MSB OF=1 tốn hạng số âm kết qủa số dương ( có nhớ từ MSB khơng có nhớ vào ) Ví dụ : SUB AX,BX AX=8000h BX= 0001h 8000h - 0001h 7FFFFh = 0111 1111 1111 1111 SF=0 MSB=0 PF=1 có ( chẳn ) số byte thấp kết qủa ZF=0 kết qủa khác CF=0 khơng có mượn OF=1 trừ số âm cho số dương ( tức cộng số âm ) mà kết qủa số dương Ví dụ : INC AL AL=FFh Kết qủa AL=00h = 0000 0000 SF=0 MSB=0 PF=1 ZF=1 kết qủa CF khơng bị ảnh hưởng lệnh INC có nhớ từ MSB OF=0 hai số khác dấu cộng với ( có số nhớ vào MSB có số nhớ từ MSB) Ví dụ 5: MOV AX,-5 Kết BX = -5 = FFFBh Khơng có cờ ảnh hưởng lệnh MOV Ví dụ 6: NEG AX AX=8000h 8000h =1000 0000 0000 0000 bù =0111 1111 1111 1111 +1 1000 0000 0000 0000 = 8000h Kết qủa AX=8000h SF=1 MSB=1 PF=1 có số chẳn số byte thấp kết qủa ZF=0 kết qủa khác CF=1 lệnh NEG làm cho CF=1 trừ kết qủa OF=1 dấu kết qủa giống với dấu tốn hạng nguồn 2.4 Chương trình DEBUG.EXE Debug chương trình DOS cho phép chạy thử chương trình hợp ngữ Người dùng cho chạy chương trình lệnh từ đầu đến cuối ,trong q trình thấy nội dung ghi thay đổi Debug cho phép nhập vào mã hợp ngữ trực tiếp sau DEBUG chuyển thành mã máy lưu trữ nhớ DEBUG cung cấp khả xem nội dung tất ghi có CPU Sau dùng DEBUG để mô tả cách thức mà lệnh ảnh hưởng đến cờ Giả sử có chương trình hợp ngữ sau : TITLE PGM2_1: CHECK - FLAGS ; dùng DEBUG để kiểm tra cờ MODEL SMALL STACK 100H CODE MOV AX,4000H ; AX=4000H ADD AX,AX ; AX=8000H SUB AX,0FFFFH ;AX=8001H NEG AX ; AX=7FFFH INC AX ; AX=8000H MOV AH,4CH ; HÀM THOÁT VỀ DOS INT 21H ; EXIT TO DOS END MAIN ENDP END MAIN Sau dịch chương trình , giả sử file chạy CHECK-FL.EXE đường dẫn C:\ASM Để chạy debug gõ lệnh sau : C:\> DEBUG C:\ASM\CHECK-FL.EXE từ lúc trở dấu nhắc làcủa debug ( dấu “_”) , người sử dụng đưa vào lệnh debug từ dấu nhắc Trước hết xem nội dung ghi lệnh R(Register) , hình có nội dung sau : -R AX=0000 BX=0000 CX=001F DX=0000 SP=000A BP=0000 SI=0000 DI=0000 DS=0ED5 ES=0ED5 SS=0EE5 CS=0EE6 IP=0000 NV UP DI PL NZ NA PO NC 0EE6:0000 B80040 MOV AX,4000 Chúng ta thấy tên ghi nội dung chúng ( dạng HEX) dòng đầu Dòng thứ trạng thái ghi theo cách biểu thị debug Bảng 2-3 cách mà Debug biểu thị trạng thái ghi cờ CPU Flags Set (1) Symbol Clear (0) Symbol CF CY (carry) NC ( no carry) PF PE (even parity) PO ( odd parity) AF AC ( auxiliary carry) NA ( no auxiliary carry) ZF ZR ( zero) NZ ( non zero) SF NG ( negative) PL ( plus) OF OV ( overflow) NV ( no overflow) DF DN ( down) UP ( up) IF EI ( enable interrupts) DI ( disable interrupts) Bảng 2.3 : Biểu thị trạng trạng cờ DEBUG Dòng cuối cho biết giá trị hành PC (địa lệnh thực dạng địa logic ) mã máy lệnh nội dung lệnh tương ứng Khi chạy chương trình máy tính khác thấy điạ đoạn khác Chúng ta dùng lệnh T(Trace) để thi hành lệnh chương trình lệnh MOV AX,4000h -T AX=4000 BX=0000 CX=001F DX=0000 SP=000A BP=0000 SI=0000 DI=0000 DS=0ED5 ES=0ED5 SS=0EE5 CS=0EE6 IP=0003 NV UP DI PL NZ NA PO NC 0EE6:0003 03C0 ADD AX,AX Sau thực lệnh MOV AX,4000 cờ không bị thay đổi , có AX=4000h Bây thực lệnh ADD AX,AX -T AX=8000 BX=0000 CX=001F DX=0000 SP=000A BP=0000 SI=0000 DI=0000 DS=0ED5 ES=0ED5 SS=0EE5 CS=0EE6 IP=0005 OV UP DI NG NZ NA PE NC 0EE6:0005 2DFFFF SUB AX,FFFF Kết qủa phép cộng 8000h , SF=1(NG) , OF=1(OV) PF=1(PE) thủ tục Chương : LỆNH NHÂN VÀ CHIA Trong chương nói đến lệnh dịch mà chúng dùng để nhân chia với hệ số Trong chương nói đến lệnh nhân chia số Quá trình xử lý lệnh nhân chia số có dấu số khơng dấu khác có lệnh nhân có dấu lệnh nhân không dấu Một ứng dụng thường dùng lệnh nhân chia thực thao tác nhập xuất thập phân Trong chương viết thủ tục cho nhập xuất thập phân mà chúng sử dụng nhiều hoạt động xuất nhập từ ngoại vi 6.1 Lệnh MUL IMUL Nhân có dấu nhân khơng dấu Trong phép nhân nhị phân số có dấu số không dấu phải phân biệt cách rõ ràng Ví dụ muốn nhân hai số bit 1000000 1111111 Trong diễn dịch không dấu , chúng 128 255 Tích số chúng 32640 = 0111111110000000b Trong diễn dịch có dấu , chúng -128 -1 Do tích chúng 128 = 0000000010000000b Vì nhân có dấu khơng dấu dẫn đến kết qủa khác nên có lệnh nhân : MUL ( multiply) nhân không dấu IMUL ( integer multiply) nhân có dấu Các lệnh nhân tốn hạng byte từ Nếu toán hạng byte nhân với kết qủa từ 16 bit Nếu tốn hạng từ nhân với kết qủa double từ 32 bit Cú pháp chúng : MUL source ; IMUL source ; Tốn hạng nguồn ghi vị trí nhớ không Phép nhân kiểu byte Đối với phép nhân mà toán hạng kiểu byte AX=AL*SOURCE ; Phép nhân kiểu từ Đối với phép nhân mà tốn hạng kiểu từ DX:AX=AX*SOURCE Aûnh hưởng lệnh nhân lên cờ SF,ZF ,AF,PF : không xác định sau lệnh MUL CF/OF= nửa kết qủa(DX) =1 trường hợp khác sau lệnh IMUL CF/OF = nửa kết qủa có bit dấu giống bit dấu nửa thấp = trường hợp khác Sau lấy vài ví dụ Ví dụ : Giả sử AX=1 BX=FFFFh INSTRUCTION Dec product Hex Product DX AX MUL BX 65535 0000FFFF 0000 FFFF IMUL BX -1 FFFFFFFF FFFF FFFF Ví dụ : Giả sử AX=FFFFh BX=FFFFh INSTRUCTION Dec product Hex Product DX AX MUL BX 4294836225 FFFE0001 FFFE 0001 IMUL BX 00000001 00000 0001 Ví dụ : Giả sử AX=0FFFh INSTRUCTION Dec product Hex Product DX AX MUL AX 16769025 00FFE001 00FF E001 IMUL AX 16769025 00FFE001 00FF E001 Ví dụ : Giả sử AX=0100h CX=FFFFh INSTRUCTION Dec product Hex Product DX AX MUL CX 16776960 00FFFF00 00FF FF00 IMUL CX -256 FFFFFF00 FFFF FF00 Ví dụ : Giả sử AL=80h BL=FFh INSTRUCTION Dec product Hex Product AH AL MUL BL 128 7F80 7F 80 IMUL BL 128 0080 00 80 6.2 Ưùng dụng đơn giản lệnh MUL IMUL CF/OF CF/OF CF/OF CF/OF CF/OF Sau lấy số ví dụ minh họa việc sử dụng lệnh MUL IMUL chương trình Ví dụ : Chuyển đoạn chương trình sau ngơn ngữ cấp cao thành mã hợp ngữ : A = 5xA -12xB Giả sử A B biến từ không xảy tràn Code : MOV AX,5 ; AX=5 IMUL A ; AX=5xA MOV A,AX ; A=5xA MOV AX,12 ; AX=12 IMUL B ; AX=12xB SUB A,AX ; A=5xA-12xB Ví Dụ : viết thủ tục FACTORIAL để tính N! cho số nguyên dương Thủ tục phải chứa N CX trả N! AX Giả sử khơng có tràn Giải : Định nghiã N! N! = N=1 = N x (N-1)x (N-2) x x N>1 Thuật tốn để tính N! sau : Product =1 Term = N FOR N times DO Product = product x term term=term -1 ENDFOR Code : FACTORIAL PROC ; computes N! ; input : CX=N ; output : AX=N! MOV AX,1 ; AX=1 MOV CX,N ; CX=N TOP: MUL CX ; Product = product x term LOOP TOP ; RET FACTORIAL ENDP 6.3 Lệnh DIV IDIV Cũng lệnh nhân , có lệnh chia DIV IDIV cho số khơng dấu cho số có dấu Cú pháp chúng : DIV divisor IDIV divisor Toán hạng byte Lệnh chia toán hạng byte chia số bị chia 16 bit ( dividend) AX cho số chia ( divisor) byte Divisor phải ghi bit byte nhớ Thương số AL số dư AH Toán hạng từ Lệnh chia toán hạng từ chia số bị chia 32 bit ( dividend) DX:AX cho số chia ( divisor) từ Divisor phải ghi 16 bit từ nhớ Thương số AX số dư DX Aûnh hưởng cờ : cờ có trạng thái khơng xác định Divide Overflow Khi thực phép chia kết qủa cóthể khơng chứa hết AL AX số chia bé nhiều so với số bị chia Trong trường hợp hình xuất thơng báo : “ Divide overflow” Ví dụ : Giả sử DX = 0000h , AX = 0005h BX = 0002h Instruction Dec Quotient Dec Remainder AX DX DIV BX 0002 0001 IDIV BX 0002 0001 Ví dụ : Giả sử DX = 0000h , AX = 0005h BX = FFFEh Instruction Dec Quotient Dec Remainder AX DX DIV BX 0000 0005 IDIV BX -2 FFFE 0001 Ví dụ : Giả sử DX = FFFFh , AX = FFFBh BX = 0002h Instruction Dec Quotient Dec Remainder AX DX IDIV BX -2 -1 FFFE FFFF DIV BX OVERFLOW Ví dụ : Giả sử AX = 00FBh BL = FFh Instruction Dec Quotient Dec Remainder AX DX DIV BL 251 FB 00 IDIV BL OVERFLOW 6.4 Mở rộng dấu số bị chia Phép chia với toán hạng từ Trong phép chia với toán hạng từ , số bị chia phải đặt DX:AX số bị chia đặt AX Trong trường hợp , cần phải sửa soạn sau • Đối với lệnh DIV , DX phải bị xố • Đối với lệnh IDIV , DX phải mở rộng dấu AX Lệnh CWD ( Convert Word to Doubleword ) thực việc Ví dụ : Chia -1250 cho MOV AX,-1250 ; AX= -1250 CWD ; mở rộng dấu AX vào DX MOV BX,7 ; BX=7 IDIV BX ; chia DX:AX cho BX , kết qủa AX , số dư ; DX Phép chia với toán hạng byte Trong phép chia với toán hạng byte , số bị chia phải đặt AX số bị chia đặt AL Trong trường hợp , cần phải sửa soạn sau • Đối với lệnh DIV , AH phải bị xố • Đối với lệnh IDIV , AH phải mở rộng dấu AL Lệnh CBW ( Convert Byte to Doublebyte ) thực việc Ví dụ : Chia số có dấu biến byte XBYTE cho -7 MOV AL, XBYTE ; AL giữ số bị chia CBW ; mở rộng dấu AL vào AH MOV BL,-7 ; BX= -7 IDIV BL ; chia AX cho BL , kết qủa AL , số dư ; AH Khơng có cờ bị ảnh hưởng lệnh CWD CBW 6.5 Thủ tục nhập xuất số thập phân Mặc dù PC tất số liệu biễu diễn dạng binary Nhưng việc biễu diễn dạng thập phân thuận tiện cho người dùng Trong phần viết thủ tục nhập xuất số thập phân Khi nhập số liệu , gõ 21543 chẳng hạn thực chất gõ vào chuỗi ký tự , bên PC , chúng biến đổi thành giá trị nhị phân tương đương 21543 Ngược lại xuất số liệu , nội dung nhị phân ghi vị trí nhớ phải biến đổi thành chuỗi ký tự biễu diễn số thập phân trước chúng in Xuất số thập phân ( Decimal Output) Chúng ta viết thủ tục OUTDEC để in nội dung ghi AX số nguyên thập phân có dấu Nếu AX>0 ,OUTDEC in nội dung AX dạng thập phân Nếu AX phần tử thứ ING NEXT ; không , tiếp tục MOV DI,SI ; DI chứa địa phần tử lớn MOV AL,[DI] ; AL chứa phần tử lớn NEXT: LOOP FIND_BIG ; swap phần tử lớn với phần tử cuối CALL SWAP DEC BX ; N= N-1 JNE SORT_LOOP ; lặp N0 END_SORT: POP SI POP DX POP CX POP BX RET SELECT ENDP SWAP PROC ; đổi chỗ phần tử mảng ; input : SI= phần tử thứ ; DI = phần tử thứ hai ; output : phần tử trao đổi PUSH AX ; cất AX MOV AL,[SI] ; lấy phần tử A[i] XCHG AL,[DI] ; đặt A[k] MOV [SI],AL ; đặt A[k] A[i] POP AX ; lấy lại AX RET SWAP ENDP Sau dịch chương trình , dùng DEBUG để chạy thử test kết qủa 7.4 Mảng chiều Mảng chiều mảng mảng , nghĩa mảng chiều mà phần tử mảng chiều khác Có thể hình dung mảng chiều ma trận chữ nhật Ví dụ mảng B gồm có hàng cột ( mảng 3x4) sau : ROW \ COLUMN B[1,1] B[1,2] B[1,3] B[1,4] B[2,1] B[2,2] B[2,3] B[2,4] B[3,1] B[3,2] B[3,3] B[3,4] Bởi nhớ chiều phần tử mảng chiều phải lưu trữ nhớ theo kiểu Có cách dùng : • Cách lưu trữ theo thứ tự dòng : mảng lưu trữ phần tử dòng đến phần tử dịng • Cách lưu trữ theo thứ tự cột : mảng lưu trữ phần tử cột đến phần tử cột Giả sử mảng B chứa 10,20,30,40 dòng chứa 50,60,70,80 dòng chưá 90,100,110,120 dòng Theo trật tự hàng chúng lưu trữ sau : B DW 10,20,30,40 DW 50,60,70,80 DW 90,100,110,120 Theo trật tự cột chúng lưu trữ sau : B DW 10,50,90 DW 20,60,100 DW 30,70,110 DW 40,80,120 Hầu hết ngôn ngữ cấp cao biên dịch mảng 2chiều theo trật tự dòng Trong ASM , dùng cách : Nếu thành phần hàng xử lý cách lưu trữ theo trật tự hàng dùng Ngược lại dùng cách lưu trữ theo trật tự cột Xác định phần tử mảng chiều : Giả sử mảng A gồm MxN phần tử lưu trữ theo trật tự dòng Goị S độ lớn phần tử : S=1 phần tử byte , S=2 phần tử từ Để tìm phần tử thứ A[i,j] cần tìm : hàng i tìm phần tử thứ j hàng Như phải tiến hành qua bước : Bước 1: Hàng bắt đầu vị trí A Vì hàng có N phần tử , Hàng bắt đầu A+ NxS Hàng bắt đầu A+2xNxS Hàng thứ i bắt đầu A+(i-1)xSxN Bước 2: Phần tử thứ j hàng cách vị trí đầu hàng (j-1)xS byte Từ bước suy mảng chiều NxM phần tử mà chúng lưu trữ theo trật tự hàng phần tử A[i,j] có địa xác định sau : A+((i-1)xN + (j-1))x S (1) Tương tự lưu trữ theo trật tự cột phần tử A[i,j] có địa sau : A+(i-1)+(j )xM)xS (2) Ví dụ : Giả sử A mảng MxN phần tử kiểu từ ( S=2) lưu trữ theo kiểu trật tự hàng Hỏi : Hàng i bắt đầu địa ? Cột j bắt đầu điạ ? Hai phần tử cốt cách bytes Giải : Hàng i bắt đầu A[i,1] theo cơng thức (1) có địa : A+(i-1)xNx2 Cột j bắt đầu A[1,j ] theo cơng thức (1) có địa : A+(j-1)x2 Vì có N cột nên phần tử cột cách 2xN byte 7.5 Chế độ địa chỉ số sở Trong chế độ , địa offset toán hạng tổng : nội dung ghi sở ( BX or BP) nội dung ghi số ( SI or DI) địa offset biến ( tuỳ chọn) âm dương ( tuỳ chọn) Nếu ghi BX dùng DS chứa số đoạn địa tốn hạng Nếu BP dùng SS chưá số đoạn Toán hạng viết theo cách đây: variable[base_register][index_register] [base_register + index_register + variable + constant ] variable [ base_register + index_register + constant] constant [ base _ register + index_register + variable] Trật tực thành phần dấu ngoặc tuỳ ý Ví dụ , giả sử W biến từ , BX=2 SI =4 Lệnh MOV AX, W[BX][SI] di chuyển nội dung mảng địa W+2+4 = W+6 vào ghi AX Lệnh viết theo cách sau : MOV AX,[W+BX+SI] MOV AX,W[BX+SI] Chế độ địa chỉ số sở thường dùng để xử lý mảng chiều ví dụ sau : Giả sử A mảng 5x7 từ lưu trữ theo trật tự dòng Viết đoạn mã dùng chế độ địa chỉ số để : 1) xóa dịng 2) xố cột Giải : 1) Dòng i bắt đầu A+(i-1)xNx2 Như dòng bắt đầu A+(2-1)x7x2 = A + 28 Có thể xóa dịng sau : MOV BX,28 ; BX đến đầu dòng XOR SI,SI ; SI mục cột MOV CX,7 ; CX= số phần tử hàng CLEAR: MOV A[BX][SI],0 ; xoá A[3,1] ADD SI,2 ; đến cột LOOP CLEAR 2) Cột j bắt đầu điạ A + (j-1)x2 Vậy cột bắt đầu điạ A+(4-1)x2 = A+ Hai phần tử cột cách Nx2 byte , N=7 , phần tử cách 14 byte Có thể xóa cột sau : MOV SI,6 ; SI đến cột XOR BX,BX ; BX đến hàng MOV CX,5 ; CX= : số phần tử cột CLEAR: MOV A[BX][SI],0 ; Xố A[i,4] ADD BX,1 ; đến dịng LOOP CLEAR 7.6 Ưùng dụng để tính trung bình Giả sử lớp gồm sinh viên có mơn thi Kết qủa cho mảng chiều sau : Tên Sinh viên TEST1 TEST2 TEST3 TEST4 MARY 67 45 98 33 SCOTT 70 56 87 44 GEORGE 82 72 89 40 BETH 80 67 95 50 SAM 78 76 92 60 Chúng ta viết1 chương trình tính điểm trung bình cho thi Để làm điều tổng theo cột chia cho Thuật toán : j = repeat Sum the scores in column j divide sum by to get average in column j j = j - Until j = Trong bước làm sau : Sum[j]= i=1 FOR times DO Sum[j]= Sum[j]+ Score[i, j] i=i+1 END_FOR Chương trình viết sau : TITLE PGM7_4 : CLASS AVERAGE MODEL SMALL STACK 100H DATA FIVE DB SCORES DW 67,45,98,33 ; MARY DW 70,56,87,44 ;SCOTT DW 82,72,89,40 ;GEORGE DW 80,67,,95,50 ; BETH DW 78,76,92,60 ;SAM AVG DW DUP (0) CODE MAIN PROC MOV AX,@DATA MOV DS,AX ;J=4 REPEAT: MOV SI,6 ; SI đến cột thứ XOR BX,BX ; BX hàng thứ XOR AX,AX ; AX chứa tổng theo cột ; Tổng điểm cột j FOR: ADD AX , SCORES[BX+SI] ADD BX,8 ; BX đến hàng thứ LOOP FOR ; end_for ; tính trung bình cột j XOR DX,DX ; xố phần cao số bị chia (DX:AX) DIV FIVE ; AX = AX/5 MOV AVG[SI],AX ; cất kết qủa mảng AVG SUB SI,2 ; đến cột tiếp ; un til j=0 JNL REPEAT ;DOS EXIT MOV AH,4CH INT 21H MAIN ENDP END MAIN Sau biên dịch chương tnh dùng DEBUG để chạy xem kết qủa lệnh DUMP 7.7 Lệnh XLAT Trong số ứng dụng cần phải chuyển số liệu từ dạng sang dạng khác Ví dụ IBM PC dùng ASCII code cho ký tự IBM Mainframes dùng EBCDIC ( Extended Binary Coded Decimal Interchange Code) Để chuyển chuỗi ký tự mã hoá ASCII thành EBCDIC , chương trình phải thay mã ASCII ký tự chuỗi thành mã EBCDIC tương ứng Lệnh XLAT ( khơng có tốn hạng ) dùng để đổi giá trị byte thành giá trị khác chứa bảng AL phải chứa byte cần biến đổi DX chứa điạ offset bảng cần biến đổi Lệnh XLAT : 1) cộng nội dung AL với địa BX để tạo điạ bảng 2) thay giá trị AL với giá trị tìm thấy bảng Ví dụ , giả sử nội dung AL vùng đến Fh muốn thay mã ASCII số hex tương đương , tức thay 6h 036h=‘6’ , thay Bh 042h=“B” Bảng biến đổi : TABLE DB 030h ,031h , 032h ,033h ,034h , 035h , 036h, 037h,038h,039h DB 041h , 042h ,043h , 044h, 045h , 046h Ví dụ , để đổi 0Ch thành “C” , thực lệnh sau : MOV AL,0Ch ; số cần biến đổi LEA BX,TABLE ; BX chưá điạ offset bảng XLAT ; AL chứa “C” Ở XLAT tính TABLE + Ch = TABLE +12 thay AL 043h Nếu AL chứa số khơng khỏang đến 15 XLAT cho giá trị sai Ví dụ : Mã hố giải mã thơng điệp mật Chương trình : Nhắc nhở người dùng nhập vào thơng điệp Mã hố dạng khơng nhận biết , In chúng dòng Dịch chúng trở lại dạng ban đầu in chúng dịng Khi chạy ct hình có dạng sau : ENTER A MESSAGE : DAI HOC DA LAT ; input OXC BUC OX EXK ; encode DAI HOC DA LAT ; translated Thuật toán sau : Print prompt Read and encode message Go to anew line Print encoded message go to a new line translate and print message TITLE PGM7_5 : SECRET MESSAGE MODEL SMALL STACK 100H DATA ;ALPHABET ABCDEFGHIJKLMNOPQRSTUVWXYZ CODE_KEY DB 65 DUP ( ’ ‘), ‘ XQPOGHZBCADEIJUVFMNKLRSTWY’ DB 37 DUP (‘ ‘) ; 128 ký tự bảng mã ASCII CODED DB 80 dup (‘$’) ; 80 ký tự gõ vào DECODE_KEY DB 65 DUP (‘ ‘), ‘JHIKLQEFMNTURSDCBVWXOPYAZG’ DB 37 DUP (‘ ‘) PROMPT DB ‘ENTER A MESSAGE :’,0DH,0AH,’$’ CRLF DB 0DH,0AH,’$’ CODE MAIN PROC MOV AX,@DATA MOV DS, AX ; in dấu nhắc MOV AH,9 LEA DX,PROMPT INT 21H ; đọc mã hoá ký tự MOV AH,1 LEA BX,CODE_KEY ; BX tới CODE_KEY LEA DI, CODED ; DI tới thơng điệp mã hố WHILE_: INT 21h ; đọc ký tự vào AL CMP AL,0DH ; có phải ký tự CR JE ENDWHILE ; , đến phần in thơng điệp mã hố XLAT ; mã hoá ký tự MOV [DI],AL ; cất ký tự CODE JMP WHILE_ ; xử lý ký tự ; xuống hàng MOV AH,9 LEA DX,CRLF INT 21H ; in thơng điệp mã hố LEA DX,CODED INT 21H ; xuống hàng LEA DX,CRLF INT 21H ; giải mã thơng điệp in MOV AH,2 LEA BX,DECODE_KEY ; BX chứa điạ bảng giải mã LEA SI,CODED ; SI tới thơng điệp mã hố WHILE1: MOV AL,[SI] ; lấy ký tự từ thông điệp mã hố CMP AL.’$’ ; có phải cuối thơng điệp JE ENDWHILE1 ; kết thúc XLAT ; giải mã MOV DL,AL ;đặt ký tự vào DL INT 21H ; in ký tự INC SI ; SI=SI+1 JMP WHILE1 ; tiếp tục ENDWHILE1: MOV AH,4CH INT 21H MAIN ENDP END MAIN Trong chương trình có đọan số liệu với khai báo sau : ; ALPHABET ABCDEFGHIJKLMNOPQRSTUVWXYZ Cho biết bảng chữa tiếng Anh CODE_KEY DB 65 DUP ( ’ ‘), ‘ XQPOGHZBCADEIJUVFMNKLRSTWY’ DB 37 DUP (‘ ‘) Khai báo 128 ký tự bảng mã ASCII , thứ tự ký tự hoa tuỳ ý CODED DB 80 dup (‘$’) 80 ký tự gõ vào , giá trị ban đầu $ để in hàm ngắt 21h DECODE_KEY DB 65 DUP (‘ ‘), ‘JHIKLQEFMNTURSDCBVWXOPYAZG’ DB 37 DUP (‘ ‘) Bảng giải mã thiết lập theo cách mã hoá , nghĩa phần mã hoá mã hoá ‘A’ thành ‘X’ giải mã ‘X’ phải giải mã thành ‘A’ Các ký tự gõ vào ký tự hoa đếu chuyển thành ký tự trống