Menu
CoddyTech

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 ghiKích thướcSố bitKhi nào dùng
rax8 byte64 bitSố đầy đủ, địa chỉ, số syscall
eax4 byte32 bitNửa dưới của rax
ax2 byte16 bitNửa dưới của eax
al1 byte8 bitNửa dưới của ax (bit 0-7)
ah1 byte8 bitNử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 bit32 bit16 bit8 bit (thấp)
rbxebxbxbl
rcxecxcxcl
rdxedxdxdl
rsiesisisil
rdiedididil

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ên

Ghi 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.

challenge icon

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ữ để:

  1. Tải giá trị từ source vào al
  2. Lưu giá trị từ al vào destination

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
    syscall
quiz iconTự kiểm tra

Bà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

Tự luyện tập: Playground Assembly