phÇn i: bé vi xö lý · web viewnhãn đích nằm trong cùng đoạn với jmp, vượt xa 126...

143
Gi¸o tr×nh vi xö lý 1.1. TỔNG QUAN VỀ CÁC BỘ VI XỬ LÝ CỦA INTEL Một hệ vi xử lý được gọi là một hệ thống trong đó bao gồm: - Đơn vị nhập xuất: Được sử dụng để nhập và xuất số liệu, dữ liệu. - Đơn vị xử lý: Xử lý các dữ liệu nhập vào, sau đó xuất ra các thiết bị ra. - Bộ nhớ: Lưu trữ thông tin, dữ liệu trong quá trình xử Tất cả các thiết bị có các chức năng như vậy đều có thể được gọi là một hệ vi xử lý. Máy vi tính là một hệ thống vi xử lý. Một thành phần quan trọng trong hệ thống máy vi tính, đó là bộ vi xử lý. Trên thự tế, có rất nhiều hãng chế tạo bộ vi xử lý cho các máy vi tính như: IBM, Intel, Cyrix, AMD, Motorola.... Nhưng thông dụng nhất vẫn là bộ vi xử lý của Intel. Các bộ vi xử lý của Intel được phát triển qua các thời kỳ như sau: Năm 1971, Intel đưa ra bộ vi xử lý 4004 với 4 bit dữ liệu, 12 bit địa chỉ; 0,8MHz Năm 1972, bộ vi xử lý Intel 8080 ra đời với 8bit dữ liệu, 12 bit địa chỉ; tốc độ xử lý 0,8-5MHz Năm 1974, bộ vi xử lý Intel 8085 ra đời với 8bit dữ liệu, 16 bit địa chỉ; tốc độ xử lý 5MHz Năm 1978, bộ vi xử lý Intel 8086 ra đời với 16bit dữ liệu, 20 bit địa chỉ; tốc độ xử lý 10MHz Khoa CNTT Trang 1 KTMT

Upload: dinhkien

Post on 21-Apr-2018

217 views

Category:

Documents


5 download

TRANSCRIPT

Gi¸o tr×nh vi xö lý

1.1. TỔNG QUAN VỀ CÁC BỘ VI XỬ LÝ CỦA INTELMột hệ vi xử lý được gọi là một hệ thống trong đó bao gồm:

- Đơn vị nhập xuất: Được sử dụng để nhập và xuất số liệu, dữ liệu. - Đơn vị xử lý: Xử lý các dữ liệu nhập vào, sau đó xuất ra các thiết bị ra.- Bộ nhớ: Lưu trữ thông tin, dữ liệu trong quá trình xử lý

Tất cả các thiết bị có các chức năng như vậy đều có thể được gọi là một hệ vi xử lý. Máy vi tính là một hệ thống vi xử lý. Một thành phần quan trọng trong hệ thống máy vi tính, đó là bộ vi xử lý.Trên thự tế, có rất nhiều hãng chế tạo bộ vi xử lý cho các máy vi tính như: IBM, Intel, Cyrix, AMD, Motorola.... Nhưng thông dụng nhất vẫn là bộ vi xử lý của Intel.Các bộ vi xử lý của Intel được phát triển qua các thời kỳ như sau:

Năm 1971, Intel đưa ra bộ vi xử lý 4004 với 4 bit dữ liệu, 12 bit địa chỉ; 0,8MHzNăm 1972, bộ vi xử lý Intel 8080 ra đời với 8bit dữ liệu, 12 bit địa chỉ; tốc độ xử lý 0,8-5MHzNăm 1974, bộ vi xử lý Intel 8085 ra đời với 8bit dữ liệu, 16 bit địa chỉ; tốc độ xử lý 5MHzNăm 1978, bộ vi xử lý Intel 8086 ra đời với 16bit dữ liệu, 20 bit địa chỉ; tốc độ xử lý 10MHzNăm 1979, bộ vi xử lý Intel 8088 ra đời nhằm mục đích giảm giá bộ vi xử lý và tương thích với hệ thống 8086 cũNăm 1982 bộ vi xử lý 80286 ra đời với 16bit dữ liệu, 20 bit địa chỉ, tốc độ xư lý là 20MHz có thể định địa chỉ ở chế độ bảo vệ và chế độ thực.Năm 1985-1988, bộ vi xử lý 80386 ra đời với 32 bit dữ liệu và 32 bit địa chỉ tốc độ xử lý 33-40MHzNăm 1989, bộ vi xử lý 80486 ra đời với 32 bit dữ liệu và 32 bit địa chỉ tốc độ xử lý 50-60MHzNăm 1993, bộ vi xử lý Pentium ra đời với 64 bit dữ liệu, tốc độ xử lý 100MHz

Sau đó là các bộ vi xử lý Pentium Pro,Pentium II, Pentium III, Celeron, Pentium 4

Khoa CNTT Trang 1 KTMT

Gi¸o tr×nh vi xö lý

1.2. CẤU TRÚC BỘ VI XỬ LÝ 8086

1.2.1. Sơ đồ khối

1.2.2. Giải thích các thành phần trong sơ đồ

Khoa CNTT Trang 2 KTMT

E.U (execution unit) B.I.U (Bus interface unit)

Các thanh ghi đa năng

Các thanh ghi con trỏ và chỉ số

Các thanh ghi tạm thời

AXBXCXDXSPBPSIDI

CSDSSSESIP

ALU

Thanh ghi cờ

Khối điều

khiển của EU

Logic điều khiển Bus

Đệm lệnh (hàng đợi lệnh)

(6 byte cho 8086)

Bus ngoài

Bus dữ liệu(8 bit)

Bus trongcủa CPU 8 bit dữ liệu20 bit địa chỉ

Bus địa chỉ (20 bit)

Các thanh ghi đoạn và con trỏ lệnh

Accumulator Base Count Data Stack pointerBase pointerSource indexDestination index

Code segmentData segmentStack segmentExtra segmentIntruction pointer

Bus dữ liệuALU (16 bit)

Hình 1.1: Sơ đồ cấu trúc bên trong bộ vi xử lý 8086/8088

Gi¸o tr×nh vi xö lý

Khối phối ghép Bus (Bus Interface Unit - BIU)Khối thực hiện lệnh (Execution Unit - EU)

Đơn vị EU Đơn vị EU của 8086 và 8088 là giống nhau nó bao gồm ALU, các thanh ghi cờ,

thanh ghi đệm và các thanh ghi đa năng. Các kênh truyền dữ liệu bên trong EU đều là 16 bit.

EU không nối trực tiếp với thế giới bên ngoài, nó lấy lệnh từ hàng đợi lệnh của BIU. Nếu lệnh cần truy xuất bộ nhớ hoặc cổng vào/ra (là nơi liên hệ với thiết bị ngoại vi ) thì EU yêu cầu BIU nhận hoặc gửi dữ liệu. Tất cả các địa chỉ mà BIU thao tác đều là 16 bit, khi gửi sang cho BIU sẽ sắp đặt lại để tạo thành địa chỉ vật lý 20 bit phát ra các chân ra địa chỉ của chip.

Đơn vị BIU Đơn vị BIU thực hiện tất cả các thao tác với Bus mà BIU yêu cầu, ngoài ra khi

BIU đang thực hiện một lệnh, thì BIU có thể lấy lệnh từ bộ nhớ về đặt trong hàng đợi lệnh. Hàng đợi lệnh của 8086 dài 6 byte, của 8088 dài 4 byte. Việc lấy lệnh về của BIU và việc thực hiện lệnh của BIU thực hiện song song với nhau (trừ một số trường hợp ngoại lệ) làm cho hiệu năng của vi xử lý tăng lên.

1.2.3. Một số khái niệm cơ bản

* Pipelining: Là một phương pháp xử lý lệnh trên một đường ống lệnh, có thể xử lý nhiều lệnh đồng thời trong cùng một khoảng thời gian. Trong khi lệnh này đang được xử lý thì lệnh tiếp sau nó đã được nhận vào...

Chúng ta có thể so sánh phương pháp xử lý bằng pipeline và phương pháp xử lý dòng lệnh tuần tự như hai hình dưới đây:

a)

b)

Khoa CNTT Trang 3 KTMT

Gi¸o tr×nh vi xö lý

Hình 1.2. So sánh pipeline và tuần tựa) Xử lý bằng Pipeline b) Xử lý tuần tự

* CISC, RISC và VLIWCISC – Complex Instruction Set Computer (Máy tính với tập lệnh đầy đủ)RISC – Reduced Instruction Set Computer (Máy tính với tập lệnh rút gọn)VLIW – Very Long Instruction Word (Máy tính với từ lệnh cực dài)

Về cơ bản, công nghệ hiện nay vẫn dựa trên cơ sở bộ vi xử lý CISC và RISC. Chúng ta có thể so sánh sơ bộ về hai công nghệ này:

RISC CISC

Cấu thành từ một vài lệnh đơn

Các lệnh được thực thi bằng phần cứng

Kích thước của một lệnh và thời gian thực thi của mỗi lệnh gần như nhau

Đầy đủ với độ phân cấp Các lệnh được thực thi

bằng các vi chương trình Kích thước và thời gian

thực hiện của các lệnh khác nhau.

1.3. TẬP THANH GHI CỦA BỘ VI XỬ LÝ 8086

1.3.1. Các thanh ghi dữ liệu

Mặc dù bộ vi xử lý có thể thao tác với dữ liệu bộ nhớ nhưng một lệnh như vậy sẽ được thực hiện nhanh hơn (cần ít chu kỳ đồng hồ hơn), nếu dữ liệu được lưu trong các thanh ghi. Đó cũng là nguyên nhân tại sao ngày nay các bộ vi xử lý được sản xuất với xu hướng có nhiều thanh ghi hơn.

Với các thanh ghi dữ liệu các byte thấp và byte cao có thể được truy nhập một cách riêng biệt, sử dụng từng 8 bit một cách rieng rẽ. Byte cao của thanh ghi AX được gọi là AH và các byte thấp được gọi là AL. Tương tự cho các thanh ghi BX, CX, DX có BH, BL, CH, CL, DH, DL.

Chức năng chuyên biệt của từng thanh ghi dữ liệu:1. Thanh ghi AX (thanh ghi chứa- Accumulator register)

Khoa CNTT Trang 4 KTMT

Gi¸o tr×nh vi xö lý

AX là thanh ghi được sử dụng nhiều nhất trong các lệnh số học, logic, và chuyển dữ liệu bởi vì việc sử dụng chúng tạo ra mã máy ngắn nhất.

Trong các phép toán nhân chia một trong các số hạng tham gia phải được chứa trong thanh ghi AX (nếu là 16 bit) và AL (nếu là 8 bit). Các thao tác vào ra cũng sử dụng thanh ghi AX hoặc AL.2. Thanh ghi BX (thanh ghi cơ sở- Base register)

Thanh ghi này ngoài việc thao tác dữ liệu nó thường chứa địa chỉ cơ sở của một bảng dùng cho lệnh XLAT.(dịch AL thành 1 giá trị trong bảng BX)3. Thanh ghi CX (thanh ghi đếm- Count register)

Việc xây dựng một chương trình lặp được thực hiện dễ dàng bằng cách sử dụng thanh ghi CX, trong đó CX đóng vai trò bộ đếm số vòng lặp (REP, LOOP). CL được dùng làm bộ đếm trong các lệnh dịch và quay bit.4. Thanh ghi DX (thanh ghi dữ liệu - Data register)

DX và AX cùng được sử dụng trong các thao tác của phép nhân hoặc chia các số 16 bit. DX còn được sử 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 (In/Out).

1.3.2. Các thanh ghi đoạn: CS, DS, ES, SS

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 được 220= 1. 048. 576 = 1 Mbyte ô nhớ. Nói cách khác không gian địa chỉ của 8088 là 1 Mbyte. Trong không gian 1 Mbyte bộ nhớ này cần chia thành nhiều đoạn khác nhau:

Đoạn chứa chương trìnhĐoạn chứa dữ liệu và kết quả trung gian của chương trìnhTạo ra vùng nhớ đặc biệt gọi là ngăn xếp

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 đoạn trên và chúng được gọi là các thanh ghi đoạn (Segment Registers): CS, DS, SS, ES.

Các thanh ghi đoạn này chỉ ra địa chỉ đàu của 4 đoạn trong bộ nhớ dung lượng lớn nhất của 4 đoạn này là 64 Kbyte. Các đoạn có thể nằm cách nhau hoặc trùm lên nhau

Nội dung của thanh ghi sẽ xác định địa chỉ của ô nhớ đầu tiên của đoạn, địa chỉ này gọi là địa chỉ cơ sở. Địa chỉ của các ô nhớ khác trong cùng đoạn được tính 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)

Khoa CNTT Trang 5 KTMT

Gi¸o tr×nh vi xö lý

Địa chỉ vật lý (20 bit) của một ô nhớ được xác định như sau:Điạ chỉ vật lý = Điạ chỉ đoạn *10 h+ thanh ghi lệch (hay offset)

và điạ chỉ logic trong máy tính luôn được biểu diễn dưới dạng: Segment:OffsetTại mọi thời điểm thì chỉ những ô nhớ được định địa chỉ bởi 4 đoạn trên mới

được truy cập.

1.3.3. Các thanh ghi con trỏ và chỉ số: SI, DI, SP, BP

Trong 8088 có 3 thanh ghi con trỏ và 2 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 gầm định như là thanh ghi lệch cho các đoạn tương ứng. Cụ thể như sau:1. Thanh ghi 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ỉ cụ thể SS:BP được xác định như trên.2. Thanh ghi SP(con trỏ ngăn xếp - Stack Pointer)

Được sử dụng kết hợp với SS để truy nhập vào đoạn ngăn xếp. SP luôn trỏ vào đỉnh hiện thời của ngăn xếp trong đoạn ngăn xếp SS. Địa chỉ cụ thể SS:SP3. Thanh ghi SI(chỉ số nguồn - Source Index). SI chỉ vào dữ liệu trong đoạn dữ liệu DS mà địa chỉ cụ thể tương ứng với DS:SI. Bằng cách tăng nội dung của SI chúng ta có thể truy nhập dễ dàng đến các ô nhớ liên tiếp.4. Thanh ghi DI (chỉ số đích - Destination Index).

SI chỉ vào dữ liệu trong đoạn dữ liệu DS mà địa chỉ cụ thể tương ứng với DS:DI. Có một số lệnh gọi là các thao tác chuỗi sử dụng DI để truy nhập đến các ô nhớ được định địa chỉ bởi ES.

1.3.4. Thanh ghi con trỏ lệnh: IP

Các thanh ghi bộ nhớ chúng ta vừa trình bày dùng để truy cập dữ liệu, để truy nhập đến các lệnh, 8088 sử dụng các thanh ghi CS và IP. Thanh ghi CS chứa điạ chỉ của lệnh tiếp theo còn IP chứa địa chỉ offset của lệnh đó. Thanh ghi IP được cập nhập mỗi khi có một lệnh được thực hiện.

1.3.5. Thanh ghi cờ

Khoa CNTT Trang 6 KTMT

Gi¸o tr×nh vi xö lý

Đây là thanh ghi 16 bit, mỗi bit được sử dụng để thể hiện một trạng thái của bộ vi xử lý tại một thời điểm nhất định trong quá trình thực hiện chương trình. Mới chỉ có 9 bit được sử dụng và người ta gọi mỗi bit là một cờ.

x x x x OF DF IF TF SF ZF X AF x PF x CF

* Các cờ trạng tháiCF (Carry Flag): được thiết lập khi phép toán thực hiện có nhớ hoặc có vay

mượnPF(Parity Flag): được thiết lập khi kết quả của phép toán có tổng số bit có giá trị

1 là một số chẵn (ở phần thấp của kết quả).AF (Auxiliary Flag): được thiết lập khi có nhớ từ "bit có trọng số lớn nhất ở

phần thấp" sang "bit có trọng số thấp nhất ở phần cao".ZF (Zero Flag): Được thiết lập khi tất cả các bit của kết quả có giá trị 0.SF ( Sign Flag): được thiết lập khi bit MSB của kết quả có giá trị 1.OF (Overflow Flag): được thiết lập khi kết quả nằm ngoài giới hạn cho phép.

*Các cờ điều khiểnTF (Trace Flag): Nếu bit này có giá trị 1 thì bộ vi xử lý cho phép thực hiện từng

bước chương trìnhIF (Interrupt Flag): Nếu bit này có giá trị 1 thì bộ vi xử lý cho phép các ngắt

cứng có thể thực hiện.DF (Direction Flag): Nếu bit này có giá trị 1 thì bộ vi xử lý cho phép duyệt

chuỗi từ phải sang trái hoặc từ địa chỉ cao đến địa chỉ thấp.

1.4. TẬP LỆNH CỦA BỘ VI XỬ LÝ

1.4.1. Sơ lược về tập lệnh của bộ vi xử lý

Tập lệnh của bộ vi xử lý là thành phần cơ bản nhất để máy tính có thể thực hiện các yêu cầu của người sử dụng. Tất cả các thao tác, các chương trình do người dùng lập ra đều được bộ vi xử lý thực hiện bằng việc ánh xạ chúng dưới dạng mã máy, mã lệnh riêng của bộ vi xử lý.

Thông thường, với các lập trình viên, các lệnh của bộ vi xử lý được hiểu dưới góc độ là các lệnh gợi nhớ (Mnemonic). Với mã lệnh gợi nhớ thì một lệnh của bộ vi xử lý bao gồm các thành phần sau:

[Mã lệnh] [Các toán hạng] Trong đó:

Khoa CNTT Trang 7 KTMT

Gi¸o tr×nh vi xö lý

Mã lệnh - Cơ bản trường này chứa mã lệnh dưới dạng mã gợi nhớ. Các toán hạng - Là các thành phần mà các lệnh sử dụng để thực hiện lệnh.Nếu là các lệnh thật thì đây chính là các toán hạng của lệnh. Với bộ vi xử lý

8086/8088, các toán hạng này có thể là 0,1 hoặc 2.Ví dụ:

ADD AL,[BX] ADD là lệnh thực hiện phép cộng; AL và [BX] là hai toán hạng với qui định nếu

tên thanh ghi hoặc một giá trị hằng nằm trong dấu [] thì đó là địa chỉ OFFSET của ô nhớ chứa dữ liệu cần thao tác.

1.4.2. Tập lệnh của CPU

Trong tập lệnh của vi xử lý 8086 có rất nhiều lệnh, mỗi lệnh thực hiện một nhiệm vụ cụ thể nào đó. Song, trong giới hạn nhất định, chúng ta có thể nghiên cứu một vài lệnh cơ bản.Để dễ hiểu, chúng ta có thể chia chúng các nhóm lệnh sau:

1. Nhóm lệnh di chuyển dữ liệu2. Nhóm lệnh số học3. Nhóm lệnh logic4. Nhóm lệnh dịch chuyển và quay5. Nhóm lệnh rẽ nhánh6. Nhóm lệnh vào ra cổng7. Nhóm lệnh điều khiển.

1.4.2.1 Nhóm lệnh di chuyển dữ liệuTrong nhóm này ta quan tâm một số lệnh cơ bản sau: MOV, MOVSB,

MOVSW XCHG, PUSH, POPa) Lệnh MOV: Move a Word or Byte (chuyển 1 từ hay 1 byte)

MOV đích, nguồnDi chuyển nội dung của toán hạng nguồn vào toán hạng đích. Hai toán hạng

phải có cùng độ lớn và không được đồng thời là 2 thanh ghi đoạn hoặc hai ô nhớ. Toán hạng đích phải là thanh ghi hay ô nhớ. Giá trị của toán hạng nguồn không bị thay đổi, sau khi thực hiện lệnh.

Ví dụ:

Khoa CNTT Trang 8 KTMT

Gi¸o tr×nh vi xö lý

MOV ax,word1Trước lệnh Mov Ax có nội dung : 0002h

Word1 : 0008hSau lệnh Mov Ax có nội dung : 0008h

Word1 : 0008hMột số chú ý:- Toán hạng đích không thể là một hằng số- Không thể chuyển trực tiếp một giá trị byte vào một toán hạng đích là một từ

và ngược lại. Nếu cần, có thể sử dụng các toán tử PTR BYTE hoặc PTR WORD- Không thể chuyển trực tiếp một hằng số vào một thanh ghi đoạn. Trong trường

hợp cần thiết, có thể chuyển tạm thời qua một thanh ghi khácVí dụ: Muốn chuyển giá trị 100 vào thanh ghi DS, ta có thể sử dụng hai lệnh sau

MOV AX,100MOV DS,AX

MOVSB/MOVSW chuỗi đích, chuỗi nguồnlà hai lệnh dùng để chuyển các phần tử của một chuỗi nguồn sang một chuỗi đích.

MOVSB: MOVe String ByteMOVSW: MOVe String Word

b) XCHG: eXCHanGe 2 operands ( tráo đổi nội dung của hai toán hạng)XCHG đích, nguồnTráo đổi nội dung của toán hạng đích và toán hạng nguồn cho nhau.Ví dụ: XCHG AX,BX

Trước lệnh XCHG AX có nội dung : 153EhBX : 28FCh

Sau lệnh Mov AX có nội dung : 28FChBX : 153Eh

Một số chú ý:- Cả hai toán hạng không thể là hằng số- Không thể tráo đổi hai toán hạng khác kiểu. Nếu cần, có thể sử dụng

các toán tử PTR BYTE hoặc PTR WORD.- Không được phép là 2 thanh ghi đoạn- Không được phép là hai ô nhớ.

Khoa CNTT Trang 9 KTMT

Gi¸o tr×nh vi xö lý

c) PUSH: PUSH Word On the Stack (Đẩy vào ngăn xếp)PUSH toánhạngĐẩy nội dung của toán hạng vào ngăn xếp, nội dung của toán hạng không bị thay

đổi. (copy nội dung) Toán hạng nhất thiết phải là thanh ghi (đối với 8086/8088)Ví dụ:

PUSH AXĐẩy nội dung của thanh ghi AX vào ngăn xếpd) POP: POP Word from Top of Stack (lấy ra từ đỉnh ngăn xếp).

POP đíchToán hạng nhất thiết phải là thanh ghi (đối với 8086/8088), trừ thanh ghi CS

1.4.2.2. Nhóm lệnh số học Trong nhóm này ta quam tâm đến các lệnh cơ bản sau: ADD, ADC, INC, SUB, SBB, DEC MUL(IMUL), DIV(IDIV)a) ADD:Addition (cộng hai toán hạng)

ADD đích, nguồnCộng toán hạng đích với toán hạng nguồn. Kết quả được chứa trong toán hạng đích

đích=đích+nguồnĐiều kiện: hai toán hạng phải cùng độ dài, không được là hai thanh ghi đoạn

ADD ax,word1Ax= ax+word1

b) SUB: Subtraction (trừ)Sub đích,nguồnTrừ nội dung của toán hạng đích cho toán hạng nguồn, kết quả chứa trong toán

hạng đích.Ví dụ: MOV BX, F0h

SUB BX,50hBX=F0h-50h=A0h

c) MUL: Multiplexing - Multiply Unsigned Byte or Word (nhân số không dấu)Nhân toán hạng với nội dung chứa trong thanh ghi AX. Tức là nhân hai toán hạng với nhau nhưng 1 toán hạng phải được chứa trong AX. Hoặc là trong DX và AX

Khoa CNTT Trang 10 KTMT

Gi¸o tr×nh vi xö lý

MUL gốcTuỳ vào độ dài của toán hạng gốc mà xác định kết quả:

- gốc: 8 bit thì số bị nhân trong AL -> kết quả trong AX- gốc: 16 bit thì số bị nhân trong AX -> kết quả trong DX:AX

Ví dụ:MOV AL,10hMOV BL,5hMUL BL

Vì toán hạng nguồn là thanh ghi BL, nên kết quả sẽ được lấy ra trong AX. AX=50hTrong trường hợp muốn nhân số có dấu, ta có thể sử dụng lệnh IMUL có dạng lệnh như lệnh MUL.d) DIV: Unsigned Divide (chia hai số không dấu)

DIV nguồn- nguồn là số 8 bit: AX/nguồn số bị chia phải là số không dấu 16 bit trong AX

sau khi chia AL chứa thương còn AH chứa số dư.- nguồn là số 16 bit: DX:AX/nguồn số bị chia phải là số không dấu và đặt

trong cặp DX:AX sau khi chia; AX chứa thương còn DX chứa số dư.nguồn =0 (chia cho 0) hoặc kết quả lớn hơn FFH, FFFFh thì gọi ngắt INT 0

Trong trường hợp muốn chia số có dấu, ta có thể sử dụng lệnh IDIV có dạng lệnh như lệnh DIV.

1.4.2.3. Nhóm lệnh logicTrong nhóm này ta quan tâm đến các lệnh sau: AND, OR, XOR, NOT

a) AND: và hai toán hạngAND đích,nguồn

Đích, nguồn phải có điều kiện: - cùng độ dài- không phải đồng là 2 ô nhớ, 2 thanh ghi đoạn.thường dùng để che đi hay giữ lại một vài bit nào đó của toán hạng đích

ví dụ: AND AX,0Fhb) OR : hoặc hai toán hạng

OR đích,nguồnĐích, nguồn phải có điều kiện:

Khoa CNTT Trang 11 KTMT

Gi¸o tr×nh vi xö lý

- cùng độ dài- không phải đồng là 2 ô nhớ, 2 thanh ghi đoạn.thường dùng để lập một vai bit nào đó của toán hạng đích= cách cộng logic toán

hạng đó với toán hạng tức thời mà các bit 1 có vị trí tương ứng với bit cần lập.Ví dụ: OR AL,BL

OR AL,0Fhc) NOT: lấy phủ định - đảo bit NOT toánhạng

Dùng để đảo bit của một toán hạng (lấy bù 1)d) XOR: hoặc loại trừ toán hạng

Dùng để xoá về 0 một thanh ghi nào đóVí dụ: XOR AX,AX ; Xoá thanh ghi AX về 0

1.4.2.4 Nhóm lệnh dịch chuyển và quayCác lệnh cần quan tâm: SHL, SHR, ROL, ROR

a) SHL: Shift Left - dịch tráiSHL đích,1SHL đích,CLDịch các bit của toán hạng đích sang trái một vị trí hoặc CL vị trí. Một giá trị 0 được đưa vào bên phải của toán hạng đích, còn bit MSB được đưa vào CF.

Thực hiện phép nhân bằng cách dịch trái.b) SHR: Shift Right ; Dịch phải

SHR đích,CLDịch các bit của toán hạng đích sang phải 1 hoặc CL vị trí.Giá trị 0 được đưa vào bit MSB còn gía trị của bit LSB được chuyển vào cờ CF.

Dùng lệnh dịch phải thực hiện phép chia.

Khoa CNTT Trang 12 KTMT

0CF

LỆNH SHL

0CF

LỆNH SHR

015

Gi¸o tr×nh vi xö lý

c) ROL:Rotation Left- quay tráiROL đích,CLDịch các bit sang bên trái. bit MSB được đưa vào LSB và cờ CF. muốn quay nhiềulần thì chứa trong CL

d) ROR:Rotation Right- quay phảiROR đích,CLDịch các bit sang bên phải. Bit LSB được đưa vào MSB và cờ CF. muốn quay nhiều lần thì chứa trong CL

* Các lệnh quay qua cờ nhớ: RCL, RCR.* Các ví dụ đưa ra và yêu cầu tìm giá trị của đích và CF sau CL lần dịch, quay.

1.4.2.5. Nhóm lệnh điều khiển rẽ nhánha) Nhảy có đìêu kiện

Jxxx nhãn_đíchNếu điều kiện nhảy được thoả thì sẽ nhảy đến nhãn_đích và thi lệnh này. nhãn có thể trước hoặc sau. Trước không quá 126 byte, sau không quá 127 byte.Bảng các lệnh nhảyNhảy có dấu

Kí hiệu Chức năng Điều kiện nhảy

Jg/jnle Nhảy nếu lớn hơn Zf=0, sf=of

Khoa CNTT Trang 13 KTMT

CF

LỆNH ROR

015LSB LSB

CF

LỆNH ROL

MSB MSB

Gi¸o tr×nh vi xö lý

Nhảy nếu không nhỏ hơn hay bằng

Jge/jnl Nhảy nếu lớn hơn hay bằngNhảy nếu không nhỏ hơn

Sf=0f

Jl/jnge Nhảy nếu nhỏ hơnNhảy nếu không lớn hơn hay bằng

Sf<>of

Jle/jng Nhảy nêu nhỏ hơn hay bằngNhảy nếu không lớn hơn

Zf=1 hay sf=of

Nhảy không dấu

Ja/jnbe Nhảy nếu lớn hơnNhảy nếu không nhỏ hơn hay bằng

Cf=0 và zf=0

Jae/jnb Nhảy nếu lớn hơn hay bằngNhảy nếu không nhỏ hơn

Cf=0

Jb/jnae Nhảy nếu nhỏ hơnNhảy nếu không lớn hơn hay bằng

Cf=1

Nhảy điều kiện đơn

Je/jz Nhảy nếu bằngNhảy nếu bằng 0

Zf=1

Jne/jnz Nhảy nếu không bằngNhảy nếu không bằng 0

Zf=0

b) Nhảy không điều kiệnJMP nhãn_đíchNhãn đích nằm trong cùng đoạn với JMP, vượt xa 126 byte đối với các lệnh nhảy có điều kiện.

1.4.2.6. Nhóm lệnh vào ra cổnga) IN: nhập vào từ cổng 1 byte hay 1 word

IN thanhchứa, cổngNếu thanh chứa là AL thì dữ liệu 8 bit được đưa vào có giá trị là điạ chỉ cổngNếu thanh chứa là AX thì dữ liệu 16 được đưa vào từ cổng có giá trị là điạ chỉ cổng +1

Khoa CNTT Trang 14 KTMT

Gi¸o tr×nh vi xö lý

Điạ chỉ cổng trong khoảng 00h - FFhb) OUT:xuất ra cổng 1 byte hay 1 wordOUT điạchỉcổng,Acc

1.4.2.7. Nhóm lệnh điều khiểna) CALL chương_trình_con

Gọi một chương trình con có tên gọi: chương_trình_conb) INT số_hiệu_ngắt

Lệnh gọi ngắt với số_hiệu_ngắtc) HLT Lệnh treo máy dừng chương trìnhd) NOP: No Operation không thực hiện lệnh nào cả.

1.5. CHẾ ĐỘ ĐỊA CHỈ CỦA BỘ VI XỬ LÝ 8086

1.5.1. Tổng quan

Các chế độ địa chỉ chính là phương pháp để xác định toán hạng hoặc kiểu toán hạng trong các câu lệnh. Bộ vi xử lý 8086/8088 có tổng số trên 20 chế độ địa chỉ cho các thành phần khác nhau như mã lệnh, dữ liệu, ngăn xếp. Nhưng trên thực tế, việc lập trình, phân tích lệnh, người ta chỉ qua tâm đến việc dữ liệu của lệnh được xử lý ra sao. Vì vậy, chúng ta cũng chỉ nghiên cứu về các chế độ địa chỉ dữ liệu của lệnh.

Trong bộ vi xử lý 8086 qui định có 7 chế độ địa chỉ cho toán hạng của lệnh. Cụ thể bao gồm các chế độ sau:

- Chế độ địa chỉ thanh ghi- Chế độ địa chỉ tức thì- Chế độ địa chỉ trực tiếp- Chế độ địa chỉ gián tiếp thanh ghi- Chế độ địa chỉ tương đối cơ sở- Chế độ địa chỉ tương đối chỉ số- Chế độ địa chỉ tương đối chỉ số cơ sở

1.5.2. Các chế độ địa chỉ dữ liệu

1.5.2.1 Chế độ địa chỉ thanh ghiTrong chế độ này việc trao đổi thông tin diễn ra trực tiếp giữa các thanh ghi.

Toán tử chỉ hoàn toàn là các thanh ghi. Loại địa chỉ thanh ghi không cần truy nhập bộ nhớ nên rất nhanh.

Khoa CNTT Trang 15 KTMT

Mã lệnh Tên các thanh ghi

Tập các thanh ghi

Toán hạng

Gi¸o tr×nh vi xö lý

Ví dụ: MOV AX, BX ;Sao chép nội dung thanh ghi BX sang thanh ghi AX.MOV AL,CL ; Sao chép nội dung thang ghi CL sang thanh ghi AL.ADD AL, CL ; Cộng nội dung thanh ghi Clvới thanh ghi AL.

1.5.2.2 Chế độ địa chỉ tức thìTrong chế độ này toán hạng đích là một thanh ghi hoặc ô nhớ, còn toán hạng

nguồn là một hằng số. Ta có thể dùng chế độ này để nạp dữ liệu vào bất kỳ thanh ghi nào, trừ thanh ghi đoạn và thanh ghi cờ.

Ví dụ: MOV CL, 5Fh; chuyển 5Fh vào thanh ghi CL.MOV AX, 0FF0h; Chuyển 0FF0h vào trong thanh ghi AXMOV DS, AX; Chuyển nội dung thanh ghi AX vào DS.MOV [BX], 10; Chuyển 10 vào ô nhớ tại địa chỉ DS:BXX

1.5.2.3 Chế độ địa chỉ trực tiếp.Trong chế độ này, một toán hạng chứa địa chỉ lệch của ô nhớ dùng chứa dữ liệu,

còn toán hạng kia chỉ có thể là thanh ghi.

Khoa CNTT Trang 16 KTMT

Mã lệnh Tên các thanh ghi

Hằng số

Gi¸o tr×nh vi xö lý

Ví dụ: MOV Al, [1053] ; Chuyển nội dung ô nhớ địa chỉ DS:1053h vào ALMOV [5307h], CX ; Chuyển nội dung CX vào 2 ô nhớ liên tiếp có địa

; chỉ DS:5307h và DS:5308hADD [5307h], AL ; Cộng nội dung AL vào ô nhớ có địa chỉ DS:5307h

1.5.2.4 Chế độ địa chỉ gián tiếp thanh ghiTrong chế độ này, một toán hạng là một thanh ghi được sử dụng để chứa địa chỉ

lệch (Offset) 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ớ.

Ví dụ: MOV AL, [BX] ; Chuyển nội dung ô nhớ có đ/c DS:BX vào ALMOV [SI], CL ; Chuyển nội dung CL vào ô nhớ có đ/c DS:SIMOV [DI], AX ; Chuyển nội dung AX vào 2 ô nhớ liên tiếp có

; địa chỉ DS:DI và DS:DI+11.5.2.5 Chế độ địa chỉ tương đối cơ sở (Base Relative Addressing)

Trong chế độ này, các thanh ghi cơ sở BX và BP là các hằng số biểu diễn các giá trị dịch chuyển (Displacement Values), kết hợp với DS và SS để tính địa chỉ hiệu dụng của toán hạng các vùng nhớ. 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ỉ.

Khoa CNTT Trang 17 KTMT

Mã lệnh Toán hạngBộ nhớToán hạng

Mã lệnh [Thanh ghi] Tập các thanh ghi

Bộ nhớ

Mã lệnh Địa chỉ thanh ghi

Tập các thanh ghi

BX,BP

Bộ nhớ

Giá trị cụ thể

Gi¸o tr×nh vi xö lý

Ví dụ 1: MOV CX, [BX]+10 ; Chuyển nội dung 2 ô nhớ liên tiếp có địa chỉ MOV CX, [BX+10] ; DS:(BX+10) và DS:(BX+11) vào CXMOV CX,10[BX] ;MOV CL, [BP]+5 ; Chuyển nội dung ô nhớ SS:(BP+5) vào AL

Chú ý: Trong các ví dụ trên, các giá trị 10 và3 được gọi là các giá trị dịch chuyển- (BX+10) hoặc (BP+5) gọi là địac chỉ hiệu dụng (Effective Address – EA)- DS:(BX+10) hoặc SS:(BP+5) chính là địa chỉ logic tương ứng với 1 PA

1.5.2.6 Chế độ địa chỉ tương đối chỉ số (Indexed Relative Addressing)Trong chế độ này, các thanh ghi chỉ số DI và SI và các hằng số biểu diễn giá trị

dịch chuyển, được dùng để tính địa chỉ của toán hạng trong vùng nhớ DS.

Ví dụ: MOV AX,[SI]+10 ; Chuyển nội dung 2 ô nhớ liên tiếp có địa chỉ ; DS:(SI+10) và DS:(SI+11) vào AX

MOV AX,[SI+10] ; Tương tự như trên.MOV AL, [DI+5]; chuyển nội dung ô nhớ DS:(DI+5) vào CL.

1.5.2.7 Chế độ địa chỉ tương đối chỉ số cơ sở (Based Indexed Relative)Là sự kết hợp của 2 chế độ địa chỉ, đó là chế độ địa chỉ tương đối chỉ số và chế độ

địa chỉ tương đối cơ sở. Trong chế độ này dùng cả 2 thanh ghi cơ sở và 2 thanh ghi chỉ số để tính địa chỉ của toán hạng. Chế độ này rất phù hợp với việc địa chỉ hoá các mảng 2 chiều.

Khoa CNTT Trang 18 KTMT

Mã lệnh Địa chỉ thanh ghi

Tập các thanh ghi

DI, SI

Bộ nhớ

Giá trị cụ thể

Gi¸o tr×nh vi xö lý

Ví dụ: MOV AX, [BX]+[SI]+8 ;chuyển nội dung 2 ô nhớ liên tiếp có địa chỉMOV AX, [BX+SI] + 8 ; DS:(BX+SI+8) và DS:(BX+SI+9) vào AXMOV AX, [BX + SI + 8] ;MOV CL, [BP][DI]+5 ; chuyển nội dung ô nhớ có địa chỉ

; DS:(BP+DI+5) vào CL Chú ý: Trong các chế độ địa chỉ trên, các thanh ghi đoạn và các thanh ghi lệch

được ngầm định đi kèm với nhau. Muốn loại bỏ sự ngầm định đó thì ta có thể viết tường minh địa chỉ của đoạn.Ví dụ: MOV AL, [BX] ; ngầm định là DS:BX

Muốn bỏ ngầm định là DS ta phải viếtMOV AL, SS:[BX]; chuyển thành SS:BX

1.5.2.8 Bảng tóm tắt các chế độ địa chỉSTT Chế độ địa chỉ Toán hạng Đoạn ngầm định

1 Thanh ghi Reg2 Tức thì Data3 Trực tiếp [Offset] DS

4 Gián tiếp thanh ghi[BX][SI][DI]

DSDSDS

5 Tương đối cơ sở [BX] + Disp[BP] + Disp

DSSS

6 Tương đối chỉ số [DI] + Disp[SI] + Disp

DSSS

7 Tương đối chỉ số cơ sở [BX] + [DI] + Disp[BX] + [SI] + Disp[BP] + [DI] + Disp

DSDSSS

Khoa CNTT Trang 19 KTMT

Mã lệnh Thanh ghi

Bộ nhớ

Giá trị cụ thể

Tập các thanh ghi

BX,BP

Thanh ghi

Tập các thanh ghi

SI,DI

Gi¸o tr×nh vi xö lý

[BP] + [SI] + Disp SS Các cặp thanh ghi đoạn và thanh ghi lệch ngầm định

Thanh ghi đoạn CS DS ES SSThanh ghi lệch IP SI, DI, BX DI SP, BP

1.6. PHÂN TÍCH MÃ LỆNH MÃ MÁY

1.6.1. Khuôn dạng lệnh

Mã lệnh dành cho vi xử lý được viết dưới dạng nhị phân. Nhưng để người lập trình có thể hiểu và lập trình được thì các lệnh của vi xử lý được biểu diễn dưới dạng mã lệnh gợi nhớ (Mnemonic). Song, về cơ bản chúng ta cũng cầm phải biết về mã lệnh mã máy của bộ vi xử lý để có thể hiểu rằng một lệnh được bộ vi xử lý thực hiện ra sao và cấu trúc của các lệnh đó như thế nào.

Vấn đề ta cần phải hiểu là một lệnh của bộ vi xử lý 8086 có độ dài lệnh tối đa là 6 byte. Cấu trúc chung của một mã lệnh đó bao gồm:

Disp Disp Disp DispOpcode D W mode reg M/R

Byte 1 Byte 2 Byte 3,4 Byte 5,6

Trong đó:- Opcode (Operation Code) - Phân biệt lệnh đó là lệnh gì. Ví dụ, lệnh

MOV=100010- D (Direction) chỉ hướng hành động của lệnh. D=0 từ thanh ghi, D=1 tới thanh

ghi.- W (Word) chỉ độ dài của toán hạng. W=1 toán hạng 2 byte, W=0 toán hạng 1

byte- mode chỉ chế độ địa chỉ của toán hạng. Ví dụ, chế độ thanh ghi mode=11.- reg (Register) chỉ mã của thanh ghi trong lệnh (nếu lệnh có toán hạng là thanh

ghi).- M/R (Memory/Register) Chỉ mã của thanh ghi hoặc ô nhớ theo chế độ địa chỉ- Disp (Displacement) đoạn dịch chuyển hoặc là toán hạng tức thì

Bảng xác định chế độ địa chỉ toán hạng bằng các trường MOD và R/M

MOD = 11 Tính địa chỉR/M W=0 W=1 R/M MOD=00 MOD=01 MOD=10000 AL AX 000 (BX)+(SI) (BX)+(SI)+d8 (BX)+(SI)+d16

Khoa CNTT Trang 20 KTMT

Gi¸o tr×nh vi xö lý

001 CL CX 001 (BX)+(DI) (BX)+(DI)+d8 (BX)+(DI)+d16010 DL DX 010 (BP)+(SI) (BP)+(SI)+d8 (BP)+(SI)+d16011 BL BX 011 (BP)+(DI) (BP)+(DI)+d8 (BP)+(DI)+d16100 AH SP 100 (SI) (SI)+d8 (SI)+d16101 CH BP 101 (DI) (DI)+d8 (DI)+d16110 DH SI 110 Địa chỉ trực tiếp (BP)+d8 (BP)+d16111 BH DI 111 (BX) (BX)+d8 (BX)+d16Bảng Mã hoá các thanh ghi

REG W=0 W=1000 AL AX001 CL CX010 DL DX011 BL BX100 AH SP101 CH BP110 DH SI111 BH DI

Bảng mã hoá các thanh ghi đoạnREG W=000 ES01 CS10 SS11 DS

1.6.2. Một số mã lệnh mã máy

a/ Lệnh MOVTừ thanh ghi đến ô nhớ: 1010001w addr_low addr_highTừ ô nhớ đến thanh ghi: 1010000w addr_low addr_highTừ ô nhớ hay thanh ghi đến thanh ghi đoạn: 10001110 mod 0 seg r/mTừ thanh ghi đoạn đến ô nhớ hay thanh ghi: 10001110 mod 0 seg r/mTừ ô nhớ hay thanh ghi đến thanh ghi/ từ thanh ghi vào ô nhớ: 100010d1 mod seg r/m (addr_low addr_high)Từ dữ liệu trực tiếp vào thanh ghi: 1011w reg data (data_High)Từ dữ liệu trực tiếp vào thanh ghi hay ô nhớ: 1100011w mod 000 r/m data (data_High)

b/ Lệnh PUSH

Khoa CNTT Trang 21 KTMT

Gi¸o tr×nh vi xö lý

Toán hạng nguồn là thanh ghi công dụng chung: 01010 regThanh ghi đoạn: 000 seg 110Ô nhớ hoặc thanh ghi: 11111111 mod 110 r/m

c/ Lệnh POPToán hạng đích là thanh ghi công dụng chung: 01011 regThanh ghi đoạn: 000 seg 111Ô nhớ hoặc thanh ghi: 10001111 mod 000 r/m

d/ Lệnh ADDCộng ô nhớ hay thanh ghi đến thanh ghi: 000000dw mod reg r/mCộng trực tiếp số hạng vào thanh ghi: 0000010w dataCộng trực tiếp ô nhớ hay thanh ghi cho toán hạng trực tiếp: 100000sw mod 000 r/m data

(Trong đó s được thiết lập nếu 1 byte số liệu được cộng vào ô nhớ hay thanh ghi 16bit)e/ Lệnh SUB

Trừ ô nhớ hay thanh ghi vào thanh ghi: 100010dw mode reg r/mTrừ thanh ghi cho toán hạng trực tiếp: 0010110w dataTrừ ô nhớ hay thanh ghi cho toán hạng trực tiếp: 100000sw mod 101 r/m data

(Trong đó s được thiết lập nếu 1 byte số liệu được cộng vào ô nhớ hay thanh ghi 16bit)f/ Lệnh AND

Và ô nhớ hay thanh ghi với thanh ghi: 001000dw mod reg r/mVà trực tiếp với thanh ghi: 0010010w dataVà trực tiếp với ô nhớ hay thanh ghi: 1000000w mod 100 r/m data

g/ Lệnh ORHoặc ô nhớ hay thanh ghi với thanh ghi: 000010dw mod reg r/mHoặc dữ liệu trực tiếp với thanh ghi: 0000110w dataHoặc trực tiếp với ô nhớ hay thanh ghi: 1000000w mod 001 r/m data

h/ Lệnh XORXOR ô nhớ hay thanh ghi với thanh ghi: 001100dw mod reg r/mXOR toán hạng trực tiếp với thanh ghi: 0011010w data

Khoa CNTT Trang 22 KTMT

Gi¸o tr×nh vi xö lý

XOR toán hạng trực tiếp với ô nhớ hay thanh ghi: 1000000w mod 110 r/m data

1.6.3. Một số ví dụ minh hoạ:

Phân tích mã lệnh mã máy của các lệnh sau:- MOV SP,BX ; sao chép nội dung trong thanh ghi BX sang thanh ghi SP

opcode=100010D=1 gửi tới thanh ghiw=1 chuyển một từ MOD=11 thanh ghi tới thanh ghiREG=100 thanh ghi SPR/M=011 thanh ghi BX==> Mã lệnh mã máy của lệnh này là: 1000101111100011b = 8BE3h

- MOV CL,[BX] ; sao chép nội dung từ ô nhớ DS:BX sang thanh ghi CLOpcode=100010D=1 tới thanh ghiW=0 toán hạng 8 bitMOD=00 ô nhớ không dịch chuyểnREG=001 thanh ghi CLR/M = 111 toán hạng là ô nhớ DS:BX==> Mã lệnh mã máy của lệnh này là: 1000101000001111b = 8A0Fh

- MOV 43h[SI], DH; chuyển nội dung thanh ghi DH sang ô nhớ DS:(SI+43h)Opcode=100010D=0 từ thanh ghiW=0 chuyển ByteMOD=01 ô nhớ, dịch chuyển 1 byteREG=110 thanh ghi DHR/M=100 ô nhớ DS:SIdisp=01000011 độ dịch chuyển là 43h

==> Mã lệnh mã máy của lệnh này là: 100010000111010001000011b = 887443h

1.7. LẬP TRÌNH VÀ GỠ RỐI BẰNG DEBUG

Khoa CNTT Trang 23 KTMT

Gi¸o tr×nh vi xö lý

Máy tính trước đây là các máy có kích thước tương đối lớn, được chế tạo từ các đèn điện tử chân không, vì vậy, các con rệp (BUGS) có thể chui vào đó và làm hỏng máy móc, dẫn đến việc máy móc có thể xử lý sai. Trước tình thế đó, người ta đưa ra một yêu cầu bắt các con rệp phá hoại này và được gọi là DEBUG (Bắt rệp).

Từ đó đến nay, công việc xử lý làm cho chương trình máy tính được thực hiện chính xác, tránh gây ra lỗi được gọi là DEBUG. Các chương trình thực hiện nhiệm vụ này được gọi là các trình gỡ rối.

Hiện nay, có rất nhiều trình gỡ rối được sử dụng để sửa lỗi cho các trình ứng dụng như: DEBUG.EXE (trong DOS), Debugging (trong WINDOWS).

Để thực hiện được trình DEBUG trong môi trường DOS, ta có thể thực hiện theo cú pháp sau:

DEBUG {ENTER}DEBUG <tên tệp cần gỡ rối> {ENTER}

1.7.1. Giới thiệu về lệnh của DEBUG

Sau khi chạy trình DEBUG, dấu nhắc lệnh của DEBUG sẽ hiện lên với dấu (-). Tại đây ta có thể gõ vào các lệnh của DEBUG. Cụ thể:A - Assemble - Hợp ngữ: được sử dụng để sửa các lệnh của chương trình

Cú pháp: A <địa chỉ offset của lệnh cần sửa>Ví dụ: A 0153 Có thể được sử dụng để lập một chương trình *.COM. Nếu lập trình thì địa chỉ

offset sẽ phải bắt đầu từ 0100h.D - Dump - Hiển thị nội dung một vùng nhớ lên màn hình.

Cú pháp: D [Address] In nội dung một vùng nhớ 128 byte bắt đầu từ địa chỉ Addresshoặc D [range] - In nội dung vùng nhớ trong dải range ra màn hìnhVí dụ: - D 100 In nội dung của 128 byte nhớ bắt đầu từ địa chỉ DS:100D CS:200 220 In nội dung vùng nhớ từ CS:200 đến CS:220D 0A00:0100 L10 In nội dung 16 byte nhớ từ địa chỉ 0A00:0100

G - Go - Thực hiện hay chạy cả chương trình nạp trong bộ nhớCú pháp: G [=address] [điểm dừng] thực hiện đoạn chương trình bắt đầu từ địa chỉ address đến địa chỉ điểm dừngVí dụ: - G =100 Thực hiện chương trình từ địa chỉ 100 đến hết chương trình

Khoa CNTT Trang 24 KTMT

Gi¸o tr×nh vi xö lý

G =100 200 Thực hiện chương trình từ địa chỉ CS:100 đến CS:200H - Hexadecimal - Thực hiện các phép cộng, trừ các số thập lục phân

Cú pháp: H <số thứ nhất> <số thứ hai> cộng, trừ số thứ nhất với số thứ haiVí dụ: H 035F 01E5 Kết quả sẽ hiện lên trên màn hình là: 0544 017A

I - Input - Nhập một Byte dữ liệu từ cổng và hiển thị trên màn hìnhCú pháp: I <#cổng> Nhập một byte từ cổng có địa chỉ là #cổngVí dụ: I 2F8 đọc giá trị từ cổng 2F8 và hiển thị

N - Name - Đặt tên cho tệp để chuẩn bị ghi dữ liệu lên.Cú pháp: N <Tên tệp> Đặt tên và phần mở rộng cho tệpVí dụ: N vanban.txt

N ctrinh.comO - Output - Xuất dữ liệu 8 bit ra một cổng

Cú pháp: O <#cổng>Ví dụ: O 70 đưa dữ liệu 8 bit ra cổng có địa chỉ là 70h

Q - Quit - Thoát khỏi DEBUGR - Register - Hiển thị và sửa nội dung một thanh ghi

Cú pháp: R <tên thanh ghi>Ví dụ: Nạp giá trị 43h vào thanh ghi CXR CX:43

U - Unassemble - Dịch ngược lệnh của CPUCú pháp: U [range]Trong đó range có thể là: - Địa chỉ bắt đầu của đoạn lệnh- Địa chỉ đầu và chiều dài đoạn lệnhVí dụ: U 100 Xem nội dung các lệnh của đoạn chương trình từ địa chỉ

CS:0100hU CS:100 110 Xem đoạn lệnh từ địa chỉ CS:100 đến CS:110U 200 L20 Xem đoạn lệnh 32 byte bắt đầu từ địa chỉ CS:0200h

W - Write - Ghi nội dung đoạn lệnh bắt đầu từ địa chỉ CS:0100h với độ dài phụ thuộc vào giá trị của thanh ghi CX vào một tệp đã được đặt tên bởi lệnh N? - Help - Hiển thị đầy đủ các lệnh, cú pháp lệnh của DEBUG.

Khoa CNTT Trang 25 KTMT

Gi¸o tr×nh vi xö lý

1.7.2. Lập trình bằng DEBUG

DEBUG là một trình gỡ rối có thể được sử dụng để lập trình các chương trình đơn giản có phần mở rộng là *.COM. Vì vậy, trong phần này chúng ta sẽ nghiên cứu về cách viết một chương trình bằng DEBUG thông qua các bước sau.Bước 1: Chạy trình DEBUG. Tại dấu nhắc lệnh của DOS ta gõ: DEBUG {ENTER}Bước 2: Tại dấu nhắc của DEBUG gõ lệnh

-A 100 Địa chỉ bắt đầu của một chương trình được bắt đầu từ CS:100hBước 3: Gõ vào các lệnh của chương trình với qui định

+ Các lệnh này phải là các lệnh của vi xử lý (lệnh thật) dưới dạng mã lệnh gợi nhớ+ Các số liệu đưa vào là các số ở dạng thập lục phân và không được có chữ h ở

cuối số đó. Riêng lệnh INT vẫn được chấp nhận tồn tại chữ h. Ví dụ: số 65d sẽ phải đưa vào là 41

+ Các lệnh nhảy, lệnh lặp, lệnh gọi chương trình con thì các toán hạng lệnh phải là địa chỉ bộ nhớ tại vị trí của lệnh đầu tiên.

Ví dụ: JMP 120 Nhảy tới địa chỉ CS:120h + Trong tất cả các lệnh chỉ tồn tại hai trường là: mã lệnh và toán hạng. Không

được có lời chú thích.Ví dụ: MOV AH,1 ;gán cho AH giá trị 1Đây được coi là một lệnh sai vì lời giải thích này không được DEBUG chấp nhận+ Một chương chương phải được kết thúc bằng một lệnh INT 20 hoặc INT 20h+ Sau lệnh INT 20, ta không đưa lệnh khác nữa thì tại địa chỉ của lệnh tiếp theo ta

nhấn ENTER. Địa chỉ này cũng chính là địa chỉ cuối của chương trình.Bước 4: Xác định số byte của chương trình.

độ dài chương trình = địa chỉ cuối - 100Sau đó gõ lệnh: R CXvà nạp vào độ dài của chương trình cho CX.

Bước 5: Đặt tên cho File chứa chương trình bằng lệnh NVí dụ: N vidu1.com

Bước 6: gõ lệnh W để ghi nội dung chương trình vào tệp đã đặt tên ở bước 5Sau khi tạo xong một chương trình, ta có thể thoát về DOS để chạy thử hoặc có

thể sử dụng lệnh G để chạy trực tiếp từ DEBUG

Khoa CNTT Trang 26 KTMT

Gi¸o tr×nh vi xö lý

Ví dụ: Viết một chương trình thực hiện nhập vào một chữ cái thường, sau đó đổi nó sang thành chữ cái hoa (Với giả thiết không kiểm tra dữ liệu nhập vào)

Sau khi viết xong chương trình, ta có thể chạy nó để kiểm tra kết quả bằng cách.Như vậy, với chương trình đơn giản trên đây, ta thấy: Nếu lập trình bằng DEBUG

thì kích thước của tệp rất nhỏ. Chương trình vừa viết có kích thước là 0Eh=14byte.

1.7.3. Gỡ rối chương trình bằng DEBUG

Để gỡ rối cho một chương trình, ta có thể thực hiện qua các bước sau:Bước 1: Khởi động DEBUG và gọi tệp cần sửa bằng lệnh

DEBUG <Tên tệp cần sửa> {ENTER}Bước 2: Xác định lệnh gây ra lỗi (lỗi do thuật toán) bằng lệnh U. Các lệnh chỉ

hiển thị trong khoảng 32 byte. Nếu muốn xem tiếp lệnh ở vị trí sau 32 byte đó thì ta có thể gõ tiếp lệnh U. Và cứ như vậy cho đến khi kết thúc chương trình (gặp lệnh INT 20)Bước 3: Sử dụng lệnh A <địa chỉ offset của lệnh sai> để bắt đầu sửaBước 4: Gõ lệnh cần thay thế.

+ Nếu lệnh thay thế có kích thước bằng lệnh đang sửa thì tại vị trí của lệnh sau lệnh vừa gõ ta nhấn ENTER.

+ Nếu lệnh thay thế có kích thước khác lệnh đang sửa thì ta phải gõ lại toàn bộ đoạn chương trình từ vị trí sửa đến hết chương trình. Vì, các lệnh gõ vào sau sẽ đè lên các lệnh trước đó. Nếu lệnh sau khi sửa lớn hơn lệnh trước khi sửa thì lệnh tiếp theo của nó sẽ bị mất đi một số bit. Khi đó, cấu trúc chương trình sẽ bị sai lệch hoàn toàn.

Bước 5: Nếu kích thước chương trình khác với kích thước ban đầu thì ta cần phải sử dụng lệnh R để thay đổi thanh ghi CX sao cho CX chứa giá trị độ lớn của chương trình sau khi sửa. Sau đó, ta sử dụng lệnh W để ghi lại nội dung của chương trình mới vào tệp.

Khoa CNTT Trang 27 KTMT

Gi¸o tr×nh vi xö lý

Ví dụ: Chương trình trên bị lỗi tại vị trí lệnh SUB. Ta cần sửa lại như sau:

Khoa CNTT Trang 28 KTMT

Cần phải gõ lệnh DEBUG với tham sốXem đoạn chương trình có lỗi khôngLệnh gây lỗi

Cần phải sửa lạiSau đó ghi lại

Địa chỉ của lệnh sai

Gi¸o tr×nh vi xö lý

CHƯƠNG 2: CÁC BỘ VI XỬ LÝ TIÊN TIẾN CỦA INTEL

2.1. BỘ VI XỬ LÝ 80286

Về cơ bản, bộ vi xử lý 80286 có cấu trúc giống như 8086, nhưng có một số đặc điểm khác biệt như sau:

2.1.1. Các thanh ghi

Bộ vi xử lý 80286 có thêm một số thanh ghi- Thanh ghi từ trạng thái (MSW - Machine Status Word)

15 4 3 2 1 0

TS EM MP PE

TS - Task Switch: chuyển nhiệm vụ EM - Emulation: cho phép mô phỏng bộ đồng xử lýMP - Math Present: Cho biết có bộ đồng xử lýPE - Protection Enable: Cho phép chế độ bảo vệ

- Thanh ghi nhiệm vụ (TR - Task Register)- Thanh ghi bảng mô tả cục bộ (LDTR - Local Descriptor Table Register)- Thanh ghi bảng mô tả toàn cục (GDTR - Global Descriptor Table Register)- Thanh ghi bảng mô tả ngắt (IDTR - Interrupt Descriptor Table Register)15 Bộ chọn 0 23 Địa chỉ cơ sở 0 15 Độ dài 0

TRLDTR

IDTRGDTR

- Các thanh ghi đoạn: bao gồm 2 phầnPhần hở: gồm 16 bit có thể nạp được bằng chương trình gọi là bộ chọnPhần kín: gồm 48bit do CPU tự nạp

+ 8bit quyền truy nhập (Access Right)+ 24bit địa chỉ cơ sở (Base Address)+ 16bit độ dài đoạn (Limit)

Khoa CNTT Trang 29 KTMT

Gi¸o tr×nh vi xö lý

Phần hở Phần kínBộ chọn Quyền

truy nhập Địa chỉ cơ sở Độ dài đoạn

CSDSSSESFSGS

2.1.2. Tập lệnh

80286 có thêm một số lệnh đặc quyền- LGDT: Nạp thanh ghi GDTR, địa chỉ cơ sở 24bit, độ dài 16bit- LIDT: Nạp thanh ghi IDTR, địa chỉ cơ sở 24bit, độ dài 16bit- LLDT: Nạp phần chọn của thanh ghi LDTR, độ dài 16bit- LTR: Nạp phần chọn của thanh ghi TR, độ dài 16bit- LMSW: Nạp từ trạng thái máy- CLTS: xoá bit TS (task Switch)- HALT: Dừng hoạt động của CPU

2.2. BỘ VI XỬ LÝ 80386

2.2.1. Sơ đồ khối của 80386

Khoa CNTT Trang 30 KTMT

Các thanh

ghi

ALU

Các thanh

ghi đoạn

Bộ chuyển đổi đoạn

Bộ đệm chuyển

hoá riêng

Bộ chuyển

hoá trang

ALUBộ giải

mã lệnh

Hàng nhận lệnh đã giải mã

Hàng nhận lệnh

Bộ nhận lệnh

Bộ ghép nối BUS

Đơn vị thực hiện

Đơn vị quản lý theo đoạn nhớ

Đơn vị quản lý theo bộ nhớ

Đơn vị BUS

Đơn vị giải mã lệnh

Đơn vị nhận lệnh

Gi¸o tr×nh vi xö lý

2.2.2. Các thanh ghi

a/ Các thanh ghi đa năng, thanh ghi cờ và con trỏ lệnhCác thanh ghi của bộ vi xử lý 80386 có độ dài 32 bit, song vẫn giữ nguyên phần 16bit đầu được truy nhập tương tự như các thanh ghi tương tự trong 8086.

31 16 15 8 7 0EAX AH ALEBX BH BLECX CH CLEDX DH DL

ESI SIEDI DIEBP BPESP SP

EIP IP

EFlags Flagsb/ Các thanh ghi đoạnBao gồm 2 phầnPhần hở: gồm 16 bit có thể nạp được bằng chương trình gọi là bộ chọnPhần kín: gồm 64 bit do CPU tự nạp

+ 12 bit quyền truy nhập (Access Right)+ 32 bit địa chỉ cơ sở (Base Address)+ 20 bit độ dài đoạn (Limit) Phần hở Phần kín

Bộ chọn Địa chỉ cơ sở Độ dài đoạn Quyền truy nhập

CSDSSS

Khoa CNTT Trang 31 KTMT

Gi¸o tr×nh vi xö lý

ESFSGS

15 0 32bit 20bit 12bitc/ Các thanh ghi điều khiểnCó 4 thanh ghi điều khiển 32 bit được đặt là: CR0, CR1, CR2, CR3

31 0

PG r TS EM MP PE

Dự trữ

Địa chỉ tuyến tính trang có lỗi

Địa chỉ cơ sở của thư mục trang 12 bit dự trữ

PG - Paging (Trang)r - reversed (dự trữ)TS - Task Switch: chuyển nhiệm vụ EM - Emulation: cho phép mô phỏng bộ đồng xử lýMP - Math Present: Cho biết có bộ đồng xử lýPE - Protection Enable: Cho phép chế độ bảo vệd/ Các thanh ghi hệ thống- Thanh ghi nhiệm vụ (TR - Task Register)- Thanh ghi bảng mô tả cục bộ (LDTR - Local Descriptor Table Register)- Thanh ghi bảng mô tả toàn cục (GDTR - Global Descriptor Table Register)- Thanh ghi bảng mô tả ngắt (IDTR - Interrupt Descriptor Table Register) 15 Bộ chọn 0 31 Địa chỉ cơ sở 0 15 Độ dài 0

TR

LDTR

IDTR

GDTR

Khoa CNTT Trang 32 KTMT

Gi¸o tr×nh vi xö lý

GDTR và IDTR chứa 32 bit địa chỉ cơ sở tuyến tính và 16 bit giới hạn độ dài của các đoạn GDT và IDT.LDTR và TR có hai phần: phần chọn đoạn hệ thống (thanh ghi chọn đoạn hệ thống) và phần chứa bộ mô tả quy chiếu đoạn này (thanh ghi mô tả đoạn hệ thống). LDTR chứa bộ chọn 16 bit trỏ đến bộ mô tả của LDT và TSS sẽ được sao sang phần kín của các thanh ghi LDTR và TR. Mỗi một nhiệm vụ có một LDT và TSS riêng.e/ Các thanh ghi kiểm tra và gỡ rối

31 0

DR0 Địa chỉ tuyến tính của điểm dừng 0

Các thanh ghi gỡ rối

DR1 Địa chỉ tuyến tính của điểm dừng 1

DR2 Địa chỉ tuyến tính của điểm dừng 2

DR3 Địa chỉ tuyến tính của điểm dừng 3

DR6 Từ trạng thái của các điểm dừng

DR7 Từ điều khiển của các điểm dừng

TR6 Từ điều khiển kiểm tra Các thanh ghi kiểm traTR7 Từ trạng thái kiểm tra

2.2.3. Quản lý bộ nhớ

2.2.3.1 Không gian nhớ và nhiệm vụ nhớKhông gian nhớ và nhiệm vụ nhớ của 80386 cũng giống 80286, có điều khác là 80386 hoạt động với môt trường với 32 bit. Do vậy bộ nhớ trong hệ thống 80386 có thể được tổ chức theo byte (8 bit), theo từ (16 bit) hay từ kép (32 bit). Từ được xếp như 2 byte liên tiếp, byte thấp có địa chỉ thấp, byte có địa chỉ cao, địa chỉ của từ là địa chỉ của byte thấp. Từ kép cũng được lưu trữ 4 byte theo cách như vậy.Ngoài quản lí bộ nhớ theo đoạn (đoạn có thể có độ dài khác nhau và có thể trao đổi với bộ nhớ ngoài hay phân chia giữa các chương trình) 80386 còn có thể quản lí bộ nhớ theo trang (page) có độ dài 4 Kbyte mỗi trang.2.2.3.2. Các đia chỉ lôgic, tuyến tính, vật lí và quản lí bộ nhớ theo trang.

Khoa CNTT Trang 33 KTMT

Gi¸o tr×nh vi xö lý

Trong 80386 có 3 loại địa chỉ cần được phân biệt: địa chỉ lôgic, tuyến tính, vật lí và quản lí bộ nhớ theo trang.

Mỗi nhiệm vụ có nhiều nhất 2 = 16k bộ chọn, offset có thể là 2 = 4 Gbyte, như vậy một nhiệm vụ có cực đại 2 = 64 tetrabyte. Nói cách khác, không gian địa chỉ lôgic là 2 = 64 tetrabyte, trong khi không gian địa chỉ vật lí chỉ rông 4 Gbyet vì 80386 có 32 dây địa chỉ. Tổ hợp của các địa chỉ cơ sở đoạn và offset bên trong các đoạn đó tạo nên thang địa chỉ tuyến tính, có nghĩa rằng ta có thể tìm thấy các địa chỉ tuyến tính lớn hơn chỉ tới một đoạn lôgic nằm ở vùng địa chỉ thấp. Địa chỉ tuyến tính 32 bit bằng 32 bit địa chỉ cơ sở cộng với 32 bit offset. Việc sử dụng địa chỉ đoạn lôgic có vài đièu bất tiện (ví dụ như trong việc trao đổi, swapping, các đoạn nhớ với đĩa từ) nên 80386 được tran bị thêm cách quản lí bộ nhớ theo trang sẽ được trình bày trong các phần sau. 1. Định địa chỉ ở chế độ thực.Sau khi bật nguồn hay reset, 80386 ở chế độ thực. Cơ chế địa chỉ hoá và kích thước bộ nhớ 80286 ( Kích thước cực đại là Mbyte ), vì vậy chỉ có các dây địa chỉ A2-A19 và BE0 -BE3 là tích cực. ở chế độ này bộ nhớ theo trang không được phép, do vậy địa chỉ tuyến tính cũng giống địa chỉ vật lí. Cách tính địa chỉ vật lí giống như ở 80386. 2. Định địa chỉ ở chế độ bảo vệ.Lúc này địa chỉ lôgic được xác định bởi hai phần:- Bộ chọn là nội dung các thanh ghi chọn đoạn 16Bit trong đó chỉ số để xác định địa chỉ cỏ sở 32 Bit của bộ mô tả đoạn.- Offset đựoc tạo nên bởi 3 thành phần: Địa chỉ có cơ sở đoạn nhớ(base), chỉ số(index) và đọ dịch chuyển (displacement).Việc chuyển từ chế độ thực sang chế độ bảo vệ được thực hiện bằng cách đặt bit PE trong thanh ghi CR0 bằng 1 và được nghi lại từ chế độ bảo vệ chế độ thực bằng cách xoá bit PE bằng 0.

Khoa CNTT Trang 34 KTMT

Cách tính địa chỉ hiệu dụng offset Chỉ

sốĐịa chỉ cơ sở Độ dịch

chuyển

Bộ chọn Đơn vị quản lý theo đoạn

Đơn vị quản lý theo trang

Bộ nhớ vật lý

offset 32bit

Chỉ số tới bộ mô tả

Địa chỉ tuyến tính

Địa chỉ vật lý

Thanh ghi chọn đoạn

Gi¸o tr×nh vi xö lý

Đơn vị quản lí đoạn sẽ chuyển địa chỉ lôgic thành địa chỉ tuyến tính 32 bit. Nếu đơn vị quản lí trang không được phép làm việc thì 32bit địa chỉ tuyến tính sẽ tương ứng với các địa chỉ vật lí.3. Khởi động và chuyển sang chế độ bảo vệNgay sau khi khởi động, 80386 làm việc ở chế độ thực. Để chuyển sang chế độ bảo vệ phải đặt bit PE của thanh ghi điều khiển CR0 bằng lệnh move CR0, R/M.Sau khi chuyển sang chế độ bảo vệ, lệnh nhảy giữa các đoạn sẽ được thực hiện để xếp lại hàng nhận lệnh trước PQ. Tiếp theo các đoạn số liệu được nạp vào bằng các bộ chọn với giá trị khởi đầu.Một cách khác để chuyển vào chế độ bảo vệ trong các hệ điều hành đa nhiệm là sử dụng phép chuyển nhiệm vụ đã nạp các thanh ghi. Lúc này trong GDTM ngoài các bộ mô tả đoạn số liệu và đoạn lệnh còn có hai bộ mô tả TSS. Lệnh JMP đầu tiên trong chế độ bảo vệ sẽ gây ra phép chuyển nhiệm vụ và nạp tất cả các thanh ghi các giá trị chứa trong TSS. Thanh ghi TR được khởi động để trỏ tới một bộ mô tả TSS, vì khi chuyển nhiệm vụ, thạng thái của nhiệm vụ đang thực hiện sẽ được cất vào TSS.

2.3. BỘ VI XỬ LÝ 80486

2.3.1. Các phần tử xử lí CISC và RISC

Họ 80x86 của Intel thường hoạt động theo nguyên tắc dùng vi xử lí có tập lệnh phức tạp CISC (Complex Instruction Set Computer). Đặc điểm là nó có số lượng lệnh lớn (thường hơn 300 lệnh), có khả năng định địa chỉ phức tạp, các lệnh được vi lệnh hoá có nghĩa là CPU hoạt động bằng vi chương trình. Nghiên cứu điều tra thống kê đã chỉ ra những kết luận sau:

Khoa CNTT Trang 35 KTMT

Gi¸o tr×nh vi xö lý

- Trong nhiều chương trình điển hình được xử lí bằng bộ vi xử lí CISC như nói trên thì đến 80% thời gian chạy chương trình được thực hiện bởi 20% số lệnh trong tập lệnh.- Có những trường hợp, để đạt được cùng một kết quả thì việc chạy một chuỗi lệnh đơn giản sẽ nhanh hơ là chạy một lệnh phức tạp.Những kết luận này là tiền đề để một loại vi xử lí khác ra đời; nó hoạt động theo phương pháp sử dụng tập lệnh ngắn gọn RISC (Reduced Instruction Set computer), thí dụ như i860 của Intel. Tập lệnh ở đây được hạn chế vào các lệnh chính yếu cần thiết trong số 20% lệnh nói trên và phần cứng được thiết kế sao cho phần tử RISC này hiểu ngay được lệnh máy do trương trình cung cấp. Do đó các lệnh loại này không cần chuyển cho bộ giải mã vi lệnh nữa mà được thực hiện ngay. Như bên phải hình 59, các lệnh máy trong hàng nhận lệnh trước PQ được trực tiếp chạy ngay mà không cần phải được giải mã thành một chuỗi các vi lệnh. Rõ ràng thời gian để thực hiện một lệnh ở đây được rút ngắn đi nhiều so với trường hợp ở bộ vi xử lí CISC.

2.3.2. vi xử lí 80486

2.3.2.1. Đặc điểm chung

Chip i486 có mật độ tích hợp rất cao gồm bên trong một vi xử lí i386 đã cải tiến, một bộ đồng xử lí toán 80387, một bộ điều khiển cache và một bộ nhớ cache 8 kbyte (Cache là một loại bộ nhớ RAM tĩnh có dung lượng nhỏ nhưng tốc độ truy cập nhanh hơn so với bộ nhớ chính là các RAM động, sẽ được đề cập tới trong các phàn sau). Giống như i386, bus số liệu và bus địa chỉ ở đây cũng rộng 32 bit, tốc đọ truyền tải dữ liệu có thể lên tới 160 Mbyte/s.Đây là thiết kế dựa trên kết quả của việc tích hợp hai loại phần tử xử lí CISC và RISC trong cùng một chip CPU. Trong i486, các lệnh mac máy thường xuyên được sử dụng sẽ được cài đặt sẵn và có thể được thực hiện ngay, trong khi các lệnh phức tạp nhất và ít được sử dụng sẽ thông qua bộ giải mã vi lệnh. Theo phương thức này, hầu như tất cả các lệnh có thể được thực hiện gọn trong một chu kì xung nhịp đồng hồ.Vi xử lí i486 hoàn toàn tương tích với i386 về tập lệnh và các loại số liệu. Nó cũng có thể chạy trong các chế đọ thực, bảo vệ cũng như phân loại và phân

Khoa CNTT Trang 36 KTMT

Gi¸o tr×nh vi xö lý

trang. Vì đơn vị đồng sử lí toán (đơn vị dấu phảy động) được tích hợp ngay trong cùng một chip với CPU nên tốc độ trao đổi dữ liệu cũng nhanh hơn so với hệ i386 và i387 tách rời.

2.3.2.2. cấu trúc bên trong i486

Bởi vì có đến 3 đơn vị xử lí cùng được tích hợp trong một chip (CPU, bộ đồng xử lí toán, bộ điều khiển cache và bộ nhớ cache) nên cấu trúc của i486 phức tạp hơn i386 nhiều. Sơ đồ khối bên trong của nó được chỉ ra trên hình 60.Các bus số liệu, địa chỉ và số liệu được nối với bên ngoài qua khối ghép nối bus, khối này được nối trực tiếp với bộ nhớ cache bên trong vi xử lí (được gọi là cache cấp một, để phân biệt với bộ nhớ cache cấp hai nằm trên bản mạch chính ở bên ngoài vi xử lí). Bộ nhớ cache nội 8 byte này được dùng làm bộ đệm cho số liệu và lệnh đến từ bộ nhớ chính trước khi chúng được chuyển tới các thanh ghi, ALU, bộ đồng xử lí toán hoặc hàng nhận lệnh trước PQ dài 32 byte.

Khoa CNTT Trang 37 KTMT

Gi¸o tr×nh vi xö lý

Khác với chu kì thâm nhập bộ nhớ cache cấp hai phải mất hai nhịp đồng hồ, việc thâm nhập cache cấp một này chỉ mất một chu kì nhịp đồng hồ. Do vậy, mặc dù dung lượng nhớ của cache nội chỉ có 8 kbyte nhưng nó vẫn cải thiện đáng kể chỉ tiêu của hệ thông. Trong trường hợp các số liệu hoặc lệnh từ bộ nhớ chính không được nạp qua cache thì chúng sẽ được đưa trực tiếp tới các thanh ghi hoặc hàng nhận lệnh trước PQ qua khối ghép nối bus. Điều này xảy ra khi i486 xử lí các số liệu rất phân tán hoặc trong trường hợp thực hiện các lệnh nhảy tới một địa chỉ xa.Sau bộ nhớ cache, các đường lệnh và số liệu được phân tách ra. Các byte số liệu được chuyển tới các thanh ghi hoặc bộ đồng xử lí toán. Các byte lệnh được đưa vào hàng nhận lệnh trước, hàng này dài 32 byte. Đơn vị giải mã sẽ giải mã các lệnh và truyền chúng tới khối điều khiển để điều khiển các thanh ghi, khối tính số học và lôgic ALU, khối phân đoạn và bộ đồng xử lí toán. Một số lệnh không cần giải mã mà có thể chạy ngay lập tức do i486 có tích hợp cả công nghệ RISC.Nếu các toán hạng tức thời hoặc độ dịch chuyển hiện diện trong dòng lệnh thì hàng nhận lệnh trước sẽ phân tách chúng và truyền chúng tới ALU hoặc khối phân đoạn. Các byte số liệu được cấp tới khối phân đoạn, các thanh ghi, ALU hoặc bộ đồng xử lí toán và được xử lí tại những nới đó. Hai bus dữ liệu 32 bit

Khoa CNTT Trang 38 KTMT

8 KBCache

Khối phân trang

Khối phân đoạn

ALU và thanh ghi

PQ32byte

Khối giải mã

Khối điều khiển

Bộ đồng xử lý toán

Khối ghép nối BUS

BUS dữ liệu 32 bitBUS địa chỉ 32 bit

BUS các lệnh nội bộ

D0-D31

A0-A31

Bus điều khiển

Gi¸o tr×nh vi xö lý

hình thành nên một bus dữ liệu 64 bit dùng cho việc truyền tải dữ liệu giữa CPU tương ứng với i386 và bộ đồng xử lí toán tương ứng với i387. Khác với tổ hợp i386/ 1387 thông thường, quá trình trao đổi số liệu và mã lệnh ở đây không cần chu kì bus vào/ra vì cả hai khối đã được tích hợp cả trên những chip rồi. Hơn nữa, do bề rộng dữ liệu bên trong chip lại là 64 bit khi sử dụng bộ đồng xử lí toán nên các lệnh ESC ở đây sẽ chạy nhanh hơn nhiều so với máy tính dùng i386 và 387.Giống như các vi xử lí họ 80x86, ở đây cũng dùng các thanh ghi đoạn và thanh ghi offset. Trong khối phân đoạn, nội dung của hai thanh ghi này được kết hợp lại thành địa chỉ tuyến tính. Trong chế độ bảo vệ, khối phân đoạn sẽ thực hiện các kiểm tra cần thiết để bảo vệ các nhiệm vụ riêng biệt và bảo vệ hệ thống. Nếu chế độ trang không được kích hoạt thì địa chỉ tuyến tính này chính là địa chỉ vật lí. Nếu chế độ trang được kích hoạt thì địa chỉ tuyến tính được chuyển thành địa chỉ vật lí bởi khối phân trang.Vì những lí do trên, CPU i486 có hiệu suất cao gấp hai đến ba lần so với các CPU trước nếu hoạt động ở cùng một tần số. Tần số hoạt động của bộ vi xử lí cũng chính là tần số của mạch tạo xung nhịp. Để thi hành đa xử lí (multiprocessing), nhiều lệnh mới đã được trang bị để dễ dàng trao đổi dữ liệu giữa các bộ vi xử lí.Với vi xử lí 486 DX2 hoặc DX4, tần số nhịp được cấp cho CPU sẽ được nhân 2 hoặc 3 ở bên trong chip cho phép có thể tăng tốc độ của vi xử lí mà không đòi hỏi bản mạch chính cũng phải có cùng tốc độ đó. Điều này làm giảm nhẹ việc thiết kế chế tạo các bản mạch chính phải chạy ở tần số cao, do đó giá thành sản phẩm cũng được giảm theo. Thí dụ, vi xử lí i486 DX2/50MHz chỉ cần chạy với bản mạch chính 25 MHz, DX2/66MHz hay DX4/100MHz với bản mạch chính 33MHz. Theo phương án này, nhìn chung máy vi tính phải chịu thiệt về hiệu suất, vì CPU tiến hành xử lí số liệu nhanh gấp hai hoặc ba lần so với các bộ phận trên bản mạch chính, do đó có thể phải xen vào một vài chu kì đợi (wait cycle). Để giải quyết vấn đề này, một bộ nhớ cache ngoài đủ rộng để giữ tạm các lệnh và dữ liệu mà bộ vi xử lí phải đợi. Nếu được thiết kế hợp lí, hệ thống như vậy có thể đạt tới hiệu suất 80% so với các hệ thống có tốc độ xung nhịp trên bản mạch chính bằng tốc độ xung nhịp ở trong CPU.

Khoa CNTT Trang 39 KTMT

Gi¸o tr×nh vi xö lý

Sự khác biệt duy nhất giữa loại 486DX và 486SX chỉ là trong 486SX không có bộ đồng xử lí toán.

2.4. CÁC BỘ VI XỬ LÝ INTEL PENTIUM

2.4.1. Đặc điểm chung

Bộ vi xử lí pentium ra đời làm cho kĩ thuật của máy PC lại thay đổi. Về phần mềm, pentium vẫn có tập lệnh, thanh ghi, các chế độ định địa chỉ và các chế độ hoạt động hoàn toàn tương thích với các CPU trước nó. Nhưng về phần cứng, pentiumcó những cải tiến đáng kể. Phiên bản đầu tiên ra đời năm 1993 được chế tạo theo công nghệ 0,8 micron BiCMOS, đó là công nghệ cho phép tạo ra các vi mạch có những phần tử tích cực trong đó có kích thước nhỏ nhất cỡ 0,8 phần triệu mét. Với công nghệ này các chip điện tử sẽ có kích thước bé hơn, tiêu thụ ita năng lượng hơn và cái chính là hiệu suất cao hơn vì các tín hiệu di chuyển trong nội bộ chip với quãng đường ngắn hơn. Với 3,1 triệu linh kiện bán dẫn trong cấu trúc gọi là superscalar xây dựng trên hai hay nhiều đường ống (pipeline), loại pentium có đặc trưng 100MIPS (Million Instruction Per Second), tức là có thể thực hiện hàng triệu lệnh trong một giây với tốc độ đồng hồ là 66 MHz. Do đó nó hoạt động nhanh gấp hai lần chip 486DX2/66 về các phép tính số nguyên và ba đến bảy lầnvới các phép tính số học có dấu phảy động. Mặc dù có bus dữ liệu rộng 64 bit nhưng pentium vẫn được thiết kế để làm việc với bus dữ liệu ngoài 32 bit tương thích với các thế hệ vi xử lí i386/i486 trước đó.

2.4.2. Cấu trúc và tính năng

Sơ đồ khối của vi xử lí pentium có thể được trình bày như sau:

Khoa CNTT Trang 40 KTMT

Vùng đệm đích rẽ nhánh

Cache lệnh 8KB

Hàng nhận lệnh trước

Bộ xử lý dấu phảy độngCác thanh ghiĐường ống U của ALU

Các thanh ghi

Đơn vị BUS

Đường ống V của ALU

Cachedữ liệu 8KB

Bus dữ liệu 64bit

Bus địa chỉ 32bit

Gi¸o tr×nh vi xö lý

- Pentium có hai bộ nhớ cache 8 kbyte riêng biệt, một dành cho lệnh một dành cho số liệu.- Có hai hàng nhận lệnh trước 32 bit và hai bộ tính số học và lôgic ALU được cung cấp lệnh và dữ liệu trên hai đường ống song song U và V (superscalr) cho phép thi hành hai lệnh máy trong một chu kì.- Bộ xử lí vẫn làm việc với các thanh ghi 32 bit và bus địa chỉ 32 bit nhưng có thể nối với bus số liệu ngoài là 64 bit.- Bus nội bộ là 64 bit và 128 bit, bus từ bộ nhớ cache nội nối với các vùng đệm của các ALU rộng 256 bit. Điều này cho phép tăng tốc độ trao đổi dữ liệu trong nội bộ vi xử lí lên rất cao.- Có một vùng nhớ gọi là vùng đêm đích rẽ nhánh BTB (branch target buffer) của lệnh đối với 256 lệnh rẽ mới đây nhất.- Có một bộ đọc xử lí với hiệu xuất cao hơn nhiều lần các thế hệ trước nhờ các giải thuật (algorthm) nhanh hơn, cách xắp sếp bố trí lệnh cũng như có thể thực hiện đồng thời hai lệnh.Một vài đặc trưng khác làm cho pentium phân biệt được với các vi xử lí trước là:- Kích thước trang của bộ nhớ trong chế độ bảo vệ và ảo không chỉ hạn chế ở 4 kbyte mà có thể lên đến 2 Mbyte hay 4Mbyte.- Khả năng tự tìm kiếm các lỗi phức tạp và gỡ rối (debugging) bằng các mạch phần cứng lắp thêm.- Có thể tự đánh giá được hiệu suất thi hành chương trình.

Khoa CNTT Trang 41 KTMT

Gi¸o tr×nh vi xö lý

Mặc dù một số vi xử lí được xây dựng trên nguyên tắc CISC nhưng pentium đã ứng dụng nhiều công nghệ mới giống như các loại vi xử lí RISC tốc độ cao, thí dụ như việc sử dụng các cấu trúc đường ống, cấu trúc superscalar và dự đoán rẽ nhánh. Điều này làm cho nó có hiệu suất cao như các vi xử lí RISC thực sự. Các lệnh chạy trong pentium được thực hiện trên cấu trúc superscalar với hai đường ống song song U và V, các cache nội bộ và vùng đệm đích rẽ nhánh BTB. Xét qua các cấu trúc này sẽ cho phép giải thích tại sao pentium lại có hiệu suất cao hơn so với các vi xử lí trước đó:Cấu trúc superscalar với hai đường ống song song.Việc thi hành lệnh trong các vi xử lí 80x86 và pentium được diễn ra qua 5 công đoạn:

1. Nhận lệnh trước từ bộ nhớ (Prefetch): lện máy được lấy từ bộ nhớ chuyển vào CPU.2. Giải mã lệnh 1 (Decode 1): giải mã, phân tích để xác định loại lệnh.3. Giải mã lệnh 2 (Decode 2): xác định địa chỉ ô nhớ cần truy nhập.4. Thực hiện lệnh (Execute)5. Viết các kết quả dữ liệu vào các thanh ghi và bộ nhớ (Writeback).

Nếu như mỗi công đoạn đòi hỏi tối thiểu một chu kì nhịp đồng hồ thì khi thi hành tuần tự các công đoạn này cho mỗi lệnh, thông thường phải mất tổng cộng năm chu kì nhịp. Nhưng với một cấu trúc đường ống có thể thực hiện đồng thời song song những công đoạn trên, pentium tạo ra một phương thức làm việc như sau: khi lệnh thứ (n) vừa chuyển sang công đoạn thứ hai thì một lệnh mới thứ (n+1) được đưa ngay vào công đoạn thứ nhất v.v… Nhờ đó cả thảy có 5 lệnh sẽ cùng được xử lí đồng thời trên một đường ống và có thể coi mỗi lệnh chỉ được xử lí trong một chu kì nhịp đông hồ.Hơn thế nữa, Pentium lại có đến hai đường ống gọi tên là U và V được chế tạo hoạt động song song với nhau. Về mặt lí thuyết, nó sẽ có khả năng thi hành cùng một lúc hai lệnh. Tuy nhiên, thực tế không phải lúc nào cũng thực hiện được điều đó vì hai lệnh kế tiếp nhau thường phụ thuộc vào nhau và lúc này chỉ có thể xử lí chúgn một cách tuần tự. Một mạch đặc biệt sẽ kiểm tra tính phụ thuộc dữ liệu đó xem chúng có yêu cầu phải liên kết trong quá trình xử lí hay không. Nếu

Khoa CNTT Trang 42 KTMT

Gi¸o tr×nh vi xö lý

không phụ thuộc, hai lệnh sẽ được gửi tới hai đường ống theo đúng thứ tự. Quá trình có thể dẫn giải như sau:trong công đoạnmột, lệnh hiện tại sẽ đưa vaod đơn vị giải mã của đường ống U, lệnh kế tiếp vào đơn vị giải mã của đường ống V. Nếu trong công đoạn hai, mạch đặc biệt nói trên xác định có thể thực hiện đồng thời hai lệnh thì mỗi lệnh sẽ trải qua các công đoạn còn lại trong mỗi đường ống của nó, ngược lại thì lệnh trong ống U sẽ trải qua công đoạn kế tiếp như bình thường còn lệnh kế tiếp trong ống V sẽ được chuyển qua thi hành trong ống U như là lệnh theo sau lệnh hiện tại.Bộ nhớ cache nội bộ 16 kbyte (cache cấp một)Pentium có hai bộ nhớ cache rieng biệt, một dành cho số liệu và một dành cho lệnh. Do tốc độ nhanh lại được tích hợp ngay trong chip vi xử lí nên các lệnh và dữ liệu ở đây có thể được truy cập rất nhanh. Mỗi cache có dung lượng 8kbyete gồm hai tuyến, 128 hàng cache, mỗi hàng dài 32byte. Cả hai cache này có thể được truy xuất đồng thời từ hai đường ống U và V nhờ vào cấu trúc đan xen gấp tám (trang).Pentium có thể hoạt động nhịp nhàng với các vi xử lí khác trong chế độ đa xử lí (mỗi vi xử lí có một cache nội riêng) nhờ được cấp một giao thức đặc biệt gọi là MESI (Modified, Exclusive, Shared, Invalid). Nó cho phép việc hỗ trợ việc đồng bộ hoá giữa các cache trong một hệ thống đa xử lí. Giao thức có chứa thủ tục bus snooping cho phép một bộ xử lí thăm dò và xử lí các thông tin được trữ trong các bộ nhớ cache của các bộ xử lí khác trong hệ thống.Vùng đệm đích rẽ nhánh BTB.Xét trường hợp khi CPU thực hiện một lệnh nhảy (JUMP). Lúc này, thay vì tiếp tục với lệnh kế tiếp trong bộ nhớ thì việc thi hành chương trình lại được tiếp tục với một lệnh hoàn toàn khác tại địa chỉ đích của lệnh nhảy. Điều đó dẫn tới việc phải "tống" lệnh kế tiếp trên, vốn đã nằm sẵn trong đường ống, ra ngoài và phải nạp một lệnh mới vào đường ống. Kết quả là hiệu suất của bộ xử lí sẽ bị giảm xuống vì phải mất đi một vài chu kì nhịp đồng hồ cho quá trình trên. Để khắc phục tình trạng này, petium có một vùng nhớ đệm gọi là vùng đệm đích rẽ nhánh BTB (nghĩa là vùng đệm dành cho các lệnh nhảy- IF/THEN). Nó được sử dụng trong công đoạn giải mã lệnh 1 (Decode 1) của tất cả các lệnh nhảy gần (NEAR JUMP). Nếu lệnh nhảy được thi hành, CPUsẽ cất cả địa chỉ lệnh nhảy và địa chỉ

Khoa CNTT Trang 43 KTMT

Gi¸o tr×nh vi xö lý

đích của lệnh vào BTB. Khi thực hiện lệnh nhảy, thay vì nạp lệnh kế tiếp theo sau lệnh nhảy vào đường ống, CPU sẽ nạp lệnh ở địa chỉ đích của lệnh nhảy. Còn nếu lệnh nhảy chưa được thi hành, tức là các địa chỉ lệnh nhảy và địa chỉ đích của nó chưa được đăng kí trong BTB thì lệnh kế tiếp theo sau lệnh nhảy sẽ được nạp vào đường ống như bình thường.* Các pentium thế hệ mớiTrong khi thế hệ pentium đầu tiên được gọi là P5 đang được sử dụng thì Intel đã đưa ra thế hệ tiếp sau, Intel P6, với tên gọi là pentium Pro. Trên cơ sở công nghệ 0,4 micro với 250 MISP, nó có thiết kế đổi mới và tốc độ xử lí nhanh hơn nhưng lại giữ được tính tương tích hoàn toàn với tập lệnh của i386/i486. Điều đó cho phép vân sử dụng được một khối lượng đồ sộ các phần mềm DOS và Microsoft Windows trên thế giới. Chip P6 thuộc loại superscalar và superpipelining. Thay vì cho 5 công đoạn là 7 công đoạn mới trong đường ống và nó có khả năng xử lí 3 chứ không phải là 2 lệnh đồng thời như P5. Khác với pentium có thiết kế CISC, P6 được chế tạo theo công nghệ RISC nhưng sử dụng các mạch thông dịch gắn trên bản mạch chính để chuyển đổi các lệnh của i486 thành các lệnh RISC. Pentium Pro dùng phương pháp thực hiện theo suy đoán (speculative execution) để tối ưu hoá quá trình xử lí, nó là phương pháp lưu trữ và phân tích trên 30 lệnh trước khi chúng được thực hiện. Các lệnh này đều được dự đoán là chúng sắp đi qua bộ xử lí nên được hướng dân và sắp xếp thứ tự thích hợp để tối thiểu hoá thời gian xử lí. Đồng thời cũng nhờ phương pháp suy đoán này mà P6 ít gặp trường hợp phải "nhốt" lệnh trong đường ống khi có hai lệnh yêu cầu phải được hoàn thành trong cùng một lúc, như P5 đã mất rất nhiều thì giờ vì nó. Nhờ suy đoán, P6 đã nâng cao hiệu quả lên 100% so với P5. Bộ xử lí P6 còn có một số tính năng tiên tiến khác: dùng phương pháp đặt tên lại thanh ghi (register renaming) cho phép tăng số lượng thanh ghi lôgic lên nhiều để tránh trường hợp tranh chấp thanh ghi và sử dụng một ghép nối trực tiếp tốc độ cao với cache cấp hai nên không bị chậm vì bus số liệu khi truy cập cache. Với 5,5 triệu transistor, đầu tiên chạy với tốc độ 133MHz đến nay có phiên bản P6 đã chạy lên đến trên 200MHz. Các chip vi xử lí pentium 11 với công nghệ MMX (Multimedia extensions) và bộ nhớ cache nội lớn tới 32kbyte lại là một phiên bản cải tiến mới. Các chip này sử dụng ít lệnh hơn nhiều so với một CPU chuẩn thông thường. Với bộ nhớ cache nội lớn, nó có thể thực hiện các phép xử lí nhanh hơn pentium tương đương từ 7 10%. Tốc độ của nó lên tới trên 266MHz. Loại pentium II cho phép dễ dàng nâng cấp nhờ một hệ thống đóng vỏ hoàn toàn mới. Thay cho loại chíp hình vuông quen thuộc có thể cắm vào chân đế, vỏ "tiếp xúc một mạch đơn" (Single Edge Contact - SEC) của nó bao gồm một vi xử lí được

Khoa CNTT Trang 44 KTMT

Gi¸o tr×nh vi xö lý

đặt trên một bản mạch nhỏ (card) nằm trong hộp (cartridge) có thể cắm vào khe cắm dành riêng nằm trên bản mạch chính. Cache cấp hai nằm cạnh vi xử lí trên cugn card, cho phép nó chạy ở tốc độ cao hơn nhiều so với cache cấp hai thông thường nằm trên bản mạch chính. Trong tương lai gần có thể có những phiên bản pentium khác chạy nhanh hơn nữa do sử dụng những qui trình sản xuất mới cho phép giảm khoảng cách giữa các transistor cấu thành chip tới 0,25 micron, vì vậy có thể tăng tốc độ xung nhịp lên cao tới trên 400MHz.2.5. BỘ ĐỒNG XỬ LÝ TOÁN 80X872.5.1. Sơ lược về các số thực

2.5.2. Cấu trúc của 8087

Các bộ đồng xử lí toán (methematical co-processor) 80x87 trợ giúp cho CPU trong việc tính các biểu thức toán với dấu phẩy động như cộng, trừ, nhân, chia các dấu phảy động; tính căn bậc hai và lôgarit v.v… Các bộ đồng xử lí thực hiện các phép toán này nhanh hơn nhièu trong CPU. Trong bảng 12, hãng Intel cho một so sánh thời gian chạy (usec) một phép toán giữa 8087và 8086 ở tốc độ đồng hồ 8MHz, ta thấy rằng tốc độ tính toán được tăng lên từ 50 đến 500 lần.Nó bao gồm một đơn vị điều khiển CU (control unit) dùng để điều khiển bus và đơn vị số học NU (numerical unit). Đơn vị NU thực hiện các phép tính dấu phảy động trong các mạch tích luỹ thừa (exponent module) và mạch tính phần định trị (mantissa module). Khác với 8086, thay vì cho các thanh ghi rời rạc là các ngăn xếp thanh ghi.Đơn vị điều khiển nhận và giải mã lệnh, đọc và viết các toán hạng và chạy các lệnh điều khiển riêng của 8087. Do vậy, CU có thể đồng bộ với CPU trong khi NU đanh làm các công việc tính toán. CU bao gồm bộ điều khiển bus, bộ đệm số liệu và hàng nhận lệnh trước. Ngay sau khi PC được reset, bằng các đường BHE/S7, bộ đồng xử lí kiểm tra xem nó có được nối với CPU không. 8087 se điều chỉnh độ dài của hàng nhận lệnh trước cho phù hợp với độ dài trong 8086 (6byte). Bằng việc đồng bộ với CPU, các byte như nhau (và do đó cũng là các lệnh như nhau) được hiện diện trong các hàng nhận lệnh trước của cả 8087 và 8086. Tuy nhiên chúng có những điểm khác nhau căn bản:- 8087 không thể chạy các lệnh của 8086 và ngược lại trong khi các lệnh cho hai bộ xử lí này được trộn lẫn trong một đường lệnh. Do vậy các lệnh của 8087 luôn

Khoa CNTT Trang 45 KTMT

Gi¸o tr×nh vi xö lý

được bắt đầu bằng chuỗi bit 11011 (27d) và được gọi là các lệnh ESC. Nói cách khác, các lệnh và tiền tố của CPU 8086 có thể bắt đầu với mọi số khác với 11011.- Đơn vị điều khiển và số học của 8087 tạo một ngăn xếp các thanh ghi với các thanh ghi 80 bit từ R0 đến R7 cũng như các thanh ghi đieu khiển và trạng thái

Khoa CNTT Trang 46 KTMT

Gi¸o tr×nh vi xö lý

CHƯƠNG 3: CẤU TRÚC LẬP TRÌNH ASSEMBLY

3.1. TỔNG QUAN VỀ NGÔN NGỮ LẬP TRÌNH ASSEMBLY

3.1.1. Khái niệm

Hợp ngữ là một ngôn ngữ bậc thấp, sử dụng tập lệnh của bộ vi xử lý và có thể tác động trực tiếp đến các thành phần bên trong của bộ vi xử lý. Mỗi một lệnh của hợp ngữ có quan hệ một - một với một lệnh mã máy.

Vì vậy, việc lập trình với hợp ngữ đòi hỏi người lập trình phải hiểu rõ cấu trúc bên trong, hoạt động, tập thanh ghi và tập lệnh của bộ vi xử lý.

Hình 2.1: Vị trí của hợp ngữ trong các máy tính IBM-PCLiên quan đến việc tạo ra một chương trình hợp ngữ, có một số khái niệm:- Trình hợp dịch (Assembler): là một chương trình chuyển đổi các chương trình mã nguồn từ hợp ngữ thành ngôn ngữ máy. - Trình liên kết (Linker): là một chương trình có khả năng tập hợp các tệp tin đã được hợp dịch lại thành một tệp tin mã máy.- Trình gỡ rối (Debuger): Là một chương trình có khả năng dịch ngược các lệnh của một chương trình mã máy. Nó còn cho phép người lập trình thực hiện sửa lỗi thuật toán cho các chương trình mã máy.

3.1.2. So sánh hợp ngữ với các ngôn ngữ bậc cao

Hợp ngữ là một ngôn ngữ lập trình sử dụng các lệnh của bộ vi xử lý, vì vậy, nó khó hơn so với các ngôn ngữ lập trình bậc cao. Mặt khác, hợp ngữ có thể tác

Khoa CNTT Trang 47 KTMT

Phần cứng PC

Hợp ngữ

NNLT Bậc cao

Các chương trình ứng dụng

Gi¸o tr×nh vi xö lý

động trực tiếp tới cấu trúc bộ vi xử lý và các thành phần phần cứng khác mà các ngôn ngữ lập trình khác khó có thể thực hiện được.Một chương trình viết bằng hợp ngữ thường có kích thước nhỏ hơn một chương trình viết bằng ngôn ngữ bậc cao có cùng chức năng.Việc dịch và chạy một tệp chương trình nguồn của hợp ngữ cũng phức tạp hơn so với một chương trình viết bằng ngôn ngữ bậc cao.Việc lập trình bằng hợp ngữ thường khó, nhưng chúng ta cũng sẽ hiểu rõ hơn về việc xử lý của máy tính và hiểu rõ nguyên tắc của việc lập trình trong các ngôn ngữ bậc cao.

3.2. CÁC ĐOẠN TRONG MỘT CHƯƠNG TRÌNH

Một chương trình khi thực hiện, nó sẽ được nạp vào bộ nhớ với 3 đoạn: Đoạn mã, đoạn ngăn xếp và đoạn dữ liệu. Mỗi đoạn này có thể có độ dài tối đa là 64K với địa chỉ đầu đoạn là 0000h và địa chỉ offset cuối của đoạn là FFFFh.Trong đó:a/ Đoạn mã được sử dụng để chứa các mã lệnh của chương trình với các mã lệnh nhị phân. Thường người ta sử dụng cặp thanh ghi CS:IP để truy xuất tới các ô nhớ chứa lệnh cần thao tác.Trong lập trình với hợp ngữ, người ta có thể mô tả đoạn mã với việc khai báo vị trí bắt đầu của đoạn là:.CODEb/ Đoạn dữ liệuĐoạn này được sử dụng để chứa các dữ liệu của chương trình. Mỗi một biến sử dụng đều được chương trình dịch chuyển thành một địa chỉ ô nhớ nhất định và tại vị trí của ô nhớ này sẽ chứa nội dung của biến khi thực hiện chương trình.Trong lập trình với hợp ngữ, người ta có thể mô tả đoạn dữ liệu với việc khai báo vị trí bắt đầu của đoạn là:.DATAc/ Đoạn ngăn xếpĐoạn này được sử dụng để chứa dữ liệu truy xuất theo phương thức "Vào trước Ra sau - First In Last Out - FILO"Trong lập trình với hợp ngữ, người ta có thể mô tả đoạn ngăn xếp với việc khai báo bằng một tên:.Stack với độ dài đoạn ngăn xếp. Thường thì độ dài tối đa là 256 byte.

Khoa CNTT Trang 48 KTMT

Gi¸o tr×nh vi xö lý

3.3. CẤU TRÚC CHUNG CỦA MỘT LỆNH ASSEMBLY

Một lệnh của hợp ngữ dù đơn giản hay phức tạp đều phải có đầy đủ một trong các thành phần sau:

[Tên] [Mã lệnh] [Các toán hạng] [;chú thích]Trong đó:

Tên - có thể là tên một chương trình con, một macro, một nhãn hoặc một thành phần nào đó.

Mã lệnh - Cơ bản trường này chứa mã lệnh dưới dạng mã gợi nhớ. Có thể là lệnh thật hoặc lệnh giả.

Nếu là lệnh thật thì đây là các lệnh của bộ vi xử lý.Nếu là các lệnh giả thì đây là các dẫn hướng của chương trình dịch.

Ví dụ PROC, MACRO, ENDP, ENDM, SEGMENT, ENDS...Các toán hạng - Là các thành phần mà các lệnh sử dụng để thực hiện lệnh.

Nếu là các lệnh thật thì đây chính là các toán hạng của lệnh. Với bộ vi xử lý 8086/8088, các toán hạng này có thể là 0,1 hoặc 2.

Nếu là các lệnh giả thì đây là các tham số. Số lượng tham số tuỳ thuộc vào việc khai báo các dẫn hướng.

Chú thích - là lời giải thích để người sử dụng hiểu rõ hơn về lệnh. Lời chú thích phải được bắt đầu bởi dấu (;) và chúng sẽ không được chương trình dịch xử lý.

Ví dụ:Lap: ADD AL,[BX] ;Cộng giá trị trong AL với ô nhớ có địa chỉ là DS:BX.

;Kết quả được đưa vào thanh ghi AL.Với ví dụ trên, thi lap la tên một nhãn và kết thúc bằng dấu (:); ADD là lệnh thực hiện phép cộng; AL và [BX] là hai toán hạng với qui định nếu tên thanh ghi hoặc một giá trị hằng nằm trong dấu [] thì đó là địa chỉ OFFSET của ô nhớ chứa dữ liệu cần thao tác; các thành phần sau dấu (;) chỉ là lời chú thích.

3.4. KHAI BÁO DỮ LIỆU VÀ KIỂU DỮ LIỆU

Khoa CNTT Trang 49 KTMT

Gi¸o tr×nh vi xö lý

Như chúng ta đã thấy qua hai ví dụ trên, khi khai báo dữ liệu cho chương trình, người ta thường sử dụng toán tử DB. Nhưng, trên thực tế, các toán tử khác cũng có thể được dùng đến để khai báo cho các dữ liệu có kiểu khác nhau.DB - Define Byte - Định nghĩa biến kiểu ByteDW - Define Word - Định nghĩa biến kiểu WordDD - Define Double Word - Định nghĩa biến kiểu Double WordDT - Define Ten Byte - Định nghĩa biến kiểu 10 byteEQU - Equal (Bằng) - Khai báo một hằng, địa chỉ cổng xác định.Vậy, chúng ta có thể sử dụng các toán tử trên để khai báo cho các biến và hằng ra sao? Thể hiện các dạng cấu trúc dữ liệu như thế nào?

3.4.1. 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 BD giá_trị_khởi_tạoVí dụ: so1 DB 3EhTrong ví dụ trên, so1 là một biến kiểu byte có giá trị khởi tạo là 3Eh. Song, đôi khi chúng ta không cần thiết phải khởi tạo giá trị cho biến, có thể sử dụng cách khai báo sau:

so2 DB ?Cũng như các ngôn ngữ lập trình khác, một biến kí tự cũng được coi là một biến kiểu byte với mỗi một kí tự được thể hiện bằng mã ASCII của chúng từ 0 - FFhGiả sử, muốn khai báo một biến kí tự và khởi tạo giá trị bằng ‘A’, ta có thể thực hiện bằng một trong hai cách sau:Ch DB ‘A’ ;khởi tạo trực tiếp giá trị ‘A’Hoặc: Ch DB 41h ;khởi tạo thông qua mã ASCII của ‘A’

3.4.2. Biến word

Để khai báo biến kiểu từ (Word), chúng ta có thể sử dụng cú pháp sau:tên DW giá_trị_khởi_tạo

Cũng giống như việc khai báo biến kiểu byte, giá_trị_khởi_tạo có thể là dấu (?) để không khởi tạo giá trị cho biến.Ví dụ:

Khoa CNTT Trang 50 KTMT

Gi¸o tr×nh vi xö lý

1/ w1 DW 3FB4h ;khai báo biến w1 với giá trị khởi tạo là 3FB4h2/ w2 DW ? ;không khởi tạo giá trị cho biến w2

3.4.3. Biến mảng

Mảng là một danh sách (dãy) các phần tử có cùng một kiểu với các giá trị (có thể) khác nhau. Vì vậy, để khai báo một mảng, chúng ta có thể thực hiện theo cú pháp sau:

Tên DB danh_sách_giá_trị_khởi_tạo ;khai báo mảng các phần tử kiểu byte

Tên DW danh_sách_giá_trị_khởi_tạo ;khai báo mảng các phần tử kiểu wordVí dụ 1: mang1 DB 30,55,73,88,33Giả thiết, mang1 được nạp vào bộ nhớ tại địa chỉ offset 23E5h. Khi đó, mảng này sẽ có các phần tử được khởi tạo và hình ảnh của chúng trong bộ nhớ như sau:

Tên phần tử Giá trị khởi tạo địa chỉ bộ nhớMang10Mang11Mang12Mang13Mang14

3055738833

23E5h23E6h23E7h23E8h23E9h

Ví dụ 2: mang2 DW 2BA3h,2748h,9843h,1F3BhCũng với giả thiết mang2 được nạp vào bộ nhớ tại địa chỉ offset 23E5h. Khi đó hình ảnh của mảng này sẽ là:

Tên phần tử Giá trị khởi tạo địa chỉ bộ nhớMang20Mang22Mang24Mang26

2BA3h2748h9843h1F3Bh

23E5h23E7h23E9h23EBh

Chúng ta cũng có thể khởi tạo các giá trị liên tiếp giống nhau. Khi đó, ta cũng có thể sử dụng toán tử DUP. Ví dụ:

Mang3 DB 100 DUP(5Ch)

Khoa CNTT Trang 51 KTMT

Gi¸o tr×nh vi xö lý

Mang3 là một mảng có 100 phần tử với các giá trị khởi tạo của các phần tử đều là 5Ch

Mang4 DB 3,4,2,10 DUP(0)Mang4 có 13pt trong đó 3 phần tử đầu lần lượt là 3,4,2; các phần tử còn lại có giá trị 0.Với mảng hai chiều, việc định nghĩa chúng có thể thực hiện theo cú pháp sau:Tên DB (DW) giá_trị_khởi_tạo_hàng_1

giá_trị_khởi_tạo_hàng_2 ....................................... giá_trị_khởi_tạo_hàng_n

Ví dụ:Mang_2_chieu DB 10 DUP(0)

10 DUP(50) 10 DUP(100) 10 DUP(150)

Khai báo một mảng hai chiều có 4 hàng 10 cột với giá trị khởi tạo của hàng 0 là 0, hàng 1 là 50, hàng 2 là 100, hàng 3 là 150.

3.4.4. Biến chuỗi

Biến chuỗi hay xâu kí tự thực chất chỉ là một mảng (1 chiều) các phần tử là các kí tự trong đó mỗi kí tự có thể được biểu diễn bằng một số là mã ASCII hoặc là kí tự nằm trong dấu ' ' hoặc " ". Vì vậy, ta có thể khai báo bằng một trong các cách sau:

Xau1 DB 'Chao'Xau2 DB 'C','h','a','o'Xau3 DB 43h,68h,61h,6Fh

3.5. KHUNG CỦA MỘT CHƯƠNG TRÌNH ASSEMBLY

Một chương trình hợp ngữ thể hiện các đoạn dành cho chúng rõ ràng với việc sử dụng kích thước bộ nhớ phù hợp và cú pháp của các lệnh rõ ràng tuân theo một cú pháp chung, mặc dù, đó là lệnh thật hoặc lệnh giả. Để thể hiện một chương trình đó, người ta đưa ra 2 dạng cấu trúc. Bao gồm:

Khoa CNTT Trang 52 KTMT

Gi¸o tr×nh vi xö lý

3.5.1. Cấu trúc chương trình để dịch ra tệp *.EXE

Một chương trình *.EXE thường thể hiện rõ ràng 3 đoạn: mã, dữ liệu, ngăn xếp. Sau khi được biên dịch (Assembled) và liên kết (Linked), chúng có thể được thực thi trực tiếp từ dòng lệnh của DOS như các chương trình khác. Cấu trúc cơ bản của một chương trình dạng này như sau:TITLE ten_chuong_trinh.MODEL <Qui mô sử dụng bộ nhớ>.STACK <Kích thước ngăn xếp>.DATA

<Khai báo các biến, hằng cho chương trình>.CODE

Main PROC;Khởi tạo cho DS hoặc/và ESMOV AX,@dataMOV DS,AX;MOV ES,AX;Các lệnh của chương trình chính;Trở về DOS bằng việc sử dụng chức năng 4Ch của ngắt 21hMOV AH,4ChINT 21h

Main ENDP;Các chương trình con (nếu có)END Main

Trong cấu trúc trên, tại dòng cuối cùng xuất hiện dẫn hướng chương trình dịch END và MAIN để kết thúc toàn bộ chương trình. Main chính 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 trình *.EXE được nạp vào bộ nhớ, DOS sẽ tạo ra một mảng gồm 256 byte cho PSP (Program Segment Prefix - Tiền tố chương trình). PSP được sử dụng để chứa các thông tin liên quan đến chương trình và đặt ngay vào trước phần chứa mã lệnh của chương trình.

Khoa CNTT Trang 53 KTMT

Gi¸o tr×nh vi xö lý

Tại dòng.MODEL chúng ta có thể khai báo qui mô sử dụng bộ nhớ phù hợp cho từng chương trình. Có thể là một trong các thành phần sau:

Kiểu kích thước Mô tả

Tiny (Hẹp) mã lệnh và dữ liệu gói gọn trong một đoạn

Small (nhỏ) mã lệnh gói gọn trong một đoạn, dữ liệu nằm trong một đoạn

Medium (Trung bình)

mã lệnh không gói gọn trong một đoạn, dữ liệu nằm trong một đoạn

Compact (Gọn) mã lệnh gói gọn trong một đoạn, dữ liệu không gói gọn trong một đoạn

Larg (rộng) mã lệnh không gói gọn trong một đoạn, dữ liệu không gói gọn trong một đoạn,không có mảng nào lớn hơn 64K

Huge (Đồ sộ) mã lệnh không gói gọn trong một đoạn, dữ liệu không gói gọn trong một đoạn,các mảng có thể lớn hơn 64K

Chương trình dịch sẽ dịch tên @data thành các giá trị số của đoạn dữ liệu và đưa các thông số của dữ liệu vào thanh ghi DS và ES.Để hiểu rõ hơn về cấu trúc chương trình này, chúng ta lấy một ví dụ minh hoạ sau:Ví dụ: Viết một chương trình hợp ngữ thực hiện in hai chuỗi kí tự trên hai dòng màn hình.

title ct.MODEL Small.STACK 100h.DATA

chao DB 'Chao cac ban sinh vien! $'hoi DB 'Cac ban muon hoc mon Vi xu ly khong? $'

.CODE

Khoa CNTT Trang 54 KTMT

Gi¸o tr×nh vi xö lý

main PROC MOV AX,@DATA ;Nap du lieu MOV DS,AX ;cho DS;Xoa man hinh bang chuc nang 0 cua ngat 10h MOV AH,0

MOV AL,3 ;che do text 80x25INT 10h

;In chuoi thu nhat ra man hinhMOV AH,9MOV DX,offset chao INT 21h

;Dua con tro xuong dong tiep theo va ve dau dongMOV AH,2MOV DL,13 ;xuong dongINT 21hMOV DL,10 ;ve dau dongINT 21h

;In chuoi thu hai ra man hinhMOV AH,9MOV DX,offset hoiINT 21h

;Ket thuc chuong trinh va tro ve DOSMOV AH,4Ch INT 21hmain ENDP END main

Như vậy, ta thấy chương trình trên là một chương trình nhỏ nên sử dụng qui mô bộ nhớ nhỏ (Small). Kích thước ngăn xếp là 256 byte. Dữ liệu cho chương trình có hai chuỗi là chao và hoi. Các chuỗi này đều được khai báo với toán tử DB.

Khoa CNTT Trang 55 KTMT

Gi¸o tr×nh vi xö lý

Đặc biệt, các lệnh hoặc nhóm lệnh của chương trình trên có giải thích để người đọc và chính bản thân người lập trình (khi đọc lại) cũng sẽ dễ hiểu hơn.

3.5.2. Cấu trúc chương trình để dịch ra tệp *.COM

Một chương trình *.COM thường có đặc điểm khác biệt với các chương trình *.EXE là chúng chỉ có thể sử dụng một đoạn duy nhất của bộ nhớ để chứa mã, dữ liệu và ngăn xếp. Vì vậy, qui mô sử dụng bộ nhớ của các chương trình dạng này thường là Tiny.Cấu trúc cơ bản của dạng chương trình này như sau:

Title Cautruc_COM.Model Tiny.Code org 100h Start: JMP Continue ;Dinh nghia cac bien, hang Continue: Main PROC ;Cac lenh cua chuong trinh chinh INT 20h Main ENDP ;Cac chuong trinh con (neu co) End Start

Với dạng cấu trúc này, khi dịch chương trình, chương trình dịch sẽ đưa ra thông báo "No Stack Segment".Trong cấu trúc trên, ta thấy, ở ngay đầu chương trình đoạn mã là lệnh giả ORG (Origin: điểm xuất phát) và lệnh JMP (nhảy). Lệnh giả ORG 100h dùng để gán địa chỉ bắt đầu cho chương trình tại địa chỉ 100h (256) trong đoạn mã, chừa lại đoạn bộ nhớ 256byte cho PSP.Lệnh JMP sau nhãn START dùng để nhảy qua phần bộ nhớ dành cho việc định nghĩa và khai báo dữ liệu. Đích của lệnh nhảy là phần đầu của chương trình chính. Hình ảnh của chương trình được thể hiện trong bộ nhớ được thể hiện như trong hình vẽ sau:

Khoa CNTT Trang 56 KTMT

Gi¸o tr×nh vi xö lý

Địa chỉ lệch

0000h Đoạn đầu chương trình (PSP)

0100h JMP Continue IP

Dữ liệu cho chương trình

FFFEh

Continue:(Chiều tiến của mã&dữ liệu)

***

(Chiều tiến của ngăn xếp) SP

Như vậy, một chương trình *.COM có một số hạn chế sau:- Dung lượng cực đại của chương trình chỉ giới hạn trong một đoạn 64K.- Chương trình chỉ được phép sử dụng ngăn xếp với kích thước nhỏ. Nếu không,

nó sẽ chiếm nhiều phần trong đoạn mã lệnh.Chương trình *.COM thường được kết thúc bởi lệnh INT 20h.

Sau đây chúng ta xét một ví dụ để hiểu rõ hơn về việc sử dụng cấu trúc trên trong lập trình hợp ngữ. Chương trình được viết như sau:

Title Cautruc_COM.Model Tiny.Code org 100h Start: JMP Continue

chao DB 'Chao cac ban sinh vien lop TK1$'hoi DB 'Cac ban co hoc mon Vi xu ly khong? $'

Continue: Main PROC;Xoa man hinh bang chuc nang 0 cua ngat 10h MOV AH,0

Khoa CNTT Trang 57 KTMT

Gi¸o tr×nh vi xö lý

MOV AL,3 ;che do text 80x25INT 10h

;In chuoi thu nhat ra man hinhMOV AH,9MOV DX,offset chao ;tro toi dia chi offset cua chuoiINT 21h

;Dua con tro xuong dong tiep theo va ve dau dongMOV AH,2MOV DL,13 ;xuong dongINT 21hMOV DL,10 ;ve dau dongINT 21h

;In chuoi thu hai ra man hinhMOV AH,9MOV DX,offset hoiINT 21h

INT 20h Main ENDP End StartChúng ta có thể nhận xét rằng một chương trình *.COM không cần phải nạp dữ liệu vào DS vì chương trình dạng này có mã, dữ liệu và ngăn xếp trong cùng một đoạn.

3.6. CÁCH TẠO VÀ CHẠY MỘT CHƯƠNG TRÌNH HỢP NGỮ

Một chương trình viết bằng ngôn ngữ bậc cao có thể chạy trực tiếp trong môi trường của chúng. Song, với ngôn ngữ lập trình bậc thấp (hợp ngữ) thì việc chạy chương trình cần phải thông qua việc hợp dịch (Assembled), liên kết (Linked). Người ta đã đưa ra các bước để soạn thảo, dịch và chạy chương trình như sau:Bước 1: Soạn thảo văn bản chương trìnhTrong bước này, ta có thể thực hiện bằng một trình soạn thảo văn bản bất kỳ nào như EDIT, NCEDIT, TURBO PASCAL, C, NOTEPAD, hoặc WINWORD... nhưng, cần phải ghi lại với phần mở rộng là *.ASM.

Khoa CNTT Trang 58 KTMT

Gi¸o tr×nh vi xö lý

Bước 2: Hợp dịch chương trình nguồn ra các tệp đối tượng *.OBJTrong bước này, ta có thể sử dụng trình MASM (MicroSoft Assembler) hoặc TASM (Turbo Assembler) theo cú pháp sau:

MASM tên_tệp[.phần_mở_rộng] Hoặc: TASM tên_tệp[.phần_mở_rộng]

Sau khi dịch, nếu có lỗi cú pháp, máy sẽ báo dòng gây lỗi và mã lỗi. Khi đó ta có thể quay lại bước 1 để sửa tệp nguồn và dịch lại cho đến khi không có lỗi.Bước 3: Liên kết các tệp đối tượng thành tệp chương trình *.EXECó thể sử dụng trình liên kết LINK hoặc TLINK (Turbo) theo cú pháp sau:

LINK tệp_đt1[+tệp_đt2+...+tệp_đtn] Hoặc: TLINK tệp_đt1[+tệp_đt2+...+tệp_đtn]

Bước 4: Nếu chương trình viết dưới dạng cấu trúc *.COM thì thực hiện dịch sang dạng *.COM bằng cú pháp sau:

EXE2BIN tên_tệp_exe tên_tệp_com.COM Nếu tệp viết để dịch ra chương trình *.EXE thì bỏ qua bước nàyBước 5: Chạy tệp chương trình vừa dịch

Tên_tệp_chương_trình Với các bước thực hiện như trên, chúng ta có thể mô phỏng bằng lưu đồ sau:

Khoa CNTT Trang 59 KTMT

Soạn thảo văn bản chương trình

Dịch ra các tệp.OBJ bằng MASM

Liên kết các tệp.OBJ thành tệp.EXE

Lỗi cú pháp?

Dịch ra tệp.COM?

Dịch từ tệp.EXE sang tệp.COM

Không Có

Chạy chương trình

Không

Gi¸o tr×nh vi xö lý

Ví dụ: Soạn thảo một chương trình đơn giản, sau đó dịch và chạy chương trình nàyBước 1: Soạn thảo văn bản chương trình

Bước 2: Dịch ra tệp.OBJ

Khoa CNTT Trang 60 KTMT

Gi¸o tr×nh vi xö lý

Nếu có lỗi như hình trên, quay lại bước 1. Cứ như vậy cho đến khi không còn lỗi

Bước 3: Liên kết các tệp *.OBJ thành tệp chương trình.

Bước 4: Vì tệp chương trình có cấu trúc *.EXE, nên ta có thể bỏ qua bước này.Bước 5: Chạy tệp chương trình

Vidu_exe

Khoa CNTT Trang 61 KTMT

Gi¸o tr×nh vi xö lý

CHƯƠNG 4: CÁC CẤU TRÚC LẬP TRÌNH

4.1. TỔNG QUAN

Trong các ngôn ngữ lập trình bậc cao, người ta thường sử dụng các cấu trúc lập trình cơ bản sau:

- Cấu trúc tuần tự- Cấu trúc rẽ nhánh

+ Rẽ một nhánh (IF...THEN....)+ Rẽ hai nhánh (IF...THEN...ELSE...)+ Rẽ nhiều nhánh (CASE...OF...)

- Cấu trúc lặp+ Lặp xác định (FOR...TO...DO)+ Lặp không xác định

Điều kiện trước (WHILE...DO...)Điều kiện sau (REPEAT...UNTIL...)

Sau đây ta sẽ nghiên cứu việc biểu diễn các cấu trúc lập trình trên bằng hợp ngữ trong khi các lệnh của hợp ngữ sẽ thực hiện theo cấu trúc tuần tự. Vì vậy, muốn điều khiển rẽ nhánh chương trình, chúng ta cần phải thực hiện các lệnh chuyển điều khiển.

4.1.1. Các lệnh chuyển điều khiển

4.1.1.1. Các định hướng- Định hướng NEAR: Thông thường các lệnh điều khiển rẽ nhánh chương trình được thực hiện theo định hướng NEAR (Mặc định). Định hướng này cho phép các lệnh chuyển điều khiển thực hiện trong khoảng 126 byte. Có nghĩa là, chỉ có thể nhảy về trước và về phía sau của lệnh 126 byte.- Định hướng FAR: Nếu có định hướng này, chương trình dịch sẽ cho phép lệnh chuyển điều khiển rẽ nhánh ra ngoài giới hạn 126byte.4.1.1.2. Điều kiện cho các lệnh nhảy

Khoa CNTT Trang 62 KTMT

Gi¸o tr×nh vi xö lý

Các lệnh điều khiển rẽ nhánh chương trình phụ thuộc vào các trạng thái của các cờ trong thanh ghi cờ. Vì vậy, ta có thể tạo ra các điều kiện cho các lệnh này bằng một số lệnh sau:a/ Lệnh CMP (Compare - so sánh)Dạng lệnh: CMP toan_hang_1,toan_hang_2ý nghĩa: Lệnh này sẽ thực hiện lấy toan_hang_1 trừ đi cho toan_hang_2 và kết quả không trả lại cho toan_hang_1. Nhưng nó sẽ tác động đến các cờ trạng thái trong thanh ghi cờ.Ví dụ: MOV AL,3Ah ;AL=00111010

CMP AL,1Ch ;CF= 00111000 00111010

-00011100 00011110

Như vậy, nếu xét đến các cờ trạng thái thì ta thấy lệnh trên sẽ ảnh hưởng đến cờ như sau: CF=0; PF=1; AF=1; ZF=0; SF=0; OF=0. b/ Lệnh Test (Kiểm tra)Dạng lệnh: TEST toan_hang_1,toan_hang_2ý nghĩa: Lệnh này sẽ kiểm tra một bit nào đó của toan_hang_1 với các bit 1 tương ứng ở toan_hang_2.Ví dụ: TEST AL,1 ;kiểm tra bit0 của AL xem bit này có bằng 1 hay không. Nếu giá trị của AL là một số lẻ thì bit0=1.4.1.1.3. Các lệnh điều khiển rẽ nhánhVề cơ bản, chúng ta có thể xét đến một số lệnh điều khiển rẽ nhánh đã nghiên cứu ở chương 1 phần 1. Ví dụ, xét lệnh JE. Lệnh này phụ thuộc vào cờ ZF. Nếu ZF=1 thì lệnh JE mới có thể thực hiện được. Song, trên thực tế, khi xét đến điều kiện thực hiện các lệnh nhảy, ta chỉ cần quan tâm đến ý nghĩa của các từ viết tắt cho từng loại lệnh nhảy. Các điều kiện đó thể hiện như: A - Above; B -Bellow; C - Carry; E - Equal; G - Greater; L - Less; N - Not; Z - Zero... nhưng cũng có thể kết hợp với nhau để có

Khoa CNTT Trang 63 KTMT

Điều_kiện

Công_việc

Sai Đúng

Gi¸o tr×nh vi xö lý

các ý nghĩa khác nhau như: NLE; NGE; NL; LE; NG; GE; NA; NB; NAE; NBE; AE; BE

4.2. CẤU TRÚC TUẦN TỰ

Cấu trúc tuần tự là một cấu trúc mà trong đó các mã lệnh hợp ngữ được thực hiện các công việc theo trình tự hết lệnh này đến lệnh khác. Ngữ pháp:

Lệnh_1Lệnh_2...........Lệnh_n

Ví dụ: Viết một đoạn chương trình thực hiện nhập vào một kí tự từ bàn phím, sau đó in ra màn hình kí tự đó tại dòng tiếp theo.Giải:

MOV AH,1INT 21hMOV AH,2MOV DL,13INT 21hMOV DL,10INT 21hMOV DL,ALINT 21h

4.3. CẤU TRÚC RẼ NHÁNH

4.3.1. Cấu trúc IF...THEN...

Đây là cấu trúc điều khiển rẽ nhánh chương trình với việc kiểm tra điều kiện. Nếu điều kiện thoả mãn thì thực hiện công việc. Nếu điều kiện không thoả mãn thì bỏ qua công việc này.

Khoa CNTT Trang 64 KTMT

Gi¸o tr×nh vi xö lý

Ngữ pháp: IF điều_kiện THEN công_việc

Ví dụ: Viết một đoạn chương trình thực hiện nhập vào một kí tự. Nếu là kí tự 'A' thì hiển thị tại dòng tiếp theo. Giải:

MOV AH,1 ;Nhap vao tu ban phim mot ki tuINT 21h ;ki tu do nam trong ALCMP AL,41hJNE ketthucPUSH AX ;Cat tam ki tu nay vao ngan xepMOV Ah,2 ;Dua con troMOV DL,13 ;xuong dong tiep theoINT 21hMOV DL,10 ;ve ve dau dongINT 21hPOP DX ;Lay ki tu ra va dua truc tiep vao DLINT 21h ;In ra man hinh

Ketthuc:MOV AH,4ChINT 21h

Đoạn chương trình trên sẽ thực hiện cho phép người sử dụng nhập vào từ bàn phím một kí tự. Sau đó, so sánh với mã ASCII của 'A'. Nếu không bằng thì sẽ thực hiện các lệnh sau lệnh "JNE ketthuc" rồi mới kết thúc. Nếu không, máy sẽ bỏ qua các lệnh đó và kết thúc chương trình bằng hàm ngắt 4Ch của ngắt 21h.

4.3.2. Cấu trúc IF...THEN...ELSE

Trong thực tế, chúng ta thường đưa ra một điều kiện nào đó. Nếu trường hợp thoả mãn thì sẽ thực hiện một công việc nào đó. Ngược lại, sẽ không thực hiện một công việc khác.

Khoa CNTT Trang 65 KTMT

Điều_kiện

Công_việc 1

Sai ĐúngCông_việc

2

Gi¸o tr×nh vi xö lý

Ngữ pháp: IF điều_kiện THEN

công_việc_1

ELSE công_việc_2

END_IFVí dụ: Viết 1 đoạn chương trình hợp ngữ thực hiện nhập vào từ bàn phím một kí tự. Nếu kí tự nhập vào có mã ASCII nhỏ hơn mã ASCII của số 1 thì đưa ra màn hình thông báo "Kí tự này đứng trước '1' trong bảng mã", ngược lại, đưa ra màn hình thông báo "Kí tự này đứng sau '1' trong bảng mã"Giải: Đoạn chương trình được thể hiện như sau:* Giả thiết: thông báo "Kí tự này đứng trước '1' trong bảng mã" được lưu trong biến truoc, thông báo "Kí tự này đứng sau '1' trong bảng mã" được lưu trong biến sauĐoạn chương trình được viết như sau:

;Nhap ki tu tu ban phim mov ah,1 int 21h ;Bat dau cau truc cmp AL,'1' ;so sanh ki tu nhap vao voi '1' JL then_ MOV AH,9 LEA DX,sau INT 21h JMP End_if then_: MOV AH,9 LEA DX,truoc INT 21h end_if:

Khoa CNTT Trang 66 KTMT

Gi¸o tr×nh vi xö lý

4.3.3. Cấu trúc rẽ nhánh CASE...OF...

Là một cấu trúc đa nhánh. Nó kiểm tra các thanh ghi, các biến hay các giá trị riêng rẽ trong miền giá trị.Ngữ pháp:CASE biểu_thức

Giá_trị_1: công_việc_1

Giá_trị_2: công_việc_2.................Giá_trị_n: công_việc_n

END CASE

Như vậy, nếu biểu thức bằng giá trị nào, thì công việc tương ứng sẽ được thực hiện.Ví dụ: Viết một đoạn chương trình thực hiện nhập vào một kí tự. Nếu kí tự đứng trước 'A' trong bảng mã ASCII thì đưa ra thông báo kí tự đứng trước 'A'. Nếu kí tự nhập vào là 'A' thì đưa ra thông báo chính là kí tự 'A'. Nếu đứng sau 'A' thì đưa ra thông báo kí tự đứng sau 'A'.Giải: Giả thiết các biến truoc, dung, sau chứa nội dung là các chuỗi thông báo cần đưa ra. Ta có thể thực hiện đoạn chương trình như sau:

;Nhap vao ki tu mov ah,1 int 21h ;CASE... OF.... CMP AL,'A' JL L1 JE L2 JG L3 L1: MOV AH,9

Khoa CNTT Trang 67 KTMT

Biểu thức

Công việc 1

Công việc 2

Công việc n

Giá trị 1 Giá trị 2 Giá trị n

Gi¸o tr×nh vi xö lý

LEA DX,TRUOC INT 21H JMP END_ L2: MOV AH,9 LEA DX,DUNG INT 21H JMP END_ L3: MOV AH,9 LEA DX,SAU INT 21H END_:

4.3.4. Cấu trúc rẽ nhánh với điều kiện kép

Là một dạng cấu trúc rẽ nhánh mà trong đó, điều kiện là một sự kết hợp của hai hay nhiều điều kiện khác nhau. Điều kiện kép có hai dạng1/ Điều kiện kết hợp AND Là cấu trúc rẽ nhánh mà trong đó có nhiều điều kiện kết hợp. Nếu tất cả các điều kiện đều thoả mãn thì công việc sẽ được thực hiện. Ngược lại, có thể thực hiện một công việc khác hoặc không thực hiện gì.Ví dụ: Viết một đoạn chương trình thực hiện nhập vào từ bàn phím một kí tự. Kiểm tra xem phím nhập vào có phải là chữ số khôngGiải: mov ah,1 int 21h CMP AL,'0' JL END_IF CMP AL,'9' JG END_IF ;THEN

Khoa CNTT Trang 68 KTMT

Gi¸o tr×nh vi xö lý

MOV AH,9 LEA DX,SO INT 21H END_IF: MOV AH,4Ch INT 21h

2/ Điều kiện kết hợp ORLà cấu trúc rẽ nhánh mà trong đó có nhiều điều kiện kết hợp. Nếu một trong các điều kiện đều thoả mãn thì công việc sẽ được thực hiện. Ngược lại, nếu tất cả các điều kiện không được thoả mãn thì có thể thực hiện một công việc khác hoặc không thực hiện gì.Ví dụ: Viết một đoạn chương trình thực hiện nhập vào từ bàn phím một kí tự. Kiểm tra xem phím nhập vào có phải là 'Y' hoặc 'y' khôngGiải: Giả thiết có hai biến. yeucau chứa thông báo nhập vào; dung chứa thông báo kí tự nhập vào đúng là 'y' hoặc 'Y'. Đoạn chương trình sẽ được viết ra như sau: MOV AH,9 LEA DX,yeucau INT 21h mov ah,1 int 21h CMP AL,'Y' JE THEN_ CMP AL,'y' JE THEN_ JMP END_IF THEN_: MOV AH,9 LEA DX,DUNG INT 21H END_IF: MOV AH,4Ch INT 21h

Khoa CNTT Trang 69 KTMT

Gi¸o tr×nh vi xö lý

4.4. CẤU TRÚC LẶP

4.4.1. Cấu trúc FOR...TO....DO....

Đây là một dạng cấu trúc lặp với số lần lặp đã được xác định.Ngữ pháp:FOR số_lần_lặp DO công_việcĐầu tiên, gán cho thanh ghi đếm CX một giá trị bằng số lần lặp. Sau đó, thực hiện công việc. Sau mỗi lần lặp, giảm giá trị trong thanh ghi CX đi 1 đơn vị và kiểm tra nó với 0. Nếu chưa bằng 0 thì tiếp tục thực hiện công viêc... cho tới khi CX=0.Trong tập lệnh của bộ vi xử lý 8086 tồn tại một lệnh sử dụng phù hợp trong cấu trúc này. Đó là lệnh LOOP.Lệnh này tự động giảm thanh ghi CX 1 đơn vị và sau đó so sánh CX với 0.Ví dụ: Viết một đoạn chương thực hiện nhập vào từ bàn phím một kí tự. Sau đó cho hiển thị nó 200 lần trên màn hìnhGiải: MOV AH,9 LEA DX,YEUCAU INT 21H MOV CX,200 MOV AH,1 INT 21H PUSH AX MOV AH,2 MOV DL,13 INT 21H MOV DL,10 INT 21H POP AX

Khoa CNTT Trang 70 KTMT

CX=số_lần_lặp

Công_việc

CX=CX-1

CX=0?

Sai

Đúng

Gi¸o tr×nh vi xö lý

MOV AH,2 FOR_: MOV DL,AL INT 21H LOOP FOR_

4.4.2. Cấu trúc WHILE...DO....

Là một cấu trúc lặp phụ thuộc vào một điều kiện.Ngữ pháp: WHILE điều_kiện DO công_việcCông_việc sẽ được thực hiện cho đến khi điều_kiện trở nên saiVí dụ: Viết một đoạn chương trình thực hiện đếm số kí tự nhập vào từ bàn phímGiải:

XOR CX,CX MOV AH,1 WHILE_: INT 21H CMP AL,13 JE END_WHILE

INC CX JMP WHILE_ END_WHILE: MOV AH,4CH INT 21H

4.4.3. Cấu trúc REPEAT...UNTIL....

Ngữ pháp:REPEAT

cong_việc

Khoa CNTT Trang 71 KTMT

Điều_kiện

Công_việcđúngsai

Điều_kiện

Công_việc

đúngsai

Gi¸o tr×nh vi xö lý

UNTIL điều_kiệnĐây là cấu trúc lặp mà trong đó công_việc thực hiện trước, sau đó mới kiểm tra điều_kiện. Nếu điều_kiện đúng thì kết thúc quá trình lặp. Ngược lại, nếu điều_kiện vẫn còn sai thì quay trở lại thực hiện công_việc...Ví dụ: Viết một đoạn chương trình thực hiện nhập vào từ bàn phím một chuỗi kí tự kết thúc bằng việc nhấn phím ENTERGiải: MOV AH,9 LEA DX,YEUCAU INT 21H REPEAT_: MOV AH,1 INT 21H CMP AL,13 JNE REPEAT_ MOV AH,4Ch INT 21h

4.5. CẤU TRÚC CHƯƠNG TRÌNH CON

Nhằm mục đích làm cho chương trình ngắn gọn và dễ hiểu, thông thường người ta thực hiện chia nhỏ chương trình thành các Module khác nhau, mỗii Module có thể thực hiện một hoặc một khèi công việc nhất định. Mỗi một Module đó được gọi là một chương trình con.

Trong lập trình hợp ngữ thông thường người ta chỉ sử dụng một loại chương trình con thủ tục. Cấu trúc của chương trình con loại này được thực hiện như sau:

4.5.1. Cấu trúc của chương trình con

1/ Cấu trúc:<Tên ctc> PROC [kiểu]

Khoa CNTT Trang 72 KTMT

Gi¸o tr×nh vi xö lý

;Thân chương trình con ;.................................... RET<Tên ctc> ENDP

Trong đó:+ Tên ctc: Là tên Chương trình con m người sử dụng tự đặt theo qui định

đặt tên của ASSEMBLY+ PROC, ENDP: Các lệnh giả được thực hiện để khai báo bắt đầu và kết

thúc chương trình con.+ kiểu: có thể là NEAR hoặc FAR.

- NEAR (Mặc định) có nghĩa là dòng lệnh gọi thủ tục ở cùng đoạn với thủ tục đó.- FAR có nghĩa là dòng lệnh gọi thủ tục ở trong một đoạn khác.

2/ Ví dụ: xoamh PROC

MOV AH,0 MOV AL,3 INT 10h RET

xoamh ENDP3/ Một số chú ý:

- Tránh trường hợp sau khi thực hiện xong chương trình con, nội dung các thanh ghi có thể bị thay đổi, thường người ta sử dụng lệnh PUSH và POP trong chương trình con để đưa tạm vào ngăn xếp và sau đó lấy lại cho các thanh ghi. Ví dụ trong đoạn chương trình trên, sau khi thực hiện chương trình con xong, nội dung của thanh ghi AX có thể bị thay đổi. Ta có thể viết lại như sau:

xoamh PROC PUSH AX ; đẩy tạm AX vào ngăn xếp MOV AH,0 MOV AL,3 INT 10h

Khoa CNTT Trang 73 KTMT

Gi¸o tr×nh vi xö lý

POP AX ;lấy lại giá trị cũ từ ngăn xếp cho AX RET ;sau đó trở về chương trình chính

xoamh ENDP- Để người khác có thể đọc và hiểu rõ thủ tục thực hiện như thế nào thì,

người lập trình phải có một đoạn giải thích như sau:;Chức năng của thủ tục;Vào: (lấy thông tin từ chương trình gọi);Ra: (Trả thông tin đã được xử lý về cho chương trình gọi);Cách sử dung (nếu có)

Ví dụ: Viết một thủ tục thực hiện nhân 2 số nguyên dương A và B bằng cách cộng và dịch các bit.Thuật toán:

tich=0Repeat

if LSB(B)=1 then tich=tich+A end_if SHL A,1 SHR B,1

until B=0Đoạn mã:nhan PROC;Nhan 2 so A,B bang phep dich va cong cac bit;Vao: AX=A;BX=B;Ra: DX=ket qua

PUSH AX ;day tam AX PUSH BX ;va BX vao ngan xepXOR DX,DX ;xoa thanh ghi DX chua tich

REPEAT:

Khoa CNTT Trang 74 KTMT

Gi¸o tr×nh vi xö lý

;if B leTEST BX,1 ;bit LSB cua BX bang 1?JZ END_IF ;Khong, dich trai AX....

;thenADD DX,AX ;tich=tich+A

END_IF:SHL AX,1 ;dich trai AXSHR BX,1 ;dich phai BX;until B=0JNZ REPEAT ;B <> 0, lap laiPOP BX ;Khoi phuc lai BX POP AX ;va AX tu ngan xepRET

nhan ENDP

4.5.2. Cách gọi và thực hiện một chương trình con

Sau khi đó lập được một thủ tục, người lập trình chỉ việc gọi chúng ra từ một đoạn chương trình nào đó như sau:

CALL <Tên thủ tục>Việc gọi chương trình con rất đơn giản, song có một số chú ý khi ta thực

hiện với chương trình con.4.5.2.1. Chương trình con nằm trong cùng một chương trình1/ Cách gọi.Nếu đoạn chương trình con nằm trong cùng một chương trình, thì ta có thể gọi và thực hiện theo mẫu sau. Ví dụ:Title ctchinh.MODEL Small.STACK 100h.DATA ;khai báo dữ liệu cho chương trình.CODE

Khoa CNTT Trang 75 KTMT

Gi¸o tr×nh vi xö lý

Main PROCMOV AX,@dataMOV DS,AX;Các lệnh của chương trình chínhCALL ctc;Các lệnh của chương trình chính

Main ENDPCtc PROC

;Các lệnh của chương trình conRET

Ctc ENDPEND Main

2/ Ví dụ: Viết một chương trình nhập vào một kí tự, sau đó in ra ở dòng tiếp theo.

4.5.2.2. Chương trình con được soạn thảo trong một tệp khác 1/ Cách gọi.Nếu các chương trình con được soạn thảo trong một tệp khác (ví dụ CTC.LIB), thì có thể sử dụng lệnh INCLUDE tại vị trí khai báo các chương trình con. Ví dụ:

Title ctchinh.MODEL Small.STACK 100h.DATA ;khai báo dữ liệu cho chương trình.CODEMain PROC

MOV AX,@dataMOV DS,AX;Các lệnh của chương trình chínhCALL ctc;Các lệnh của chương trình chính

Main ENDPINCLUDE ctc.lib

Khoa CNTT Trang 76 KTMT

Gi¸o tr×nh vi xö lý

END Main

2/ Ví dụ: Viết một chương trình nhập vào một kí tự, sau đó in ra ở dòng tiếp theo.

4.6. MACRO

Trong lập trình với ngôn ngữ bậc cao, thông thường người ta sử dụng các chương trình con với các tham số. Song trong hợp ngữ không sử dụng được các tham số, vì các chương trình con qui định trả lại các giá trị qua ngăn xếp. Vì vậy, việc trả lại các tham số cho chương trình gọi khó khăn.

Để đáp ứng vấn đề này, người ta sử dụng một loại cấu trúc được gọi là MACRO.

4.6.1. Định nghĩa MACRO

1/ Khái niệm: MACRO thực chất chỉ là một khối văn bản có tên. Khi trình biên dịch gặp tên

đó, nó sẽ chèn khối văn bản tương ứng vào chương trình. Khối văn bản trong MACRO có thể là các lệnh, các toán tử giả hoặc lời bình...2/ Cách định nghĩa:

<Tên MACRO> MACRO <các tham số hình thức> ;các lệnh trong thân MACROENDM

Trong đó:- Tên MACRO là một tên do người lập trình tự đặt và phải theo đúng qui định đặt

tên.- MACRO,ENDM là các toán tử giả cho biết bắt đầu và kết thúc MACRO.- Các tham số hình thức: có thể là 1,2,3 hoặc nhiều tham số cần thiết cho việc trả

lại giá trị trong chương trình gọi. Các tham số này phải được ngăn cách nhau bởi dấu phẩy.

Ví dụ: Định nghĩa MACRO chuyển dữ liệu từ một biến kiểu WORD sang một biến khác kiểu WORD.

MOVW MACRO w1,w2PUSHw2;đẩy nội dung biến w1 vào ngăn xếp

Khoa CNTT Trang 77 KTMT

Gi¸o tr×nh vi xö lý

POP w1;sau đó lấy ra cho w2ENDM

Chú ý: - Nếu trong đoạn MACRO cần sử dụng nhãn cho các lệnh chuyển điều khiển, thì

các nhãn này phải được khai báo trước bằng lệnhLOCAL <danh sách các nhãn>

- Nên sử dụng các lệnh PUSH và POP trước và sau khi thực hiện một MACROVí dụ:

enter MACROLOCAL L

PUSH AX ;AX day vao ngan xep truoc khi bi thay doi MOV AH,08H ;Nhap vao 1 ki tu L: INT 21H CMP AL,13 ;ki tu la ENTER? JNE L ;Khong, nhap lai

POP AX ;thuc hien xong, khoi phuc laiENDM

4.6.2. Gọi MACRO trong chương trình

1/ Cú pháp:Sau khi đã định nghĩa MACRO, ta có thể gọi trực tiếp chúng từ chương trình

hiện tại tương tự như các lệnh khác của hợp ngữ. Theo dạng sau: <tên MACRO> <Các tham số thực sự>

trong đó:- Tên MACRO là tên đã được khai báo trong phần định nghĩa.- Các tham số thực sự là các tham số, các biến của chương trình gọi. Các tham số

này cũng phải được ngăn cách nhau bởi dấu phẩy.

2/ Ví dụ: Giả sử có hai biến kiểu WORD là a và b. Nếu gọi MACRO đã định nghĩa ở trên thì ta sử dụng lời gọi như sau:

MOVW a,b ;chuyen noi dung cua bien b sang cho bien a

Khoa CNTT Trang 78 KTMT

Gi¸o tr×nh vi xö lý

3/ Chú ý:- Lời gọi MACRO phải nằm trong đoạn mã của chương trình.

- Trong trường hợp các thanh ghi có thể bị thay đổi, ta có thể sử dụng ngăn xếp để chứa dữ liệu tạm thời, và sau đó có thể khôi phục lại.

4/ Bài tập: Viết một chương trình in ra màn hình các thông tin về bản thân. Sau mỗi lần hiển thị ra một thông tin, người sử dụngChương trình:

title ct.MODEL Small.STACK 100h.DATA hoten DB 'Ho va ten: Nguyen Thanh Toan $' nsinh DB 'Ngay sinh: 10-10-1983 $' que DB 'Que quan: Thanh Mien-Hai Duong $'

;Dinh nghia MACRO in chuoi ki tu ra man hinhWRITE MACRO st MOV AH,9 MOV DX,OFFSET st INT 21HENDM;dinh nghia MACRO nhan phim ENTERenter MACROLOCAL L MOV AH,08H L: INT 21H CMP AL,13 JNE LENDM;dinh nghia MACRO in chuoi tren 1 dong WRITELN MACRO STR MOV AH,09 LEA DX,STR

Khoa CNTT Trang 79 KTMT

Gi¸o tr×nh vi xö lý

INT 21H MOV AH,02 MOV DL,13 INT 21H MOV DL,10 INT 21HENDM.CODEmain PROC MOV AX,@DATA ;khoi tao DS MOV DS,AX WRITELN HOTEN ;in ra ho va ten ENTER ;nhan enter

WRITELN NSINH ;in ra ho va ten ENTER ;nhan enter WRITELN QUE ;in ra ho va ten ENTER ;nhan enter MOV AH,4Ch ;ket thuc

INT 21h ;chuong trinh

main ENDP END main

4.6.3. Gọi MACRO từ đoạn chương trình khác

Đôi khi người lập trình muốn sử dụng các MACRO trong nhiều chương trình khác nhau. Nhưng nếu viết chúng trong cùng một chương trình với chương trình chính thì không thuận tiện vì mỗi một chương trình ta đều phải viết lại MACRO cho chúng.

Trong lập trình với ASSEMBLY, cho phép người lập trình có thể viết các MACRO trong một tệp riêng biệt (Tệp MACRO này chỉ chứa các MACRO, không có các cấu trúc của chương trình). Sau đó có thể sử dụng các MACRO này bằng cách chèn vào văn bản chương trình chính bằng lệnh:

INCLUDE <tên tệp MACRO>Lệnh này có thể chèn vào bất kì vị trí nào của chương trình mà có thể định

nghĩa MACRO

Khoa CNTT Trang 80 KTMT

Gi¸o tr×nh vi xö lý

Ví dụ: Viết một chương trình hiển thị các thông tin về bản thân. Các MACRO được thực hiện trong một tệp nào đó.*Tệp chứa các MACRO

LOAD_DATA MACRO MOV AX,@DATA MOV DS,AXENDMWRITE MACRO st MOV AH,9 MOV DX,OFFSET st INT 21HENDMenter MACROlocal L MOV AH,08H L: INT 21H CMP AL,13 JNE LENDMWRITELN MACRO STR MOV AH,09 LEA DX,STR INT 21H MOV AH,02 MOV DL,13 INT 21H MOV DL,10 INT 21HENDMRET_DOS MACRO MOV AH,4Ch INT 21H

Khoa CNTT Trang 81 KTMT

Gi¸o tr×nh vi xö lý

ENDM*Tệp chứa chương trình chính

title ct.MODEL Small.STACK 100h.DATA hoten db 'Ho va ten: Nguyen Thanh Toan $' nsinh db 'Ngay sinh: 10-10-1983 $' que db 'Que quan: Thanh Mien - Hai Duong $'INCLUDE macro.lib.CODEmain PROC LOAD_DATA WRITELN HOTEN ENTER WRITELN NSINH ENTER WRITELN QUE ENTER RET_DOSmain ENDP END main

Khoa CNTT Trang 82 KTMT

Gi¸o tr×nh vi xö lý

CHƯƠNG 5: MỘT SỐ VẤN ĐỀ NÂNG CAO

5.1. LẬP TRÌNH XỬ LÝ SỐ NGUYÊN

5.2. CẤU TRÚC DỮ LIỆU MẢNG

Trong lập trình với một số ngôn ngữ bậc cao, ta đã xét đến một số loại cấu trúc dữ liệu, trong đó có kiểu dữ liệu mảng. Kiểu cấu trúc này có ưu điểm là chỉ cần sử dụng một tên cho nhiều phần tử khác nhau. Các phần tử này được truy nhập thông qua các chỉ số.

5.2.1. Khai báo mảng.

Để khai báo các mảng, thông thường người ta sử dụng theo cách sau:a/ Mảng 1 chiều

<Tên mảng> <Kiểu> <Danh sách các giá trị khởi tạo>Ví dụ:

A DB 54,66,87,0,42Khai báo mảng 1 chiều, trong đó mỗi phần tử cử mảng là một giá trị kiểu Byte. Giả sử địa chỉ offset gán cho A bằng 0100h, mảng này sẽ được phân bố trong bộ nhớ như sau:

Địa chỉ OFFSET Tên các phần tử Giá trị khởi tạo

0100h0101h0102h0103h0104h

AA+1A+2A+3A+4

546687042

b/ Mảng 2 chiều<tên mảng> <kiểu> <Các giá trị hàng 1>

<kiểu> <Các giá trị hàng 2>..............................................<kiểu> <Các giá trị hàng 3>

Ví dụ:

Khoa CNTT Trang 83 KTMT

Gi¸o tr×nh vi xö lý

B DW 10,20,30DW 50,60,70DW 90,100,110

Với mảng hai chiều thì thứ tự của các phần tử trong bộ nhớ được bố trí theo thứ tự phần tử đầu của hàng dưới đứng ngay sau phần tử đầu hàng trên và được lưu trữ tuần tự.

5.2.2. Sử dụng mảng.

Vì các phần tử của mảng được phân bố tuần tự và địa chỉ của các phần tử này trong bộ nhớ sát nhau. Vì vậy khi truy nhập đến một phần tử nào đó, ta chỉ cần biết điạ chỉ đầu, sau đó cộng với độ dịch chuyển.

- Mảng 1 chiều: độ dịch chuyển=i*S- Mảng 2 chiều: độ dịch chuyển=i*j*S

Trong đó: i,j là chỉ số của mảng theo hàng (i) và theo cột (j)S độ dài của mỗi phần tử (kiểu byte: S=1;kiểu Word: S=2)

Để truy nhập đến một phần tử của mảng bằng các lệnh, ta có thể sử dụng một số chế độ của các toán hạng trong lệnh như:

Chế độ gián tiếp thanh ghi.Chế độ địa chỉ cơ sởChế độ địa chỉ chỉ sốChế độ địa chỉ chỉ số cơ sở

Để hoán chuyển hai phần tử của mảng. Ví dụ phần tử thứ 3 và thứ 5 trong mảng A, ta có thể thực hiện theo mẫu sau:

MOV AX,A+2 ;AX =A[3]XCHG A+4,AX ;AX =A[5], A[5]=A[3]MOV A+2,AX ;A[3]=A[5]

Ví dụ: Sắp xếp một mảng theo thứ tự tăng dầntitle ct.MODEL Small.STACK 100h

Khoa CNTT Trang 84 KTMT

Gi¸o tr×nh vi xö lý

.DATA A DB 31H,39H,37H,35H,33H ;khai bao mang 1 chieu.CODEmain PROC MOV AX,@DATA MOV DS,AX LEA SI,A ;SI tro toi dia chi offset cua mang MOV BX,5 ;so phan tu cua mang can sap xep CALL SELECT ;sap xep MOV AH,4Ch INT 21hmain ENDPselect proc push bx push cx push dx push si dec bx ;giam BX di 1 je end_sort ;BX=0, ket thuc mov dx,si ;chep offset cua mang;for n-1 dosort15: mov si,dx ;SI tro toi mang mov cx,bx ;so lan so sanh mov di,si ;DI tro toi phan tu max mov al,[di] ;AL chua phan tu lon nhat;xac dinh phan tu lon nhat con laifind_big: inc si ;SI tro toi pha tu tiep theo cmp [si],al ;> phan tu lon nhat

Khoa CNTT Trang 85 KTMT

Gi¸o tr×nh vi xö lý

jng next ;khong, tiep tuc mov di,si ;dung, tro den no mov al,[di] ;AL chua phan tu lon nhatnext: loop find_big ;lap den khi hoan thanh;doi cho phan thu lon nhat voi phan tu cuoi cung call swap ;doi cho phan tu cuoi cung dec dx ;n=n-1 jne sort15 ;n>0, lap tiepend_sort: pop si pop dx pop cx pop bx retselect endp;doi cho hai phan tu trong mangswap PROC PUSH AX MOV AL,[SI] XCHG AL,[DI] MOV [SI],AL POP AX RETswap ENDP END main

5.3. CẤU TRÚC DỮ LIỆU XÂU KÍ TỰ

Khoa CNTT Trang 86 KTMT

Gi¸o tr×nh vi xö lý

Về cơ bản, cấu trúc dữ liệu này là một trường hợp đặc biệt của mảng với các phần tử của mảng là mã ASCII của các kí tự. Vì vậy, các lệnh thao tác với mảng cũng có thể thực hiện cho chuỗi.

Các công việc thực hiện bằng các lệnh thao tác chuỗi có thể sử dụng các chế độ địa chỉ gián tiếp thanh ghi. Tuy nhiên các lệnh thao tác chuỗi có thể tự động điều chỉnh thanh ghi con trỏ và cho phép có những thao tác giữa bộ nhớ với bộ nhớ.

5.3.1. Cờ định hướng

Trong thanh ghi cờ của bộ vi xử lý 8086 có một cờ điều khiển thường sử dụng trong các thao tác với chuỗi kí tự, nó chỉ hướng sắp xếp của chuỗi là tăng hay giảm dần. Cờ này chính là cờ DF.

Nếu cờ DF=0, SI và DI được xử lý theo chiều tăng của các địa chỉ bộ nhớ từ trái qua phải trong chuỗi. Ngược lại, nếu DF=1 thì phép xử lý này sẽ là từ phải sang phải, có nghĩa là theo chiều giảm của các địa chỉ bộ nhớ.

Cờ định hướng có thể thay đổi được bằng lệnh:+ CLD - CLear Direction flag (xoá cờ hướng)Lệnh này sẽ gán giá trị 0 cho cờ định hướng.+ STD - SeT Direction flag (lập cờ hướng)Lệnh này sẽ thiết lập giá trị 1 cho cờ định hướng.

5.3.2. Lệnh chuyển một chuỗi.

Giả sử đã khai báo 2 biến st1 DB 'XIN CHAO'st2 DB 8 DUP (?)Muốn chuyển nội dung của chuỗi st1 sang chuỗi st2, người ta sử dụng lệnh:

MOVSB - MOVement String ByteLệnh này sẽ sao chép nội dung của byte được định địa chỉ bởi DS:SI đến

byte được định địa chỉ bởi ES:DI. Nội dung của byte nguồn không bị thay đổi. Sau khi một byte được chuyển, cả hai thanh ghi SI và DI đều tự động tăng nếu DF=0 hay giảm đi 1 nếu DF=1.Ví dụ muốn chuyển 2 byte đầu của st1 đến st2, ta có thể thực hiện:

Khoa CNTT Trang 87 KTMT

Gi¸o tr×nh vi xö lý

MOV AX,@DATAMOV DS,AX ;Khoi tao DSMOV ES,AX ;va ESLEA SI,st1 ;SI tro den chuoi nguonLEA DI,st2 ;DI tro toi chuoi dichCLD ;Dinh huong tu trai sang phaiMOVSB ;Chuyen byte thu nhatMOVSB ;chuyen byte thu hai

Vậy, muốn chuyển cả chuỗi thì phải mất nhiều lệnh MOVSB, do đó chương trình có thể rất dài, không cần thiết. Trong trường hợp này, ta có thể sử dụng lệnh khởi tạo REP (REPeat) như sau:

REP MOVSBVí dụ chuyển cả chuỗi st1 sang chuỗi st2, ta thực hiện như sau:

MOV AX,@DATAMOV DS,AX ;Khoi tao DSMOV ES,AX ;va ESLEA SI,st1 ;SI tro den chuoi nguonLEA DI,st2 ;DI tro toi chuoi dichCLD ;Dinh huong tu trai sang phaiMOV CX,8 ;so ki tu trong chuoi st1REP MOVSB ;Chuyen ca 8 byte trong st1 sang st2

5.3.3. Lệnh lưu chuỗi

Trong nhiều trường hợp, chúng ta cần phải thực hiện nhập vào một chuỗi, sau đó in chuỗi đó ra màn hình. Muốn thực hiện được điều này, ta phải lưu chuỗi nhập vào vào một biến kiểu chuỗi. Lệnh lưu chuỗi như sau:

Dạng lệnh: STOSB ;STOre String Byte - lưu chuỗi các byteLệnh này có tác dụng chuyển nội dung của thanh ghi AL đến byte được

định địa chỉ bởi ES:DI. Sau khi lệnh được thực hiện, DI tăng 1 nếu DF=0 hoặc giảm 1 nếu DF=1. Lệnh này không ảnh hưởng đến các cờ.

5.3.4. Lệnh nạp chuỗi

Khoa CNTT Trang 88 KTMT

Gi¸o tr×nh vi xö lý

Muốn chuyển một chuỗi kí tự đã được lưu ra màn hình, ta có thể sử dụng hàm 09h của ngắt 21h. Song, hàm này yêu cầu chuỗi phải được kết thúc bằng dấu '$'. Mặt khác, trên thực tế, khi nhập vào ít người quan tâm tới việc phải nhập vào dấu '$' khi kết thúc.

Để giải quyết vấn đề này, ta có thể sử dụng hàm 02h của ngắt 21h kết hợp với lệnh nạp chuỗi.

Dạng lệnh: LODSB ;LOaD String Byte - Nạp chuỗi byteLệnh này chuyển byte tại địa chỉ DS:SI vào AL. Sau lệnh này, SI sẽ được

tăng thêm 1 nếu DF=0 hoặc giảm đi 1 nếu DF=15.4.2.4. LệDS,AX ;Khoi tao DSMOV ES,AX ;va ESLEA DI,st1 ;DI tro den chuoi st1CLD ;Xu li tu trai sang phaiMOV AL,'A' ;Ki tu can timMOVSB ;Duyet Byte dau tienMOVSB ;Duyet Byte thu hai

5.3.5. Ví dụ:

Nhập vào một chuỗi kí tự, sau đó hiển thị 10 kí tự đầu tiên ra màn hình ở dòng tiếp theoChương trình:

title ct.MODEL Small.STACK 100h.DATA STR DB 80 DUP(0) ;chuoi luu ki tu nhap vao CRLF DB 13,10,'$' ;xuong dong va ve dau dong.CODEmain PROC MOV AX,@DATA

Khoa CNTT Trang 89 KTMT

Gi¸o tr×nh vi xö lý

MOV DS,AX ;khoi tao DS MOV ES,AX ;va ES LEA DI,STR ;DI tro toi chuoi CALL READ ;nhap chuoi tu ban phim MOV AH,09H ;xuong dong LEA DX,CRLF ;ve dau dong INT 21H LEA SI,STR ;SI tro toi chuoi MOV BX,10 ;so ki tu hien thi CALL DISP ;hien thi cac ki tu MOV AH,4Ch INT 21hmain ENDPREAD PROC NEAR;Doc va luu chuoi;Vao: DI chua dia chi offset ua chuoi;Ra: DI chua dia chi offset cua chuoi; BX chua so ki tu nhan duoc PUSH AX PUSH DI CLD ;Xu li tu ben trai sang XOR BX,BX ;BX=0 MOV AH,1 ;Nhap ki tu INT 21hWHILE1: CMP AL,13 ;ki tu nhap la ENTER? JE END_WHILE ;Dung, thoi nhap CMP AL,8 ;ki tu nhap la BACKSPACE? JNE ELSE_ ;Khong, ki tu tiep theo DEC BX ;dung, xoa ki tu truoc

Khoa CNTT Trang 90 KTMT

Gi¸o tr×nh vi xö lý

JMP READ_ ;Nhap tiepELSE_: STOSB ;Luu vao chuoi INC BX ;chuan bi ki tu tiepREAD_: INT 21H ;nhap tiep JMP WHILE1 ;ki tu sauEND_WHILE: POP DI POP AX RETREAD ENDPDISP PROC NEAR;Hien thi mot chuoi ki tu;Vao: SI=offset chuoi; BX=so cac ki tu can hien thi PUSH AX PUSH BX PUSH DX PUSH SI MOV CX,BX ;so lan hien thi JCXZ EXIT ;bang 0, khong hien thi CLD ;xu li tu trai sang phai MOV AH,2 ;chuan biTOP: LODSB ;ki tu trong AL MOV DL,AL ;chuyen sang DL de hien thi INT 21h ;hien thi ki tu LOOP TOP ;Lap lai cho den khi het chuoiEXIT:

Khoa CNTT Trang 91 KTMT

Gi¸o tr×nh vi xö lý

POP SI POP DX POP BX POP AX RETDISP ENDP END main

5.4. LẬP TRÌNH XỬ LÝ SỐ THỰC

5.5. LẬP TRÌNH CHO CÁC BỘ VI XỬ LÝ TIÊN TIẾN

Cấu trúc và bộ lệnh của các bộ vi xử lý thay đổi, dẫn đến phương thức tác động cũng phần nào được thay đổi. Mặc dù các bộ VXL tiên tiến có hỗ trợ cho các chế độ của 8086, song sẽ không thể tận dụng tối đa những đặc tính mới này.

Để có thể sử dụng tối đa công dụng của những bộ VXL tiên tiến, ta cần phải truy nhập bằng các lệnh và sử dụng một số dẫn hướng tuỳ theo qui định của từng loại vi xử lý.

Ví dụ: Bộ VXL 80286 bổ sung một số lệnh như: PUSHA, POPA, Lệnh IMUL với nhiều toán hạng....Ta có thể sử dụng các lệnh này bằng cách: Trước khi sử dụng các lệnh này ta phải đặt dẫn hướng.286 tại 1 dòng, và sau cùng trả lại cho chế độ của 8086 ta đặt dẫn hướng.8086

MOV AL,5MOV BL,10ADD AL,BL.286PUSHA ;Dat lenh nay trong doan lenh 80286, dungMOV AL,15HSUB AL,BLMOV [BX],10IMUL AL,[BX],3 ;co the su dung IMUL nhu vay

Khoa CNTT Trang 92 KTMT

Gi¸o tr×nh vi xö lý

POPA.8086PUSHA ;Dat ngoai doan lenh cua 286 la sai

Khoa CNTT Trang 93 KTMT

Gi¸o tr×nh vi xö lý

CHƯƠNG 6: LIÊN KẾT ASSEMBLY VỚI NGÔN NGỮ BẬC CAO

6.1. LẬP TRÌNH MÃ LỆNH MÃ MÁY

Một chương trình viết bằng hợp ngữ (Assembly) thường là dài và khó hơn, nhưng lại thực hiện nhanh hơn một chương trình tương tự viết bằng ngôn ngữ bậc cao (Turbo PASCAL, C++,...). Vì vậy, để một chương trình viết kết hợp về tốc độ của hợp ngữ và tính dễ hiểu, ngắn gọn của ngôn ngữ lập trình bậc cao, các lập trình viên thường viết một số Modul chương trình cần đến việc xử lý nhanh bằng hợp ngữ, cáclục phân) trực tiếp vào trong chương trình taij vị trí bất kỳ (có thể trong thủ tục, hàm hoặc chương trình chính). Phương pháp này được thực hiện bởi thủ tục INLINE.

6.1.1. Cú pháp

INLINE(val/val/val/.../val);Trong đó: val: Là các giá trị và phải được phân cách bằng dấu “ / ”

Các giá trị có thể là dạng thập phân, thập lục phân hoặc nhị phân. Các giá trị này chính là các lệnh mã máy thực hiện thao tác nào đó.

Các giá trị thuộc kiểu dữ liệu 8 bit sẽ tạo ra 1byte mã lệnh hoặc dữ liệu, các giá trị thuộc kiểu dữ liệu 16 bit sẽ tạo ra 2 byte mã lệnh hoặc dữ liệu.

6.1.2 Thực hiện

Khi gặp phát biểu INLINE, PASCAL sẽ chuyển các giá trị trong đó sang các mã máy tương ứng và máy sẽ trực tiếp thực hiện. Chương trình dịch sẽ không phải tốn nhiều thời gian cho việc dịch lệnh. Vì vậy, việc thực hiện lệnh được nhanh hơn.

6.1.3 Một số chú ý.

- Các giá trị nếu được biểu diễn dưới dạng thập lục phân thì phải có dấu “ $ ” đứng trước.

- Có thể ghép các biến của PASCAL vào vị trí các giá trị thích hợp bằng cách trước tên biến sử dụng dấu “ < ”

Khoa CNTT Trang 94 KTMT

Gi¸o tr×nh vi xö lý

- Các phát biểu INLINE có thể viết tách ra hoặc gộp lại- Nếu phát biểu INLINE nội dung của một hàm nào đó thì giá trị trả lại của

hàm phải tuân thủ quy định sau:

Kiểu dữ liệu Giá trị trả lại

ByteBoolean

CharLiệt kê (8 bít)

Shortint

AL

WordInteger

Liệt kê (16 bít)AX

Longint DX: AX

Real DX:BX:AX

6.1.4 Ví dụ

1. Viết một chương trình sử dụng phát biểu INLINE thực hiện tính tổng hai số.

Giải: Program thu;Uses crt;Var so1,so2:integer;(*---------------------------------------------*)Function sum(num1:integer;num2:integer):integer; Begin Inline($8B/$46/<num1/ {AX <-- num1} $03/$46/<num2/ {AX <-- num2} $89/$46/$FE); {[BP-2] <--AX} End; {Gia tri tra lai chuyen qua ngan xep}

Khoa CNTT Trang 95 KTMT

Gi¸o tr×nh vi xö lý

(*--------------------------------------------*)Begin Clrscr; Write('So thu nhat: ');Readln(so1); Write('So thu hai: ');Readln(so2); Writeln('Tong cua hai so la: ',sum(so1,so2)); Readln;End.

2. Viết chương trình sử dụng phát biểu INLINE thực hiện việc hiển thị một ký tự ra màn hình đồ hoạ.

Giải:Program man_hinh; Begin Inline($B4/$00/ {MOV AH,00 ;Ham lap che do man hinh} $B0/$12/ {MOV AL,12h ;Che do 640*480*16} $CD/$10); {INT 10h ;Lap che do} Inline($B4/$0B/ {MOV AH,0Bh ;lap mau nen va vien } $B7/$00/ {MOV BH,0 ;Trang man hinh 0 } $B3/$03/ {MOV BL,0 ;mau vien va nen} $CD/$10); {INT 10h ;Dat mau} Inline($B4/$02/ {MOV AH,02 ;Ham dat vi tri con tro} $B7/$00/ {MOV BH,00 ;Trang so 0} $B6/$0C/ {MOV DH,0ch ;Toa do y} $B2/$28/ {MOV DL,28h ;Toa do X} $CD/$10); {INT 10h ;Dat con tro} Inline($B4/$09/ {MOV AH,09 ;Ham ghi ky tu} $B0/$41/ {MOV AL,01 ;Ma ASCII cua ky tu} $B3/$04/ {MOV BL,04 ;Mau cua ky tu } $B9/$01/$00/{MOV CX,01 ;So lan lap lai ky tu} $CD/$10); {INT 10h ;Ghi ky tu}

Khoa CNTT Trang 96 KTMT

Gi¸o tr×nh vi xö lý

Readln;End.

6.2. LẬP TRÌNH MÃ LỆNH GỢI NHỚ

6.2.1 Cú pháp

PASCAL hỗ trợ một lệnh chèn đoạn mã lệnh gợi nhớ (MNEMONIC) của hợp ngữ vào bất cứ vị trí nào cần thiết trong chương trình. Cú pháp thực hiện như sau:

ASM

{Khối các lệnh hợp ngữ}

END;

Trong đó:

ASM, END là từ khoá cho biết vị trí bắt đầu và kết thúc của đoạn mã

{Khối các lệnh hợp ngữ} là các mã lệnh gợi nhớ của hợp ngữ.

6.2.2 Thực hiện

Khi chương trình dịch của PASCAL gặp từ khoá ASM trong dòng lệnh thì nó sẽ chuyển dòng lệnh ASSEMBLY vào và dịch với việc quy chiếu biến PASCAL ra dạng tương ứng của ASSEMBLY để thực hiện.

Nếu biến kiểu Integer thì chương trình dịch sẽ quy chiếu sang dạng DW của Assembly.

6.2.3 Một số chú ý.

- Lời chú thích, chú giải cần phải có với mỗi lệnh hợp ngữ và phải tuân thủ theo quy định của PASCAL.

Khoa CNTT Trang 97 KTMT

Gi¸o tr×nh vi xö lý

- Các lệnh nhảy của Assembly có thể nhảy ra ngoài phần lệnh ngôn ngữ PASCAL hoặc đoạn lệnh bên trong phần lệnh hợp ngữ, nhưng lệnh nhảy của PASCAL không thể nhảy đến nhãn trong phần lệnh hợp ngữ.

- Các nhãn (nếu có) trong phần lệnh của Assembly phải có dấu '@' đứng trước.

- Các lệnh hợp ngữ phải kết hợp chính xác, tránh hiện tượng treo máy.

6.2.4 Ví dụ

Viết một chương trình thực hiện việc đưa ra số nhỏ nhất và lớn nhất trong hai số.

LỜI GIẢI

Thuật toán tìm số nhỏ nhất: Thuật toán tìm số lớn nhất:

Mã lệnh:

Program min_max;Uses crt;Var so1,so2:integer;

Khoa CNTT Trang 98 KTMT

AX:=số thứ 1

AX >số thứ 2

AX:=số thứ 2

Min:=AX

Sai

Đúng

AX:=số thứ 1

AX<số thứ 2

AX:=số thứ 2

Max:=AX

Sai

Đúng

Gi¸o tr×nh vi xö lý

{*---------------------------------------------*}Function min(num1:integer;num2:integer):integer;Var tg:integer; BEGIN ASM MOV AX,num1 {AX:=num1} CMP AX,num2 {If AX>num2 then} JNG @END_If MOV AX,num2 {AX:=num2} @END_If: {tg:=AX} MOV tg,AX END; min:=tg;END;{*---------------------------------------------*}Function max(num1:integer;num2:integer):integer;LABEL END_IF; Begin ASM MOV AX,num1 {AX:=num1} CMP AX,num2 {If AX<num2 then} JNL END_IF {Begin} MOV AX,num2 {AX:=num2} MOV num1,AX {END} END;END_IF: max:=num1; {Gia tri tra lai cua ham}END;(*--------------------------------------------*)Begin Clrscr;

Khoa CNTT Trang 99 KTMT

Gi¸o tr×nh vi xö lý

Write('So thu nhat:');Readln(so1); Write('So thu hai:');Readln(so2); Write('So nho nhat la: ',min(so1,so2)); Write('So lon nhat la: ',max(so1,so2)); Readln;END.

6.3. NGẮT VÀ LẬP TRÌNH NGẮT TRONG CÁC NGÔN NGỮ BẬC CAO

ASSEMBLY là một ngôn ngữ lập trình tác động trực tiếp tới các thành phần phần cứng. Các thành phần phần cứng này có thể tác động bằng địa chỉ cổng, song cũng có thể tác động bằng các ngắt.

Việc tác động bằng ngắt đã được qui định cho từng thiết bị ngoại vi cũng như các thành phần khác trong máy tính. Hệ điều hành đã qui định chúng trong các ngắt mềm.

6.3.1. Khái niệm về ngắt

Ngắt là quá trình CPU tạm thời ngừng hoạt động hiện tại khi có một yêu cầu ngắt gọi đến để chuyển sang thực hiện chương trình con phục vụ ngắt tương ứng. Sau khi thực hiện xong thì quay trở lại thực hiện tiếp công việc đang dở trên.

6.3.2. Phân loại ngắt

Hình 3: Phân loại các ngắt.

Khoa CNTT Trang 100 KTMT

CT chính CT con phục vụ ngắt

Gi¸o tr×nh vi xö lý

1/ Ngắt cứng là ngắt do các thành phần phần cứng gây ra.- Ngắt trong: Là các ngắt xảy ra ngay bên trong CPU.- Ngắt ngoài: Là các ngắt do các thành phần phần cứng khác gây ra.

+ Ngắt có cấm (Maskable Interrupt) là các ngắt chỉ được thực hiện khi cờ IF được thiết lập (IF=1)

+ Ngắt không cấm (Non Maskable Interrupt) là các ngắt có thể thực hiện được ngay cả khi cờ IF không được thiết lập.

2/ Ngắt mềm là các ngắt nằm bên trong chương trình phần mềm.- Ngắt của người sử dụng là các ngắt được viết ra bởi những chương trình

của người sử dụng.- Ngắt hệ thống là các ngắt nằm bên trong các chương trình của BIOS hoặc

hệ điều hành (ví dụ: DOS)+ Ngắt DOS là các ngắt nằm bên trong chương trình của DOS trong Module

vào/ra (IO.SYS)+ Ngắt BIOS là các ngắt nằm bên trong chương trình của BIOS.

6.3.3. Giới thiệu về một số ngắt

6.3.3.1.Cách thực hiện ngắt trong một số ngôn ngữ lập trình1.Gọi ngắt trong ASSEMBLY

Một số ngắt thông thường cể các tham số đầu vào.Phô thuộc vào các tham số này,chương trình sẽ thực hiện giải quyết và đưa ra các tham số đầu ra.

Các tham số đầu vào là các giá trị chuyển tới các thanh ghi hoặc ô nhớ nào đã Các tham đầu ra là các giá trị nhận được sau khi hàm này xử lý xong.

Để gọi ngắt trong ASSEMBLY ta có thể thực hiện theo mẫu sau:- Chuyển các tham số đầu vào- Gọi ngắt INT <số hiệu ngắt>- Xử lý các tham số đầu ra

Ví dụ: MOV AH,01h ;Nhập vào một kí tự INT 21h ;Kí tự nằm trong AL MOV DL,AL ;Lấy từ AL sang DL INT 21h ;Hiển thị

2.Gọi ngắt trong PASCAL

Khoa CNTT Trang 101 KTMT

Gi¸o tr×nh vi xö lý

Việc gọi ngắt trong PASCAL cũng được thực hiện theo mẫu trên.Song phải theo một số quy định sau:- Các lệnh được sử dụng là các lệnh của PASCAL. Lệnh gán tương đương

với lệnh MOV trong ASSEMBLY- Nếu sử dụng hệ đếm thập lục phân,thì phải cài đặt dấu ‘$’ đứng trước mỗi số

đó.- Muốn tác động trực tiếp tới các thanh ghi của bộ vi xử lý,ta phải sử dụng

biến có kiểu là REGISTERS. kiểu này được quy định trong UNIT DOS như sau:

+ Kiểu REGISTERS được khai báo trong UNIT DOS:TYPE

REGISTERS=RECORDCASE integer OF 0:(AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags:word); 1:(AL,AH,BL,BH,CL,CH,DL,DH:Byte);END;

+ Các thanh ghi của bộ vi xử lý được quy định bằng các tên biến. Muốn truy nhập đến các biến này, ta phải quy định về kiểu bản ghi. Ví dụ: R là biến kiểu REGISTERS

=>R.AH:=$01; hoặc with R do AH:=$01;- Muốn gọi ngắt trong PASCAL, có thể sử dụng thủ tục:

INTR(<số hiệu ngắt>,<biến kiểu REGISTERS>);Ví dụ: R là biến kiểu REGISTERS => INTR($ 10,R);- Riêng với số hiệu ngắt 21h ta có thể sử dụng thủ tục

MSDOS(<biến kiểu RETERGES>);Ví dụ: INTR($21,R); <=>MSDOS(R);

6.3.3.2. Một số ngắt thông dụngNgắt 21h: Ngắt chức năng của DOSHàm 01h: Vào một kí tự từ bàn phím và hiển thị ra màn hình

Mô tả Ví dụ minh hoạVào: AH=01h MOV AH,01H

Khoa CNTT Trang 102 KTMT

Gi¸o tr×nh vi xö lý

Ra: AL=Mã ASCII của kí tự nhập vào INT 21HMOV ktu,AL

Hàm 02h: In một ký tự ra màn hình văn bảnVào AH=02h DL= mã ASCII của kí tự nhập vàoRa Không

MOV AH,02H ;In ra màn hìnhMOV DL,’A’ ; chữ ’A’INT 21H

Hàm 08h: Vào một kí tự từ bàn phím,không hiển thị kí tự ra màn hìnhVào AH=01hRa AL= mã ASCII của kí tự nhập vào

MOV AH,08HINT 21HMOV ktu,AL

Hàm 09h: In một chuỗi kí tự ra màn hình

Vào AH=09h DS:DX=Con trỏ đến chuỗi kết thúc bằng ‘$’ Ra Không

MOV AH,09HLEA DX,chuỗiINT 21H

Hàm 4Ch: Kết thúc chương trình.EXE

Vào: AH=4ChRa : Không

MOV AH,4CHINT 21H

Hàm 2Ah: Xác định ngày thángVào: AH=2Ah

Ra : AL=ngày trong tuần(0-6) CX=năm(1980-2099) DH=tháng(1-12) DL=ngày(1-31)

R.AH:=$2AINTR($21,R)Ngay-tuan:=R.AL;Nam:=R.CX;Thang:=R.DH;Ngay:=R.DL;

Hàm 2Bh: Đặt ngày tháng (Đặt lại ngày hệ thống)Vào : AH= 2Bh CX=năm(1980-2099)

R.AH:=$2B;Nam:=R.CX;

Khoa CNTT Trang 103 KTMT

Gi¸o tr×nh vi xö lý

DH=tháng(1-12) DL= ngày(1-31)

Ra : AL=0 nếu ngày hợp lệ; AL=FFh nếu ngày không hợp lệ

Thang:=R.DH;Ngay:=R.DL;INTR($21,R);IF R>AL=0 then write(‘OK!’);Else write(‘Not OK!’);

Hàm 2Ch: Xác định thời gian hệ thống

Vào: AH=2Ch

Ra : CH=giờ(0-23) CL=phút(0-59) DH=giây(0-59) DL=phần trăm giây(0-99)

R.AH:=$2C;NTR($21,R);Gio:=R.CH;Phut:=R.CL;Giay:=R.DH;Phan_tram:=R.DL

Hàm 2Dh: Đặt thời gian (Đặt lại thời gian hệ thống)

Vào: AH=2Dh CH=giờ(0-23) CL=phút(0-59) DH=giây(0-59) DL=phần trăm giây(0-99)

Ra: AL=0 nếu thời gian hợp lệ AL=FFh nếu thời gian không hợp lệ

R.AH:=$2D;R.CH:=gio;R.CL:=phut;R.DH:=giay;R.DL:=phan_tram;INTR($21,R);If R.AL=0 then write(‘OK!’)Else write(‘Not OK!’);

Hàm 30h: Xác định số phiên bản của DOSVào : AH=30hRa : BX=0000h CX=0000h AL=số trước dấu phẩy AH=số sau dấu phẩy

R.AH:=30HINTR($21,R);Ver1:=R.AL;Ver2:=R.AH;Write(‘MS_DOS Version ‘,ver1,’,’,ver2)

Hàm 36h: Xác định dung lượng còn trống trên đĩa

Khoa CNTT Trang 104 KTMT

Gi¸o tr×nh vi xö lý

Vào :AH=36hDL=ổ đĩa(0_mặc định;1_A;1_B;...)

Ra : BX=Số liên cung chưa dùng CX=Số byte/cung DX=Số liên cung / đĩa AX=FFFFh nếu ổ đĩa không hợp lệ=số cung/liên cung(hợp lệ)

R.AH:=36H;R.DL:=1;INTR($21,R);Free_cyl:=R.BX;Bps:=R.CX; {byte per sector}Cpd:=R.DX; {cylinder per dick}If AX=$FFFF then write(‘No Dick’)Else spc:=R.AX; {sector per cylinder);

Ngắt 10h: Ngắt màn hình

Hàm 00h: Chọn chế độ hiển thị cho màn hìnhVào: AH=0h AL=chế độ 03h:Text 80*25*16 12h:Grapt 640*480*16 13h: Grapt 320*200*256 Ra : Không

R.AH:=0h;R.AL:=mode;INTR($10,R);

Hàm 02h: Dịch chuyển Con trỏVào: AH=02h BH=trang số DH=hàng DL=cộtRa : Không

R.AH:=02h;R.BH:=trang;R.DH:=hang;R.DL:=cot;INTR($10,R)

Hàm 06h: Cuốn màn hình hay cửa sổ lên một số dòng xác địnhVào: AH=06h AL=số dòng cuốn(=0;toàn bộ) BH=thuộc tính của dòng trống CH,DL=dòng,cột góc trên trái

R.AH:=06h;R.AL:=so_dong;R.BH:=thuoc_tinh;R.CH:=dong1;R.CL=cot1;

Khoa CNTT Trang 105 KTMT

Gi¸o tr×nh vi xö lý

DL,DL=dòng,cột góc dưới phải Ra: Không

R.DH:=dong2;R.DL=cot2;INTR($10,R);

Hàm 07h: Cuốn màn hình hay cửa sổ xuống một dòng xác địnhVào : AH=07h AL=số dòng cuốn(=0;toàn bộ) BH=thuôc tính các dòng trống CH,CL=dong,cột góc dưới phải Ra : Không

R.AH:=07h;R.AL:=so_dong;R.BH:=thuoc_tinh;R.CH:=dong1;R.CL=cot1;R.DH:=dong2;R.DL=cot2;INTR($10,R);

Hàm 09h: Hiển thị kí tự với thuộc tính tại vị trí Con trỏVào: AH=09h AL=mã ASCII của kí tự BH=trang số BL=thuộc tính(text); màu(graph) CX=số lần viết kí tựRa :Không

R.AH:=09h;R.AL:=kitu;R.BH:=0; {trang so 0}R.BL:=mau;R.CX=solan;INTR($10,R);

Ngắt 16h: Ngắt bàn phím

Hàm 00h: Đọc kí tự từ bàn phím

Vào : AH=00hRa :AH=mã quét của phím AL=mã ASCII của kí tự

R.AH:=00h;INTR($16,R);R.AH:=ma_scan;R.AL:=ma_ascii;

Hàm 02h: Lấy các cờ bàn phímVào : AH=02hRa : AL=các cờ

R.AH:=00h;INTR($16,R);

Khoa CNTT Trang 106 KTMT

Gi¸o tr×nh vi xö lý

Bit 7: insert; bit 6:capslock; bit 5:numlock; bit 4:scrollock

R.AH:=ma_scan;R.AL:=ma_ascii;

Ngắt 33h: Ngắt con chuột

Hàm 00h: Khởi tạo chuột

Vào : AX=00hRa : AX=FFFFh không nhận chuột

R.AX:=00h;INTR($33,R);if R.AX=FFFFh then WRITE('Khong khoi tao duoc chuot!');

Hàm 01h: Hiện trỏ chuột

Vào : AX=01hRa : Không

R.AX:=01h;INTR($33,R);

Hàm 02h: ẩn trỏ chuột

Vào : AX=02hRa : Không

R.AX:=02h;INTR($33,R);

Hàm 03h: Trạng thái nhấn chuộtVào : AX=03hRa : CX,DX=toạ độ ảo của chuột. BX=trạng thái nút chuột nhấnbit 0: Nút tráibit 1: Nút phảibit 2: Nút giữa

R.AX:=03h;INTR($33,R);X=R.CX shl 3+1;Y=R.DX shl 3+1;if (R.BX and 1)=1 then WRITE('Phim trai chuot!!!');

Khoa CNTT Trang 107 KTMT

Gi¸o tr×nh vi xö lý

1.1. TỔNG QUAN VỀ CÁC BỘ VI XỬ LÝ CỦA INTEL............................11.2. CẤU TRÚC BỘ VI XỬ LÝ 8086......................................................2

1.2.1. Sơ đồ khối.......................................................................................21.2.2. Giải thích các thành phần trong sơ đồ..........................21.2.3. Một số khái niệm cơ bản.........................................................3

1.3. TẬP THANH GHI CỦA BỘ VI XỬ LÝ 8086..............................41.3.1. Các thanh ghi dữ liệu.......................................................................41.3.2. Các thanh ghi đoạn: CS, DS, ES, SS...............................................51.3.3. Các thanh ghi con trỏ và chỉ số: ................................SI, DI, SP, BP

61.3.4. Thanh ghi con trỏ lệnh: IP..............................................................61.3.5. Thanh ghi cờ.......................................................................................6

1.4. TẬP LỆNH CỦA BỘ VI XỬ LÝ.........................................................71.4.1. Sơ lược về tập lệnh của bộ vi xử lý....................................71.4.2. Tập lệnh của CPU........................................................................8

1.5. CHẾ ĐỘ ĐỊA CHỈ CỦA BỘ VI XỬ LÝ 8086..............................151.5.1. Tổng quan....................................................................................151.5.2. Các chế độ địa chỉ dữ liệu........................................................15

1.6. PHÂN TÍCH MÃ LỆNH MÃ MÁY....................................................201.6.1. Khuôn dạng lệnh...........................................................................201.6.2. Một số mã lệnh mã máy.......................................................211.6.3. Một số ví dụ minh hoạ:..........................................................23

1.7. LẬP TRÌNH VÀ GỠ RỐI BẰNG DEBUG...................................231.7.1. Giới thiệu về lệnh của DEBUG............................................241.7.2. Lập trình bằng DEBUG...............................................................261.7.3. Gỡ rối chương trình bằng DEBUG....................................27

2.1. BỘ VI XỬ LÝ 80286..............................................................................292.1.1. Các thanh ghi....................................................................................292.1.2. Tập lệnh.........................................................................................30

2.2. BỘ VI XỬ LÝ 80386.........................................................................302.2.1. Sơ đồ khối của 80386..............................................................302.2.2. Các thanh ghi....................................................................................312.2.3. Quản lý bộ nhớ............................................................................33

2.3. BỘ VI XỬ LÝ 80486.........................................................................352.3.1. Các phần tử xử lí CISC và RISC............................................352.3.2. vi xử lí 80486...............................................................................36

Khoa CNTT Trang 108 KTMT

Gi¸o tr×nh vi xö lý

2.3.2.1. Đặc điểm chung...................................................362.3.2.2. cấu trúc bên trong i486......................................37

2.4. CÁC BỘ VI XỬ LÝ INTEL PENTIUM...........................................402.4.1. Đặc điểm chung.........................................................................402.4.2. Cấu trúc và tính năng............................................................40

2.5. BỘ ĐỒNG XỬ LÝ TOÁN 80X87..............................................................452.5.1. Sơ lược về các số thực...........................................................452.5.2. Cấu trúc của 8087.......................................................................45

3.1. TỔNG QUAN VỀ NGÔN NGỮ LẬP TRÌNH ASSEMBLY....473.1.1. Khái niệm.........................................................................................473.1.2. So sánh hợp ngữ với các ngôn ngữ bậc cao..................47

3.2. CÁC ĐOẠN TRONG MỘT CHƯƠNG TRÌNH............................483.3. CẤU TRÚC CHUNG CỦA MỘT LỆNH ASSEMBLY..............493.4. KHAI BÁO DỮ LIỆU VÀ KIỂU DỮ LIỆU.....................................49

3.4.1. Biến byte.......................................................................................503.4.2. Biến word......................................................................................503.4.3. Biến mảng.....................................................................................513.4.4. Biến chuỗi......................................................................................52

3.5. KHUNG CỦA MỘT CHƯƠNG TRÌNH ASSEMBLY.................523.5.1. Cấu trúc chương trình để dịch ra tệp *.EXE...............533.5.2. Cấu trúc chương trình để dịch ra tệp *.COM.............56

3.6. CÁCH TẠO VÀ CHẠY MỘT CHƯƠNG TRÌNH HỢP NGỮ. .584.1. TỔNG QUAN........................................................................................62

4.1.1. Các lệnh chuyển điều khiển.................................................624.2. CẤU TRÚC TUẦN TỰ.......................................................................644.3. CẤU TRÚC RẼ NHÁNH...................................................................64

4.3.1. Cấu trúc IF...THEN..................................................................644.3.2. Cấu trúc IF...THEN...ELSE....................................................654.3.3. Cấu trúc rẽ nhánh CASE...OF..........................................674.3.4. Cấu trúc rẽ nhánh với điều kiện kép..............................68

4.4. CẤU TRÚC LẶP...................................................................................704.4.1. Cấu trúc FOR...TO....DO.....................................................704.4.2. Cấu trúc WHILE...DO.............................................................714.4.3. Cấu trúc REPEAT...UNTIL...................................................71

4.5. CẤU TRÚC CHƯƠNG TRÌNH CON.............................................724.5.1. Cấu trúc của chương trình con.........................................724.5.2. Cách gọi và thực hiện một chương trình con..............75

4.6. MACRO...................................................................................................77

Khoa CNTT Trang 109 KTMT

Gi¸o tr×nh vi xö lý

4.6.1. Định nghĩa MACRO..................................................................774.6.2. Gọi MACRO trong chương trình.......................................784.6.3. Gọi MACRO từ đoạn chương trình khác.......................80

5.1. LẬP TRÌNH XỬ LÝ SỐ NGUYÊN.................................................835.2. CẤU TRÚC DỮ LIỆU MẢNG..........................................................83

5.2.1. Khai báo mảng................................................................................835.2.2. Sử dụng mảng............................................................................84

5.3. CẤU TRÚC DỮ LIỆU XÂU KÍ TỰ.................................................865.3.1. Cờ định hướng............................................................................875.3.2. Lệnh chuyển một chuỗi........................................................875.3.3. Lệnh lưu chuỗi............................................................................885.3.4. Lệnh nạp chuỗi...........................................................................885.3.5. Ví dụ:.................................................................................................89

5.4. LẬP TRÌNH XỬ LÝ SỐ THỰC.......................................................925.5. LẬP TRÌNH CHO CÁC BỘ VI XỬ LÝ TIÊN TIẾN..................926.1. LẬP TRÌNH MÃ LỆNH MÃ MÁY.................................................94

6.1.1. Cú pháp.............................................................................................946.1.2 Thực hiện........................................................................................946.1.3 Một số chú ý.................................................................................946.1.4 Ví dụ...................................................................................................95

6.2. LẬP TRÌNH MÃ LỆNH GỢI NHỚ................................................976.2.1 Cú pháp...............................................................................................976.2.2 Thực hiện........................................................................................976.2.3 Một số chú ý.................................................................................976.2.4 Ví dụ...................................................................................................98

6.3. NGẮT VÀ LẬP TRÌNH NGẮT TRONG CÁC NGÔN NGỮ BẬC CAO....................................................................................................100

6.3.1. Khái niệm về ngắt.....................................................................1006.3.2. Phân loại ngắt..............................................................................1006.3.3. Giới thiệu về một số ngắt........................................................101

Khoa CNTT Trang 110 KTMT