Menu
CoddyTech

Luyện tập: hoán đổi thanh ghi

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 21 trên 45.

Đôi khi bạn cần hoán đổi giá trị giữa hai thanh ghi. Ví dụ, nếu rax chứa 5 và rbx chứa 10, sau khi hoán đổi, rax sẽ là 10 và rbx sẽ là 5.

Bạn không thể làm việc này chỉ với một hoặc hai lệnh MOV. Bạn cần thêm một thanh ghi thứ ba để lưu trữ tạm thời.

Tại sao bạn không thể làm điều đó trực tiếp:

; Cách này KHÔNG hoạt động
mov rax, rbx   ; Giờ rax = 10, nhưng giá trị 5 ban đầu đã mất hẳn
mov rbx, rax   ; Giờ rbx cũng = 10 (không phải 5)

Phương pháp đúng: dùng một thanh ghi tạm thời:

mov rcx, rax   ; Bước 1: Lưu giá trị ban đầu của rax vào rcx (rcx = 5)
mov rax, rbx   ; Bước 2: Sao chép giá trị từ rbx sang rax (rax = 10)
mov rbx, rcx   ; Bước 3: Sao chép giá trị đã lưu từ rcx sang rbx (rbx = 5)

Từng bước:

BướcHướng dẫnraxrbxrcx
Bắt đầu(trước khi chạy bất kỳ đoạn code nào)510?
1mov rcx, rax5105
2mov rax, rbx10105
3mov rbx, rcx1055

Sau ba câu lệnh này, các giá trị được hoán đổi. Thanh ghi tạm thời rcx vẫn chứa giá trị ban đầu (5), nhưng điều đó không sao.

Thanh ghi tạm thời có thể là bất kỳ thanh ghi nào bạn không dùng:

  • Bạn có thể dùng rcx, rdx, r8 hoặc bất kỳ thanh ghi nào còn trống
  • Chỉ cần đảm bảo bạn không cần giá trị ban đầu trong thanh ghi đó

Vì sao điều này quan trọng:

Đổi chỗ các giá trị là thao tác phổ biến trong các thuật toán sắp xếp và xử lý dữ liệu. Việc này giúp bạn suy nghĩ cẩn thận về thứ tự của các lệnh MOV.

challenge icon

Thử thách

Viết ba dòng assembly để hoán đổi các giá trị giữa r8 và r9.

Giá trị ban đầu (do bộ kiểm thử cung cấp):

  • r8 bắt đầu với giá trị 6
  • r9 bắt đầu với giá trị 2

Sau khi chạy code của bạn:

  • r8 phải có giá trị 2
  • r9 phải có giá trị 6

Dùng r10 làm thanh ghi tạm.

Tự làm thử

section .data
    msg_r8 db 'r8 = '
    msg_r8_len equ $ - msg_r8
    msg_r9 db 'r9 = '
    msg_r9_len equ $ - msg_r9
    newline db 0xa

section .bss
    digit resb 1

section .text
    global _start

_start:
    ; Đặt giá trị ban đầu
    mov r8, 6
    mov r9, 2
    
    %include "solution.asm"       ; Viết code hoán đổi của bạn ở đây
    
    ; Lưu các giá trị để in ra
    mov r12, r8
    mov r13, r9
    
    ; In ra "r8 = "
    mov rax, 1
    mov rdi, 1
    mov rsi, msg_r8
    mov rdx, msg_r8_len
    syscall
    
    ; In giá trị của r8
    mov rax, r12
    add rax, 48
    mov [digit], al
    mov rax, 1
    mov rdi, 1
    mov rsi, digit
    mov rdx, 1
    syscall
    
    ; In ký tự xuống dòng
    mov rax, 1
    mov rdi, 1
    mov rsi, newline
    mov rdx, 1
    syscall
    
    ; In ra "r9 = "
    mov rax, 1
    mov rdi, 1
    mov rsi, msg_r9
    mov rdx, msg_r9_len
    syscall
    
    ; In giá trị của r9
    mov rax, r13
    add rax, 48
    mov [digit], al
    mov rax, 1
    mov rdi, 1
    mov rsi, digit
    mov rdx, 1
    syscall
    
    ; In ký tự xuống dòng
    mov rax, 1
    mov rdi, 1
    mov rsi, newline
    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