Menu
CoddyTech

MOV z różnymi rozmiarami

Część sekcji Podstawy ścieżki Assembly w Coddy. Lekcja 20 z 45.

Używałeś już al (8 bitów) i rax (64 bity). Są też inne rozmiary. Różne rejestry przechowują różne ilości danych.

Rodziny rejestrów x86-64:

RejestrRozmiarBityKiedy używać
rax8 bajtów64 bityPełne liczby, adresy, numery wywołań systemowych
eax4 bajty32 bityDolna połowa rax
ax2 bajty16 bitówDolna połowa eax
al1 bajt8 bitówDolna połowa ax (bity 0-7)
ah1 bajt8 bitówGórna połowa ax (bity 8-15)

Ten sam wzorzec dotyczy innych rejestrów:

64-bitowy32-bitowy16-bitowy8-bitowy (młodszy)
rbxebxbxbl
rcxecxcxcl
rdxedxdxdl
rsiesisisil
rdiedididil

Dlaczego rozmiar ma znaczenie:

Podczas przenoszenia danych rozmiary źródła i miejsca docelowego powinny być takie same. Jeśli są różne, procesor może:

  • Skopiować tylko część danych
  • Skopiować dodatkowe bajty z nieznanego obszaru pamięci
  • Spowodować błąd

Przykłady zgodnych rozmiarów:

mov rax, 1000        ; 64-bitowe na 64-bitowe (w porządku)
mov eax, 1000        ; 32-bitowe na 32-bitowe (w porządku)
mov ax, 1000         ; 16-bitowe na 16-bitowe (w porządku)
mov al, 5            ; 8-bitowe na 8-bitowe (w porządku)

Co się dzieje, gdy rozmiary się nie zgadzają:

mov rax, 0x123456789ABC   ; wartość 64-bitowa
mov al, 0xFF              ; al otrzymuje 0xFF, pozostałe bity rax pozostają bez zmian

Zapis do rejestru 8- lub 16-bitowego (al, ah, ax) zmienia tylko te bity, a pozostała część pełnego rejestru pozostaje bez zmian. Zapis do rejestru 32-bitowego działa inaczej: mov eax, 0xFF zeruje bity 32–63, więc rax staje się 0xFF. Może to prowadzić do nieoczekiwanych wyników.

Bezpieczna zasada:

Jak dotąd w tym kursie wszystkie dane w pamięci zajmują 1 bajt. Dlatego używasz al (a nie rax).

Podczas przenoszenia danych rozmiar rejestru musi odpowiadać rozmiarowi pamięci:

  • 1 bajt pamięci → użyj al, bl, cl itd.
  • 8 bajtów pamięci → użyj rax, rbx, rcx itd.

W rozdziale 3 poznasz różne rozmiary pamięci.

challenge icon

Wyzwanie

Masz już utworzone następujące adresy danych:

  • source: zawiera wartość o rozmiarze 1 bajtu (5)
  • destination: puste miejsce (1 bajt)

Napisz dwie linie kodu asemblera, aby:

  1. Załadować wartość z source do al
  2. Zapisać wartość z al do destination

Spróbuj swoich sił

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

section .bss
    digit resb 1

section .text
    global _start

_start:
    ; Kod ucznia wykonuje się jako pierwszy (wczytuje wartość z source i zapisuje ją do destination)
    
    %include "solution.asm"
    
    ; Wczytaj wartość zapisaną w destination
    mov al, [destination]
    
    ; Zapisz ją
    mov r12, rax
    
    ; Wyświetl "destination = "
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, msg_len
    syscall
    
    ; Wyświetl wartość
    mov rax, r12
    add rax, 48
    mov [digit], al
    mov rax, 1
    mov rdi, 1
    mov rsi, digit
    mov rdx, 1
    syscall
    
    ; Zakończ program
    mov rax, 60
    mov rdi, 0
    syscall
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Podstawy

Poćwicz samodzielnie: Edytor online Assembly