# 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` |