- Các câu lệnh ngôn ngữ hợp ngôn được nhập một câu lệnh trên mỗi dòng. Mỗi câu lệnh tuân theo định dạng sau đây: [nhãn] tên ngắn [tham số] [;bình luận] - Cách khai báo giá trị hằng (hằng số): **tên gọi, chỉ thị và lệnh ** # ***Integer Literals(Số nguyên hằng)** -The number's base: [{+ | - }] digits [ radix ] - The possible radix values: + h: hexadecimal + q/o: octal + d (alternate: t): decimal + b(alternate: y): binary + r: encoded real example: 26 ;decimal 26d ;decimal 11010011b ; binary 42q ; octal 42o ; octal 1Ah ; hexadecimal 0A3h ; hexadecimal ** Lưu ý**: Một số hằng thập lục phân bắt đầu bằng chữ cái phải có một số 0 đứng đầu để tránh trình dịch hiểu nó là một tên biến # ***Constant Integer Expressions(Biểu thức số nguyên)** - Một biểu thức số nguyên hằng là một biểu thức toán học liên quan đến số nguyên hằng và các toán tử số học. - Mỗi biểu thức phải đánh giá thành một số nguyên, có thể được lưu trữ trong 32 bit (từ 0 đến FFFFFFFFh). ![](https://hackmd.io/_uploads/HJF6y4uMp.png) example: 4 + 5 * 2 Multiply, add (14) 12 -1 MOD 5 Modulus, subtract (2) -5 + 2 Unary minus, add (-3) (4 + 2) * 6 Add, multiply (36) # ***Real Number Literals(Số thực)** - Số thực được biểu diễn dưới dạng số thập phân hoặc số thực mã hoá(hệ thập lục) - Cú pháp:[sign]integer.[integer][exponent] Ví dụ về định dạng dấu và mũ: sign {+,-} exponent E[{+,-}]integer Ví dụ về số thực thập phân hợp lệ: 2. +3.0 -44.2E+05(-44.2x10^5) 26.E5(26x10^5) # ***Character Literals(Hằng số ký tự)** - Một hằng số kí tự là một kí tự đơn được đặt trong dấu ngoặc đơn hoặc ngoặc kép. Trình dịch lưu trữ giá trị trong bộ nhớ dưới dạng mã nhị phân ASCII của ký tự. Example: 'A' "d" - Hằng số kí tự lưu trữ nội tại dưới dạng số nguyên, sử dụng chuỗi mã hóa ASCII. Vì vậy, hằng số kí tự 'A' nó được lưu trữ trong bộ nhớ dưới dạng dạng số 65 (41 hex). # ***String Literals(Hằng số chuỗi)** - Một hằng số chuỗi là một chuỗi các kí tự (bao gồm cả khoảng trắng) đặt trong dấu ngoặc đơn hoặc dấu ngoặc kép. Example: 'ABC' 'X' "Good night, Gracie" '4096' - Các dấu ngoặc kép nhúng được phép khi sử dụng theo cách được thể hiện bởi các ví dụ sau: Example "This isn't a test" 'Say "Good night," Gracie' # ***Reverse Word** - Các từ khóa đặc biệt có ý nghĩa đặc biệt và chỉ có thể được sử dụng trong ngữ cảnh chính xác của chúng. Các từ khóa đặc biệt, theo mặc định, không phân biệt chữ hoa chữ thường. Ví dụ, MOV giống như mov và Mov. Có nhiều loại từ khóa đặc biệt: # ***Identifiers** Một tên định danh trong ngôn ngữ assembly là một tên được lập trình viên lựa chọn để đại diện cho một biến, một hằng số, một thủ tục, hoặc một nhãn mã. Có một số quy tắc về cách chúng có thể được hình thành: • Chúng có thể chứ từ 1 đến 247 ký tự • Chúng không phân biệt chữ hoa và chữ thường, nghĩa là cùng một tên định danh có thể viết hoa hoặc viết thường mà không thay đổi ý nghĩa của nó. Ví dụ "MOV" giống như "mov" và "Mov" • Ký tự đầu tiên của một tên định danh là một chữ cái (A..Z, a..z), gạch dưới (_), @ ,? hoặc $. Các ký tự sau đó cũng có thể là chữ số characters may also be digits. • Một tên định danh không được trùng với một từ khóa đã được dự trữ bởi bộ dịch ngôn ngữ ASM. Example : data_segment SEGMENT variable1 DWORD ? counter DD ? data_segment ENDS .code main PROC MOV AX, variable1 ; Truy cập biến sử dụng một tên định danh ADD counter, 1 ; Sửa đổi một bộ đếm sử dụng một tên định danh ; Các lệnh khác... main ENDP Đoạn mã là một ví dụ về cách khai bóa và sử dụng biến trong ngôn ngữ Assembly. Nó minh họa cú pháp cơ bản và cách truy cập dữ liệu. Trong đoạn dữ liệu (data segment) của đoạn mã Assembly, có hai biến được khai báo: "variable1" và "counter": 1. "variable1": + Loại "DWORD" là double word có kích thước 4 byte (32 bit). + Dấu '?' có nghĩa là giá trị của biến chưa được khởi tạo. + Được sử dụng như một ví dụ về biến có thể truy cập và sử dụng trong đoạn mã chính. 2. "counter": + Loại "DD" là double word (DWORD). + Dùng để đếm, vận dụng phép cộng (ADD counter, 1) để tăng giá trị của nó lên 1 trong đoạn mã chính. + Có thể đại diện cho một bộ đếm hoặc một giá trị đếm trong quá trình thực hiện chương trình. # ***Directives** Directives là các lệnh được nhúng trong mã nguồn được bộ dịch hiểu và thực hiện. Tuy nhiên, chúng không thực thi trong quá trình chạy chương trình chạy, mà thay vào dó chúng chỉ định các công việc quản lý, định nghĩa biến, và cấu trúc dữ liệu khác trong quá trình biên dịch. Example: myVar DWORD 26 mov eax, myVar Đoạn mã thực thi 2 công việc chính 1. Định nghĩa một biến: 'myVar': tên biến 'DWORD': nó chỉ định kích thước của biến 'myVar' '26': là giá trị khởi tạo của biến 'myVar' 2. Sao chép giá trị của biến vào thanh ghi 'mov': đây là lệnh di chuyển dữ liệu 'eax': thanh ghi 'myVar': đây là địa chỉ của biến 'myVar'. Lệnh 'mov' di chuyển giá trị từ địa chỉ này vào thanh ghi EAX Định nghĩa các đoạn (Segments) Segments là các phần của chương trình thành các phần nhỏ hơn và xác định mục đích sử dụng của từng phần. 1. .Data Segment: .data + Mục đích: chứa các định nghĩa biến và cấu trúc dữ liệu myVar DWORD 26 ; Ví dụ về định nghĩa biến DWORD 2. .CODE Segment: .code + Mục đích: chứa mã mấy thực thi, tức là nơi đặt các chỉ thị thực thi start: MOV eax, myVar ; Ví dụ về chỉ thị thực thi 3. .STACK Segment: .stack 100h ; Đặt kích thước ngăn xếp là 100h + Mục đích: Xác định và đặt ra các kích thước cửa ngăn xếp thời gian chạy (runtime stack). 4. REPT Segment: Cho phép lặp lại một phần của mã nguồn một số lần cụ thể. REPT 3 MOV AX, BX ; Lặp lại 3 lần ENDM 5.END: Kết thúc chương trình hoặc kết thúc một thủ tục. END start ; Kết thúc chương trình, nhảy đến nhãn start # ***Instructions** Một chỉ thị là một câu lệnh mà máy tính có thể thực hiện khi chương trình được thực thi. Mỗi chỉ thị chuyển đổi thành một chuỗi các byte ngôn ngữ máy, được máy tính thực thi một cách tuần tự để thực hiện các nhiệm vụ cụ thể. Một phần chỉ thị bao gồm các phần cơ bản sau: Nhãn (tùy chọn): Là một định danh cho chỉ thị hoặc dữ liệu. Nhãn được sử dụng để đánh dấu vị trí của chỉ thị trong bộ nhớ. Mã-vi-điều-khiển (bắt buộc): Là phần chỉ định hành động cụ thể mà máy tính phải thực hiện. Ví dụ như MOV (di chuyển dữ liệu), ADD (cộng), SUB (trừ), JMP (nhảy), v.v. Toán-tử (thường là bắt buộc): Là dữ liệu hoặc địa chỉ được xử lý bởi chỉ thị. Toán-tử cung cấp dữ liệu cho các phép toán hoặc chỉ định vị trí của dữ liệu trong bộ nhớ. Chú thích (tùy chọn): Là một phần giải thích hoặc mô tả thêm về công việc của chỉ thị. Chú thích không ảnh hưởng đến việc thực thi chỉ thị và thường được sử dụng để làm cho mã nguồn dễ đọc hơn cho con người. **[nhãn:] mã-vi-điều-khiển [toán-tử] [;chú-thích]** LABEL: Một nhãn là một định danh hoạt động như một điểm đánh dấu cho các chỉ thị và dữ liệu. Một nhãn đặt ngay trước một chỉ thị ngụ ý địa chỉ của chỉ thị. Tương tự, một nhãn đặt trước một biến ngụ ý địa chỉ của biến. Có hai loại nhãn: Nhãn dữ liệu và Nhãn mã: + Một nhãn dữ liệu xác định vị trí của một biến, cung cấp một cách thuận tiện để tham chiếu đến biến trong mã nguồn.Ví dụ định nghĩa một biến có tên là count: count DWORD 100 Instruction Mnemonic các lệnh đơn giản: MOV (MOVE): Di chuyển dữ liệu từ một địa chỉ hoặc thanh ghi đến địa chỉ hoặc thanh ghi khác. ADD (ADDITION): Thực hiện phép cộng giữa hai giá trị và lưu kết quả. SUB (Subtraction): Thực hiện phép trừ giữa hai giá trị và lưu kết quả. INC (Increment): Tăng giá trị của thanh ghi hoặc vùng nhớ tăng 1. DEC (Decrement): Giảm giá trị của thanh ghi hoặc vùng nhớ đi 1. CMP (Compare):So sánh hai giá trị mà không thay đổi giá trị của bất kỳ thanh ghi nào. JMP (Jump):Nhảy tới một địa chỉ cụ thể trong chương trình. JE (Jump if Equal):Nhảy tới địa chỉ cụ thể nếu hai giá trị bằng nhau.