LẬP TRÌNH ASSEMBLY TRÊN VI XỬ LÝ 8088/8086

Share:

1. Giới thiệu về Hợp ngữ:

Hợp ngữ (Assembly) là một ngôn ngữ lập trình cấp thấp, nó thực chất là dạng gợi nhớ (Mnemonic), hay dạng kí hiệu, của ngôn ngữ máy.

Lập trình hợp ngữ - tinhoccoban.netNhư đã biết, lệnh ngôn ngữ máy là một dãy các con số 0, 1 nên rất khó đọc và khó lập trình, vì thế các nhà thiết kế vi xử lý đã đưa ra tập lệnh hợp ngữ gần với ngôn ngữ tự nhiên hơn nên dễ đọc và dễ lập trình hơn. Tuy vậy, các lệnh hợp ngữ vẫn giao tiếp với phần cứng máy tính một cách rất chặt chẽ, nhờ đó việc tiếp cận với lập trình hợp ngữ giúp chúng ta hiểu rõ hơn về kiến trúc và tổ chức hoạt động của máy tính.

Ngoài ra nó còn giúp chúng ta thấy rõ hơn mối quan hệ giữa các thành phần chức năng bên trong máy tính và hệ điề hành. Có thể nói ngược lại là, việc tìm hiểu và lập trình trên hợp ngữ giúp chúng ta hiểu rõ hơn về kiến trúc máy tính, tổ chức hoạt động bên trong máy tính và hệ điều hành.

Trong giới hạn của tài liệu này chúng ta chỉ tìm hiểu tập lệnh hợp ngữ của các vi xử lý họ Intel 8088/8086, để  lập trình chạy trên các máy IBM-PC: Sử dụng họ vi xử lý này và hoạt động trong sự phối hợp với hệ điều hành MS_DOS.

Một trong những đặc điểm của hợp ngữ là chương trình viết trên nó có kích thước nhỏ hơn và tốc độ nạp/thực hiện chương trình nhanh hơn so với viết (chương trình cùng chức năng) trên các ngôn ngữ lập trình bậc cao.

Ngoài ra, hầu hết các ngôn ngữ lập trình bậc cao hiện nay đều cho phép viết (“nhúng”) mã lệnh hợp ngữ trong nó. Điều này giúp người lập trình khai thác tối đa thế mạnh của các ngôn ngữ lập trình, hợp ngữ rất mạnh trong các thao tác can thiệp sâu vào các thành phần bên trong hệ thống, trong khi đó ngôn ngữ bậc cao mạnh trong các thao tác xử lý dữ liệu và thiết kế giao diện. Như vậy sẽ là rất thuận lợi nếu sử dụng ngôn ngữ bậc cao để viết chương trình xử lý thông tin hệ thống, khi đó nhiệm vụ truy xuất hệ thống (thanh ghi, bộ nhớ, cổng vào/ra, thiết bị,...) để lấy dữ liệu sẽ được giao cho các đoạn mã lệnh hợp ngữ được nhúng trong chương trình này.

Hợp ngữ hỗ trợ 2 chế độ tương tác hệ thống: (1) Nhập trực tiếp từng lệnh/đoạn lệnh vào bộ nhớ rồi cho phép thực hiện ngay trên bộ nhớ mà không cần qua bước biên dịch chương trình. Chương trình gỡ rối Debug (đi kèm hệ điều hành MS_DOS: Debug.exe) là một trong những chương trình hỗ trợ chế độ này cho hợp ngữ 16 bít; (2) Viết chương trình hợp ngữ, rồi sau đó sử dụng các chương trình biên dịch để dịch nó sang chương trình thực thi (dạng EXE hoặc COM) và cho thực hiện chương trình này.

Hiện nay có hai loại trình biên dịch được sử dụng để biên dịch chương trình hợp ngữ (từ tập lệnh hợp ngữ của các vi xử lý họ Intel) sang chương trình thực thi: Trình biên dịch hợp ngữ 16 bít, MASM (Macro Assembler), được sử dụng để dịch thành các chương trình chạy trên nền hệ điều hành 16 bít MS_DOS; Trình biên dịch hợp ngữ 32 bít, MASM32 (Macro Assembler 32 bít), được sử dụng để dịch thành các chương trình chạy trên nền hệ điều hành 32 bít MS_Windows. Trong thực tế, để chuyển một chương trình hợp ngữ sang dạng chương trình thực thi EXE 16 bít hoặc COM 16 bít thì cần phải có sự hỗ trợ của chương trình tiện ích của hệ điều hành MS_DOS: Link (Link.exe) và EXE2Bin (EXE2Bin.com).

Chương trình hợp ngữ 16 bít sử dụng hệ thống các ngắt mềm (Interrupt) của BIOS và DOS như là thư viện lập trình của nó, trong khi đó chương trình hợp ngữ 32 bít sử dụng tập hàm API làm thư viện lập trình của nó.

2. Biến – Hằng trong chương trình hợp ngữ:

Biến và hằng

Biến và hằng (hằng có tên) trong chương trình hợp ngữ có tính chất, mục đích sử dụng, kiểu dữ liệu, quy tắc đặt tên, quy tắc gán giá trị,... tương tự như biến và hằng trong các ngôn ngữ lập trình bậc cao khác. Biến trong chương trình hợp ngữ chỉ có các kiểu dữ liệu là: Byte, Word, Doubleword,... và hằng trong chương trình hợp ngữ có thể là số, kí tự hoặc một xâu kí tự.  

Khi viết chương trình hợp ngữ chúng ta cần quan tâm đến địa chỉ của biến trong bộ nhớ. Một biến được khai báo trong chương trình sẽ được hệ thống gán cho một địa chỉ trong bộ nhớ (khi chương trình được nạp vào bộ nhớ để hoạt động). Cụ thể: mỗi biến trong chương trình sẽ được định vị tại một địa chỉ xác định trong bộ nhớ, và các biến được khai báo liên tiếp nhau trong chương trình (từ trên xuống dưới) sẽ được định vị tại các địa chỉ liên tiếp nhau trong bộ nhớ (từ offset thấp đến offset cao). Nhờ đó, nếu chương trình xác định được địa chỉ của một biến nào đó thì nó dễ dàng có được địa chỉ và nội dung của các biến khác trong chương trình.

Khác với biến, hằng trong chương trình hợp ngữ không được cấp phát bộ nhớ để lưu trữ, tức là, nơi nào trong chương trình chứa trên hằng thì sẽ được trình biên dịch thay bằng giá trị của nó một cách trực tiếp.

Hợp ngữ cung cấp các toán tử giả để định nghĩa/khai báo dữ liệu: DB (định nghĩa byte), DW (định nghĩa word), DD (định nghĩa doubleword),.... Và toán tử EQU để khai báo hằng. Biến có thể được khai báo ở đầu hoặc ở cuối chương trình. Trong khi đó, hằng có thể khai báo ở bất kỳ nơi đâu trong chương trình, khi đó ta có thể sử dụng toán tử dấu “=” để gán giá trị cho hằng.  

Khai báo biến – hằng:

Cú pháp khai báo:          

a:        <Tên biến>    DB       <Trị khởi tạo>      
b:        <Tên biến>    DW      <Trị khởi tạo>      
c:         <Tên biến>    DD      <Trị khởi tạo>      
d:        <Tên hằng>   EQU    <Hằng số>
            Trường hợp a được sử dụng để khai báo biến kiểu byte, trường hợp b được sử dụng để khai báo biến kiểu word, trường hợp c được sử dụng để khai báo biến kiểu doubleword, trường hợp d được sử dụng để khai báo hằng. <Trị khởi tạo> có thể một hoặc nhiều giá trị, nó có thể là một số, một kí tự hoặc một xâu kí tự, và cũng có thể là một dấu hỏi chấm (“?”). <Hằng số> có thể là một số, một kí tự hay một xâu kí tự.

Ví dụ 1:        
Spt                 DB      0
KiTu               DB      ‘a’
TieuDe           DB      ‘Tin hoc’
SoNguyen      DW     ?
DaySo           DD      1020, 1345, 2389, 5763
Trong ví dụ trên, hai biến Spt và Kitu đều là biến kiểu byte, kích thước 1byte. Biến TieuDe cũng là biến kiểu byte nhưng gồm 7 byte ô nhớ liên tiếp (kích thước 7 byte), mỗi byte chứa 1 kí tự ASCII. Biến SoNguyen là biến kiểu word, chưa được gán giá trị khởi tạo. Biến DaySo là biến kiểu doubleword, gồm 4 phần tử có giá trị lần lượt (từ thấp đến cao) là: 1020, 1345, 2389, 5763.