Cơ bản về hợp ngữ
Một chương trình hợp ngữ bao gồm một loạt các mệnh đề ( statement) được viết liên tiếp nhau , mỗi mệnh đề được viết trên 1 dòng . Một mệnh đề có thể là: · một lệnh ( instruction) : được trình biên dịch ( Assembler =ASM) chuyển ...
Một chương trình hợp ngữ bao gồm một loạt các mệnh đề ( statement) được viết liên tiếp nhau , mỗi mệnh đề được viết trên 1 dòng .
Một mệnh đề có thể là:
· một lệnh ( instruction) : được trình biên dịch ( Assembler =ASM) chuyển thành mã máy.
· một chỉ dẫn của Assembler ( Assembler directive) : ASM không chuyển thành mã máy
Các mệnh đề của ASM gồm 4 trường :
Name Operation Operand(s) Comment
các trường cách nhau ít nhất là một ký tự trống hoặc một ký tự TAB
ví dụ lệnh đề sau :
START : MOV CX,5 ; khởi tạo thanh ghi CX Sau đây là một chỉ dẫn của ASM :
MAIN PROC ; tạo một thủ tục có tên là MAIN
Trường Tên ( Name Field)
Trường tên được dùng cho nhãn lệnh , tên thủ tục và tên biến . ASM sẽ chuyển tên thành địa chỉ bộ nhớ .
Tên có thể dài từ 1 đến 31 ký tự . Trong tên chứa các ký tự từ a-z , các số và các ký tự đặc biệt sau : ? ,@ , _ , $ và dấu . Không được phép có ký tự trống trong phần tên . Nếu trong tên có ký tự . thì nó phải là ký tự đầu tiên . Tên không được bắt đầu bằng một số . ASM không phân biệt giữa ký tự viết thường và viết hoa .
Sau đây là các ví du về tên hợp lệ và không hợp lệ trong ASM .
Tên hợp lệ | Tên không hợp lệ |
COUNTER1 | TWO WORDS |
@CHARACTE R | 2ABC |
SUM_OF_DIGITS | A45.28 |
DONE? | YOU&ME |
.TEST | ADD-REPEAT |
Trường toán tử ( operation field)
Đối với 1 lệnh trường toán tử chứa ký hiệu ( sumbol) của mã phép toán ( operation code = OPCODE) .ASM sẽ 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 toán mô tả chức năng của phép toán , ví dụ ADD ,
SUB , INC , DEC , INT ...
Đối với chỉ dẫn của ASM , trường toán tử chứa một 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 hiện một việc gì đó ví du tạo ra một thủ tục , định nghĩa các biến ...
Trường các toán hạng ( operand(s) field)
Trong một lệnh trường toán hạng chỉ ra các số liệu tham gia trong lệnh đó.
Một lệnh có thể không có toán hạng , có 1 hoặc 2 toán hạng . Ví du :
NOP | ; không có toán hạng | |
INC | AX | ; 1 toán hạng |
ADD | WORD1,2 | ; 2 toán hạng cộng 2 với nội dung của từ nhớ WORD1 |
Trong các lệnh 2 toán hạng toán hạng đầu là toán hạng đích ( destination operand) . Toán hạng đích thường là thanh ghi hoặc vị trí nhớ dùng để lưu trữ kết
quả . Toán hạng thứ hai là toán hạng nguồn . Toán hạng nguồn thường không bị thay đổi sau khi thực hiện lệnh .
Đối với một chỉ dẫn của ASM , trường toán hạng chứa một hoặc nhiều thông tin mà ASM dùng để thực thi chỉ dẫn .
Trường chú thích ( comment field)
Trường chú thích là một tùy chọn của mệnh đề trong ngôn ngữ ASM . Lập
trình viên dùng trường chú thích để thuyết minh về câu lệnh . Điều này là cần thiết
vì ngôn ngữ ASM là ngôn ngữ cấp thấp ( low level) vì vậy sẽ rất khó hiểu chương
trình nếu nó không được chú thích một cách đầy đủ và rõ ràng . Tuy nhiên không nên
có chú thích đối với mọi dòng của chương trình , kể cả những lệnh mà ý nghĩa của nó đã rất ro ràng như :
NOP ; không làm chi cả
Người ta dùng dấu chấm phẩy (;) để bắt đầu trường chú thích .
ASM cũng cho phép dùng toàn bộ một dòng cho chú thích để tạo một khoảng trống ngăn cách các phần khác nhau cuả chương trình ,ví dụ :
;
; khởi tạo các thanh ghi
;
MOV AX,0
MOV BX,0
CPU chỉ làm việc với các số nhị phân . Vì vậy ASM phải chuyển tất cả các loại số liệu thành số nhị phân . Trong một chương trình hợp ngữ cho phép biểu diễn số liệu dưới dạng nhị phân , thập phân hoặc thập lục phân và thậm chí là cả ký tự nữa .
Các số
Một số nhị phân là một dãy các bit 0 và 1 và 2 phải kết thúc bằng h hoặc H Một số thập phân là một dãy các chữ số thập phân và kết thúc bởi d hoặc D (có thể không cần)
Một số hex phải bắt đầu bởi 1chữ số thập phân và phải kết thúc bởi h hoặc H .
Sau đây là các biểu diễn số hợp lệ và không hợp lệ trong 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 |
Các ký tự
Ký tự và một chuỗi các ký tự phải được đóng giữa hai dấu ngoặc đơn hoặc
hai dấu ngoặc kép . Ví du ‘A’ và “HELLO” . Các ký tự đều được chuyển thành mã ASCII bởi ASM . Do đo trong một chương trình ASM sẽ xem khai báo ‘A’ và 41h ( mã ASCII của A) là giống nhau .
Trong ASM biến đóng vai trò như trong ngôn ngữ cấp cao . Mỗi biến có một loại dữ liệu và nó được gán một địa chỉ bộ nhớ sau khi dịch chương trình . Bảng sau đây liệt kê các toán tử giá dùng để định nghĩa các loại số liệu .
PSEUD O - O P | STAND S FOR |
DB | define byte |
DW | define word ( doublebyte) |
DD | define doubeword ( 2 tự liên tiếp) |
DQ | define quadword ( 4 tự liên tiếp ) |
DT | define tenbytes ( 10 bytes liên tiếp) |
Biến byte
Chỉ dẫn của ASM để định nghĩa biến byte có dạng như sau : NAME DB initial_value
ALPHA DB 4
Chỉ dẫn này sẽ gán tên ALPHA cho một byte nhớ trong bộ nhớ mã giá
trị ban đầu của nó là 4 . Nếu giá trị của byte là không xác định thì đặt dấu chấm hỏi
( ?) vào giá trị ban đầu .
BYT DB ?
Đối với biến byte vùng giá trị khả dĩ mà nó lưu trư được là -128 đến
127 đối với số có dấu và 0 đến 255 đối với số không dấu .
Biến từ
Chỉ dẫn của ASM để định nghĩa một biến từ như sau :
NAME DW initial_value
WRD DW -2
Cũng có thể dùng dấu ? để thay thể cho biến từ có giá trị không xác định . Vùng giá trị của biến từ là -32768 đến 32767 đối với số có dấu và 0 đến 56535 đối với số không dấu .
Mảng ( arrays)
Trong ASM một mảng là một loạt các byte nhớ hoặc tự nhớ liên tiếp nhau . Ví dụ để định nghĩa một mảng 3 byte gọi là B_ARRAY ma giá trị ban đầu của nó là 10h,20h và 30h chúng ta có thể viết :
B_ARRAY DB 10h,20h,30h
B_ARRAY là tên được gán cho byte đầu tiên B_ARRAY+1 là tên của byte thứ hai B_ARRAY+2 là tên của byte thứ ba
Nếu ASM gán địa chỉ offset là 0200h cho mảng B_ARRAY thì nội dung bộ nhớ sẽ như sau :
SYMBOL | ADDRESS | CONTENTS |
B_ARRAY | 200h | 10h |
B_ARRAY+1 | 201h | 20h |
B_ARRAY+2 | 202h | 30h |
Chỉ dẫn sau đây sẽ định nghĩa một mảng 4 phần từ có tên là W_ARRAY:
W_ARRAY DW 1000,40,29887,329
Giả sử mảng bắt đầu tại 0300h thì bộ nhớ sẽ 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 và byte cao của mộ t từ
Đôi khi chúng ta cần truy xuất tới byte thấp và byte cao của một biến từ . Giả
sư chúng ta định nghĩa :
WORD1 DW 1234h
Byte thấp của WORD1 chứa 34h , còn byte cao của WORD1 chứa 12h
Ký hiệu địa chỉ của byte thấp là WORD1 còn ký hiệu địa chỉ của byte cao là
WORD1+1 .
Chuỗi các ký tự ( character strings)
Một mảng các ma ASCII có thể được định nghĩa bằng một chuỗi các ký tự
LETTERS DW 41h,42h,43h tương đương với
LETTERS DW ‘ABC ’
Bên trong một chuỗi , ASM sẽ phân biệt chữ hoa và chữ thường . Vì vậy chuỗi
‘abc’ sẽ được chuyển thành 3 bytes : 61h ,62h và 63h.
Trong ASM cũng có thể tổ hợp các ký tự và các số trong một định nghĩa .
MSG DB ‘HELLO’, 0AH, 0DH, ‘$’
tương đương với
MSG DB 48H,45H,4CH,4Ch,4FH,0AH,0DH,24H
Trong một chương trình các hằng có thể được đặt tên nhờ chỉ dẫn EQU
(equates) . Cú pháp của EQU là :
NAME EQU constant
LF EQU 0AH
sau khi có khai báo trên thì LF được dùng thay cho 0Ah trong chương trình . Vì vậy ASM sẽ chuyễn các lệnh :
MOV DL,0Ah và MOV DL,LF
thành cùng một mã máy .
Cũng có thể dùng EQU để định nghĩa một chuỗi ,
PROMPT EQU‘TYPE YOUR NAME ’
Sau khi có khai báo này , thay cho
MSG DB ‘TYPE YOUR NAME ’
chúng ta có thể viết
MSG DB PROMPT
CPU 8086 có hàng trăm lệnh , trong chương này ,chúng ta sẽ xem xét 7 lệnh đơn giản của 8086 mà chúng thường được dùng với các thao tác di chuyển số liệu và
thực hiện các phép toán số học .
Trong phần sau đây , WORD1 và WORD2 là các biến từ , BYTE1 và
BYTE2 là các biến byte .
Lệnh MOV và XCHG
Lệnh MOV dùng để chuyển số liệu giữa các thanh ghi , giữa 1 thanh ghi và
một vị trí nhớ hoặc để di chuyển trực tiếp một số đến một thanh ghi hoặc một vị trí nhớ . Cú pháp của lệnh MOV là :
MOV Destination , Source
MOV AX,WORD1 ; lấy nội dung của tư nhớ WORD1 đưa vào thanh ghi AX MOV AX,BX ; AX lấy nội dung của BX , BX không thay đổi
MOV AH,’A’ ; AX lấy giá trị 41h
Bảng sau cho thấy các trường hợp cho phép hoặc cấm của lệnh MOV
Destinatio n operand
sourc e 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 của 2 thanh ghi hoặc của một thanh ghi và một vị trí nhớ .
XCHG AH,BL
XCHG AX,WORD1 ; trao đổi nội dung của thanh ghi AX và từ nhớ WORD1.
Cũng như lệnh MOV có một số hạn chế đối với lệnh XCHG như bảng sau :
Destinatio n operand
Sourc e operand | GeneralRegister | Memory Locatin |
General MemoryMemory Location | Y Y | Y No |
Lệnh ADD, SUB, INC , DEC
Lệnh ADD và SUB được dùng để cộng và trừ nội dung của 2 thanh ghi , của một thanh ghi và một vị trí nhớ , hoặc cộng ( trừ) một số với (khỏi) một thanh ghi hoặc một vị trí nhớ . Cú pháp là :
ADD Destination , Source SUB Destination , Source Ví du :
ADD WORD1, AX
ADD | BL , 5 | |
SUB | AX,DX | ; AX=AX-DX |
Vì lý do kỹ thuật , lệnh ADD và SUB cũng bị một số hạn chế như bảng sau:
Destinatio n operand
Sourc e operand | General Reg | Memory Loacation |
Gen Memory Memory Location Constant | Y Y Y | Y NO Y |
Việc cộng hoặc trừ trực tiếp giữa 2 vị trí nhớ là không được phép . Để giải
quyết vấn đề này người ta phải di chuyển byte ( từ ) nhớ đến một thanh ghi sau đó mới cộng hoặc trừ thanh ghi này với một byte ( từ ) nhớ khác .
MOV AL, BYTE2
ADD BYTE1, AL
Lệnh INC ( incremrent) để cộng thêm 1 vào nội dung của một thanh ghi hoặc một vị trí nhớ . Lệnh DEC ( decrement) để giảm bớt 1 khỏi một thanh ghi hoặc 1 vị trí nhớ . Cú pháp của chúng là :
INC Destination
DEC Destination
INC WORD1
INC AX
DEC BL
Lệnh NEG ( negative)
Lệnh NEG để đổi dấu ( lấy bu 2 ) của một thanh ghi hoặc một vị trí nhớ . Cú pháp :
NEG destination
NEG AX ;
Giả sử AX=0002h sau khi thực hiện lệnh NEG AX thì AX=FFFEh
Giả sử A và B là 2 biến từ .
Chúng ta sẽ chuyển các mệnh đề sau trong ngôn ngữ cấp cao ra ngôn ngữ ASM
Mệnh đề B=A
MOV AX,A ; đưa A vào AX MOV B,AX ; đưa AX vào B
Mệnh đề A=5-A
MOV AX,5 ; đưa 5 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-
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
Một chương trình ngôn ngữ máy bao gồm mã ( code) , số liệu ( data) và ngăn xếp (stack ) . Mỗi một phần chiếm một đoạn bộ nhớ . Mỗi một đoạn chương trình là được chuyển thành một đoạn bộ nhớ bởi ASM .
Các kiểu bộ nhớ ( memory models)
Độ lớn của mã và số liệu trong một chương trình được quy định bởi chỉ dẫn MODEL nhằm xác định kiểu bộ nhớ dùng với chương trình . Cú pháp của chỉ dẫn MODEL như sau :
.MODEL memory_model
Bảng sau cho thấy các kiểu bộ nhớ :
MODEL | DESCRITION |
SMALL MEDIUM COMPACT LARGE HUGE | code và data nằm trong 1 đoạncode nhiều hơn 1 đoạn , data trong 1 đoạn data nhiều hơn 1 đọan , code trong 1 đoạncode và dayta lớn hơn 1 đoạn , array không qúa 64KBcode ,data lớn hớn 1 đoạn , array lớn hơn 64KB |
Đoạn số liệu
Đoạn số liệu của chương trình chưá các khai báo biến , khai báo hằng ... Để bắt đầu đoạn số liệu chúng ta dùng chỉ dẫn DATA với cú pháp như sau :
.DATA
;khai báo tên các biến , hằng và mãng
.DATA | ||
WORD1 | DW | 2 |
WORD2 | DW | 5 |
MSG | DB | ‘THIS IS A MESSAGE ’ |
MASK EQU 10010010B
Đoạn ngăn xếp
Mục đích của việc khai báo đoạn ngăn xếp là dành một vùng nhớ ( vùng satck) để lưu trữ cho stack . Cú pháp của lệnh như sau :
.STACK size
nếu không khai báo size thì 1KB được dành cho vùng stack .
.STACK 100h ; dành 256 bytes cho vùng stack
Đọan mã
Đoạn mã chứa các lệnh của chương trình . Bắt đầu đoạn mã bằng chỉ dẫn
CODE như sau :
.CODE
Bên trong đoạn mã các lệnh thường được tổ chức thành thu tục
(procedure) mà cấu trúc của một thủ tục như sau :
name PROC
; body of the procedure name ENDP
Sau đây là câu trúc của một chương trình hợp ngữ mà phần CODE là thủ tục có tên là MAIN
.MODEL SMALL
.STACK 100h
.DATA
; định nghĩa số liệu tại đây
.CODE
MAIN PROC
;thân của thủ tục MAIN MAIN ENDP
; các thủ tục khác nếu có
END MAIN
CPU thông tin với các ngoại vi thông qua các cổng IO . Lệnh IN và OUT của
CPU cho phép truy xuất đến các cổng này . Tuy nhiên hầu hết các ứng dụng không dùng lệnh IN và OUT vì 2 lý do:
· các địa chỉ cổng thay đổi tùy theo loại máy tính
· có thể lập trình cho các IO de dàng hơn nhớ các chương trình con ( routine) được cung cấp bởi các hãng che tạo máy tính
Có 2 loại chương trình phục vu IO là : các routine của BIOS ( Basic Input
Output System) và các routine của DOS .
Lện h IN T ( interrupt)
Để gọi các chương trình con của BIOS và DOS có thể dùng lệnh INT với cú pháp như sau :
INT interrupt_number
ở đây interrupt_number là một số mã nó chỉ định một routine .
INT 16h gọi routine thực hiện việc nhập số liệu từ Keyboard .
Lệnh INT 21h
INT 21h được dùng để gọi một số lớn các các hàm ( function) của DOS . Tuỳ theo giá trị mà chúng ta đặt vào thanh ghi AH , INT 21h sẽ gọi chạy một routine
tương ứng .
Trong phần này chúng ta sẽ quan tâm đến 2 hàm sau đây :
FUNCTION NUMBER | ROUTINE |
1 | Single key input |
2 | Single character output |
FUNTION 1 : 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 này thực hiện các lệnh sau : MOV AH,1 ; input key function
INT 21h ; ASCII code in AL and display character on the screen
FUNTION 2 : 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 sẽ in lên màn hình dấu ?
MOV AH,2
MOV DL,’?’ ; character is ‘?’ INT 21H ; display character
Hàm 2 cũng có thể dùng để thực hiện chức năng điều khiển .Nếu DL chứa ký
từ điều khiển thì khi gọi INT 21h , ký tự điều khiển sẽ được thực hiện .
Các ký tự điều khiển thường dùng là :
ASCII code (Hex) SYMBOL FUNCTION
7 | BEL | beep |
8 | BS | backspace |
9 | HT | tab |
A | LF | line feed |
D | CR | carriage return |
Chúng ta sẽ viết một chương trình hợp ngữ nhằm đọc một ký tự từ bàn phím và in nó trên đầu dòng mới .
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 1 ký tự
MOV AH,1 ; hàm đọc ký tự
INT 21H ; ký tự được đưa vào AL MOV BL,AL ; cất ký tự trong BL
; nhảy đến dòng mới
MOV AH,2 ; hàm xuất 1 ký tự
MOV DL,0DH ; ký tự carriage return
INT 21H , thực hiện carriage return
MOV DL,0AH ; ký tự line feed
INT 21H ; thực hiện line feed
; xuất ký tự
MOV DL,BL ; đưa ký tự vào DL INT 21H ; xuất ký tự
; trở ve DOS
MOV AH,4CH ; hàm thoát ve DOS INT 21H ; exit to DOS
MAIN ENDP
END MAIN
Có 4 bước để tạo ra và chạy một chương trình hợp ngữ là :
· Dùng một trình sốạn thảo văn bản để tạo ra tập tin chương trình nguồn ( sốurce program file ) .
· Dùng một trình biên dịch (Assembler ) để tạo ra tập tin đối tượng (object file)
ngôn ngữ máy
· Dùng trình LINK để liên kết một hoặc nhiều tập tin đối tượng rồi tạo ra file thực
thi được .
· Cho thực hiện tập tin EXE hoặc COM .
Bước1 : Tạo ra chương trình nguồn
Dùng một trình sốạn thảo văn bản (NC chẳng hạn) để tạo ra chương trình
nguồn .Ví du lất tên là PGM1.ASM. Phần mơ rộng ASM là phần mơ rộng quy ước để
Assembler nhận ra chương trình nguồn .
Bước2 :Biên dịch chương trình
Chúng ta sẽ dùng MASM ( Microsốft 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ị là PGM1.OBJ bằng lệnh sau :
MASM PGM1;
Sau khi in thông tin ve bản quyền MASM sẽ kiểm tra file nguồn để tìm lỗi cú pháp . Nếu có lỗi thì MASM sẽ inra số dòng bị lỗi và một mo tả ngắn ve lỗi đo .
Nếu không có lỗi thì MASM sẽ chuyển PGM1.ASM thành tậo tin đối tượng ngôn ngữ máy gọi là PGM1.OBJ .
Dấu chấm phẩy sau lệnh MASM PGM1 có nghĩa là chúng ta không muốn tạo ra một 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 thì MASM sẽ yêu cầu chúng ta go vào tên của một số tập tin mã nó có thể tạo
ra như hình dưới đây :
Object file name [ PGM1.OBJ]:
Sốurce listing [NUL.LIST] : PGM1
Cross-reference [NUL.CRF] : PGM1
Tên mặc nhiên là NUL có nghĩa là không tạo ra file tương ứng trừ khi lập trình viên go vào tên tập tin .
Tậptin danhsáchnguồn(sốurcelistingfile): là một tập tin Text có đánh số dòng , trong đo mã hợp ngữ và mã nguồn nằm cạnh nhau . Tập tin này thường dùng
để gỡ rối chương trình nguồn vì MASM thông báo lỗi theo số dòng .
Tậptinthamchiếuchéo(Cross-ReferenceFile): là 1 tập tin chứa danh sách các tên mà chúng xuất hiện trong chương trình kèm theo số dòng mã tên ấy xuất hiện . Tập tin này đưọc dùng để tìm các biến và nhãn trong một chương trình lớn .
Bước3 : Liên kết chương trình
Tập tin đối tượng tạo ra ở bước 2 là một tập tin ngôn ngữ máy nhưng nó không chạy được vì chưa có dạng thích hợp của 1 file chạy . Hơn nữa nó chưa biết chương trình được nạp vào vị trí nào trên bộ nhớ để chạy . Một số địa chỉ dưới dạng mã máy có thể bị thiếu .
Trình LINK sẽ liên kết một hoặc nhiều file đói tượng thành một file chạy duy nhất ( *.EXE ) .Tập tin này có thể được nạp vào bộ nhớ và thi hành .
Để liên kết chương trình ta go : LINK PGM1;
Nếu không có dấu chấm phẩy ASM sẽ yêu câu chúng ta go vào tên tập tin thực thi .
Bước4 : Chạy chương trình
Từ dấu nhắc lệnh có thể chạy chương trình bằng cách gõ tên nó rồi nhấn
ENTER .
Trong chương trình PGM1 trên đây chúng ta đã dùng INT 21H hàm 2 và 4 để đọc và xuất một ký tự . Hàm 9 ngắt 21H có thể dùng để xuất một chuỗi ký tự .
IN T 21 H , Functio n 9 : Displa y a string
Input : DX=offse t addres s o f string
Th e strin g mus t en d wit h a ‘$ ’ character
Ký tự $ ở cuối chuỗi sẽ không được in lên màn hình . Nếu chuỗi có chứa ký
tự điều khiển thì chức năng điều khiển tương ứng sẽ được thực hiện .
Chúng ta sẽ viết 1 chương trình in lên màn hình chuỗi “HELLO!” . Thông điệp HELLO được định nghĩa như sau trong đoạn số liệu :
MSG DB ‘HELLO!$’
Lệnh LEA ( Load Effective Address )
LEA destnation , sốurce
Ngắt 21h , hàm số 9 sẽ xuất một chuỗi ký tự ra màn hình với điều kiện địa chỉ hiệu dụng của biến chuỗi phải ơ trên DX . Có thể thực hiện điều này bởi lệnh :
LEA DX,MSG ; đưa địa chỉ offset của biến MSG vào DX
ProgramSegmentPrefix(PSP) : Phần đầu của đoạn chương trình
Khi một chương trình được nạp vào bộ nhớ máy tính , DOS dành ra 256 byte cho cái gọi là PSP . PSP chưa một số thông tin về chương trình đang được nạp trong bộ nhớ . Để cho các chương trình có thể truy xuất tới PSP , DOS đặt số phân đoạn của nó (PSP) trong ca DS và ES trước khi thực thi chương trình . Kết qủa là thanh ghi DS không chứa số đoạn của đoạn số liệu của chương trình . Để khắc phục điều này , một chương trình có chứa đoạn số liệu phải được bắt đầu bởi 2 lệnh sau đây :
MOV AX,@DATA
MOV DS,AX
Ở đây @DATA là tên của đoạn số liệu được định nghĩa bởi DATA . Assembler sẽ chuyển @DATA thành số đoạn .
Sau đây là chương trình hoà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
Chúng ta sẽ viết 1 chương trình yêu cầu người dùng go vào một ký tự bằng chư thường . Chương trình sẽ đổi nó sang dạng chư hoa rồi in ra ơ dòng tiếp
theo .
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ố 1
MOV AH,9
INT 21H ; xuất nó ra màn hình
;nhập vào một ký tự thường và đổi nó thành ký tự hoa
MOV AH,1 ; nhập vào 1 ký tự
INT | 21H | ; cất nó trong AL |
SUB | AL,20H | ; đổi thành chư hoa và cất nó trong AL |
MOV CHAR, AL ; cất ký tự trong biến CHAR
; xuất ký tự trên dòng tiếp theo
LEA DX, MSG2 ; lấy thông điệp thứ 2
MOV AH,9
INT 21H ; xuất chuỗi ký tự thứ hai , vì MSG2 không kết
;thúc bởi ký tự $ nên nó tiếp tục xuất ký tự có trong biến CHAR
;dos exit
MOV AH,4CH
INT 21H ; dos exit
MAIN
ENP END