# 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!"*