---
# System prepended metadata

title: 'NASM '

---

# DEADLINE: 12h 26-11-2024
Tìm hiểu về ngôn ngữ NASM, viết báo cáo chi tiết hết về những gì mà bản thân tìm hiểu được(ít nhất phải đủ để code được 2 chương trình bên dưới) viết dưới dạng file Markdown. Có thể tham khảo nguồn dưới đâu hoặc bất kì nguồn nào khác tìm được
Tài liệu: 
1: https://www.tutorialspoint.com/assembly_programming/assembly_tutorial.pdf
2: https://asmtutor.com/
Code 2 chương trình bằng nasm(comment từng dòng code vì 2 chương trình này cực dễ)
1: In ra chuỗi "Hello World!!!"
2: Nhập và in ra chuỗi " I LOVE KMA" 
Trong quá trình code có thể sử dụng pwndbg hoặc gefdbg để xem debug trong trường hợp chương trình có lỗi tại đâu đó 
Link pwndbg: https://github.com/pwndbg/pwndbg
Link gefdbg: https://github.com/hugsy/gef
# Tìm hiểu về NASM 
## 1. Lý Thuyết
 - Theo em tìm hiểu thì NASM là một cầu nối giữa ngôn ngữ bậc cao( c++, c, python,...) và ngôn ngữ máy.
 - ví dụ một quy trình: một chương trình c++ --> biên dịch chuyển đổi mã nguồn thành mã máy hoặc mã trung gian(assembly) --> mã máy --> và gửi tín hiệu đến phần cứng --> thực hiện lệnh.
 
  - Có nhiều dạng ngôn ngữ assembly( hợp ngữ ): MASM, ARM, MIPS, x86, RISC-V,...
 
  - Assembly chủ yếu làm việc nhiều với phần cứng của máy tính: Thanh ghi, bộ nhớ , ngăn xếp(stack), cổng vào ra(I/O Ports), Thiết bị ngoại vi, bộ đếm thời gian, CPU. Nhưng phần lớn là làm việc với thanh ghi.
## 2. Thanh ghi 
### Các dạng thanh ghi: 16 bit, 32 bit, 64 bit. Thanh ghi 64 bit mô phỏng:
  ![image](https://hackmd.io/_uploads/r1AdyheQ1x.png)
  ### Chức năng của các thanh ghi 64 bit:
 #### a. Thanh ghi chức năng:
- RAX: Dùng cho các phép toán số học và lưu giá trị kết quả của các phép toán.

- RBX: Dùng để lưu trữ giá trị tạm thời trong quá trình thực hiện chương trình, RBX thường được sử dụng với các lệnh như MOV, ADD, SUB, MUL, DIV
 
- RCX: Thường dùng cho các phép toán vòng lặp và các phép toán đếm.

- RDX: Dùng trong các phép toán số học đặc biệt là nhân và chia.

- RSI: Thường được sử dụng như một chỉ số nguồn khi thao tác với chuỗi hoặc mảng dữ liệu, nó lưu trữ địa chỉ đầu tiên trong mảng hoặc chuỗi dữ liệu mà bạn muốn thao tác.

- RDI: Lưu vị trí đích, thường lưu địa chỉ của cùng nhớ.

- RBP: Được sử dụng chủ yếu trong quá trình quản lí ngăn xếp(stack), dùng để truy xuất các biến cục bộ và tham số.

- RSP: Cũng quản lí ngăn xếp nhưng khác cách hoạt động, thường là đẩy dữ liệu vào ngăn xếp, lấy giá trị ra ngăn xếp.
#### b.Thanh ghi đoạn:
- CS: Xác định vị trí của mã chương trình.

- DS: Xác định vị trí của dữ liệu chương trình.

- SS: Xác định vị trí của ngăn xếp.

- ES: Thường được sử dụng trong các phép toán chuỗi.

- FS, GS: Hai thanh ghi đoạn.

#### c.Thanh ghi điều khiển:
- CR0 đến CR4: các thanh ghi dùng để điều khiển chế độ hoạt động của CPU, quản lí bộ nhớ ảo.

- DR0 đến DR7: thanh ghi theo dõi quá trình hoạt động của chương trình, thường là debug.

#### d.Thanh ghi cờ trạng thái:
- ZF: Được đặt nếu kết quả của phép toán là 0.

- SF: Được đặt nếu kết quả có dấu âm.

- OF: Được đặt nếu phép toán gây tràn.

- CF: Được đặt nếu phép toán có mượn hoặc chuyển.

- PF: Được đặt nếu số lượng bit 1 trong kết quả là số chẵn.

- AF: Được đặt trong các phép toán với BCD(Binary-Coded Decimal)
 
 ## 3.Cấu trúc 1 chương trình NASM
 ### Section .data
 - ```.data``` Dùng để khai báo dữ liệu tĩnh, hằng số
 
 ### Section .bss
 - ```.bss``` Dùng khai báo các biến chưa khởi tạo

### Section .text
- ```.text``` Đây là nơi mã lệnh của chương trình thực hiện, thường được đánh dấu với ```global``` để định nghĩa điểm bắt đầu của chương trình

### Section .rodata
- ```.rodata``` là phần đặc biệt trong nasm, dùng để lưu trữ các hằng số hoặc dữ liệu chỉ đọc không thay đổi.
# Code trong NASM
## Hello, World! 
trong ubuntu vào terminal 
cài nasm dùng lệnh:
    *sudo apt update
    sudo apt install nasm* 
Sau khi cài xong dùng lệnh 
     *nasm -v*
```nasm!
section .data                    ;khai báo dưới dạng tĩnh
    msg db "Hello, World!", 0ah  ;nhập chuỗi cần in, xuống dòng
section .text                    ;chứa lệnh cần thực hiện 
    global _start                ;chỉ thị nơi bắt đầu
_start:
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, 13
    syscall
    
    mov rax, 0
    xor rdi, 0
    syscall
```
ctrl x
Dùng lệnh
*nasm -f elf64 HelloWorld.asm -o HelloWorld.o*
*ld HelloWorld.o -o HelloWorld*
*./HelloWorld*
Chương trình sẽ in ra Hello, World!
## Nhập và in chuỗi "I love KMA!!!"
viết chương trình và lưu với phần mở rộng *.asm*
```nasm 
section .bss
    buffer resb 64    
section .text
    global _start
_start:
    mov rax, 0
    mov rdi, 0
    mov rsi, buffer
    mov rdx, 64
    syscall
    
    mov byte[buffer + rax], 0
    
    mov rax, 1
    mov rdi, 1
    mov rsi, buffer
    mov rdx, 64
    syscall
    
    mov rax, 60
    xor rdi, rdi
    syscall```

Vào terminal nhập *nasm -v*
    *cd Desktop/*
    *nano ilovekma.asm
    nasm -f elf64 -o ilovekma.o ilovekma.asm
    ld -s -o ilovekma ilovekma.o
    ./iloveyou chạy chương trình 
    nhập chuỗi cần in "I Love KMA!"*
