Menu
Coddy logo textTech

MOV с операндами разных размеров

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

Вы уже использовали al (8 бит) и rax (64 бита). Но существуют и другие размеры. Разные регистры содержат разное количество данных.

Семейства регистров x86-64:

РегистрРазмерbitsКогда использовать
rax8 байт64 bitsПолные числа, адреса, номера syscall
eax4 байта32 bitsМладшая половина rax
ax2 байта16 bitsМладшая половина eax
al1 байт8 bitsМладшая половина ax (bits 0-7)
ah1 байт8 bitsСтаршая половина ax (bits 8-15)

Та же закономерность применяется к другим регистрам:

64-битный32-битный16-битный8-битный (low)
rbxebxbxbl
rcxecxcxcl
rdxedxdxdl
rsiesisisil
rdiedididil

Почему размер имеет значение:

При перемещении data размеры source и destination должны совпадать. Если они не совпадают, CPU может:

  • Скопировать только часть data
  • Скопировать дополнительные байты из неизвестной памяти
  • Вызвать ошибку

Примеры соответствующих размеров:

mov rax, 1000        ; 64-бит в 64-бит (нормально)
mov eax, 1000        ; 32-бит в 32-бит (нормально)
mov ax, 1000         ; 16-бит в 16-бит (нормально)
mov al, 5            ; 8-бит в 8-бит (нормально)

Что происходит при несовпадении размеров:

mov rax, 0x123456789ABC   ; 64-битное значение
mov al, 0xFF              ; al получает 0xFF, остальные биты rax остаются без изменений

Когда вы перемещаете меньшее значение в больший регистр, верхние биты остаются unchanged. Это может привести к неожиданным результатам.

Безопасное правило:

До этого момента в курсе все данные в памяти занимают 1 байт. Поэтому используется al (а не rax).

При перемещении данных размер регистра должен соответствовать размеру памяти:

  • 1 байт памяти → используйте al, bl, cl и т. д.
  • 8 байт памяти → используйте rax, rbx, rcx и т. д.

О разных размерах памяти вы узнаете в главе 3.

challenge icon

Задание

У вас уже созданы следующие адреса данных:

  • source: содержит значение размером 1 байт (5)
  • destination: пустое пространство (1 байт)

Напишите две строки ассемблера, чтобы:

  1. загрузить значение из source в al
  2. сохранить значение из al в destination

Попробуйте сами

section .data
    msg db 'destination = '
    msg_len equ $ - msg

section .bss
    digit resb 1

section .text
    global _start

_start:
    ; Код студента выполняется первым (загружает из source, сохраняет в destination)
    
    %include "solution.asm"
    
    ; Загрузить сохранённое значение из destination
    mov al, [destination]
    
    ; Сохранить его
    mov r12, rax
    
    ; Вывести "destination = "
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, msg_len
    syscall
    
    ; Вывести значение
    mov rax, r12
    add rax, 48
    mov [digit], al
    mov rax, 1
    mov rdi, 1
    mov rsi, digit
    mov rdx, 1
    syscall
    
    ; Выход
    mov rax, 60
    mov rdi, 0
    syscall
quiz iconПроверьте себя

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

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

Потренируйтесь самостоятельно: Песочница Assembly