# Note REV - Day 1: Thanh ghi - Register
## 1. Khái niệm
Thanh ghi là các đơn vị bộ nhớ kích thước nhỏ được đặt bên trong CPU. Thanh ghi chứa dữ liệu như biến, địa chỉ bộ nhớ và các thông tin khác. Chúng nhanh hơn các loại bộ nhớ khác.
Các thanh ghi lưu trữ các phần tử dữ liệu để xử lý mà không cần phải truy cập vào bộ nhớ.
## 2. Kiến trúc 32-bit
*Thanh ghi bộ xử lý (Processors Register - PR)*
Trong kiến trúc `IA-32`, có 10 PR 32-bit và 6 PR 16-bit. Được nhóm thành 3 loại chính là `General`, `Control` và `Segment`. Sau đây ta sẽ đi sâu hơn vào từng loại.
### 2.1. General Register (GR)
GR chia thành 3 loại nhỏ hơn, bao gồm :
#### 2.1.1. Data Register (Thanh ghi dữ liệu)
Sử dụng cho các phép toán số học, logic và phép toán khác. 4 thanh ghi dữ liệu bao gồm : `EAX`, `EBX`, `ECX`, `EDX`. Nửa dưới của mỗi thanh ghi 32-bit này có thể sử dụng làm 4 thanh ghi dữ liệu 16-bit. Mỗi thanh ghi 16-bit này lại có thể chia nhỏ hơn thành 2 thanh ghi 8-bit. Xem hình dưới đây :

Vậy thì H và L là gì ?. H là High - phần cao (các bit từ 8-15), L là Low - phần thấp (các bit từ 0 - 7), của thanh ghi. Ví dụ ta có 1 lệnh asm như sau :
```
MOV AX, 1337h ; -> AX lúc này có giá trị là 0x1337
```
Lúc này về mặt cấu trúc thì nó sẽ thể hiện như sau :
```
AH : 13h
AL : 37h
```
Nếu ta thay đổi AH, chẳng hạn :
```
MOV AH, 24h ;
```
Thì giá trị của AH sẽ thay đổi và AL sẽ giữ nguyên, cụ thể:
```
AH : 24h
AL : 37h
```
Còn cả thanh ghi AX sẽ là `2437h`.
*Về chức năng từng thanh ghi* :
- `EAX` - Thanh ghi tích lũy : Lưu trữ các giá trị hàm trả về. Ví dụ như : Return 5 sẽ tương ứng với > MOV EAX,5. Ngoài ra, nó được sử dụng trong nhập, xuất và các phép tính số học như nhân, chia.
- `EBX` - Thanh ghi cơ sở : Sử dụng để đánh dấu địa chỉ, lưu địa chỉ bắt đầu của 1 mảng.
- `ECX` - Thanh ghi đếm : Sử dụng để đếm các chỉ mục (index) trong các hoạt động vòng lặp và chuỗi.
- `EDX` - Thanh ghi dữ liệu : Tương tự như EAX. Thường dùng phối hợp với EAX trong nhân, chia...
#### 2.1.2 Pointer Register (Thanh ghi con trỏ)
Bao gồm các thanh ghi EIP, ESP và EBP. Mỗi thanh ghi 32-bit. Phần thấp của chúng (16-bit) cũng được sử dụng như với các thanh ghi dữ liệu, bao gồm : IP, SP và BP.

*Về chức năng từng thanh ghi:*
- `EIP` - Thanh ghi con trỏ lệnh : Lưu trữ địa chỉ của lệnh tiếp theo sẽ được thực thi.
- `EBP` - Thanh ghi con trỏ cơ sở : Tham chiếu đến các biến tham số sử dụng trong chương trình con.
- `ESP` - Thanh ghi con trỏ ngăn xếp (stack) : Trỏ tới đỉnh hiện thời của stack.
#### 2.1.3 Index Register (Thanh ghi chỉ mục)
Bao gồm ESI và EDI. Phần thấp của chúng được sử dụng tương tự như các thanh ghi trước đó, bao gồm : SI và DI. Các thanh ghi này được sử dụng để để đánh chỉ số cho các địa chỉ của mảng, xâu. Thỉnh thoảng thì được dùng trong phép toán như cộng, trừ.

*Về chức năng từng thanh ghi:*
- `ESI` - Thanh ghi chỉ mục nguồn: sử dụng làm chỉ mục nguồn cho các phép toán với xâu.
- `EDI` - Thanh ghi chỉ mục đích : sử dụng làm chỉ mục đích cho các phép toán với xâu.
### 2.2. Control Register (CR)
Thanh ghi con trỏ lệnh 32-bit và thanh ghi cờ (Flag Register) 32-bit kết hợp với nhau được gọi là thanh ghi điều khiển (Control Register).
Tại sao lại phải sử dụng các thanh ghi cờ (FR) ? Vì trong Assembly không có các cấu trúc điều khiển như : if else, while... . Để sử dụng chúng ta cần kết hợp các lệnh so sánh, nhảy và giá trị của các cờ.

Hình trên thể hiện vị trí của các bit flag trong thanh ghi Flags 16-bit.
*Về chức năng từng bit flag:*
- `OF` (Cờ tràn) : Cho biết sự tràn của một bit dữ liệu bậc cao (bit ngoài cùng bên trái) sau một phép toán số học có dấu. Có giá trị bằng `1` khi kết quả của phép toán có dấu lớn hơn so với kích thước của địa chỉ đích.
- `DF` (Cờ hướng) : Xác định hướng trái hoặc phải để di chuyển hoặc so sánh dữ liệu chuỗi. DF = 0, thao tác chuỗi lấy từ trái -> phải, DF = 1 thì ngược lại.
- `IF` (Cờ ngắt) : Xác định khi nào các ngắt ngoài như nhập dữ liệu từ bàn phím được xử lý. Khi IF = 1 thì tín hiệu ngắt sẽ được xử lý, ngược lại thì bỏ qua.
- `TF` (Cờ bẫy) : Nó cho phép thiết lập hoạt động của bộ xử lý ở chế độ một bước. Chương trình DEBUG mà ta thường sử dụng đặt TF, vì vậy ta có thể thực hiện từng lệnh một.
- `SF` (Cờ dấu) : Hiển thị dấu kết quả của một phép toán số họ là âm hay dương. Giá trị của SF tùy thuộc vào giá trị của bit ngoài cùng bên trái (MSB). SF = 1 nếu kết quả của phép toán là âm.
- `ZF` (Cờ không) : Cho biết kết quả của một phép toán số học hoặc so sánh. ZF = 0 khi kết quả phép toán = 0 hoặc so sánh bằng nhau. Bằng 1 thì ngược lại.
- `AF` (Cờ nhớ phụ trợ) : Chứa giá trị nhớ khi chuyển từ bit có trọng số 3 lên bit có trọng số 4 (nhớ từ lower nibble sang high nibble) khi thực hiện phép toán số học.
- `PF` (Cờ chẵn lẻ) : Cho biết tổng số 1 bit trong kết quả thu được từ một phép toán số học. PF = 0 khi số bit 1 là chẵn và ngược lại.
- `CF` (Cờ nhớ) : Chứa giá trị nhớ (nhớ 0, hoặc nhớ 1) của MSB sau khi thực hiện phép toán số học. Ngoài ra, khi thực hiện lệnh dịch bit (shift) hoặc quay (rotate) thì giá trị của bit bị đẩy ra cuối cùng sẽ được lưu tại CF. Ví dụ : 0010 1110 khi dịch phải 1 bit -> 0001 0111 -> Bit 1 bị đẩy ra sẽ lưu ở CF -> CF lúc này = 1.
*Mở rộng:*
- Ở `AF` ta thấy 1 khái niệm là `nibble`. Nibble là 1 byte được chia đôi làm 2 nửa. Phần thấp gọi là `Low Nibble` (từ bit 0 - 3, phần cao gọi là `High Nibble` (từ bit 4-7).
- DF, IF và TF được gọi là các cờ điều khiển. Còn lại được gọi là cờ trạng thái.
### 2.3. Segment Register (SR)
Một chương trình Assembly được chia thành các đoạn (Segment) chứa dữ liệu, code và stack:
- Code Segment (CS): chứa các mã lệnh thực thi. Thanh ghi đoạn code CS chứa địa chỉ bắt đầu của Code Segment.
- Data Segment (DS): chứa các biến, hằng số, dữ liệu của chương trình. Thanh ghi đoạn dữ liệu DS chứa địa chỉ bắt đầu của Data segment.
- Stack Segment (SS): chứa dữ liệu và địa chỉ trả về của các chương trình con. Các dữ liệu này được lưu trữ theo cấu trúc Stack. Thanh ghi đoạn stack SS chứa địa chỉ bắt đầu của Stack segment.
Ngoài ra còn có các thanh ghi phân đoạn bổ sung khác như ES, FS và GS.
# Tham khảo
- [Tôi đã học Assembly như thế nào ? - Phần 2](https://viblo.asia/p/toi-da-hoc-assembly-32bit-nhu-the-nao-phan-2-1Je5EmDG5nL)
- [Assembly - Registers](https://www.tutorialspoint.com/assembly_programming/assembly_registers.htm)
- [Các thanh ghi 32-bit](https://lttqstudy.wordpress.com/2011/08/22/cac-thanh-ghi-32bit/)
- [x86-32bit function call in Assembly explained](https://geekyarthurs.medium.com/x86-32bit-function-calls-in-assembly-explained-c1a683e5ddc4)