Bước đầu Với Lập Trình Assembly Trên Vi Xử Lý Intel 8086/8088
Có thể bạn quan tâm
- Ngôn ngữ lập trình
- Lập trình hướng đối tượng
- Lập trình Android
- Lập trình Java
- Lập trình IOS
- HOT
- FORM.07: Bộ 125+ Biểu Mẫu Báo Cáo...
- LV.11: Bộ Luận Văn Tốt Nghiệp Chuyên...
- FORM.08: Bộ 130+ Biểu Mẫu Thống Kê...
- CEO.27: Bộ Tài Liệu Dành Cho StartUp...
- LV.26: Bộ 320 Luận Văn Thạc Sĩ Y...
- FORM.04: Bộ 240+ Biểu Mẫu Chứng Từ Kế...
- CEO.29: Bộ Tài Liệu Hệ Thống Quản Trị...
- CEO.24: Bộ 240+ Tài Liệu Quản Trị Rủi...
- TL.01: Bộ Tiểu Luận Triết Học
Chia sẻ: Vuong Dinh | Ngày: | Loại File: DOCX | Số trang:66
Thêm vào BST Báo xấu 738 lượt xem 59 download Download Vui lòng tải xuống để xem tài liệu đầy đủBài 1 "Bước đầu với lập trình assembly trên vi xử lý intel 8086/8088" hướng dẫn các bạn việc tự học lập trình assembly. Đây là tài liệu lập trinh Assembly giảng dạy tại Trường Đại học Bách khoa Hà Nội dùng cho việc học vi xử lí rất quan trọng. Mời các bạn cùng tham khảo.
AMBIENT/ Chủ đề:- Tự học lập trình assembly
- Bước đầu với lập trình assembly
- Vi xử lý intel 8086/8088
- Vi xử lý
- Lập trình assembly
- Hướng dẫn học vi xử lí
Bình luận(0) Đăng nhập để gửi bình luận!
Đăng nhập để gửi bình luận! LưuNội dung Text: Tự học lập trình assembly: Bài 1 - Bước đầu với lập trình assembly trên vi xử lý intel 8086/8088
- Tự học lập trình Assembly Bài 1: Bước đầu với lập trình Assembly trên vi xử lý Intel 8086/8088 BƯỚC ĐẦU VỚI LẬP TRÌNH ASSEMBLY TRÊN VI XỬ LÝ 8088/8086 1. Giới thiệu về Hợp ngữ: Hợp ngữ (Assembly) là một ngôn ngữ lập trình cấp thấp, nó thực chất là dạng gợi nhớ (Mnemonic), hay dạng kí hiệu, của ngôn ngữ máy. Như đã biết, lệnh ngôn ngữ máy là một dãy các con số 0, 1 nên rất khó đọc và khó lập trình, vì thế các nhà thiết kế vi xử lý đã đưa ra tập lệnh hợp ngữ gần với ngôn ngữ tự nhiên hơn nên dễ đọc và dễ lập trình hơn. Tuy vậy, các lệnh hợp ngữ vẫn giao tiếp với phần cứng máy tính một cách rất chặt chẽ, nhờ đó việc tiếp cận với lập trình hợp ngữ giúp chúng ta hiểu rõ hơn về kiến trúc và tổ chức hoạt động của máy tính. Ngoài ra nó còn giúp chúng ta thấy rõ hơn mối quan hệ giữa các thành phần chức năng bên trong máy tính và hệ điề hành. Có thể nói ngược lại là, việc tìm hiểu và lập trình trên hợp ngữ giúp chúng ta hiểu rõ hơn về kiến trúc máy tính, tổ chức hoạt động bên trong máy tính và hệ điều hành. Trong giới hạn của tài liệu này chúng ta chỉ tìm hiểu tập lệnh hợp ngữ của các vi xử lý họ Intel 8088/8086, để lập trình chạy trên các máy IBMPC: Sử dụng họ vi xử lý này và hoạt động trong sự phối hợp với hệ điều hành MS_DOS. Một trong những đặc điểm của hợp ngữ là chương trình viết trên nó có kích thước nhỏ hơn và tốc độ nạp/thực hiện chương trình nhanh hơn so với viết (chương trình cùng chức năng) trên các ngôn ngữ lập trình bậc cao. Ngoài ra, hầu hết các ngôn ngữ lập trình bậc cao hiện nay đều cho phép viết (“nhúng”) mã lệnh hợp ngữ trong nó. Điều này giúp người lập trình khai thác tối đa thế mạnh của các ngôn ngữ lập trình, hợp ngữ rất mạnh trong các thao tác can thiệp sâu vào các thành phần bên trong hệ thống, trong khi đó ngôn ngữ bậc cao mạnh trong các thao tác xử lý dữ liệu và thiết kế giao diện. Như vậy sẽ là rất thuận lợi nếu sử dụng ngôn ngữ bậc cao để viết chương trình xử lý thông tin hệ thống, khi đó nhiệm vụ truy xuất hệ thống (thanh ghi, bộ nhớ, cổng vào/ra, thiết bị,...) để lấy dữ liệu sẽ được giao cho các đoạn mã lệnh hợp ngữ được nhúng trong chương trình này. Hợp ngữ hỗ trợ 2 chế độ tương tác hệ thống: (1) Nhập trực tiếp từng lệnh/đoạn lệnh vào bộ nhớ rồi cho phép thực hiện ngay trên bộ nhớ mà không cần qua bước biên dịch chương trình. Chương trình gỡ rối Debug (đi kèm hệ điều hành MS_DOS: Debug.exe) là một trong những chương trình hỗ trợ chế độ này cho hợp ngữ 16 bít; (2) Viết chương trình hợp ngữ, rồi sau đó sử dụng các chương trình biên dịch để dịch nó sang chương trình thực thi (dạng EXE hoặc COM) và cho thực hiện chương trình này. Hiện nay có hai loại trình biên dịch được sử dụng để biên dịch chương trình hợp ngữ (từ tập lệnh hợp ngữ của các vi xử lý họ Intel) sang chương trình thực thi: Trình biên dịch hợp ngữ 16
- bít, MASM (Macro Assembler), được sử dụng để dịch thành các chương trình chạy trên nền hệ điều hành 16 bít MS_DOS; Trình biên dịch hợp ngữ 32 bít, MASM32 (Macro Assembler 32 bít), được sử dụng để dịch thành các chương trình chạy trên nền hệ điều hành 32 bít MS_Windows. Trong thực tế, để chuyển một chương trình hợp ngữ sang dạng chương trình thực thi EXE 16 bít hoặc COM 16 bít thì cần phải có sự hỗ trợ của chương trình tiện ích của hệ điều hành MS_DOS: Link (Link.exe) và EXE2Bin (EXE2Bin.com). Chương trình hợp ngữ 16 bít sử dụng hệ thống các ngắt mềm (Interrupt) của BIOS và DOS như là thư viện lập trình của nó, trong khi đó chương trình hợp ngữ 32 bít sử dụng tập hàm API làm thư viện lập trình của nó. 2. Biến – Hằng trong chương trình hợp ngữ: Biến và hằng Biến và hằng (hằng có tên) trong chương trình hợp ngữ có tính chất, mục đích sử dụng, kiểu dữ liệu, quy tắc đặt tên, quy tắc gán giá trị,... tương tự như biến và hằng trong các ngôn ngữ lập trình bậc cao khác. Biến trong chương trình hợp ngữ chỉ có các kiểu dữ liệu là: Byte, Word, Doubleword,... và hằng trong chương trình hợp ngữ có thể là số, kí tự hoặc một xâu kí tự. Khi viết chương trình hợp ngữ chúng ta cần quan tâm đến địa chỉ của biến trong bộ nhớ. Một biến được khai báo trong chương trình sẽ được hệ thống gán cho một địa chỉ trong bộ nhớ (khi chương trình được nạp vào bộ nhớ để hoạt động). Cụ thể: mỗi biến trong chương trình sẽ được định vị tại một địa chỉ xác định trong bộ nhớ, và các biến được khai báo liên tiếp nhau trong chương trình (từ trên xuống dưới) sẽ được định vị tại các địa chỉ liên tiếp nhau trong bộ nhớ (từ offset thấp đến offset cao). Nhờ đó, nếu chương trình xác định được địa chỉ của một biến nào đó thì nó dễ dàng có được địa chỉ và nội dung của các biến khác trong chương trình. Khác với biến, hằng trong chương trình hợp ngữ không được cấp phát bộ nhớ để lưu trữ, tức là, nơi nào trong chương trình chứa trên hằng thì sẽ được trình biên dịch thay bằng giá trị của nó một cách trực tiếp. Hợp ngữ cung cấp các toán tử giả để định nghĩa/khai báo dữ liệu: DB (định nghĩa byte), DW (định nghĩa word), DD (định nghĩa doubleword),.... Và toán tử EQU để khai báo hằng. Biến có thể được khai báo ở đầu hoặc ở cuối chương trình. Trong khi đó, hằng có thể khai báo ở bất kỳ nơi đâu trong chương trình, khi đó ta có thể sử dụng toán tử dấu “=” để gán giá trị cho hằng. Khai báo biến – hằng: Cú pháp khai báo: a: DB b: DW c: DD
- d: EQU Trường hợp a được sử dụng để khai báo biến kiểu byte, trường hợp b được sử dụng để khai báo biến kiểu word, trường hợp c được sử dụng để khai báo biến kiểu doubleword, trường hợp d được sử dụng để khai báo hằng. có thể một hoặc nhiều giá trị, nó có thể là một số, một kí tự hoặc một xâu kí tự, và cũng có thể là một dấu hỏi chấm (“?”). có thể là một số, một kí tự hay một xâu kí tự. Ví dụ 1: Spt DB 0 KiTu DB ‘a’ TieuDe DB ‘Tin hoc’ SoNguyen DW ? DaySo DD 1020, 1345, 2389, 5763 Trong ví dụ trên, hai biến Spt và Kitu đều là biến kiểu byte, kích thước 1byte. BiếnTieuDe cũng là biến kiểu byte nhưng gồm 7 byte ô nhớ liên tiếp (kích thước 7 byte), mỗi byte chứa 1 kí tự ASCII. Biến SoNguyen là biến kiểu word, chưa được gán giá trị khởi tạo. Biến DaySo là biến kiểu doubleword, gồm 4 phần tử có giá trị lần lượt (từ thấp đến cao) là: 1020, 1345, 2389, 5763. Ví dụ 2: LF EQU 0Ah TB EQU ‘Cong nghe Thong tin’ TieuDe DB TB Khai báo trên cho thấy, có thể khởi tạo giá trị ban đầu cho biến thông qua một hằng đã được định nghĩa trước. Ví dụ 3: TenKhoa DB ‘Cong nghe Thong tin’, 0Ah, 0Dh, ‘$’ Khai báo biến TenKhoa cho thấy, có thể khai báo một biến mà trong đó bao gồm cả số, kí tự và xâu kí tự, đây là biến kiểu byte, gồm 22 byte. Ví dụ 4: SoPT DW 2345h Biến SoPT ở trên là một biến word, trong trường hợp này byte thấp của nó nhận giá trị 45h, byte cao nhận giá trị 23h, nhưng byte thấp định vị tại địa chỉ SoPT, byte cao định vị tại địa chỉ SoPT + 1. Trong hợp ngữ, một dãy các byte hay word liên tiếp nhau trong bộ nhớ có thể xem là một mảng (mảng byte hay mảng word). Biến DaySo trong ví dụ 1 ở trên có thể được xem là một mảng word gồm 4 phần tử. Giá trị của các phần tử trong mảng có thể được xác định thông qua tên biến và chỉ số tương ứng (địa chỉ). Cụ thể: DaySo[0] = 1020; DaySo[2] = 1345; DaySo[4] = 2389; DaySo[6] = 5763.
- Hợp ngữ cho phép sử dụng toán tử DUP để khai báo một biến dạng mảng mà trong đó gồm nhiều phần tử có cùng giá trị khởi tạo. Dạng sử dụng toán tử DUP là m Dup (n): gồm m phần tử có cùng giá trị khởi tạo là n. Ví dụ 5: MangSN DW 23, 45, 50 Dup (0), 12 Như vậy, biến MangSN được xem là một mảng word gồm 53 phần tử, hai phần tử đầu tiên nhận giá trị lần lượt là 23 và 45, 50 phần tử tiếp theo nhận cùng giá trị 0 và phần tử cuối cùng nhận giá trị 12. Trong ví dụ 1 ở trên: Các biến được khai báo ở đây sẽ được định vị tại các địa chỉ liên tiếp nhau trong bộ nhớ. Nếu biến Spt được định vị tại địa chỉ offset 100 trong đoạn nhớ dữ liệu thì các biến tiếp theo sẽ được định vị tại các offset sau đó. Cụ thể: Biến KiTu bắt đầu tại offset 101, biến TieuDe bắt đầu tại offset 102, biến SoNguyen định vị tại offset 109, biến DaySo bắt đầu tại offset 111 (xem hình sau): 100 101 102 103 104 105 106 107 108 109 111 113 115 117 0 a T i n _ H o c 1020 1345 2389 5763 (dòng trên là địa chỉ offset của biến, dòng dưới là các ô nhớ chứa giá trị của các phần tử trong biến) Điều cần quan tâm ở đây là, có thể truy xuất đến giá trị của một phần tử trong biến này thông qua tên của một biến khác. Ví dụ: Spt[0] = 0, TieuDe[0] = ‘T’, TieuDe[1] = ‘’i, DaySo[0] = 1020, DaySo[6] = 5763,... nhưng cũng có thể Spt[2] = KiTu[1] = ‘T’, KiTu[5] = ‘h’, DaySo[5] = ‘h’, TieuDe[11] = 1345,... Tự học lập trình Assembly Bài 2: Biên dịch chương trình Assembly chạy trên môi trường hệ điều hành 16bit Thứ Năm, 29/08/2013 18:47 Bài viết này hướng dẫn sử dụng các chương trình biên dịch 16 bít: Microsoft MacroAssembler và A86 MacroAssembler V4.05 để dịch các chương trình hợp ngữ (*.asm) sang chương trình thực thi (*.exe và *.com), chạy được trên nền hệ điều hành MS_DOS: ∙ Chương trình A86 Macro Assembly (tập tin chính là: A86.com) thường được sử dụng để dịch chương trình hợp ngữ sang chương trình thực thi dạng COM. ∙ Chương trình Macro Assembly (tập tin chính là: MASM.exe) thường được sử dụng để dịch chương trình hợp ngữ sang chương trình thực thi dạng EXE. Tuy nhiên, MASM chỉ có thể dịch tập tin chương trình hợp ngữ sang dạng tập tin đối tượng mã máy dạng Obj. Để chuyển tập tin Obj sang tập tin chương trình thực thi EXE ta phải sử dụng chương trình liên kết của MSDOS, đó là Link.exe. Để chuyển tập tin thực thi dạng EXE sang tập tin thực thi dạng COM ta phải sử dụng thêm một chương trình khác của MS_DOS, đó là EXE2Bin.com.
- Có thể sử dụng các tập tin TASM.Exe và TLINK.Exe để thay thế cho MASM.exe và Link.exe. Các tập tin này, và cả tập tin EXE2Bin.com, có thể tìm thấy trong bộ chương trình Turbo Pascal. Chức năng của các tập tin biên dịch hợp ngữ liên quan: Tập tin MASM.exe/TASM.exe: Hỗ trợ dịch chương trình hợp ngữ nguồn sang tập tin mã máy dạng Obj tương ứng. Tập tin Link.exe/TLink.exe: Hỗ trợ liên kết các tập tin mã máy, dạng tập tin đối tượng (*.Obj), thành tập tin thực thi dạng EXE. Tập tin EXE2Bin.exe: Hỗ trợ chuyển các tập tin EXE, viết theo cấu trúc dạng COM, thành tập tin thực thi dạng COM. MASM có thể dịch tập tin chương trình hợp ngữ sang các tập tin: tập tin đối tượng (*.Obj), tập tin liệt kê thông tin (*.Lst), tập tin tham khảo chéo (*.Crf). Tập tin đối tượng (Object File): Chứa bảng dịch mã máy của các lệnh trong chương trình nguồn hợp ngữ, và các thông tin cần thiết để có thể tạo nên một tập tin thực thi. Đây là tập tin chính để tạo nên tập tin thực thi. Tập tin liệt kê thông tin (List File): Là một tập tin văn bản cho biết địa chỉ offset của từng lệnh trong đoạn Code; mã lệnh của các lệnh trong chương trình; danh sách các tên/nhãn dùng trong chương trình; các thông báo lỗi và một số thông tin khác. Đây là tập tin cơ sở hỗ trợ việc gỡ rối chương trình. Tập tin tham khảo chéo (Cross Reference File): Liệt kê các tên sử dụng trong chương trình và dòng mà chúng xuất hiện. Hầu hết các chương trình biên dịch hợp ngữ 16 bít đều không hỗ trợ màn hình soạn thảo chương trình. Nhưng, nó cho phép chúng ta sử dụng bất kỳ chương trình/màn hình soạn thảo nào đó, như Turbo Pascal, C,…, để viết chương trình. Chúng ta có thể sử dụng chương trình soạn thảo Notepad trên Windows (Windows XP) để viết và chỉnh sửa chương trình hợp ngữ, trong trường hợp này ta nên đặt phần mở rộng cho tập tin chương trình là asm (*.asm). Sử dụng A86 để dịch chương trình hợp ngữ sang chương trình dạng COM: Trước hết, các bạn nên viết chương trình hợp ngữ theo cấu trúc chương trình dạng COM và lưu tập tin với phần tên mở rộng là asm. Các bạn nên đặt tập tin chương trình hợp ngữ cần dịch ở cùng thư mục với tập tin dịch a86.com. Ở đây chúng tôi giả sử chúng được đặt ở E:\ASSEM. Sử dụng A86 để biên dịch chương trình: Cú pháp : A86 [đường dẫn]; Ví dụ: E:\>\ASSEM\A86 In_Ascii.asm Trên môi trường hệ điều hành Windows các bạn phải chuyển về cửa sổ MSDOS (Cmd) để thực hiện việc biên dịch này.
- Nếu chương trình không có lỗi thì màn hình sẽ xuất hiện thông báo như sau: Thông báo này cho biết việc biên dịch chương trình đã thành công. Tập tin chương trình hợp ngữ In_Ascii.asm đã được dịch thành tập tin chương trình In_Ascii.COM (chính xác hơn là hình thành thêm 2 tập tin mới In_Ascii.COM và In_Ascii.SYM). Nếu chương trình bị lỗi thì A86 sẽ xuất hiện thông báo lỗi như sau: Thông báo này cho biết, trong quá trình biên dịch A86 đã phát hiện thấy lỗi trong chương trình In_Ascii.asm, tức là, chưa thể dịch chương trình In_Ascii.asm sang chương trình thực thi. Cụ thể: Thông báo “Error message inserted into In_Asscii.asm” cho biết thông báo lỗi đã được chèn vào ngay trong tập tin chương trình In_Asscii.asm. Thông báo “Original source renamed as In_Ascii.OLD” cho biết tập tin chương trình gốc đã được đổi tên thành In_Asscii.OLD.
- Trong trường hợp này chúng ta phải quay về chương trình Notepad để mở (Open) lại tập tin chương trình In_Ascii.asm và tiến hành tìm và chỉnh sửa lỗi. Tập tin In_Ascii.asm xuất hiện các dòng thông báo lỗi như sau: Sau khi sửa lỗi và ghi lại chúng ta tiếp tục dịch lại chương trình như ban đầu. Chúng ta có thể sử dụng kết hợp cả 3 tập tin Masm.exe, Link.exe và EXE2Bin.com để dịch một chương trình hợp ngữ viết theo dạng COM thành tập tin thực thi dạng COM. Sử dụng MASM để dịch chương trình hợp ngữ sang chương trình dạng EXE: Trước hết, các bạn nên viết chương trình hợp ngữ theo cấu trúc của chương trình dạng EXE và lưu vào file với phần mở rộng là asm. Quá trình biên dịch chương trình gồm 2 bước: Bước 1: Dùng MASM hoặc TASM để dịch chương trình hợp ngữ sang tập tin đối tượng ngôn ngữ máy. Cú pháp đơn giản như sau: MASM [đường dẫn] ; TASM [đường dẫn] ; Ví dụ: E:\>\ASSEM\Tasm In_Ascii.asm In_Ascii.obj
- Nếu chương trình không có lỗi thì TASM sẽ xuất hiện thông báo như trên. Thông báo này cho biết quá trình biên dịch chương trình đã thành công. Tập tin chương trình hợp ngữ In_Ascii.asm đã được dịch sang tập tin đối tượng ngôn ngữ máy In_Ascii.obj. Nếu chương trình bị lỗi thì TASM sẽ xuất hiện thông báo lỗi, cùng với số thứ tự của dòng chương trình bị lỗi và nội dung lỗi trên màn hình, thông báo sau đây cho biết In_Ascii.asm bị lỗi tại dòng 10 và 11: Trong trường hợp này chúng ta phải quay về chương trình Notepad để mở (Open) lại tập tin chương trình In_Ascii.asm và tiến hành tìm và chỉnh sửa lỗi. Chú ý: Để MASM/TASM tạo ra các tập tin LST và CRF trong khi biên dịch thì ta phải viết ra tên của các tập tin này trong câu lệnh biên dịch. Ví dụ: E:\>\ASSEM\Tasm In_Ascii.asm, In_Ascii.obj, In_Ascii.lst, In_Ascii.crf Với câu lệnh dịch này Tasm sẽ đồng thời tạo ra cả 3 tập tin In_Ascii.obj, In_Ascii.lst, In_Ascii.crf, các tập tin này rất thiết cho việc kiểm tra lỗi và gỡ rối chương trình. Bước 2: Dùng Link hoặc Tlink để liên kết một hoặc nhiều file đối tượng thành một file thực thi duy nhất. Cú pháp đơn giản:
- LINK [đường dẫn]; TLINK [đường dẫn]; Ví dụ: E:\>\ASSEM\TLink In_Ascii.obj; Nếu việc liên kết không bị lỗi (đối với các chương trình đơn giản chỉ có một file đối tượng thì bước này thường không gây ra lỗi) thì màn hình sẽ xuất hiện thông báo: Microsoft (R) Overlay Linker Version 3.64 Copyright (c) Microsoft Corp 1981, 1988. All right reserved. Thông báo này cho biết việc liên kết các tập tin đối tượng chương trình đã thành công. Tập tin chương trình hợp ngữ In_Ascii.asm đã được dịch thành tập tin chương trình In_Ascii.exe. Sau khi biên dịch chương trình hợp ngữ thành chương trình thực thi EXE hoặc COM chúng ta tiến hành cho chạy thử chương trình để kiểm tra, nếu kết quả không đúng như mong muốn thì phải xem và thay đổi lại nội dung chương trình và sau đó thực hiện biên dịch trở lại từ đầu. Tự học lập trình Assembly Bài 3: Cấu trúc của một chương trình Assembly Hầu hết các hệ điều hành máy tính hiện nay, đặc biệt là các hệ điều hành của Microsoft, đều hỗ trợ hai dạng cấu trúc tập tin thực thi có thể hoạt động trên nó, đó là tập tin cấu trúc dạng COM và tập tin cấu trúc dạng EXE. Có nhiều điểm khác nhau giữa hai cấu trúc chương trình này, nhưng điểm khác biệt lớn nhất là: Các chương trình cấu trúc dạng EXE gồm 3 đoạn: Mã lệnh (Code), dữ liệu (Data) và Ngăn xếp (Stack). Khi hoạt động, 3 đoạn này sẽ được nạp vào 3 đoạn (Segment) bộ nhớ tách biệt trên bộ nhớ; Các chương trình dạng COM thì ngược lại, nó chỉ có 1 đoạn mã lệnh, trong đó chứa cả mã lệnh và ngăn xếp. Vì thế, khi được nạp vào bộ nhớ để hoạt động nó chỉ được cấp phát một đoạn bộ nhớ. Rõ ràng kích thước của một chương trình dạng COM không thể vượt quá giới hạn của một đoạn bộ nhớ (với Intel 8088/80286 và MSDOS, 1 Segment bộ nhớ = 64KB). Trong khi đó một chương trình dạng EXE có thể lớn hơn 3 Segment bộ nhớ. Do đó, khi thiết kế các chương trình lớn, với chức năng phức tạp, trong đó có liên kết giữa các modun chương trình khác nhau thì ta phải thiết kế theo cấu trúc chương trình dạng EXE. Hợp ngữ hỗ trợ thiết kế cả hai dạng cấu trúc chương trình EXE và COM, mỗi dạng phù hợp với một nhóm trình biên dịch nào đó. Muốn biên dịch một chương trình hợp ngữ sang dạng EXE thì ngoài việc nó phải được viết theo cấu trúc dạng EXE ta còn cần phải sử dụng một trình biên dịch phù hợp. Điều này cũng tương tự với việc muốn có một chương trình thực thi dạng COM. Văn bản của một chương trình hợp ngữ dạng EXE cũng cho thấy rõ nó gồm 3 đoạn: Code, Data và Stack. Tương tự, văn bản của chương trình hợp ngữ dạng COM cho thấy nó chỉ có 1 đoạn: Code, cả Data và Stack (không tường minh) đều nằm ở đây. Một chương trình hợp ngữ gồm hai thành phần chính: phần lệnh hợp ngữ và phần chỉ dẫn biên dịch. Chỉ có các lệnh là được biên dịch thành ngôn ngữ máy. Phần hướng dẫn biên dịch không được dịch sang ngôn ngữ máy, nó chỉ có tác dụng với các trình biên dịch. Thông
- thường mỗi chương trình biên dịch có một nhóm hướng dẫn biên dịch phù hợp với nó, những với các hướng dẫn biên dịch cơ bản và đơn giản thì nó phù hợp với hầu hết các trình biên dịch hợp ngữ hiện nay. Trong tài liệu này chúng tôi sử dụng các hướng dẫn biên dịch phù hợp với trình biên dịch Microsoft Macro Assembler (MASM). Cấu trúc chương trình được giới thiệu sau đây sử dụng các hướng dẫn biên dịch định nghĩa đoạn đơn giản (.Model, .Code, .Stack, .Data) phù hợp với MASM, TASM (Turbo Macro Assembler), A86. Việc sử dụng định nghĩa đoạn đơn giản sẽ làm cho văn bản chương trình sáng sủa và dễ đọc hơn. Với các định nghĩa đoạn đơn giản ta cũng có thể xây dựng được các chương trình từ đơn giản đến phức tạp. Cấu trúc chương trình dạng COM: .Model .Code ORG 100h : JMP PROC Endp End Trong cấu trúc chương trình trên các từ khóa Model, Code, ORG, Proc, Endp, End là các hướng dẫn biên dịch. là nhãn của lệnh Jmp. Cấu trúc này cho thấy rõ, một chương trình hợp ngữ dạng COM chỉ có 1 đoạn, đó chính là đoạn Code (đoạn mã lệnh), trong này bao gồm cả phần khai báo dữ liệu. Các khai báo dữ liệu trong chương trình dạng COM có thể đặt ở đầu hoặc ở cuối chương trình, nhưng với việc sử dụng định nghĩa đoạn đơn giản các khai báo dữ liệu phải đặt ở đầu chương trình. Chỉ dẫn ORG 100h và lệnh JMP sẽ được đề cập trở lại ở các phần sau đây của tài liệu này. Cấu trúc chương trình dạng EXE: .Model .Stack 100h .Data .Code PROC
- Endp END Trong cấu trúc chương trình trên các từ khóa Model, Code, Data, Stack, Proc, Endp, End là các hướng dẫn biên dịch. Cấu trúc này cho thấy rõ, một chương trình hợp ngữ dạng gồm 3 đoạn: đoạn Code, chứa toàn bộ mã lệnh của chương trình. Đoạn Data, chứa phần khai báo dữ liệu của chương trình. Đoạn Stack, nơi chứa stack (ngăn xếp) của chương trình khi chương trình được nạp vào bộ nhớ để hoạt động. Chỉ dẫn .Stackđặt ở đầu chương trình với mục đích khai báo kích thước của Stack dùng cho chương trình sau này. Kích thước thường được chọn là 100h (256) byte. Chỉ dẫn .Model được đặt ở đầu cả cấu trúc chương trình dạng COM và EXE với mục đích khai báo chế độ bộ nhớ mà chương trình sử dụng. Ví dụ: Sau đây là hai chương trình hợp ngữ đơn giản, dạng COM và dạng EXE, cùng thực hiện nhiệm vụ in ra màn hình 3 dòng văn bản như sau : Nguyen Kim Le Tuan Nguyen Le Tram Thanh Nguyen Le Tram Uyen Hai chương trình dưới đây chỉ có tác dụng minh họa cho việc sử dụng các hướng dẫn biên dịch định nghĩa đoạn đơn giản và giúp các bạn thấy được những điểm giống nhau, khác nhau giữa hai dạng cấu trúc chương trình dạng COM và EXE, vì vậy, ở đây các bạn chưa cần quan tâm đến ý nghĩa của các lệnh và các hàm/ngắt trong nó. Phần lệnh hợp ngữ và các hàm/ngắt sẽ được trình bày ngay sau đây. Chương trình viết theo cấu trúc dạng COM: .Model Small .Code ORG 100h Start: Jmp Main MyChildren DB ‘Nguyen Kim Le Tuan’,0Ah,0Dh DB ‘Nguyen Le Tram Thanh’,0Ah,0Dh DB ‘Nguyen Le Tram Uyen’,’$’ Main PROC ; in ra mot xau voi ham 09/21h Mov Ah, 09h Lea Dx, MyChildren Int 21h ; ket thuc chuong trinh Int 20h
- Main Endp End Start Chương trình này chọn chế độ bộ nhớ Small. Tên thủ tục chính là Main (tên thủ tục chính là tùy ý). Nhãn chính của chương trình là Start (tên thủ tục chính là tùy ý), đó chính là nhãn của lệnh Jmp. Phần khai báo dữ liệu chỉ khai báo một biến, đó là MyChildren. Chương trình này gọi hàm 4Ch của ngắt 21h để kết thúc chương trình. Có thể gọi ngắt 20h để kết thúc các chương trình dạng COM. Chương trình viết theo cấu trúc dạng EXE: .Model Small .Stack 100h .Data MyChildren DB ‘Nguyen Kim Le Tuan’,0Ah,0Dh DB ‘Nguyen Le Tram Thanh’,0Ah,0Dh DB ‘Nguyen Le Tram Uyen’,’$’ .Code Main PROC ; khởi tạo DS Mov Ax, @Data Mov DS, Ax ; in ra mot xau voi ham 09/21h Mov Ah, 09h Lea Dx, MyChildren Int 21h ; ket thuc chuong trinh Mov Ah, 4Ch Int 21h Main Endp END Main Chương trình này chọn chế độ bộ nhớ Small. Khai báo kích thước Stack là 100h byte. Phần khai báo dữ liệu được đặt trong đoạn Data, ở đây chỉ khai báo một biến, đó là MyChildren. Tên thủ tục chính là Main (tên thủ tục chính là tùy ý). Thao tác đầu tiên của chương trình là trỏ thanh ghi đoạn DS về đầu đoạn Data, hay còn gọi là khởi tạo thanh ghi đoạn DS: Mov Ax, @Data Mov DS, Ax thao tác này được xem như là bắt buộc đối với cấu trúc chương trình dạng EXE sử dụng định nghĩa đoạn đơn giản. Các chương trình viết theo cấu trúc dạng EXE phải gọi hàm 4Ch của ngắt 21h để kết thúc. Có thể thấy, cấu trúc chương trình dạng COM và cấu trúc chương trình dạng EXE chỉ khác phần hướng dẫn biên dịch, phần khai báo biến và phần lệnh thao tác chính hoàn toàn giống
- nhau. Hai chương trình đơn giản ở trên hoàn toàn giống nhau ở biến là MyChildren và các lệnh gọi hàm 09h của ngắt 21h để in ra màn hình một xâu kí tự (xâu này chính là giá trị khởi tạo của biến MyChildren). Chú ý 1: Trình biên dịch hợp ngữ (Macro Assembler) cho phép các chương trình được dịch bởi nóc họn sử dụng một trong các chế độ bộ nhớ sau: Small: Đoạn mã lệnh (Code) và đoạn dữ liệu (Data) của chương trình đều chỉ có thể chứa trong một đoạn (segment) bộ nhớ. Tức là, kích thước của chương trình chỉ có thể tối đa là hai đoạn bộ nhớ. Tuy vậy chế độ bộ nhớ này đủ dùng cho hầu hết các chương trình hợp ngữ. Medium: Đoạn Code của chương trình có thể chiếm nhiều hơn một đoạn bộ nhớ. Trong khi đó, đoạn Data chỉ có thể chiếm 1 đoạn bộ nhớ. Compact: Đoạn Data của chương trình có thể chiếm nhiều hơn một đoạn bộ nhớ. Trong khi đó, đoạn Code chỉ có thể chiếm 1 đoạn bộ nhớ. Large: Đoạn Code và đoan Data của chương trình đều có thể chiếm nhiều hơn một đoạn bộ nhớ. Nhưng trong trường hợp này không thể định nghĩa một mảng dữ liệu có kích thước lớn hơn 64 Kbyte. Huge: Tương tự như Large, nhưng trong trường hợp này có thể định nghĩa một mảng dữ liệu có kích thước lớn hơn 64 Kbyte. Chế độ bộ nhớ Small là đơn giản nhất, được hầu hết các chương trình lựa chọn. Chú ý 2: Với các chương trình hợp ngữ sử dụng định nghĩa đoạn đơn giản: Khi được nạp vào bộ nhớ để hoạt động thì các thanh ghi đoạn sẽ tự động trỏ về các đoạn chương trình tương ứng. Cụ thể: Thanh ghi đoạn CS chứa địa chỉ segment của đoạn bộ nhớ chứa đoạn Code của chương trình. Thanh ghi đoạn DS (và có thể cả ES) chứa địa chỉ segment của đoạn bộ nhớ chứa đoạn Data của chương trình. Thanh ghi đoạn SS chứa địa chỉ segment của đoạn bộ nhớ chứa đoạn Stack của chương trình. Tuy nhiên, trong thực tế, khi nạp chương trình EXE vào bộ nhớ DOS luôn dành ra 256 byte đầu tiên của vùng nhớ, mà DOS cấp phát cho chương trình, để chứa PSP (Program Segment Prefix) của chương trình. PSP chứa các thông tin cần thiết mà trình biên dịch chuyển đến cho DOS để hỗ trợ DOS trong việc thực hiện chương trình này, đặc biệt, chương trình cũng có thể truy xuất vùng nhớ PSP. Do đó, DOS phải đưa địa chỉ segment của vùng nhớ chứa PSP vào cả DS và ES trước khi chương trình được thực hiện. Tức là, ngay khi chương trình được nạp vào bộ nhớ DS không phải chứa địa chỉ segment của đoạn Data của chương trình mà chứa địa chỉ segment của PSP. Vì vậy, để trỏ DS về lại đoạn Data chương trình chúng ta phải đặt ngay hai lệnh sau đây ở đầu chương trình viết theo cấu trúc EXE: Mov Ax, @Data Mov DS, Ax Với việc khởi tạo thanh ghi đoạn DS ở trên, địa chỉ segment của tất cả các biến khai báo trong đoạn Data đều được chứa trong thanh ghi DS, do đó, trong các thao tác xử lý biến sau này chương trình không cần quan tâm đến địa chỉ segment của nó nữa. Chú ý 3: Hợp ngữ còn cho phép các chương trình sử dụng các hướng dẫn biên dịch định nghĩa đoạn toàn phần, các định nghĩa này phù hợp với hầu hết các trình biên dịch hợp ngữ hiện nay.
- Định nghĩa đoạn toàn phần giúp cho việc viết chương trình hợp ngữ trở nên mềm dẻo và linh hoạt hơn, nó giúp người lập trình có thể điều khiển thứ tự các đoạn chương trình, kết hợp các đoạn chương trình, liên kết các đoạn chương trình trong bộ nhớ,... , ngay trong khi lập trình. Chi tiết về cách sử dụng và mục đích sử dụng của các hướng dẫn biên dịch nói chung và các định nghĩa đoạn toàn phần nói riêng dễ dàng tìm thấy trong rất nhiều tài liệu về lập trình hợp ngữ [1], [2]. Ở đây chúng tôi chỉ giới thiệu sơ lược về nó thông qua ví dụ dưới đây. Ví dụ: Sau đây là một chương trình dạng EXE sử dụng các hướng dẫn biên dịch định nghĩa đoạn toàn phần (phù hợp với Macro Assembler): S_Seg Segment Stack DB 100h DUP (?) S_Seg Ends D_Seg Segmet MyChildren DB ‘Nguyen Kim Le Tuan’,0Ah,0Dh DB ‘Nguyen Le Tram Thanh’,0Ah,0Dh DB ‘Nguyen Le Tram Uyen’,’$’ D_Seg Ends C_Seg Segment ASSUME CS:C_Seg, SS:S_Seg, DS:D_Seg Main PROC ; khởi tạo DS Mov Ax, D_Seg Mov DS, Ax Mov Ah, 09h Lea Dx, MyChildren ; địa chỉ offset của biến MyChildren Int 21h Mov Ah, 4Ch Int 21h Main Endp C_Seg Ends END Main Điều dễ nhận thấy đầu tiên là phần khai báo biến và phần lệnh chính trong chương trình này hoàn toàn giống như trong chương trình sử dụng định nghĩa đoạn đơn giản (hai chương trình ví dụ ở trên). Chương trình này sử dụng hướng dẫn biên dịch định nghĩa đoạn toàn phần Segment ... Ends để định nghĩa 3 đoạn chương trình với tên lần lượt là: S_Seg (đoạn stack), D_Seg (đoạn Data), C_Seg (đoạn Code). Tên của các đoạn được định nghĩa ở đây là tùy ý. Hướng dẫn biên dịch Assume được sử dụng để báo cho trình biên dịch biết chương trình muốn chứa địa chỉ segment của các đoạn chương trình trong các thanh ghi đoạn nào (trỏ thanh
- ghi đoạn về đoạn chương trình). Cụ thể ở đây là: Thanh ghi đoạn CS chứa địa chỉ segment của đoạn Code (CS:C_Seg). Thanh ghi đoạn SS chứa địa chỉ segment của đoạn Stack (SS:S_Seg). Thanh ghi đoạn DS chứa địa chỉ segment của đoạn Data (DS:C_Seg). Tuy nhiên, trong thực tế Assume DS:D_Seg không tự động nạp địa chỉ segment của D_Seg vào DS, do đó chương trình phải nạp trực tiếp bằng các lệnh: Mov Ax, D_Seg Mov DS, Ax Nên nhớ, hướng dẫn biên dịch Segment ... Ends chỉ có tác dụng định nghĩa đoạn, nó không thể báo cho trình biên dịch biết đoạn được định nghĩa thuộc loại đoạn chương trình nào (Code, Data, Stack, Extra). Chỉ có định nghĩa Segment Stack ... Ends là báo cho trình biên dịch biết đoạn được định nghĩa là đoạn Stack, nhờ đó, khi chương trình được nạp vào bộ nhớ thanh ghi đoạn SS sẽ được trỏ về đoạn này. Tự học lập trình Assembly Bài 4: Tập lệnh assembly của Intel 8086/8088 (1) MỘT SỐ LỆNH ASSEMBLY CƠ SỞ Cú pháp lệnh: Một lệnh hợp ngữ đầy đủ gồm bốn thành phần sau đây: [Nhãn lệnh:] [Các toán hạng] [;Lời giải thích] Trong đó: [Nhãn lệnh:]: Là một dãy các kí tự đứng trước câu lệnh (kết thúc bởi dấu hai chấm (:)), nó được chỉ định thay thế cho địa chỉ của câu lệnh trong các đoạn lệnh lặp, rẽ nhánh,... Do đó, nó chỉ được sử dụng khi cần. Trong một chương trình hợp ngữ không thể có hai nhãn lệnh trùng tên, tên của các nhãn cũng không thể trùng với tên của các thủ tục trong chương trình. : Là một trong các lệnh thuộc tập lệnh hợp ngữ (lệnh gợi nhớ: Mnemonic) của vi xử lý trên máy tính thực hiện lệnh này. Lệnh hợp ngữ không phân biệt chữ hoa hay chữ thường. Trong chương trình hợp ngữ mỗi dòng chỉ có thể chứa một lệnh và mỗi lệnh phải được đặt trên một dòng. [Các toán hạng]: Là đối tượng mà lệnh tác động vào. Một lệnh hợp ngữ của Intel 8088/8086 có thể không có toán hạng, có một toán hạng, hoặc có hai toán hạng. Nếu có hai toán hạng thì toán hạng đứng trước gọi là [Toán hạng đích], toán hạng đứng sau gọi là [Toán hạng nguồn]. [Toán hạng đích] không thể là một hằng số. Một số lệnh hợp ngữ của các Intel 80286/80386/... có thể có đến 3 toán hạng, trong trường hợp này cũng chỉ có một [Toán hạng đích]. [;Lời giải thích]: Chỉ có tác dụng với người viết và người đọc chương trình, nó không có ý nghĩa với trình biên dịch, tức là, không được dịch sang mã máy. Lời giải thích thường được
- sử dụng để làm rõ ý nghĩa của câu lệnh (khi người viết thấy cần). Lời giải thích phải nằm sau dấu chấm phảy (;). Ví dụ 1: Xét lệnh sau đây: Lenh_VD: Mov AX,BX ; đặt giá trị thanh ghi BX vào thanh ghi AX Trong đó: Lenh_VD: Trong trường hợp này dãy kí tự Lenh_VD được sử dụng làm nhãn lệnh cho lệnh Mov. Mov: Là tên lệnh. AX và BX: Là các toán hạng (đích và nguồn). Trong trường hợp này toán hạng là các thanh ghi đa năng 16 bít. “đặt giá trị thanh ghi BX vào thanh ghi AX”: Là lời giải thích cho lệnh này. Trong thực tế lời giải thích thường là tiếng Việt không dấu. Ví dụ 2: Xem các lệnh sau đây: NOP ; đây là lệnh không có toán hạng Mov Ax, Bl ; lệnh này có hai toán hạng, [Toán hạng đích] là thanh ; ghi 16 bít, [Toán hạng nguồn] là thanh ghi 8 bít Add Cl, Spt ; lệnh này có hai toán hạng, [Toán hạng đích] là thanh ; ghi 8 bít, [Toán hạng nguồn] là một biến byte Mov Ax, [SI] ; lệnh này có hai toán hạng, [Toán hạng đích] là thanh ; ghi 16 bít, [Toán hạng nguồn] là một ô nhớ Sub Dl, ‘a’ – ‘A’ ; lệnh này có hai toán hạng, [Toán hạng đích] là thanh ; ghi 8 bít, [Toán hạng nguồn] là một hằng số IMul Ax, Bx, 20 ; lệnh này có ba toán hạng, [Toán hạng đích] là thanh ; ghi 16 bit (Ax), [Toán hạng nguồn] là thanh ghi 16 bít ; (Bx) và một hằng số (20) Lệnh Imul ở trên là một lệnh nhân mới của vi xử lý Intel 80286. Lệnh này thực hiện như sau: lấy nội dung/giá trị hai [Toán hạng nguồn] nhân với nhau, kết quả chứa ở [Toán hạng đích] (trong lệnh trên là: Bx*20, tích kết quả chứa ở thanh ghi Ax (chỉ lấy 16 bít thấp của tích để đưa vào Ax)). 1. Lệnh Mov (Move): Cú pháp lệnh:
- Mov [Toán hạng đích], [Toán hạng nguồn] Trong đó: [Toán hạng đích]: Có thể là thanh ghi (8 bít hay 16 bít), ô nhớ (chính xác hơn là địa chỉ của một ô nhớ) hay một biến nào đó. [Toán hạng đích] không thể là hằng số. [Toán hạng nguồn]: Có thể là hằng số, biến, thanh ghi, ô nhớ (chính xác hơn là địa chỉ của một ô nhớ) nào đó. Tác dụng: Lấy nội dung (giá trị) của [Toán hạng nguồn] đặt vào [Toán hạng đích]. Nội dung của [Toán hạng nguồn] không bị thay đổi. Ví dụ 1: Mov Ax, 5 ; Ax ß 5: đặt giá trị 5 vào thành ghi Ax Mov Ax, 5*2 ; Ax ß 5*2: đặt giá trị 10 vào thành ghi Ax Mov Bx, (80*(Dong 1) + (Cot 1))*2 ; Dong, Cot là các biến Mov Dl, ‘A’ ; Dl = 41h: đặt mã ASCII của ‘A’ vào thanh ghi Dl Mov Cx, Var1 ; Cx = Var1: đặt giá trị của biến Var1 vào thanh ghi Cx Mov Ax, Bx ; Ax = Bx: đặt giá trị của thanh ghi Bx vào Ax Mov Ax, Dl ; Ax = Dl: đặt giá trị của Dl (8 bít) vào Ax (16 bít) Mov Bl, Dx ; Bl = Dx: không hợp lệ, vì: Dx (16 bít) mà Bl (8 bít) Mov Dl, 300 ; Dl = 300: không hợp lệ, vì 300 vượt giới hạn 1 byte Ví dụ 2: Giả sử DI = 100; Ô nhớ tại địa chỉ offset 100 trong đoạn nhớ Data (được chỉ bởi DS) chứa kí tự B. Thì : Mov Ax, DI ; (1) đặt giá trị thanh ghi DI vào thanh ghi Ax: Ax = 100 Mov Ax, [DI] ; (2) Ax = . Tức là, đặt nội dung của ; ô nhớ được chỉ bởi DI vào thanh ghi Ax: Ax = 41h Hãy phân biệt sự khác nhau giữa hai lệnh trên: Lệnh (1) sử dụng chế độ địa chỉ thanh ghi. Lệnh (2) sử dụng chế độ địa chỉ gián tiếp thanh ghi. Nhớ lại rằng: Trong chế độ địa chỉ gián tiếp thanh ghi, các thanh ghi chỉ có thể là BX, DI, SI (địa chỉ đoạn chứa trong DS) hay BP (địa chỉ đoạn chứa trong SS). Như vậy lệnh (2) tương đương với lệnh (3) nhưng khác lệnh (4): Mov Ax, DS:[DI] ; (3)
- Mov Ax, ES:[DI] ; (4) Ví dụ 3: Mov Ax, [SI] ; đặt nội dung ô nhớ được chỉ bởi SI vào thanh ghi Ax Mov [DI], Bx ; đặt giá trị của thanh ghi bx vào ô nhớ được chỉ bởi DI Mov [DI], [SI] ; [DI] ß [SI] : lệnh không hợp lệ, vì: không thể chuyển ; nội dung của ô nhớ vào một ô nhớ một cách trực tiếp Mov Var1, Ax ; Var1 ß Ax : đặt giá trị t/ghi Ax vào biến word Var1 Chú ý: Lệnh Mov không làm ảnh hưởng đến các cờ. Mov DS:[DI], ES:[SI] ; lệnh không hợp lệ, vì: không thể chuyển dữ liệu ; trực tiếp giữa hai toán hạng bộ nhớ với nhau Mov DS, ES ; DS ß ES: lệnh không hợp lệ, Mov ES, 0100 ; lệnh không hợp lệ, vì: không thể chuyển ; trực tiếp một hằng số vào thanh ghi đoạn. Để chuyển giá trị của hai thanh ghi đoạn hay nội dung của hai ô nhớ ta có thể mượn một thanh ghi đa năng làm trung gian: Mov Ax, ES ; hai lệnh này chuyển nội dung của thanh ghi đoạn ES Mov DS, Ax ; vào thanh ghi đoạn DS thông qua thanh ghi Ax Theo cách thông thường, để hoán đổi giá trị của hai thanh ghi đoạn hay nội dung của hai ô nhớ người ta thường sử dụng hai thanh ghi đa năng làm trung gian: Mov Ax, [DI] ; lưu tạm nội dung ô nhớ được chỉ bởi DI và Ax Mov Bx, [SI] ; lưu tạm nội dung ô nhớ được chỉ bởi SI và Bx Mov [DI], Bx ; chuyển giá trị của t/ghi Bx và ô nhớ được chỉ bởi DI Mov [SI], Ax ; chuyển giá trị của t/ghi Ax và ô nhớ được chỉ bởi SI Bốn lệnh trên có tác dụng hoán đổi nội dung của hai ô nhớ trong đoạn Data (DS) được chỉ bởi DI và SI (DI và SI chứa địa chỉ Offset của các ô nhớ). Không thể dùng thanh ghi đoạn CS làm [Toán hạng đích] trong lệnh Mov. 2. Các lệnh Inc – Dec – Add và Sub Cú pháp lệnh:
- Inc [Toán hạng đích] Add [Toán hạng đích],[Toán hạng nguồn] Dec [Toán hạng đích] Sub [Toán hạng đích],[Toán hạng nguồn] Trong đó: [Toán hạng đích], [Toán hạng nguồn]: tương tự lệnh Mov. Tác dụng: Lệnh Inc (Increment): làm tăng giá trị của [Toán hạng đích] lên 1 đơn vị. Lệnh Dec (Decrement): làm giảm giá trị của [Toán hạng đích] xuống 1 đơn vị. Lệnh Add (Addition): lấy giá trị/nội dung của [Toán hạng nguồn] cộng vào giá trị/nội dung của [Toán hạng đích], kết quả này đặt vào lại [Toán hạng đích]. Lệnh Sub (Subtract): lấy giá trị/nội dung của [Toán hạng đich] trừ đi giá trị/nội dung của [Toán hạng nguồn], kết quả này đặt vào lại [Toán hạng đích]. Ví dụ 1: Mov Ax, 121 ; đặt giá trị 121 vào thanh ghi Ax Mov Bx, 223 ; đặt giá trị 232 vào thanh ghi Bx Inc Ax ; Ax = Ax + 1: tăng Ax lên 1 đơn vị (Ax = 122) Dec Bx ; Bx = Bx + 1: giảm Bx xuống 1 đơn vị (Bx = 222) Sub Ax, Bx ; Ax = Ax – Bx : Ax = 100 Add Ax, 120 ; Ax = Ax + 120 : Ax = 20 Mov Cx, Ax ; Cx= Ax : Cx = 20 Dãy lệnh trên, đặt giá trị cuối cùng của thanh ghi Ax vào thanh ghi Cx (Cx = 20). Ví dụ 2: Inc Spt ; Spt = Spt + 1; tăng giá trị biến Spt lên 1 đơn vị Inc DS:[SI] ; tăng ndung ô nhớ được chỉ bởi DS:SI lên 1 đơn vị Add Ax, Var1 ; Ax = Ax + Var1; cộng giá trị biến Var1 vào Ax Add Var2, Dx ; Var2 = Var2 + Dx. Biến Var2 là biến dạng word Add Dx, [SI] ; cộng thêm nội dung ô nhớ được chỉ bởi SI vào Dx Add [DI], [SI] ; [DI] = [DI] + [SI] : lệnh không hợp lệ, vì: không thể ; cộng trực tiếp nội dung hai ô nhớ với nhau. ; Yêu cầu của lệnh trên có thể được viết lại như sau:
- Mov Ax, [SI] ; lưu tạm nội dung ô nhớ được chỉ bởi SI và Ax Mov Bx, [DI] ; lưu tạm nội dung ô nhớ được chỉ bởi DI và Bx Add Bx, Ax ; cộng Ax và Bx, kết quả chứa ở Bx Mov [DI], Bx ; đặt kết quả phép cộng vào lại ô nhớ được chỉ bởi DI Ví dụ 3: Cộng thêm giá trị của thanh ghi Ax vào nội dung của ô nhớ tại địa chỉ offset 0100 trong đoạn DS: Mov DI, 0100 ; trỏ DI về ô nhớ offset 0100 Mov Bx, DS:[DI] ; lưu tạm ndung ô nhớ DS:DI vào thanh ghi Bx Add Bx, Ax ; cộng thêm Ax vào Bx Mov DS:[DI], Bx ; đặt kết quả vào lại ô nhớ DS:DI (DS:0100) Trong trường hợp này ta có thể sử dụng lệnh Add DS:[DI],Ax. Ví dụ 4: Giả sử tại ô nhớ 0B800:0100 trong bộ nhớ có chứa một word dữ liệu. Hãy tăng nội dung của ô nhớ này lên một đơn vị. Mov Ax, 0B800h ; mượn thanh ghi Ax làm trung gian để chuyển Mov ES, Ax ; địa chỉ đoạn của ô nhớ cần truy xuất vào ES Mov DI, 01 ; đặt địa chỉ offset của ô nhớ cần truy xuất vào DI ;; (gọi ngắn gọn: trỏ ES:DI về ô nhớ cần truy xuất) Mov Dx, ES:[DI] ; chuyển tạm nội dung ô nhớ cần tăng vào Dx Inc Dx ; tăng giá trị thanh ghi Dx lên 1 đơn vị Mov ES:[DI], Dx ; đặt giá trị Dx đã tăng vào lại ô nhớ cần tăng Ví dụ 5: Giả sử tại địa chỉ 0A00:0100 trong bộ nhớ có chứa một byte dữ liệu. Hãy chuyển nội dung của ô nhớ này vào thành ghi AL. Mov Ax, 0A00h ; (1); Các lệnh (1), (2), (3) trỏ cặp thanh Mov ES, Ax ; (2); ghi ES:DI về ô nhớ có địa chỉ 0A00:0100 Mov DI, 0100h ; (3); trong đó 0A00 là địa chỉ Segment và ; ; 0100 là địa chỉ Offset. Lệnh (4) chuyển nội Mov Al, ES:[DI] ; (4); dung ô nhớ được chỉ bởi ES:DI vào Al. Ví dụ 6: Giả sử tại địa chỉ 0100:0100 trong bộ nhớ có chứa 2 word dữ liệu liên tiếp (hai ô nhớ liên tiếp). Hãy tính tổng nội dung hai word nhớ này, rồi lấy kết quả ghi vào ô nhớ tại địa chỉ 0100:0120.
CÓ THỂ BẠN MUỐN DOWNLOAD
-
Giáo trình về Hợp ngữ
96 p | 571 | 257
-
Tài liệu: Lập trình hợp ngữ MIPS
10 p | 1145 | 226
-
Chương III : Lập trình hợp ngữ và tóm tắt tập lệnh
10 p | 497 | 218
-
Bài thực hành số 2: Lệnh so sánh – Lệnh nhảy – Lệnh lặp
7 p | 438 | 98
-
Lập trình Virus bằng ngôn ngữ assemble
11 p | 472 | 80
-
Giáo trình lập trình Verilog Tiếng Việt 7
6 p | 231 | 67
-
C# and .NET Framework Lassion 9
13 p | 178 | 51
-
LẬP TRÌNH XỬ LÝ ĐĨA&FILE
65 p | 160 | 37
-
Giáo trình môn lập trình hợp ngữ
0 p | 107 | 21
-
C# và kiến trúc .NET.C# cơ bản - Bài 9
13 p | 137 | 14
-
C# and .NET Framework phần 9
13 p | 69 | 7
-
Bài giảng Hợp ngữ và lập trình hệ thống: Chương 0 - Phạm Công Hòa
7 p | 81 | 4
- Hãy cho chúng tôi biết lý do bạn muốn thông báo. Chúng tôi sẽ khắc phục vấn đề này trong thời gian ngắn nhất.
- Không hoạt động
- Có nội dung khiêu dâm
- Có nội dung chính trị, phản động.
- Spam
- Vi phạm bản quyền.
- Nội dung không đúng tiêu đề.
- Về chúng tôi
- Quy định bảo mật
- Thỏa thuận sử dụng
- Quy chế hoạt động
- Hướng dẫn sử dụng
- Upload tài liệu
- Hỏi và đáp
- Liên hệ
- Hỗ trợ trực tuyến
- Liên hệ quảng cáo
Chịu trách nhiệm nội dung:
Nguyễn Công Hà - Giám đốc Công ty TNHH TÀI LIỆU TRỰC TUYẾN VI NA
LIÊN HỆ
Địa chỉ: P402, 54A Nơ Trang Long, Phường 14, Q.Bình Thạnh, TP.HCM
Hotline: 093 303 0098
Email: support@tailieu.vn
Giấy phép Mạng Xã Hội số: 670/GP-BTTTT cấp ngày 30/11/2015 Copyright © 2022-2032 TaiLieu.VN. All rights reserved.
Đang xử lý... Đồng bộ tài khoản Login thành công! AMBIENTTừ khóa » Tự Học Assembly
-
Assembly Là Gì? Cách Tự Học Lập Trình Assembly Mới Nhất 2020 - Coder
-
Lập Trình Viên Có Nên Học Assembly Không? | TopDev
-
[ASSEMBLY] BÀI 1: NHẬP MÔN ASSEMBLY VỚI HELLO WORD
-
Tôi đã Học Assembly 32bit Như Thế Nào (Phần 1) - Viblo
-
(Tải Về) Tài Liệu Lập Trình Hợp Ngữ Assembly Tiếng Việt - Du Học
-
[PDF] Chương 1. NGÔN NGỮ ASM VÀ CÁCH LẬP TRÌNH (25 Tiết)
-
Lập Trình Assembly Là Gì? Có Nên Học Assembly Hay Không? - Teky
-
Assembly Là Gì? Tìm Hiểu Về Ngôn Ngữ Assembly Từ A - Z - FPT Cloud
-
Ngôn Ngữ Lập Trình Assembly
-
Tự Học Assembly | How Kteam
-
Khóa Học Assembly Language Từ Đầu Như Thế Nào? Cách Tự ...
-
Học Assembly Language Từ đầu Như Thế Nào? - Dev Chat
-
Assembly Là Ngôn Ngữ Lập Trình Gì?
-
Cách Học + Tài Liệu Assembly - YouTube