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ước | Hướng dẫn | rax | rbx | rcx |
|---|---|---|---|---|
| Bắt đầu | (trước khi chạy bất kỳ đoạn code nào) | 5 | 10 | ? |
| 1 | mov rcx, rax | 5 | 10 | 5 |
| 2 | mov rax, rbx | 10 | 10 | 5 |
| 3 | mov rbx, rcx | 10 | 5 | 5 |
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,r8hoặ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.
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):
r8bắt đầu với giá trị 6r9bắt đầu với giá trị 2
Sau khi chạy code của bạn:
r8phải có giá trị 2r9phả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
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