Pratik: Yazmaçları Takas Etme
Coddy'nin Assembly Journey'sinin Temel Bilgiler bölümünün bir parçası. Ders 21 / 45.
Bazen iki yazmaç arasındaki değerleri değiş tokuş etmeniz gerekir. Örneğin, rax 5 ve rbx 10 içeriyorsa, değiş tokuştan sonra rax 10 ve rbx 5 olmalıdır.
Bunu bir veya iki MOV komutuyla yapamazsın. Geçici depolama için üçüncü bir yazmaç gerekir.
Neden bunu doğrudan yapamazsınız:
; Bu ÇALIŞMAZ
mov rax, rbx ; Şimdi rax = 10, ama orijinal 5 sonsuza kadar gitti
mov rbx, rax ; Şimdi rbx de = 10 (5 değil)Doğru yöntem: geçici bir yazmaç kullanmak:
mov rcx, rax ; Adım 1: Orijinal rax'ı rcx'e kaydet (rcx = 5)
mov rax, rbx ; Adım 2: rbx'i rax'e kopyala (rax = 10)
mov rbx, rcx ; Adım 3: rcx'ten kaydedilen değeri rbx'e kopyala (rbx = 5)Adım adım:
| Adım | Talimat | rax | rbx | rcx |
|---|---|---|---|---|
| Başlangıç | (herhangi bir koddan önce) | 5 | 10 | ? |
| 1 | mov rcx, rax | 5 | 10 | 5 |
| 2 | mov rax, rbx | 10 | 10 | 5 |
| 3 | mov rbx, rcx | 10 | 5 | 5 |
Bu üç talimattan sonra değerler yer değiştirilir. Geçici yazmaç rcx hâlâ özgün değeri (5) içeriyor, ancak bu sorun değil.
Geçici yazmaç, kullanmadığınız herhangi bir yazmaç olabilir:
rcx,rdx,r8veya kullanılabilir herhangi bir yazmacı kullanabilirsiniz- Yalnızca o yazmaçtaki özgün değere ihtiyaç duymadığınızdan emin olun
Bu neden önemli:
Değerleri takas etmek, sıralama algoritmalarında ve veri işleme işlemlerinde yaygın bir uygulamadır. Bu, MOV talimatlarının sırası hakkında dikkatlice düşünmeyi öğretir.
Görev
r8 ve r9 arasındaki değerleri değiştirmek için üç assembly satırı yazın.
Başlangıç değerleri (test harness tarafından sağlanır):
r86 ile başlarr92 ile başlar
Kodunuzdan sonra:
r82 olmalıdırr96 olmalıdır
Geçici yazmaç olarak r10 kullanın.
Kendin dene
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:
; Başlangıç değerlerini ayarla
mov r8, 6
mov r9, 2
%include "solution.asm" ; Öğrencinin swap kodu buraya gelir
; Yazdırma için değerleri kaydet
mov r12, r8
mov r13, r9
; "r8 = " yazdır
mov rax, 1
mov rdi, 1
mov rsi, msg_r8
mov rdx, msg_r8_len
syscall
; r8 değerini yazdır
mov rax, r12
add rax, 48
mov [digit], al
mov rax, 1
mov rdi, 1
mov rsi, digit
mov rdx, 1
syscall
; Yeni satır yazdır
mov rax, 1
mov rdi, 1
mov rsi, newline
mov rdx, 1
syscall
; "r9 = " yazdır
mov rax, 1
mov rdi, 1
mov rsi, msg_r9
mov rdx, msg_r9_len
syscall
; r9 değerini yazdır
mov rax, r13
add rax, 48
mov [digit], al
mov rax, 1
mov rdi, 1
mov rsi, digit
mov rdx, 1
syscall
; Yeni satır yazdır
mov rax, 1
mov rdi, 1
mov rsi, newline
mov rdx, 1
syscall
; Çıkış
mov rax, 60
mov rdi, 0
syscallBu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Temel Bilgiler bölümündeki tüm dersler
3İlk komut - MOV
MOV nedir?MOV Anlık DeğerMOV Yazmaçtan YazmacaMOV Bellekten YazmacaMOV Yazmaçtan BelleğeLEA - Adres YüklemeFarklı Boyutlarla MOVPratik: Yazmaçları Takas EtmeÖzet: MOV Meydan OkumasıKendi başına pratik yap: Assembly playground