MOV với các kích thước khác nhau
Thuộc phần Kiến thức nền tảng trong hành trình Assembly của Coddy. Bài học 20 trên 45.
Bạn đã dùng al (8 bit) và rax (64 bit). Nhưng còn có những kích thước khác nữa. Các thanh ghi khác nhau chứa lượng dữ liệu khác nhau.
Các nhóm thanh ghi x86-64:
| Thanh ghi | Kích thước | Số bit | Khi nào dùng |
|---|---|---|---|
rax | 8 byte | 64 bit | Số đầy đủ, địa chỉ, số syscall |
eax | 4 byte | 32 bit | Nửa dưới của rax |
ax | 2 byte | 16 bit | Nửa dưới của eax |
al | 1 byte | 8 bit | Nửa dưới của ax (bit 0-7) |
ah | 1 byte | 8 bit | Nửa trên của ax (bit 8-15) |
Mẫu tương tự cũng áp dụng cho các thanh ghi khác:
| 64 bit | 32 bit | 16 bit | 8 bit (thấp) |
|---|---|---|---|
rbx | ebx | bx | bl |
rcx | ecx | cx | cl |
rdx | edx | dx | dl |
rsi | esi | si | sil |
rdi | edi | di | dil |
Vì sao kích thước lại quan trọng:
Khi bạn di chuyển dữ liệu, kích thước của nguồn và đích phải khớp nhau. Nếu không khớp, CPU có thể:
- Chỉ sao chép một phần dữ liệu
- Sao chép thêm byte từ vùng nhớ không xác định
- Gây ra lỗi
Ví dụ về kích thước tương thích:
mov rax, 1000 ; 64 bit sang 64 bit (hợp lệ)
mov eax, 1000 ; 32 bit sang 32 bit (hợp lệ)
mov ax, 1000 ; 16 bit sang 16 bit (hợp lệ)
mov al, 5 ; 8 bit sang 8 bit (hợp lệ)Điều gì xảy ra khi kích thước không khớp:
mov rax, 0x123456789ABC ; Giá trị 64 bit
mov al, 0xFF ; al nhận 0xFF, các bit khác của rax vẫn giữ nguyênGhi vào thanh ghi 8 bit hoặc 16 bit (al, ah, ax) chỉ thay đổi các bit đó, phần còn lại của thanh ghi đầy đủ vẫn giữ nguyên. Ghi vào thanh ghi 32 bit thì khác: mov eax, 0xFF xóa các bit từ 32 đến 63, nên rax trở thành 0xFF. Điều này có thể gây ra kết quả không mong muốn.
Quy tắc an toàn:
Trong khóa học này đến giờ, mọi dữ liệu trong bộ nhớ đều có kích thước 1 byte. Đó là lý do bạn dùng al (không dùng rax).
Khi bạn di chuyển dữ liệu, kích thước thanh ghi phải khớp với kích thước bộ nhớ:
- 1 byte bộ nhớ → dùng
al,bl,cl, v.v. - 8 byte bộ nhớ → dùng
rax,rbx,rcx, v.v.
Bạn sẽ tìm hiểu về các kích thước bộ nhớ khác nhau trong Chương 3.
Thử thách
Bạn đã có sẵn các địa chỉ dữ liệu sau:
source: chứa giá trị 1 byte (5)destination: vùng trống (1 byte)
Viết hai dòng hợp ngữ để:
- Tải giá trị từ
sourcevàoal - Lưu giá trị từ
alvàodestination
Tự làm thử
section .data
msg db 'destination = '
msg_len equ $ - msg
section .bss
digit resb 1
section .text
global _start
_start:
; Đoạn code của bạn chạy trước (nạp từ source, lưu vào destination)
%include "solution.asm"
; Nạp giá trị đã lưu từ destination
mov al, [destination]
; Lưu giá trị đó
mov r12, rax
; In ra "destination = "
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, msg_len
syscall
; In ra giá trị
mov rax, r12
add rax, 48
mov [digit], al
mov rax, 1
mov rdi, 1
mov rsi, digit
mov rdx, 1
syscall
; Thoát
mov rax, 60
mov rdi, 0
syscallBài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Kiến thức nền tảng
3Lệnh đầu tiên: MOV
MOV là gì?MOV với giá trị tức thờiMOV từ thanh ghi sang thanh ghiMOV từ bộ nhớ sang thanh ghiMOV từ thanh ghi vào bộ nhớLEA: nạp địa chỉMOV với các kích thước khác nhauLuyện tập: hoán đổi thanh ghiÔn tập: thử thách MOVTự luyện tập: Playground Assembly