Практика: обмен значениями регистров
Часть раздела Основы путешествия по Assembly на Coddy. Урок 21 из 45.
Иногда нужно выполнить swap значений между двумя регистрами. Например, если rax содержит 5, а rbx содержит 10, после swap в rax должно быть 10, а в rbx — 5.
Вы не можете сделать это с помощью одной или двух инструкций MOV. Вам нужен третий регистр как временное хранилище.
Почему это нельзя сделать напрямую:
; Это НЕ работает
mov rax, rbx ; Теперь rax = 10, но исходная 5 исчезла навсегда
mov rbx, rax ; Теперь rbx тоже = 10 (не 5)Правильный метод: using временный регистр:
mov rcx, rax ; Шаг 1: Сохранить исходный rax в rcx (rcx = 5)
mov rax, rbx ; Шаг 2: Скопировать rbx в rax (rax = 10)
mov rbx, rcx ; Шаг 3: Скопировать сохранённое значение из rcx в rbx (rbx = 5)Пошагово:
| Step | Инструкция | rax | rbx | rcx |
|---|---|---|---|---|
| Начало | (до выполнения какого-либо кода) | 5 | 10 | ? |
| 1 | mov rcx, rax | 5 | 10 | 5 |
| 2 | mov rax, rbx | 10 | 10 | 5 |
| 3 | mov rbx, rcx | 10 | 5 | 5 |
После этих трёх инструкций values swapped. Временный temporary register rcx всё ещё содержит original значение (5), но это нормально.
Временным регистром может быть любой регистр, который вы не используете:
- Вы можете использовать
rcx,rdx,r8или любой доступный регистр - Просто убедитесь, что вам не понадобится исходное значение в этом регистре
Почему это важно:
Обмен значениями — распространённая операция в алгоритмах сортировки и манипуляциях с данными. Он учит тебя внимательно продумывать порядок инструкций MOV.
Задание
Напиши три строки на языке assembly, чтобы поменять местами значения между r8 и r9.
Исходные значения (предоставлены тестовым окружением):
r8начинается со значения 6r9начинается со значения 2
После выполнения твоего кода:
r8должен иметь значение 2r9должен иметь значение 6
Используй r10 в качестве временного регистра.
Попробуйте сами
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:
; Установить начальные значения
mov r8, 6
mov r9, 2
%include "solution.asm" ; Сюда идёт код обмена студента
; Сохранить значения для печати
mov r12, r8
mov r13, r9
; Печать "r8 = "
mov rax, 1
mov rdi, 1
mov rsi, msg_r8
mov rdx, msg_r8_len
syscall
; Печать значения r8
mov rax, r12
add rax, 48
mov [digit], al
mov rax, 1
mov rdi, 1
mov rsi, digit
mov rdx, 1
syscall
; Печать новой строки
mov rax, 1
mov rdi, 1
mov rsi, newline
mov rdx, 1
syscall
; Печать "r9 = "
mov rax, 1
mov rdi, 1
mov rsi, msg_r9
mov rdx, msg_r9_len
syscall
; Печать значения r9
mov rax, r13
add rax, 48
mov [digit], al
mov rax, 1
mov rdi, 1
mov rsi, digit
mov rdx, 1
syscall
; Печать новой строки
mov rax, 1
mov rdi, 1
mov rsi, newline
mov rdx, 1
syscall
; Выход
mov rax, 60
mov rdi, 0
syscallВ этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Основы
1Машина
Что такое CPUПамятьРегистры против памятиКак работают инструкцииПаттерн двух файловАрхитектура x86-643Первая инструкция — MOV
Что такое MOV?MOV: непосредственные значенияMOV: из регистра в регистрMOV: из памяти в регистрMOV: из регистра в памятьLEA — загрузка адресаMOV с операндами разных размеровПрактика: обмен значениями регистровИтоги: испытание MOVПотренируйтесь самостоятельно: Песочница Assembly