MOV z różnymi rozmiarami
Część sekcji Podstawy ścieżki Assembly w Coddy. Lekcja 20 z 45.
Używasz już al (8 bitów) i rax (64 bity). Istnieją też inne rozmiary. Różne rejestry przechowują różne ilości danych.
Rodziny rejestrów x86-64:
| Rejestr | Rozmiar | Bity | Kiedy używać |
|---|---|---|---|
rax | 8 bajtów | 64 bity | Pełne liczby, adresy, numery wywołań systemowych |
eax | 4 bajty | 32 bity | Dolna połowa rax |
ax | 2 bajty | 16 bitów | Dolna połowa eax |
al | 1 bajt | 8 bitów | Dolna połowa ax (bity 0-7) |
ah | 1 bajt | 8 bitów | Górna połowa ax (bity 8-15) |
Ten sam wzorzec dotyczy innych rejestrów:
| 64-bitowy | 32-bitowy | 16-bitowy | 8-bitowy (młodszy) |
|---|---|---|---|
rbx | ebx | bx | bl |
rcx | ecx | cx | cl |
rdx | edx | dx | dl |
rsi | esi | si | sil |
rdi | edi | di | dil |
Dlaczego rozmiar ma znaczenie:
Podczas przenoszenia danych rozmiary źródła i miejsca docelowego powinny być zgodne. Jeśli nie są zgodne, procesor może:
- Skopiować tylko część danych
- Skopiować dodatkowe bajty z nieznanej pamięci
- Spowodować błąd
Przykłady zgodnych rozmiarów:
mov rax, 1000 ; 64-bitowy na 64-bitowy (w porządku)
mov eax, 1000 ; 32-bitowy na 32-bitowy (w porządku)
mov ax, 1000 ; 16-bitowy na 16-bitowy (w porządku)
mov al, 5 ; 8-bitowy na 8-bitowy (w porządku)Co się dzieje przy niezgodnych rozmiarach:
mov rax, 0x123456789ABC ; wartość 64-bitowa
mov al, 0xFF ; al otrzymuje 0xFF, pozostałe bity rax pozostają bez zmianGdy przenosisz mniejszą wartość do większego rejestru, starsze bity pozostają takie same. 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,clitd. - 8 bajtów pamięci → użyj
rax,rbx,rcxitd.
W rozdziale 3 dowiesz się o różnych rozmiarach pamięci.
Wyzwanie
Masz już utworzone te adresy danych:
source: zawiera wartość 1-bajtową (5)destination: puste miejsce (1 bajt)
Napisz dwie linie asemblera, aby:
- Załadować wartość z
sourcedoal - Zapisać wartość z
aldodestination
Spróbuj swoich sił
section .data
msg db 'destination = '
msg_len equ $ - msg
section .bss
digit resb 1
section .text
global _start
_start:
; Najpierw wykonywany jest kod ucznia (wczytuje wartość z source i zapisuje ją w destination)
%include "solution.asm"
; Wczytaj wartość zapisaną w destination
mov al, [destination]
; Zapisz ją
mov r12, rax
; Wypisz "destination = "
mov rax, 1
mov rdi, 1
mov rsi, msg
mov rdx, msg_len
syscall
; Wypisz 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
syscallTa lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Podstawy
1Maszyna
Czym jest CPUPamięćRejestry a pamięćJak działają instrukcjeWzorzec dwóch plikówArchitektura x86-642Systemy liczbowe
Dlaczego system binarny?Liczby binarneZamiana z systemu dziesiętnego na binarnyDlaczego system szesnastkowy?Zamiana z systemu szesnastkowego na dziesiętnyZamiana z systemu dziesiętnego na szesnastkowyASCII i system szesnastkowy5Wywołanie systemowe zakończenia
Czym jest syscall?Wywołanie systemowe zakończenia (60)Kody zakończeniaPodsumowanie: prawidłowe zakończenie3Pierwsza instrukcja – MOV
Czym jest MOV?MOV z wartością natychmiastowąMOV między rejestramiMOV z pamięci do rejestruMOV z rejestru do pamięciLEA – załaduj adresMOV z różnymi rozmiaramiĆwiczenie: zamiana rejestrówPowtórka: wyzwanie MOVPoćwicz samodzielnie: Edytor online Assembly