# Assembly 8086 Cheat sheets ## General structure ### `.exe` ``` .MODEL SMALL .STACK 100 .DATA ; các định nghĩa biến và hằng để ở đây .CODE MAIN PROC ; khởi đầu cho DS MOV AX, @data MOV DS, AX ; Các lệnh của chương trình chính ; Trở về DOS MOV AH, 4Ch INT 21h MAIN ENDP ; các chương trình con (nếu có) để ở đây END MAIN ``` ### `.com` ``` .MODEL Small .CODE ORG 100h START: JMP CONTINUE ; các định nghĩa cho biến và hằng để ở đây CONTINUE: MAIN PROC ; các lệnh của chương trình chính để ở đây INT 20h ; trở về DOS MAIN ENDP ; các chương trình con (nếu có) để ở đây END START ``` ## Syntax ### `CMP` — Compare So sánh hai giá trị với nhau. Thực hiện A - B nhưng không lưu kết quả, chỉ cập nhật flags bên trong CPU. Cú pháp: `CMP operand1, operand2` Các flag bị ảnh hưởng: |Flag| Ý nghĩa| Khi dùng để làm gì| |-|-|-| ZF (Zero Flag)| Kết quả phép trừ = 0 → ZF=1| Hai giá trị bằng nhau CF (Carry Flag)| Có vay mượn khi trừ → CF=1| Kiểm tra lớn bé SF (Sign Flag)| Kết quả âm → SF=1| Kết quả âm OF (Overflow Flag)| Tràn số| Đôi khi dùng với số có dấu |Flag| Ý nghĩa| |-|-| |`=`| ZF=1| |'>'| ZF=0, CF=0, SF=0| |'<'| ZF=0, CF=1, SF=1| Ví dụ đơn giản: ``` mov ax, 10 cmp ax, 10 ; thực hiện 10 - 10 ; ZF = 1 (bằng nhau) ; CF = 0 ; SF = 0 mov ax, 5 cmp ax, 10 ; thực hiện 5 - 10 ; ZF = 0 (khác nhau) ; CF = 1 (vay mượn) ; SF = 1 (âm) ``` Thường dùng với các lệnh nhảy có điều kiện: |Lệnh nhảy| Điều kiện| |-|-| `JE` / `JZ`| Jump if Equal (ZF=1) `JNE` / `JNZ`| Jump if Not Equal (ZF=0) `JA` / `JNBE`| Jump if Above (unsigned lớn hơn) `JB` / `JC` / `JNAE`| Jump if Below (unsigned nhỏ hơn) `JL` / `JNGE`| Jump if Less (signed nhỏ hơn) `JG` / `JNLE`| Jump if Greater (signed lớn hơn) ### `TEST` — Logical Test (AND) Thực hiện phép AND giữa hai toán hạng. Không lưu kết quả. Cập nhật flags (ZF, SF, PF). Cú pháp: `TEST operand1, operand2` Dùng khi: - Kiểm tra bit bật/tắt. - Kiểm tra trạng thái cờ, mask. Ví dụ đơn giản: ``` mov al, 10110010b test al, 00000010b ; kiểm tra bit số 1 có bật không ; Nếu bật: kết quả khác 0 → ZF = 0 ; Nếu tắt: kết quả = 0 → ZF = 1 ``` Từ đó dùng lệnh: ``` jz label ; nếu bit tắt jnz label ; nếu bit bật ``` ### `LOOP` — Vòng lặp tự động Tự động giảm thanh ghi CX (DEC CX). - Nếu CX ≠ 0 → nhảy đến nhãn lặp. - Nếu CX = 0 → tiếp tục chương trình. Cú pháp: `LOOP label` CPU thực hiện chính xác: ``` DEC CX IF (CX ≠ 0) THEN IP ← label ELSE continue ``` * Không ảnh hưởng đến các flags khác. Ví dụ đơn giản: ``` mov cx, 5 start_loop: ; thực hiện gì đó loop start_loop ``` * Chạy tổng cộng 5 lần. ## Common commands ### LỆNH DỮ LIỆU (Data Movement) | Lệnh | Ý nghĩa | Ví dụ | | ------ | ---------------------------- | ------------- | | `MOV` | Di chuyển dữ liệu | `mov ax, bx` | | `XCHG` | Đổi chéo giá trị 2 thanh ghi | `xchg ax, bx` | | `LEA` | Load Effective Address | `lea si, var` | | `PUSH` | Đẩy lên stack | `push ax` | | `POP` | Lấy từ stack | `pop bx` | ### LỆNH SỐ HỌC (Arithmetic) | Lệnh | Ý nghĩa | Ví dụ | | ------ | --------------- | ------------ | | `ADD` | Cộng | `add ax, bx` | | `SUB` | Trừ | `sub ax, bx` | | `INC` | Tăng 1 | `inc cx` | | `DEC` | Giảm 1 | `dec cx` | | `MUL` | Nhân (unsigned) | `mul bx` | | `IMUL` | Nhân (signed) | `imul bx` | | `DIV` | Chia (unsigned) | `div bx` | | `IDIV` | Chia (signed) | `idiv bx` | | `NEG` | Đảo dấu | `neg ax` | ### LỆNH LOGIC & BITWISE | Lệnh | Ý nghĩa | Ví dụ | | ----- | ---------------------- | ----------------------------- | | `AND` | Phép AND | `and al, 0Fh` | | `OR` | Phép OR | `or al, 10h` | | `XOR` | XOR | `xor ax, ax` (đặt về 0 nhanh) | | `NOT` | Đảo bit | `not ax` | | `SHL` | Dịch trái (×2) | `shl ax, 1` | | `SHR` | Dịch phải (÷2) | `shr ax, 1` | | `SAR` | Dịch phải bảo toàn dấu | `sar ax, 1` | | `ROL` | Xoay trái | `rol al, 1` | | `ROR` | Xoay phải | `ror al, 1` | ### LỆNH SO SÁNH & KIỂM TRA | Lệnh | Ý nghĩa | Ví dụ | | ------ | ---------------- | ------------ | | `CMP` | So sánh | `cmp ax, 5` | | `TEST` | AND kiểm tra bit | `test al, 1` | ### LỆNH NHẢY ĐIỀU KIỆN | Lệnh | Ý nghĩa | Ví dụ | | ----------- | ------------------------ | -------------------------------------- | | `JMP` | Nhảy vô điều kiện | `jmp exit` | | `JE / JZ` | Nhảy nếu bằng (ZF=1) | `cmp ax, 5`<br>`je equal` | | `JNE / JNZ` | Nhảy nếu khác (ZF=0) | `cmp ax, 5`<br>`jne not_equal` | | `JA` | Nhảy nếu trên (unsigned) | `cmp ax, bx`<br>`ja above` | | `JB` | Nhảy nếu dưới (unsigned) | `cmp ax, bx`<br>`jb below` | | `JG` | Nhảy nếu lớn (signed) | `cmp ax, bx`<br>`jg greater` | | `JL` | Nhảy nếu nhỏ (signed) | `cmp ax, bx`<br>`jl less` | | `JC` | Nhảy nếu carry (CF=1) | `cmp ax, bx`<br>`jc carry_set` | | `JO` | Nhảy nếu overflow | `add ax, bx`<br>`jo overflow_detected` | | `JS` | Nhảy nếu dấu âm | `cmp ax, bx`<br>`js negative` | ### LỆNH VÒNG LẶP | Lệnh | Ý nghĩa | Ví dụ | | ----------------- | --------------------- | -------------------------------------- | | `LOOP label` | Giảm CX, lặp nếu CX≠0 | `mov cx, 5`<br>`loop my_loop` | | `LOOPZ / LOOPE` | Lặp khi ZF=1 | `cmp ax, bx`<br>`loope continue_loop` | | `LOOPNZ / LOOPNE` | Lặp khi ZF=0 | `cmp ax, bx`<br>`loopne continue_loop` | ### LỆNH TƯƠNG TÁC VỚI FILE | Hàm | Mục đích | Tham số | | -------- | ----------------- | --------------------------------------------------------------- | | `AH=3Dh` | Open file | `DS\:DX = filename` | | `AH=3Ch` | Create file | `DS\:DX = filename` | | `AH=3Eh` | Close file | `BX = file handle` | | `AH=3Fh` | Read file | `BX = file handle, CX = byte count, DS\:DX = buffer` | | `AH=40h` | Write file | `BX = file handle, CX = byte count, DS\:DX = buffer ` | | `AH=42h` | Move file pointer | `BX = handle, CX\:DX = offset, AL = mode (0=start, 1=cur, 2=end)` | ### LỆNH GỌI HÀM & QUẢN LÝ STACK | Lệnh | Ý nghĩa | Ví dụ | | ------ | ------------- | ------------------ | | `CALL` | Gọi hàm | `call my_function` | | `RET` | Trả về | `ret` | | `PUSH` | Đẩy lên stack | `push ax` | | `POP` | Lấy từ stack | `pop bx` | ### LỆNH NGẮT (INTERRUPTS - DOS 21h) #### Basic | AH | Chức năng | Input | Output | Ghi chú | | ----- | ---------------------------------------- | -------------------------- | ---------- | ----------------------------- | | `01h` | Đọc 1 ký tự từ bàn phím (có hiển thị) | `AH=01h` | `AL=ký tự` | Dừng đợi nhấn phím | | `02h` | Hiển thị 1 ký tự | `AH=02h, DL=ký tự` | - | In DL ra màn hình | | `08h` | Đọc 1 ký tự từ bàn phím (không hiển thị) | `AH=08h` | `AL=ký tự` | Thường dùng nhập mật khẩu | | `09h` | Hiển thị chuỗi ký tự | `AH=09h, DX=địa chỉ chuỗi` | - | Chuỗi kết thúc bằng ký tự `$` | | `0Ah` | Đọc chuỗi từ bàn phím | `AH=0Ah, DX=buffer` | - | Dữ liệu đọc vào buffer | | `4Ch` | Kết thúc chương trình | `AH=4Ch` | - | Trả quyền điều khiển về DOS | #### Advanced | AH | Chức năng | Input | Output | Ghi chú | | --- | ------------------------------ | ------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------- | | `00h` | Kết thúc chương trình | `AH=00h` | - | Cũ, ít dùng, thay bằng 4Ch | | `0Bh` | Kiểm tra trạng thái bàn phím | `AH=0Bh` | `AL=0` hoặc `AL=FFh` | `AL=0`: không có phím nhấn, `AL=FFh`: có phím | | `0Ch` | Xóa keyboard buffer và đọc lại | `AH=0Ch`, `AL=function code callback` | Theo function code | Giống `01h` nhưng xóa buffer trước | | `25h` | Cài đặt vector ngắt | `AH=25h`, `AL=int number, DS\:DX=offset` | - | TSR, hook ngắt | | `35h` | Lấy địa chỉ vector ngắt | `AH=35h`, `AL=int number` | `ES\:BX=ISR` | Dùng lấy ISR hiện tại | | `3Dh` | Mở file | `AH=3Dh, DS\:DX = file address, AL=access mode` | `CF clear: AX=handle`; `CF set: AX=error code` | Handle trả về trong AX | | `3Eh` | Đóng file | `AH=3Eh`, `BX=file` handle | CF clear: thành công; `CF set: AX=error code` | Đóng handle file | | `3Fh` | Đọc file | `AH=3Fh BX=handle, CX=số byte, DS\:DX=buffer` | `CF clear: AX=byte readed; CF set: AX=error code` | Đọc từ file mở | | `40h` | Ghi file hoặc xuất ra thiết bị | `AH=40h, BX=handle, CX=số byte, DS\:DX=buffer` | `CF clear: AX=byte written; CF set: AX=error code` | Viết dữ liệu ra file hoặc stdout | | `41h` | Xóa file | `AH=41h, DS\:DX=file address` | `CF clear: success; CF set: AX=error code` | Xóa file từ DOS | | `42h` | Định vị con trỏ file | `AH=42h, AL=seek mode, BX=handle, CX\:DX=offset` | `CF clear: DX\:AX=new pointer; CF set: AX=error code` | Seek file | | `44h` | IOCTL (Điều khiển thiết bị) | `AH=44h, AL=subfunction, BX=handle,... ` | Tùy subfunction | Điều khiển thiết bị thô | `01h-0Ah` -> nhập xuất ký tự / chuỗi `3Dh-42h` -> thao tác file `25h, 35h` -> thao tác ngắt (TSR, hook, virus cổ điển) `4Ch` -> kết thúc chương trình chuẩn DOS ### CÁC LỆNH KHÁC | Lệnh | Ý nghĩa | Ví dụ | | ----- | -------------------------------- | ----- | | `NOP` | Không làm gì (delay, anti-debug) | `nop` | | `HLT` | Dừng CPU | `hlt` | | `STC` | Set Carry | `stc` | | `CLC` | Clear Carry | `clc` |