Към съдържанието

Глава III — Типове данни при 32- и 64-разрядните x86 микропроцесори

1. Основни и числови типове данни. Разположение в паметта

Основни типове данни

ТипРазмерБитовеДиапазон (без знак)Типично предназначение
Байт (Byte)1 байт80 … 255ASCII символи, булеви флагове, хардуерни регистри, малки броячи
Дума (Word)2 байта160 … 65 535Unicode (UCS-2) символи, 16-битови портови адреси, сегментни селектори
Двойна дума (Doubleword)4 байта320 … 4 294 967 295Стандартна целочислена аритметика, 32-битови указатели, цветове RGBA, IPv4 адреси
Четворна дума (Quadword)8 байта640 … 264−164-битови указатели, файлови отмествания, временни маркери (timestamps), 64-битова аритметика
Двойна четворна дума (Double Quadword)16 байта128— (за SIMD)SIMD операции — обработка на изображения, криптография, векторни изчисления

Числови типове данни (знакови)

  • Цели знакови числа: представяне в допълнителен код (two’s complement)
    • Байт: −128 … +127
    • Дума: −32 768 … +32 767
    • Двойна дума: −2 147 483 648 … +2 147 483 647
    • Четворна дума: −263 … +263−1

Наредба на байтовете в паметта: Little-Endian

В компютрите многобайтовите числа могат да се съхраняват по два начина:

  • Little-Endianнай-малкозначимият байт (LSB) се записва на най-ниския адрес. Използва се от x86/x86-64.
  • Big-Endianнай-значимият байт (MSB) се записва на най-ниския адрес. Използва се от мрежови протоколи (TCP/IP), SPARC, PowerPC (в Motorola режим).

Пример: 32-битовото число 0x12345678 на адрес n:

АдресLittle-Endian (x86)Big-Endian (мрежа)
n+00x78 (LSB) ← записва се пръв0x12 (MSB) ← записва се пръв
n+10x560x34
n+20x340x56
n+30x12 (MSB)0x78 (LSB)

Пример с 16-битово число 0xABCD на адрес 1000h:

АдресБайт
1000h0xCD (LSB)
1001h0xAB (MSB)

Запомнете: Little = „малкото” (LSB) е на малкия (нисък) адрес.

Защо Little-Endian е по-удобен за x86?
При четене на подмножество от байтове (напр. четете само долния байт на 32-битова стойност) то се намира директно на оригиналния адрес — независимо дали четете байт, дума или двойна дума от n. При Big-Endian подмножеството е на различен адрес спрямо типа.

Практическо значение — мрежово програмиране:
TCP/IP използва Big-Endian (“network byte order”). При изпращане на данни от x86 трябва да се конвертира: htons() (host-to-network short), htonl() (host-to-network long). При получаване: ntohs(), ntohl().

Изравняване на данните в паметта

За оптималност, данните трябва да бъдат изравнени на адреси, кратни на размера им:

  • Дума: на четен адрес (кратен на 2)
  • Двойна дума: на адрес кратен на 4
  • Четворна дума: на адрес кратен на 8
  • 128-битови данни: на адрес кратен на 16

Неизравнени достъпи водят до изключение #AC (когато е разрешен AC флагът) или до по-бавно изпълнение.


2. Указатели, полета и стрингове

Указатели

В защитен режим x86 поддържа два типа указатели:

Близък (Near) указател — 32-битово отместване в рамките на текущия сегмент:

[32-битово отместване]

Използва се за повечето извиквания на функции и достъп до данни в рамките на един и същ сегмент (обичайният случай при плоски модели на паметта).

Далечен (Far) указател — 48 бита: 16-битов селектор + 32-битово отместване:

[16-битов сегментен селектор] : [32-битово отместване]

Използва се при многосегментни модели, системен код (прескачания между пръстени на привилегия) и обработка на прекъсвания — там, където е необходим явен смяна на сегмента.

В 64-битов режим (Long Mode): Near указатели са 64-битови (RIP-relative или абсолютни).

Битови полета

  • x86 поддържа операции върху отделни битове и битови полета в цели числа
  • Инструкции: BT, BTS, BTR, BTC (тест/задаване/нулиране/инвертиране на бит)
  • Размер на поле: 0–31 бита (или до 63 бита в 64-битов режим)

Предназначение: Управление на хардуерни управляващи регистри (CR0–CR4, EFLAGS), компактно съхранение на флагове в ОС, декодиране на протокол полета, управление на разрешения (permission bitmasks).

Стрингове (низове от байтове)

  • Стринг = линейна поредица от байтове, думи или двойни думи в паметта
  • Размер: до 4 GB (в 32-битов режим) или до 264−1 байта (в 64-битов)
  • Обработват се с стрингови инструкции: MOVS, CMPS, SCAS, LODS, STOS, INS, OUTS
  • Посоката на обработка се задава с флага DF (Direction Flag):
    • DF = 0: индексите ESI/EDI нарастват
    • DF = 1: индексите ESI/EDI намаляват
  • Prefix REP/REPE/REPNE повтаря стрингова инструкция до изчерпване на CX/ECX

Предназначение: Ефективно копиране на блокове памет (memcpy/memset), сравнение на буфери (memcmp), търсене на байт в масив (strchr), предаване на данни към I/O портове.


3. SIMD пакетирани типове данни

Какво е SIMD?

SIMD (Single Instruction, Multiple Data) — една инструкция се прилага едновременно върху множество малки типове данни, опаковани в един широк регистър.

MMX регистри (64-битови)

Въведени с Pentium MMX (1997). 8 регистъра: MM0–MM7 (физически FPU ST0–ST7).

Предназначение: Обработка на аудио и 2D видео (DCT за MPEG-1/2 декодиране), ефекти върху изображения (смесване на пиксели, яркост/контраст), компресия на данни в реално врeме.

Видове опакования в 64 бита:

| Bits 63–56 | 55–48 | 47–40 | 39–32 | 31–24 | 23–16 | 15–8 | 7–0 | | ---------- | ----- | ----- | ----- | ------ | ----- | ----- | ----- | ----------- | | byte7 | byte6 | byte5 | byte4 | byte3 | byte2 | byte1 | byte0 | 8×byte | | word3 | | word2 | | word1 | | word0 | | 4×word | | dword1 | | | | dword0 | | | | 2×dword |

XMM регистри (128-битови) — SSE, SSE2, SSE3, SSE4

Въведени с Pentium III (SSE, 1999). 8 регистъра (SSE) → 16 в 64-битов режим: XMM0–XMM15.

Предназначение: 3D графика (трансформации на върхове, матрично умножение в игрови двигатели), физически симулации, декодиране на H.264/H.265 видео, DSP операции (FFT, FIR филтри), криптографски примитиви (AES-NI).

РазширениеТип данниОперации
SSE4 × float32 (packed single)Плаваща запетая с единична точност
SSE22 × float64 (packed double)Плаваща запетая с двойна точност
SSE216 × int8 / 8 × int16 / 4 × int32 / 2 × int64Целочислени 128-битови SIMD
SSE4.1/4.2Допълнителни смесени операции
Bits 127–9695–6463–3231–0Режим
float32float32float32float324 × SP float (SSE)
float64float642 × DP float (SSE2)
int32int32int32int324 × int32 (SSE2)
int16 | int16int16 | int16int16 | int16int16 | int168 × int16 (SSE2)

YMM регистри (256-битови) — AVX, AVX2

Въведени с Sandy Bridge (AVX, 2011). Разширяват XMM до 256 бита: YMM0–YMM15.

  • AVX: 8 × float32 или 4 × float64 packed операции
  • AVX2: Разширява целочислените SIMD до 256 бита
  • Използват VEX prefix вместо REX

Предназначение: Машинно самообучение (матрични операции в невронни мрежи), обработка на изображения с висока разделителна способност (фотографски RAW конвертори), научни изчисления (симулация на молекулярна динамика, метеорология), кодиране на видео (x264/x265 енкодери).

ZMM регистри (512-битови) — AVX-512

Въведени с Knight’s Landing (2016) и Skylake-X. Регистри: ZMM0–ZMM31.

Предназначение: HPC (суперкомпютри), дълбоко самообучение (тензорни операции), геномика (поравняване на последователности), криптография с голяма прецизност, бази данни с колонарно съхранение.


4. BCD типове данни и числа с плаваща запетая

BCD (Binary Coded Decimal)

Предназначение: Финансови приложения и касови системи (избягва грешките при конвертиране между двоично и десетично представяне при парични суми), вградени системи с 7-сегментни дисплеи, банкови и счетоводни стандарти изискващи точна десетична аритметика без закръгляне.

BCD кодира всяка десетична цифра в 4 бита (тетрада):

Unpacked BCD (разопакован): 1 цифра/байт, цифрата е в младшата тетрада:

Десетично 9 → 0000 1001 (0x09)

Packed BCD (опакован): 2 цифри/байт:

Десетично 59 → 0101 1001 (0x59)

80-битов BCD (в FPU): 18 десетични цифри в 10 байта → само в ST(x) регистрите чрез FBLD/FBSTP

Корекционни инструкции за BCD:

  • DAA — корекция след BCD събиране
  • DAS — корекция след BCD изваждане
  • AAA / AAS — корекция при unpacked BCD
  • AAM / AAD — умножение/деление при unpacked BCD

Забележка: В 64-битов режим (Long Mode) DAA, DAS, AAA, AAS, AAM, AAD са невалидни инструкции.

Числа с плаваща запетая (IEEE 754)

Предназначение:

  • Single precision (32b): Игрова графика и 3D рендиране (DirectX/OpenGL шейдъри), физически двигатели, сензорни данни от вградени системи — достатъчна точност при минимална памет
  • Double precision (64b): Научни изчисления (инженерни симулации, астрономия, финансови модели), езикови интерпретатори (Python float, JavaScript number)
  • Extended precision (80b): Вградени изчисления в x87 FPU за намаляване на натрупаните грешки при дълги вериги от аритметични операции

x87 FPU поддържа три формата:

ФорматРазмерМантиса (бита)Показател (бита)Точност
Single precision32 бита23 (+1 неявен)8~7 десетични цифри
Double precision64 бита52 (+1 неявен)11~15–17 десетични цифри
Extended precision80 бита64 (явен)15~18–19 десетични цифри

Формат на single precision (32 бита) — знак (1 бит), показател (8 бита, отместване 127), мантиса (23 бита, неявен водещ 1):

Бит 31Битове 30–23Битове 22–0
S (знак)E (показател, 8b, offset=127)M (мантиса, 23b)

Стойност: (−1)^S × 2^(E−127) × 1.M

Формат на double precision (64 бита) — знак (1 бит), показател (11 бита, отместване 1023), мантиса (52 бита):

Бит 63Битове 62–52Битове 51–0
S (знак)E (показател, 11b, offset=1023)M (мантиса, 52b)

Стойност: (−1)^S × 2^(E−1023) × 1.M

Специални стойности:

  • +∞, −∞ (показател = 0xFF, мантиса = 0)
  • NaN — Not a Number (показател = 0xFF, мантиса ≠ 0)
  • Суbnormal числа (показател = 0, мантиса ≠ 0)

FPU регистри:

  • 8 регистъра ST(0)–ST(7) образуват стек (8 × 80-битови)
  • Операциите работят с ST(0) (top of stack)

SSE2 работи с 32/64-битов IEEE 754 в XMM регистрите (не 80-битов).


Резюме за изпита

  • x86 използва Little-Endian и изисква изравняване за оптимална работа
  • Far указател = 16-битов селектор + 32-битово отместване
  • SIMD: MMX (64 бита, MM0–MM7), SSE/SSE2 (128 бита, XMM0–XMM15), AVX (256 бита, YMM)
  • BCD: packed (2 цифри/байт) и unpacked (1 цифра/байт); корекция с DAA/DAS/AAA/AAS
  • FPU поддържа 32/64/80-битов IEEE 754; 80-битовото extended е характерно за x87

→ Речник на всички съкращения


Източници: