Menu
Coddy logo textTech

Практика: обмен значениями регистров

Часть раздела Основы путешествия по Assembly на Coddy — урок 21 из 45.

Иногда вам нужно обменять значения между двумя регистрами. Например, если rax содержит 5, а rbx содержит 10, то после обмена rax должен содержать 10, а rbx — 5.

Вы не можете сделать это с помощью одной или двух инструкций MOV. Вам понадобится третий регистр в качестве временного хранилища.

Почему это нельзя сделать напрямую:

; Это НЕ работает
mov rax, rbx   ; Теперь rax = 10, но исходное значение 5 потеряно навсегда
mov rbx, rax   ; Теперь rbx тоже = 10 (а не 5)

Правильный метод — использование временного регистра:

mov rcx, rax   ; Шаг 1: Сохраняем исходное значение rax в rcx (rcx = 5)
mov rax, rbx   ; Шаг 2: Копируем rbx в rax (rax = 10)
mov rbx, rcx   ; Шаг 3: Копируем сохраненное значение из rcx в rbx (rbx = 5)

Шаг за шагом:

ШагИнструкцияraxrbxrcx
Начало(перед выполнением кода)510?
1mov rcx, rax5105
2mov rax, rbx10105
3mov rbx, rcx1055

После этих трех инструкций значения меняются местами. Временный регистр rcx все еще содержит исходное значение (5), но это нормально.

Временным регистром может быть любой регистр, который вы не используете:

  • Вы можете использовать rcx, rdx, r8 или любой доступный регистр
  • Просто убедитесь, что вам не нужно исходное значение в этом регистре

Почему это важно:

Перестановка значений — это распространенная операция в алгоритмах сортировки и манипулировании данными. Это учит вас внимательно продумывать порядок инструкций MOV.

challenge icon

Задание

Напишите три строки ассемблерного кода, чтобы поменять местами значения между r8 и r9.

Начальные значения (предоставляются тестовой средой):

  • r8 начинается с 6
  • r9 начинается с 2

После выполнения вашего кода:

  • r8 должен быть равен 2
  • r9 должен быть равен 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
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Основы