# DEADLINE 1 due date: 11:59 17/1/2024
> Tìm hiểu về ngôn ngữ assembly, 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, thiếu có thể bỏ sung tiếp trong task sau) 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: https://www.tutorialspoint.com/assembly_programming/assembly_tutorial.pdf
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 KCSC!!"
2: Nhập và in ra chuỗi "Minh Triet AT20"
# I. Tìm hiểu về ASM
## 1.Tổng quan
* Theo em qua tìm hiểu thì Assembly là một ngôn ngữ lập trình gần với ngôn ngữ máy, được sử dụng để viết chương trình cho các vi xử lý thông qua các hướng dẫn (instruction) cơ bản mà vi xử lý hiểu được
* Khi viết code trong một ngôn ngữ lập trình bậc cao như C, C++, Java, hoặc Python, code sẽ được compile từ ngôn ngữ bậc cao này sang ngôn ngữ bậc thấp hơn để máy tính có thể hiểu được. Ví dụ nếu code một chương trình bằng Python thì source sẽ được compile như sau Python ---> C++ ---> C ---> ASM ---> Binary.
* Có nhiều dạng ngôn ngữ assembly, mỗi loại phụ thuộc vào kiến trúc của bộ vi xử lý mà nó hướng đến như : MASM32, NASM, MISP, ARM.
* ASM sẽ k dùng các biến như các ngôn ngữ bậc cao khác mà dữ liệu sẽ được lưu trữ tạm thời ở các thanh ghi. Có nhiều loại thanh ghi nhưng NASM sẽ chỉ tương tác đa phần ở các thanh ghi 32bit  đây là tổng quan về các thanh ghi 32bit
## 2.Thanh Ghi
### a.Thanh ghi Đa Năng
Có 8 thanh ghi đa năng khác nhau:
* EAX : Thanh ghi chính được sử dụng trong tính toán số học chứa kết quả của các phép tính số học và giá trị trả về của hàm.
* EBX : Thanh ghi cơ sở được sử dụng để lưu trữ địa chỉ cơ sở của chương trình.
* ECX : Thanh ghi bộ đếm thường được sử dụng để giữ giá trị biểu thị số lần một quá trình được lặp lại. Được sử dụng cho các hoạt động vòng lặp và chuỗi.
* EDX : được dùng tương tự như EAX ngoài ra sẽ mở rộng EAX lên 64-bit.
* ESI : Thanh ghi chỉ mục nguồn được sử dụng làm địa chỉ nguồn cho các phép toán với xâu.'
* EDI được sử dụng làm địa chỉ đích cho các phép toán với xâu.
* EBP : Con trỏ cơ sở trỏ đến cuối khung ngăn xếp hiện tại. Nó được sử dụng để tham chiếu các biến cục bộ.
* ESP : Con trỏ ngăn xếp . Nó trỏ đến đầu khung ngăn xếp hiện tại. Nó được sử dụng để tham chiếu các biến cục bộ.
### b.Thanh ghi đoạn
* CS : Thanh ghi đoạn mã lưu trữ vị trí cơ sở của phần mã (section .text) được sử dụng để truy cập dữ liệu.
* DS : Thanh ghi phân đoạn dữ liệu lưu trữ vị trí mặc định cho các biến (phần .data) được sử dụng để truy cập dữ liệu.
* SS: chứa dữ liệu và địa chỉ trả về của các chương trình con.
* ES : Thanh ghi phân đoạn bổ sung được sử dụng trong các hoạt động chuỗi.
* FS : Thanh ghi phân đoạn bổ sung.
* GS : Thanh ghi phân đoạn bổ sung.
### c.Thanh ghi điều khiển
Thanh ghi con trỏ lệnh 32 bit và thanh ghi cờ 32 bit (Flags Register) kết hợp với nhau được coi là thanh ghi điều khiển.Có các thanh ghi cờ như sau:
* CF : Mang cờ
* PF : Cờ chẵn lẻ
* AF : Cờ điều chỉnh
* ZF : Cờ không
* SF : Cờ hiệu
* OF : Cờ tràn
## Cấu trúc chương trình NASM
### Section bss
* Dùng để khai báo các `dynamic variable`
### Section data
* Dùng để khai báo các hằng số và các `static variable`
### Section text
* Dùng để ghi code, bắt đầu với `global _start` được coi như là nhãn để đánh dấu bắt đầu chương trình.
```
Section .text
global _start
_start:
```
### Một số command thường được dùng
* `mov` : Dùng để gán giá trị
* `add, sub` : Tính tổng, hiệu
* `cmp` : So sánh hai giá trị với nha
* `push` : Đẩy giá trị
* `pop` : Lấy giá trị ra
* `ret` : Trả về từ hàm (quay lại địa chỉ được lưu trước đó trên stack)
* `inc` : Tăng giá trị lên 1
* `dec ` : giảm giá trị đi 1
## Cách compile và link file asm
* Đầu tiên cần tạo file một file có đuôi là `.asm` ở đây ví dụ là `deadline.asm` và push code asm vào file 
* Tiếp đó là gõ `nasm -f elf32 -0 deadline.o deadline.asm` để compiled file và tạo ra file object

* Để liên kết file object và tạo file execute thì gõ `ld -m elf_i386 -o deadline deadline.o`

# Code Chương Trình NASM
## In ra dòng chữ `Hello KCSC!!`
```
section .data
msg db 'Hello KCSC!!', 0xa
len equ $ - msg
section .text
global _start
_start:
mov edx, len
mov ecx, msg
mov ebx, 1
mov eax, 4
int 0x80
mov ebx, 0
mov eax, 1
int 0x80
```
### **Giải thích Code:**
* Ở phần `Section .data` khai báo biến `msg` với kiểu dữ liệu là byte `db` và `0xa` là kí tự xuống dòng.
`len equ $ - msg` định nghĩa biến len là địa chỉ hiện tại và trừ đi địa chỉ của biến `msg` để lấy độ dài của biến `msg`
* Ở phần `Section .text` nhãn `_start` để báo cho kernel nơi bắt đầu chương trình.
Gán địa chỉ biến len vào thanh ghi `edx` vầ gán địa chỉ của biến msg vào ecx.
Gán file descriptor của STDOUT vào thanh ghi ebx.
Gán mã hệ thống bằng 4 (SYS_Write) vào thanh ghi eax và gọi hàm ngắt để in chuỗi ra màn hình.
Gàn ebx = 0, eax = 1 (SYS_Exit) và gọi hàm ngắt để tránh lỗi `Segmentation fault`

## Nhập và in chuỗi `Minh Triet AT20`
```
section .data
msg: db "Nhap chuoi: ",0xa
len equ $ - msg
str: times 256 db 0
section .text
global _start
_start:
mov edx, len
mov ecx, msg
mov ebx, 1
mov eax, 4
int 0x80
mov edx, len
mov ecx, str
mov ebx, 0
mov eax, 3
int 0x80
mov edx, len
mov ecx, str
mov ebx, 1
mov eax, 4
int 0x80
mov eax, 1
int 0x80
```
* Từ section .data đến in chuỗi ra màn hình giống như bài đầu.
```
mov edx, len
mov ecx, str
mov ebx, 0
mov eax, 3
int 0x80
```
* gán len vào edx và str vào ecx. gán ebx = 0 và eax = 3 (SYS_read) gọi hệ thống nhận chuỗi nhập vào từ user và gọi hàm ngắt.
```
mov edx, len
mov ecx, str
mov ebx, 1
mov eax, 4
int 0x80
```
* In chuỗi user vừa nhập và màn hình và gọi hàm ngắt
```
mov eax, 1
int 0x80
```
* Gọi SYS_exit và kết thúc chương trình
