Práctica: Intercambiar registros
Parte de la sección Fundamentos del Journey de Assembly de Coddy — lección 21 de 45.
A veces necesitas intercambiar los valores entre dos registros. Por ejemplo, si rax contiene 5 y rbx contiene 10, después del intercambio rax debería ser 10 y rbx debería ser 5.
No puedes hacer esto con una o dos instrucciones MOV. Necesitas un tercer registro como almacenamiento temporal.
Por qué no puedes hacerlo directamente:
; Esto NO funciona
mov rax, rbx ; Ahora rax = 10, pero el 5 original se ha ido para siempre
mov rbx, rax ; Ahora rbx también = 10 (no 5)El método correcto — usando un registro temporal:
mov rcx, rax ; Paso 1: Guardar el rax original en rcx (rcx = 5)
mov rax, rbx ; Paso 2: Copiar rbx en rax (rax = 10)
mov rbx, rcx ; Paso 3: Copiar el valor guardado de rcx en rbx (rbx = 5)Paso a paso:
| Paso | Instrucción | rax | rbx | rcx |
|---|---|---|---|---|
| Inicio | (antes de cualquier código) | 5 | 10 | ? |
| 1 | mov rcx, rax | 5 | 10 | 5 |
| 2 | mov rax, rbx | 10 | 10 | 5 |
| 3 | mov rbx, rcx | 10 | 5 | 5 |
Después de estas tres instrucciones, los valores se intercambian. El registro temporal rcx todavía contiene el valor original (5), pero eso está bien.
El registro temporal puede ser cualquier registro que no estés utilizando:
- Puedes usar
rcx,rdx,r8, o cualquier registro disponible - Solo asegúrate de que no necesitas el valor original en ese registro
¿Por qué esto es importante?:
Intercambiar valores es una operación común en los algoritmos de ordenamiento y la manipulación de datos. Te enseña a pensar detenidamente sobre el orden de las instrucciones MOV.
Desafío
Escribe tres líneas de ensamblador para intercambiar los valores entre r8 y r9.
Valores iniciales (proporcionados por el entorno de prueba):
r8comienza con 6r9comienza con 2
Después de tu código:
r8debería ser 2r9debería ser 6
Usa r10 como tu registro temporal.
Pruébalo tú mismo
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:
; Establecer valores iniciales
mov r8, 6
mov r9, 2
%include "solution.asm" ; El código de intercambio del estudiante va aquí
; Guardar valores para imprimir
mov r12, r8
mov r13, r9
; Imprimir "r8 = "
mov rax, 1
mov rdi, 1
mov rsi, msg_r8
mov rdx, msg_r8_len
syscall
; Imprimir el valor de r8
mov rax, r12
add rax, 48
mov [digit], al
mov rax, 1
mov rdi, 1
mov rsi, digit
mov rdx, 1
syscall
; Imprimir nueva línea
mov rax, 1
mov rdi, 1
mov rsi, newline
mov rdx, 1
syscall
; Imprimir "r9 = "
mov rax, 1
mov rdi, 1
mov rsi, msg_r9
mov rdx, msg_r9_len
syscall
; Imprimir el valor de r9
mov rax, r13
add rax, 48
mov [digit], al
mov rax, 1
mov rdi, 1
mov rsi, digit
mov rdx, 1
syscall
; Imprimir nueva línea
mov rax, 1
mov rdi, 1
mov rsi, newline
mov rdx, 1
syscall
; Salir
mov rax, 60
mov rdi, 0
syscallEsta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Fundamentos
1La máquina
¿Qué es la CPU?MemoriaRegistros vs. MemoriaCómo funcionan las instruccionesPatrón de dos archivosLa arquitectura x86-643Primera instrucción - MOV
¿Qué es MOV?MOV InmediatoMOV de Registro a RegistroMOV de Memoria a RegistroMOV de Registro a MemoriaLEA - Cargar direcciónMOV con diferentes tamañosPráctica: Intercambiar registrosResumen: Desafío MOV