diff --git a/casm/.vscode/launch.json b/casm/.vscode/launch.json index e3c42af..527b37d 100644 --- a/casm/.vscode/launch.json +++ b/casm/.vscode/launch.json @@ -11,6 +11,27 @@ "env": { "PATH": "${env:PATH}:${command:cmake.getLaunchTargetDirectory}" } + }, + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "${command:cmake.launchTargetPath}", + "cwd": "${workspaceFolder}", + "environment": [ + { + "name": "PATH", + "value": "${env:PATH}:${command:cmake.getLaunchTargetDirectory}" + }, + ], + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] } ] } \ No newline at end of file diff --git a/casm/CMakeLists.txt b/casm/CMakeLists.txt index d61c00b..48c399c 100644 --- a/casm/CMakeLists.txt +++ b/casm/CMakeLists.txt @@ -7,4 +7,4 @@ enable_language(ASM_NASM) set(CMAKE_ASM_NASM_FLAGS "-f elf64") set(CMAKE_ASM_NASM_FLAGS_DEBUG "-gdwarf") -add_executable(casm asm.asm c.c cpp.cpp) \ No newline at end of file +add_executable(casm asm.asm c.c) \ No newline at end of file diff --git a/casm/asm.asm b/casm/asm.asm index be431d4..140cd14 100644 --- a/casm/asm.asm +++ b/casm/asm.asm @@ -1,5 +1,6 @@ global main -extern sum, print, scan, test_vector, a +extern sum, print, scan +extern a section .text main: @@ -11,11 +12,12 @@ main: mov rsi, rax ; b call sum ; сумма mov rdi, rax ; результат + push rax call print ; напечатать - call test_vector + pop rax pop rbx ; восстановить rbx - mov dword [rel a], 42 ; записать значение 42 в переменную a + mov dword [rel a], eax ; записать значение 42 в переменную a mov rdi, 0 mov rax, 60 diff --git a/casm/cpp.cpp b/casm/cpp.cpp deleted file mode 100644 index eb50a8c..0000000 --- a/casm/cpp.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -extern "C" void test_vector() { - std::vector vec = std::vector(); - for(auto i = 0; i < 10; i++) - vec.push_back(i); - for(auto num : vec) - std::cout << num << ", "; - std::cout << std::endl; -} \ No newline at end of file diff --git a/docs/nasmdoc.pdf b/docs/nasmdoc.pdf new file mode 100644 index 0000000..45d056e Binary files /dev/null and b/docs/nasmdoc.pdf differ diff --git a/docs/x86-64_asm_sheet.ru.md b/docs/x86-64_asm_sheet.ru.md new file mode 100644 index 0000000..a953f08 --- /dev/null +++ b/docs/x86-64_asm_sheet.ru.md @@ -0,0 +1,568 @@ +# Шпаргалка по x86‑64 ASM + +## Адресация + +* Без сегментации (кроме `fs` и `gs` для специальных целей, например, потоков) + +* Относительно базового регистра + * используется для **данных в стеке**, **массивов**, **структур** и **членов классов** + * [`base` + `index` * `scale` + `immediate_offset`] + * `base` обязателен, может быть любым 64‑битным регистром + * `index` может быть любым 64‑битным регистром, кроме `rsp` + * `scale` может быть 1, 2, 4 или 8 + * `immediate_offset` (в GAS называется displacement) — смещение относительно базового регистра + * Синтаксис GAS: `immediate_offset(base, index, scale)` + +* Относительно RIP (также PC‑relative) + * используется для **статических данных** + * содержит 32‑битное знаково расширяемое смещение относительно указателя команд + * явно задаётся в NASM через `mov eax [rel label]` или директивы `default rel` / `default abs` (в противном случае используется 32‑битная абсолютная адресация) + * явно задаётся в GAS через `mov eax label(%rip)` + +* 32‑битная абсолютная адресация + * 32‑битный константный адрес, знаково расширяемый до 64 бит + * работает для адресов ниже 2^31 + * не используйте для простых операндов памяти: RIP‑relative короче, быстрее (не нужны релокации) и работает везде + * используется для доступа к **статическим массивам с индексным регистром**, например `mov ebx, [intarray + rsi*4]`, однако это не работает для DLL в Windows и Linux, а также для исполняемых файлов и DLL в macOS, потому что адреса выше 2^32 (gcc и clang используют это для Linux‑исполняемых файлов; для Windows‑исполняемых MASM использует адресацию относительно базы образа) + * альтернативный, работающий везде вариант: сначала загрузить адрес статического массива в `rbx` через `lea` с RIP‑relative адресом, а затем адресовать относительно этого базового регистра (`lea rbx, [array]`, затем `mov eax, [rbx + rcx*4]`); другие статические массивы затем можно адресовать относительно (`mov [(array2-array1) + rbx + rcx*4], eax`) + +* 64‑битная абсолютная адресация + * `mov eax, dword [qword a]` + * применима только с `mov` и регистрами `al`, `ax`, `eax` или `rax` (источник или приёмник) + * не может содержать сегмент, базовый или индексный регистр + +## Позиционно‑независимый код (PIC) + +* Проще и быстрее, чем 32‑битная техника GOT (Global Offset Table), поскольку RIP‑relative уже позиционно‑независим (заметьте, что описанная выше техника доступа к статическим массивам с индексным регистром также позиционно‑независима) + +## Регистры общего назначения + + bit 0 - 63 | bit 0 - 31 | bit 0 - 15 | bit 8 - 15 | bit 0 - 7 +:----------:|:----------:|:----------:|:----------:|:---------: + `rax` | `eax` | `ax` | `ah` | `al` + `rbx` | `ebx` | `bx` | `bh` | `bl` + `rcx` | `ecx` | `cx` | `ch` | `cl` + `rdx` | `edx` | `dx` | `dh` | `dl` + `rsi` | `esi` | `si` | | `sil` + `rdi` | `edi` | `di` | | `dil` + `rbp` | `ebp` | `bp` | | `bpl` + `rsp` | `esp` | `sp` | | `spl` + `r8` | `r8d` | `r8w` | | `r8b` + `r9` | `r9d` | `r9w` | | `r9b` + `r10` | `r10d` | `r10w` | | `r10b` + `r11` | `r11d` | `r11w` | | `r11b` + `r12` | `r12d` | `r12w` | | `r12b` + `r13` | `r13d` | `r13w` | | `r13b` + `r14` | `r14d` | `r14w` | | `r14b` + `r15` | `r15d` | `r15w` | | `r15b` + `rflags` | | `flags` | | + `rip` | | | | + +## Регистр `rflags` + +* CF (Carry Flag, бит 0) — устанавливается, если арифметическая операция генерирует перенос или заём из старшего бита результата; очищается иначе. Флаг показывает переполнение для беззнаковой арифметики. Также применяется в многоточечной (многословной) арифметике. +* PF (Parity Flag, бит 2) — устанавливается, если младший байт результата содержит чётное число единиц; очищается иначе. +* AF (Auxiliary carry Flag, бит 4) — устанавливается, если операция вызывает перенос или заём из бита 3 результата; очищается иначе. Используется в двоично‑десятичной (BCD) арифметике. +* ZF (Zero Flag, бит 6) — устанавливается, если результат равен нулю; очищается иначе. +* SF (Sign Flag, бит 7) — устанавливается равным старшему биту результата, то есть знаковому биту знакового целого (0 — положительное, 1 — отрицательное). +* OF (Overflow Flag, бит 11) — устанавливается, если целочисленный результат слишком велик (без учёта знакового бита), чтобы поместиться в операнд назначения: слишком большой положительный или слишком маленький отрицательный; очищается иначе. Показывает переполнение для знаковой (дополнительный код) арифметики. + +## Режимы насыщения и циклического переполнения (набора инструкций) + +* Циклическая арифметика (wraparound) — истинный выход за диапазон усечётся (перенос/переполнение игнорируется, возвращаются только младшие биты результата). Подходит, когда диапазон операндов контролируется. Иначе возможны большие ошибки. Пример: сложение двух больших знаковых чисел может вызвать положительное переполнение и дать отрицательный результат. +* Арифметика со знаковым насыщением — выход за диапазон ограничивается представимым диапазоном знаковых целых для данного размера. Например, при положительном переполнении для знаковых слов результат насыщается до 7FFFH (наибольшее положительное 16‑битное); при отрицательном — до 8000H. +* Арифметика с беззнаковым насыщением — выход за диапазон ограничивается представимым диапазоном беззнаковых целых данного размера. Положительное переполнение для беззнаковых байтов даёт FFH, отрицательное — 00H. + +## Стековые кадры + +## Инструкции передачи данных + +* [**MOV**](http://www.felixcloutier.com/x86/MOV.html) — Перемещение данных между регистрами общего назначения; между памятью и регистрами общего назначения или сегментными; загрузка непосредственных значений в регистры общего назначения. +* [**CMOVcc**](http://www.felixcloutier.com/x86/CMOVcc.html) — Условное перемещение. +* [**XCHG**](http://www.felixcloutier.com/x86/XCHG.html) — Обмен значениями. +* [**BSWAP**](http://www.felixcloutier.com/x86/BSWAP.html) — Перестановка байтов. +* [**XADD**](http://www.felixcloutier.com/x86/XADD.html) — Обмен с добавлением. +* [**CMPXCHG**](http://www.felixcloutier.com/x86/CMPXCHG.html) — Сравнить и обменять. +* [**CMPXCHG8B / CMPXCHG16B**](http://www.felixcloutier.com/x86/CMPXCHG8B:CMPXCHG16B.html) — Сравнить и обменять 8/16 байт. +* [**PUSH**](http://www.felixcloutier.com/x86/PUSH.html) — Поместить на стек. +* [**POP**](http://www.felixcloutier.com/x86/POP.html) — Снять со стека. +* [**PUSHA / PUSHAD**](http://www.felixcloutier.com/x86/PUSHA:PUSHAD.html) — Поместить все регистры общего назначения на стек. +* [**POPA / POPAD**](http://www.felixcloutier.com/x86/POPA:POPAD.html) — Снять все регистры общего назначения со стека. +* [**CWD / CDQ / CQO**](http://www.felixcloutier.com/x86/CWD:CDQ:CQO.html) — Расширить слово до двойного слова / двойное слово до квадрослова. +* [**CBW / CWDE / CDQE**](http://www.felixcloutier.com/x86/CBW:CWDE:CDQE.html) — Расширить байт до слова / слово до двойного слова в регистре `rax`. +* [**MOVSX / MOVSXD**](http://www.felixcloutier.com/x86/MOVSX:MOVSXD.html) — Перемещение с знаковым расширением. +* [**MOVZX**](http://www.felixcloutier.com/x86/MOVZX.html) — Перемещение с нулевым расширением. + +## Инструкции целочисленной арифметики + +* [**ADCX**](http://www.felixcloutier.com/x86/ADCX.html) — Беззнаковое сложение с переносом. +* [**ADOX**](http://www.felixcloutier.com/x86/ADOX.html) — Беззнаковое сложение с переполнением. +* [**ADD**](http://www.felixcloutier.com/x86/ADD.html) — Сложение целых. +* [**ADC**](http://www.felixcloutier.com/x86/ADC.html) — Сложение с переносом. +* [**SUB**](http://www.felixcloutier.com/x86/SUB.html) — Вычитание. +* [**SBB**](http://www.felixcloutier.com/x86/SBB.html) — Вычитание с заёмом. +* [**IMUL**](http://www.felixcloutier.com/x86/IMUL.html) — Умножение со знаком. +* [**MUL**](http://www.felixcloutier.com/x86/MUL.html) — Умножение без знака. +* [**IDIV**](http://www.felixcloutier.com/x86/IDIV.html) — Деление со знаком. +* [**DIV**](http://www.felixcloutier.com/x86/DIV.html) — Деление без знака. +* [**INC**](http://www.felixcloutier.com/x86/INC.html) — Инкремент. +* [**DEC**](http://www.felixcloutier.com/x86/DEC.html) — Декремент. +* [**NEG**](http://www.felixcloutier.com/x86/NEG.html) — Изменить знак (двойка‑дополнение). +* [**CMP**](http://www.felixcloutier.com/x86/CMP.html) — Сравнение. + +## Логические инструкции + +* [**AND**](http://www.felixcloutier.com/x86/AND.html) — Побитовое И. +* [**OR**](http://www.felixcloutier.com/x86/OR.html) — Побитовое ИЛИ. +* [**XOR**](http://www.felixcloutier.com/x86/XOR.html) — Побитовое исключающее ИЛИ. +* [**NOT**](http://www.felixcloutier.com/x86/NOT.html) — Побитовое НЕ. + +## Сдвиги и ротации + +* [**SAL / SAR / SHL / SHR**](http://www.felixcloutier.com/x86/SAL:SAR:SHL:SHR.html) — Арифметический/логический сдвиг влево/вправо. +* [**SHLD**](http://www.felixcloutier.com/x86/SHLD.html) — Двойной сдвиг влево. +* [**SHRD**](http://www.felixcloutier.com/x86/SHRD.html) — Двойной сдвиг вправо. +* [**RCL / RCR / ROL / ROR**](http://www.felixcloutier.com/x86/RCL:RCR:ROL:ROR.html) — Ротация влево/вправо и через перенос. + +## Битовые и байтовые инструкции + +* [**BT**](http://www.felixcloutier.com/x86/BT.html) — Тест бита. +* [**BTS**](http://www.felixcloutier.com/x86/BTS.html) — Тест и установка бита. +* [**BTR**](http://www.felixcloutier.com/x86/BTR.html) — Тест и сброс бита. +* [**BTC**](http://www.felixcloutier.com/x86/BTC.html) — Тест и инверсия бита. +* [**BSF**](http://www.felixcloutier.com/x86/BSF.html) — Поиск первого (младшего) установленного бита. +* [**BSR**](http://www.felixcloutier.com/x86/BSR.html) — Поиск последнего (старшего) установленного бита. +* [**SETcc**](http://www.felixcloutier.com/x86/SETcc.html) — Установить байт по условию. +* [**TEST**](http://www.felixcloutier.com/x86/TEST.html) — Логическое сравнение (AND, флаги). +* [**CRC32**](http://www.felixcloutier.com/x86/CRC32.html) — Аппаратное ускорение вычисления CRC для быстрого контроля целостности данных. +* [**POPCNT**](http://www.felixcloutier.com/x86/POPCNT.html) — Подсчёт количества единичных битов во втором операнде с возвратом счётчика в первый (регистр назначения). + +## Инструкции передачи управления + +* [**JMP**](http://www.felixcloutier.com/x86/JMP.html) — Безусловный переход. +* [**Jcc**](http://www.felixcloutier.com/x86/Jcc.html) — Переход при выполнении условия (операнд RIP‑relative). +* [**LOOP / LOOPcc**](http://www.felixcloutier.com/x86/LOOP:LOOPcc.html) — Цикл с счётчиком в `rcx`. +* [**CALL**](http://www.felixcloutier.com/x86/CALL.html) — Вызов процедуры. +* [**RET**](http://www.felixcloutier.com/x86/RET.html) — Возврат из процедуры. +* [**IRET / IRETD / IRETQ**](http://www.felixcloutier.com/x86/IRET:IRETD.html) — Возврат из прерывания. +* [**INT n / INTO / INT 3**](http://www.felixcloutier.com/x86/INTn:INTO:INT3.html) — Вызов обработчика прерывания. +* [**ENTER**](http://www.felixcloutier.com/x86/ENTER.html) — Высокоуровневый вход в процедуру. +* [**LEAVE**](http://www.felixcloutier.com/x86/LEAVE.html) — Высокоуровневый выход из процедуры. + +## Строковые инструкции + +* [**MOVS / MOVSB / MOVSW / MOVSD / MOVSQ**](http://www.felixcloutier.com/x86/MOVS:MOVSB:MOVSW:MOVSD:MOVSQ.html) — Копирование данных из строки в строку. +* [**CMPS / CMPSB / CMPSW / CMPSD / CMPSQ**](http://www.felixcloutier.com/x86/CMPS:CMPSB:CMPSW:CMPSD:CMPSQ.html) — Сравнение строковых операндов. +* [**SCAS / SCASB / SCASW / SCASD**](http://www.felixcloutier.com/x86/SCAS:SCASB:SCASW:SCASD.html) — Сканирование строки. +* [**LODS / LODSB / LODSW / LODSD / LODSQ**](http://www.felixcloutier.com/x86/LODS:LODSB:LODSW:LODSD:LODSQ.html) — Загрузка из строки. +* [**STOS / STOSB / STOSW / STOSD / STOSQ**](http://www.felixcloutier.com/x86/STOS:STOSB:STOSW:STOSD:STOSQ.html) — Запись в строку. +* [**REP / REPE / REPZ / REPNE / REPNZ**](http://www.felixcloutier.com/x86/REP:REPE:REPZ:REPNE:REPNZ.html) — Префиксы повторения строковых операций. + +## Инструкции управления `rflags` + +* [**STC**](http://www.felixcloutier.com/x86/STC.html) — Установить флаг переноса. +* [**CLC**](http://www.felixcloutier.com/x86/CLC.html) — Очистить флаг переноса. +* [**CMC**](http://www.felixcloutier.com/x86/CMC.html) — Инвертировать флаг переноса. +* [**CLD**](http://www.felixcloutier.com/x86/CLD.html) — Очистить флаг направления. +* [**STD**](http://www.felixcloutier.com/x86/STD.html) — Установить флаг направления. +* [**LAHF**](http://www.felixcloutier.com/x86/LAHF.html) — Загрузить флаги в регистр `ah`. +* [**SAHF**](http://www.felixcloutier.com/x86/SAHF.html) — Сохранить регистр `ah` в флаги. +* [**PUSHF / PUSHFQ**](http://www.felixcloutier.com/x86/PUSHF:PUSHFD:PUSHFQ.html) — Поместить `rflags` на стек. +* [**POPF / POPFQ**](http://www.felixcloutier.com/x86/POPF:POPFD:POPFQ.html) — Снять `rflags` со стека. +* [**STI**](http://www.felixcloutier.com/x86/STI.html) — Установить флаг прерываний. +* [**CLI**](http://www.felixcloutier.com/x86/CLI.html) — Очистить флаг прерываний. + +## Прочие инструкции + +* [**LEA**](http://www.felixcloutier.com/x86/LEA.html) — Загрузка эффективного адреса. +* [**NOP**](http://www.felixcloutier.com/x86/NOP.html) — Пустая операция. +* [**UD**](http://www.felixcloutier.com/x86/UD.html) — Неопределённая инструкция. +* [**XLAT / XLATB**](http://www.felixcloutier.com/x86/XLAT:XLATB.html) — Табличное преобразование байта. +* [**CPUID**](http://www.felixcloutier.com/x86/CPUID.html) — Идентификация процессора. +* [**MOVBE**](http://www.felixcloutier.com/x86/MOVBE.html) — Перемещение данных с перестановкой байтов. +* [**PREFETCHW**](http://www.felixcloutier.com/x86/PREFETCHW.html) — Предвыборка данных в кэш с ожиданием записи. +* [**CLFLUSH**](http://www.felixcloutier.com/x86/CLFLUSH.html) — Сброс и инвалидация операнда памяти и связанной линии кэша на всех уровнях иерархии кэшей процессора. +* [**CLFLUSHOPT**](http://www.felixcloutier.com/x86/CLFLUSHOPT.html) — То же, с оптимизацией пропускной способности памяти. +* [**RDRAND**](http://www.felixcloutier.com/x86/RDRAND.html) — Получение случайного числа, сгенерированного аппаратно. +* [**RDSEED**](http://www.felixcloutier.com/x86/RDSEED.html) — Получение зерна (seed) для ГСЧ из аппаратного источника. + +## Сохранение/восстановление расширенных состояний в пользовательском режиме + +* [**XSAVE**](http://www.felixcloutier.com/x86/XSAVE.html) — Сохранить расширенные состояния процессора в память. +* [**XSAVEC**](http://www.felixcloutier.com/x86/XSAVEC.html) — Сохранить расширенные состояния с уплотнением. +* [**XSAVEOPT**](http://www.felixcloutier.com/x86/XSAVEOPT.html) — Оптимизированное сохранение расширенных состояний. +* [**XRSTOR**](http://www.felixcloutier.com/x86/XRSTOR.html) — Восстановить расширенные состояния из памяти. +* [**XGETBV**](http://www.felixcloutier.com/x86/XGETBV.html) — Прочитать состояние расширенного управляющего регистра. + +## Манипуляции битами (BMI1, BMI2) + +* [**ANDN**](http://www.felixcloutier.com/x86/ANDN.html) — Побитовое AND первого операнда с инвертированным вторым. +* [**BEXTR**](http://www.felixcloutier.com/x86/BEXTR.html) — Извлечение непрерывного диапазона битов. +* [**BLSI**](http://www.felixcloutier.com/x86/BLSI.html) — Извлечь младший установленный бит. +* [**BLSMSK**](http://www.felixcloutier.com/x86/BLSMSK.html) — Установить в 1 все младшие биты ниже первого установленного. +* [**BLSR**](http://www.felixcloutier.com/x86/BLSR.html) — Сбросить младший установленный бит. +* [**BZHI**](http://www.felixcloutier.com/x86/BZHI.html) — Обнулить старшие биты, начиная с указанной позиции. +* [**LZCNT**](http://www.felixcloutier.com/x86/LZCNT.html) — Подсчёт ведущих нулей. +* [**MULX**](http://www.felixcloutier.com/x86/MULX.html) — Беззнаковое умножение без изменения флагов. +* [**PDEP**](http://www.felixcloutier.com/x86/PDEP.html) — Параллельная «загрузка» битов по маске. +* [**PEXT**](http://www.felixcloutier.com/x86/PEXT.html) — Параллельное «извлечение» битов по маске. +* [**RORX**](http://www.felixcloutier.com/x86/RORX.html) — Ротация вправо без изменения флагов. +* [**SARX / SHLX / SHRX**](http://www.felixcloutier.com/x86/SARX:SHLX:SHRX.html) — Арифметический/логический сдвиг без изменения флагов. +* [**TZCNT**](http://www.felixcloutier.com/x86/TZCNT.html) — Подсчёт замыкающих нулей (с конца). + +## Обзор x87 FPU + +* Состояние x87 FPU отображается на состояние MMX; при переходах к MMX‑инструкциям нужно соблюдать осторожность, чтобы избежать неконсистентности результатов. + +## Инструкции передачи данных x87 FPU + +* [**FLD**](http://www.felixcloutier.com/x86/FLD.html) — Загрузка числа с плавающей точкой. +* [**FST / FSTP**](http://www.felixcloutier.com/x86/FST:FSTP.html) — Сохранить число с/без извлечения из стека FPU. +* [**FILD**](http://www.felixcloutier.com/x86/FILD.html) — Загрузка целого. +* [**FIST / FISTP**](http://www.felixcloutier.com/x86/FIST:FISTP.html) — Сохранить целое с/без извлечения. +* [**FBLD**](http://www.felixcloutier.com/x86/FBLD.html) — Загрузка BCD. +* [**FBSTP**](http://www.felixcloutier.com/x86/FBSTP.html) — Сохранение BCD и извлечение. +* [**FXCH**](http://www.felixcloutier.com/x86/FXCH.html) — Обмен регистров. +* [**FCMOVcc**](http://www.felixcloutier.com/x86/FCMOVcc.html) — Условное перемещение (FPU). + +## Базовая арифметика x87 FPU + +* [**FADD / FADDP / FIADD**](http://www.felixcloutier.com/x86/FADD:FADDP:FIADD.html) — Сложение с плавающей точкой. +* [**FSUB / FSUBP / FISUB**](http://www.felixcloutier.com/x86/FSUB:FSUBP:FISUB.html) — Вычитание с плавающей точкой. +* [**FSUBR / FSUBRP / FISUBR**](http://www.felixcloutier.com/x86/FSUBR:FSUBRP:FISUBR.html) — Вычитание в обратном порядке. +* [**FMUL / FMULP / FIMUL**](http://www.felixcloutier.com/x86/FMUL:FMULP:FIMUL.html) — Умножение с плавающей точкой. +* [**FDIV / FDIVP / FIDIV**](http://www.felixcloutier.com/x86/FDIV:FDIVP:FIDIV.html) — Деление с плавающей точкой. +* [**FDIVR / FDIVRP / FIDIVR**](http://www.felixcloutier.com/x86/FDIVR:FDIVRP:FIDIVR.html) — Деление в обратном порядке. +* [**FPREM**](http://www.felixcloutier.com/x86/FPREM.html) — Частный остаток. +* [**FPREM1**](http://www.felixcloutier.com/x86/FPREM1.html) — Частный остаток (IEEE). +* [**FABS**](http://www.felixcloutier.com/x86/FABS.html) — Модуль. +* [**FCHS**](http://www.felixcloutier.com/x86/FCHS.html) — Смена знака. +* [**FRNDINT**](http://www.felixcloutier.com/x86/FRNDINT.html) — Округление до целого. +* [**FSCALE**](http://www.felixcloutier.com/x86/FSCALE.html) — Масштабирование по степени двойки. +* [**FSQRT**](http://www.felixcloutier.com/x86/FSQRT.html) — Квадратный корень. +* [**FXTRACT**](http://www.felixcloutier.com/x86/FXTRACT.html) — Извлечение показателя и мантиссы. + +## Сравнения x87 FPU + +* [**FCOM / FCOMP / FCOMPP**](http://www.felixcloutier.com/x86/FCOM:FCOMP:FCOMPP.html) — Сравнение чисел с плавающей точкой. +* [**FUCOM / FUCOMP / FUCOMPP**](http://www.felixcloutier.com/x86/FUCOM:FUCOMP:FUCOMPP.html) — Неупорядоченное сравнение чисел с плавающей точкой. +* [**FICOM / FICOMP**](http://www.felixcloutier.com/x86/FICOM:FICOMP.html) — Сравнение целых. +* [**FCOMI / FCOMIP / FUCOMI / FUCOMIP**](http://www.felixcloutier.com/x86/FCOMI:FCOMIP:FUCOMI:FUCOMIP.html) — Сравнение чисел с плавающей точкой с установкой флагов `rflags`. +* [**FTST**](http://www.felixcloutier.com/x86/FTST.html) — Тест (сравнение с 0.0). +* [**FXAM**](http://www.felixcloutier.com/x86/FXAM.html) — Анализ (exam) числа с плавающей точкой. + +## Трансцендентные функции x87 FPU + +* [**FSIN**](http://www.felixcloutier.com/x86/FSIN.html) — Синус. +* [**FCOS**](http://www.felixcloutier.com/x86/FCOS.html) — Косинус. +* [**FSINCOS**](http://www.felixcloutier.com/x86/FSINCOS.html) — Синус и косинус. +* [**FPTAN**](http://www.felixcloutier.com/x86/FPTAN.html) — Частичная тангенс‑функция. +* [**FPATAN**](http://www.felixcloutier.com/x86/FPATAN.html) — Частичная арктангенс‑функция. +* [**F2XM1**](http://www.felixcloutier.com/x86/F2XM1.html) — 2^x − 1. +* [**FYL2X**](http://www.felixcloutier.com/x86/FYL2X.html) — y ∗ log2(x). +* [**FYL2XP1**](http://www.felixcloutier.com/x86/FYL2XP1.html) — y ∗ log2(x + 1). + +## Загрузка констант x87 FPU + +* [**FLD1 / FLDL2T / FLDL2E / FLDPI / FLDLG2 / FLDLN2 / FLDZ**](http://www.felixcloutier.com/x86/FLD1:FLDL2T:FLDL2E:FLDPI:FLDLG2:FLDLN2:FLDZ.html) — Загрузка констант. + +## Управление x87 FPU + +* [**FINCSTP**](http://www.felixcloutier.com/x86/FINCSTP.html) — Инкремент указателя стека FPU. +* [**FDECSTP**](http://www.felixcloutier.com/x86/FDECSTP.html) — Декремент указателя стека FPU. +* [**FFREE**](http://www.felixcloutier.com/x86/FFREE.html) — Освободить регистр FPU. +* [**FINIT / FNINIT**](http://www.felixcloutier.com/x86/FINIT:FNINIT.html) — Инициализация FPU. +* [**FCLEX / FNCLEX**](http://www.felixcloutier.com/x86/FCLEX:FNCLEX.html) — Очистка флагов исключений FPU. +* [**FSTCW / FNSTCW**](http://www.felixcloutier.com/x86/FSTCW:FNSTCW.html) — Сохранить управляющее слово FPU. +* [**FLDCW**](http://www.felixcloutier.com/x86/FLDCW.html) — Загрузить управляющее слово FPU. +* [**FSTENV / FNSTENV**](http://www.felixcloutier.com/x86/FSTENV:FNSTENV.html) — Сохранить окружение FPU. +* [**FLDENV**](http://www.felixcloutier.com/x86/FLDENV.html) — Загрузить окружение FPU. +* [**FSAVE / FNSAVE**](http://www.felixcloutier.com/x86/FSAVE:FNSAVE.html) — Сохранить состояние FPU. +* [**FRSTOR**](http://www.felixcloutier.com/x86/FRSTOR.html) — Восстановить состояние FPU. +* [**FSTSW / FNSTSW**](http://www.felixcloutier.com/x86/FSTSW:FNSTSW.html) — Сохранить статусное слово FPU. +* [**WAIT / FWAIT**](http://www.felixcloutier.com/x86/WAIT:FWAIT.html) — Ожидание готовности FPU. +* [**FNOP**](http://www.felixcloutier.com/x86/FNOP.html) — Пустая операция FPU. + +## Управление состоянием x87 FPU и SIMD + +* [**FXSAVE**](http://www.felixcloutier.com/x86/FXSAVE.html) — Сохранить состояние x87 FPU и SIMD. +* [**FXRSTOR**](http://www.felixcloutier.com/x86/FXRSTOR.html) — Восстановить состояние x87 FPU и SIMD. + +## Обзор MMX + +* SIMD‑модель вычислений для 64‑битных упакованных целых. +* Восемь 64‑битных регистров данных MMX. +* Три новых типа упакованных данных: + * 64‑битные упакованные байтовые целые (со знаком и без) + * 64‑битные упакованные словные целые (со знаком и без) + * 64‑битные упакованные двойные слова (со знаком и без) +* Состояние MMX отображается на состояние x87 FPU; при переходах к инструкциям x87 FPU требуется осторожность во избежание неконсистентности результатов. + +## Передача данных MMX + +* [**MOVD / MOVQ**](http://www.felixcloutier.com/x86/MOVD:MOVQ.html) — Перемещение двойного/квадрослова между MMX и памятью/регистрами. + +## Преобразования MMX + +* [**PACKSSWB / PACKSSDW**](http://www.felixcloutier.com/x86/PACKSSWB:PACKSSDW.html) — Упаковка слов/двойных слов в байты со знаковым насыщением. +* [**PACKUSWB**](http://www.felixcloutier.com/x86/PACKUSWB.html) — Упаковка слов в байты с беззнаковым насыщением. +* [**PUNPCKHBW / PUNPCKHWD / PUNPCKHDQ**](http://www.felixcloutier.com/x86/PUNPCKHBW:PUNPCKHWD:PUNPCKHDQ:PUNPCKHQDQ.html) — Распаковка старших байтов/слов/двойных слов. +* [**PUNPCKLBW / PUNPCKLWD / PUNPCKLDQ**](http://www.felixcloutier.com/x86/PUNPCKLBW:PUNPCKLWD:PUNPCKLDQ:PUNPCKLQDQ.html) — Распаковка младших байтов/слов/двойных слов. + +## Упакованная арифметика MMX + +* [**PADDB / PADDW / PADDD**](http://www.felixcloutier.com/x86/PADDB:PADDW:PADDD:PADDQ.html) — Сложение упакованных байтов/слов/двойных слов. +* [**PADDSB / PADDSW**](http://www.felixcloutier.com/x86/PADDSB:PADDSW.html) — Сложение упакованных знаковых байтов/слов со знаковым насыщением. +* [**PADDUSB / PADDUSW**](http://www.felixcloutier.com/x86/PADDUSB:PADDUSW.html) — Сложение упакованных беззнаковых байтов/слов с беззнаковым насыщением. +* [**PSUBB / PSUBW / PSUBD**](http://www.felixcloutier.com/x86/PSUBB:PSUBW:PSUBD.html) — Вычитание упакованных байтов/слов/двойных слов. +* [**PSUBSB / PSUBSW**](http://www.felixcloutier.com/x86/PSUBSB:PSUBSW.html) — Вычитание упакованных знаковых байтов/слов со знаковым насыщением. +* [**PSUBUSB / PSUBUSW**](http://www.felixcloutier.com/x86/PSUBUSB:PSUBUSW.html) — Вычитание упакованных беззнаковых байтов/слов с беззнаковым насыщением. +* [**PMULHW**](http://www.felixcloutier.com/x86/PMULHW.html) — Умножение упакованных знаковых слов с сохранением старшей части результата. +* [**PMULLW**](http://www.felixcloutier.com/x86/PMULLW.html) — Умножение упакованных знаковых слов с сохранением младшей части. +* [**PMADDWD**](http://www.felixcloutier.com/x86/PMADDWD.html) — Умножение и сложение упакованных слов. + +## Сравнения MMX + +* [**PCMPEQB / PCMPEQW / PCMPEQD**](http://www.felixcloutier.com/x86/PCMPEQB:PCMPEQW:PCMPEQD.html) — Сравнение упакованных байтов/слов/двойных слов на равенство. +* [**PCMPGTB / PCMPGTW / PCMPGTD**](http://www.felixcloutier.com/x86/PCMPGTB:PCMPGTW:PCMPGTD.html) — Сравнение упакованных знаковых байтов/слов/двойных слов «больше чем». + +## Логика MMX + +* [**PAND**](http://www.felixcloutier.com/x86/PAND.html) — Побитовое И. +* [**PANDN**](http://www.felixcloutier.com/x86/PANDN.html) — Побитовое И‑НЕ. +* [**POR**](http://www.felixcloutier.com/x86/POR.html) — Побитовое ИЛИ. +* [**PXOR**](http://www.felixcloutier.com/x86/PXOR.html) — Побитовое исключающее ИЛИ. + +## Сдвиги и ротации MMX + +* [**PSLLW / PSLLD / PSLLQ**](http://www.felixcloutier.com/x86/PSLLW:PSLLD:PSLLQ.html) — Логический сдвиг упакованных слов/двойных слов/квадрослов влево. +* [**PSRLW / PSRLD / PSRLQ**](http://www.felixcloutier.com/x86/PSRLW:PSRLD:PSRLQ.html) — Логический сдвиг упакованных слов/двойных слов/квадрослов вправо. +* [**PSRAW / PSRAD**](http://www.felixcloutier.com/x86/PSRAW:PSRAD:PSRAQ.html) — Арифметический сдвиг упакованных слов/двойных слов вправо. + +## Управление состоянием MMX + +* [**EMMS**](http://www.felixcloutier.com/x86/EMMS.html) — Очистить состояние MMX. + +## Обзор SSE + +* Расширяет SIMD‑модель, добавляя операции над упакованными и скалярными числами одиночной точности в 128‑битных регистрах. +* Шестнадцать (в 32‑битном режиме — восемь) 128‑битных регистров XMM. +* 128‑битные инструкции для упакованных и скалярных чисел одиночной точности. +* Расширения MMX‑инструкций новыми операциями над упакованными целыми в регистрах MMX. +* Явная предвыборка данных, управление кэшируемостью данных и упорядочиванием операций записи. + +## Передача данных SSE + +* [**MOVAPS**](http://www.felixcloutier.com/x86/MOVAPS.html) — Перемещение четырёх выровненных упакованных чисел одиночной точности между XMM и памятью. +* [**MOVUPS**](http://www.felixcloutier.com/x86/MOVUPS.html) — Перемещение четырёх невыровненных упакованных чисел одиночной точности между XMM и памятью. +* [**MOVHPS**](http://www.felixcloutier.com/x86/MOVHPS.html) — Перемещение двух чисел одиночной точности из/в старшую квадрословную часть XMM и память. +* [**MOVHLPS**](http://www.felixcloutier.com/x86/MOVHLPS.html) — Перемещение двух чисел из старшей части одного XMM в младшую часть другого XMM. +* [**MOVLPS**](http://www.felixcloutier.com/x86/MOVLPS.html) — Перемещение двух чисел одиночной точности из/в младшую квадрословную часть XMM и память. +* [**MOVLHPS**](http://www.felixcloutier.com/x86/MOVLHPS.html) — Перемещение двух чисел из младшей части одного XMM в старшую часть другого XMM. +* [**MOVMSKPS**](http://www.felixcloutier.com/x86/MOVMSKPS.html) — Извлечь маску знаков из четырёх упакованных чисел одиночной точности. +* [**MOVSS**](http://www.felixcloutier.com/x86/MOVSS.html) — Перемещение скалярного числа одиночной точности между XMM и памятью. + +## Арифметика SSE (FP32) + +* [**ADDPS**](http://www.felixcloutier.com/x86/ADDPS.html) — Сложение упакованных чисел одиночной точности. +* [**ADDSS**](http://www.felixcloutier.com/x86/ADDSS.html) — Сложение скалярных чисел одиночной точности. +* [**SUBPS**](http://www.felixcloutier.com/x86/SUBPS.html) — Вычитание упакованных чисел одиночной точности. +* [**SUBSS**](http://www.felixcloutier.com/x86/SUBSS.html) — Вычитание скалярных чисел одиночной точности. +* [**MULPS**](http://www.felixcloutier.com/x86/MULPS.html) — Умножение упакованных чисел одиночной точности. +* [**MULSS**](http://www.felixcloutier.com/x86/MULSS.html) — Умножение скалярных чисел одиночной точности. +* [**DIVPS**](http://www.felixcloutier.com/x86/DIVPS.html) — Деление упакованных чисел одиночной точности. +* [**DIVSS**](http://www.felixcloutier.com/x86/DIVSS.html) — Деление скалярных чисел одиночной точности. +* [**RCPPS**](http://www.felixcloutier.com/x86/RCPPS.html) — Обратные значения (1/x) для упакованных чисел. +* [**RCPSS**](http://www.felixcloutier.com/x86/RCPSS.html) — Обратное значение для скаляра. +* [**SQRTPS**](http://www.felixcloutier.com/x86/SQRTPS.html) — Квадратные корни упакованных чисел. +* [**SQRTSS**](http://www.felixcloutier.com/x86/SQRTSS.html) — Квадратный корень скалярного числа. +* [**RSQRTPS**](http://www.felixcloutier.com/x86/RSQRTPS.html) — Обратные квадратные корни упакованных чисел. +* [**RSQRTSS**](http://www.felixcloutier.com/x86/RSQRTSS.html) — Обратный квадратный корень скаляра. +* [**MAXPS**](http://www.felixcloutier.com/x86/MAXPS.html) — Максимумы упакованных чисел одиночной точности. +* [**MAXSS**](http://www.felixcloutier.com/x86/MAXSS.html) — Максимум скаляра одиночной точности. +* [**MINPS**](http://www.felixcloutier.com/x86/MINPS.html) — Минимумы упакованных чисел одиночной точности. +* [**MINSS**](http://www.felixcloutier.com/x86/MINSS.html) — Минимум скаляра одиночной точности. + +## Сравнения SSE + +* [**CMPPS**](http://www.felixcloutier.com/x86/CMPPS.html) — Сравнение упакованных чисел одиночной точности. +* [**CMPSS**](http://www.felixcloutier.com/x86/CMPSS.html) — Сравнение скалярных чисел одиночной точности. +* [**COMISS**](http://www.felixcloutier.com/x86/COMISS.html) — Упорядоченное сравнение скаляров и установка флагов `rflags`. +* [**UCOMISS**](http://www.felixcloutier.com/x86/UCOMISS.html) — Неупорядоченное сравнение скаляров и установка флагов `rflags`. + +## Логика SSE + +* [**ANDPS**](http://www.felixcloutier.com/x86/ANDPS.html) — Побитовое И упакованных чисел одиночной точности. +* [**ANDNPS**](http://www.felixcloutier.com/x86/ANDNPS.html) — Побитовое И‑НЕ упакованных чисел. +* [**ORPS**](http://www.felixcloutier.com/x86/ORPS.html) — Побитовое ИЛИ упакованных чисел. +* [**XORPS**](http://www.felixcloutier.com/x86/XORPS.html) — Побитовое XOR упакованных чисел. + +## Перестановки и распаковка SSE + +* [**SHUFPS**](http://www.felixcloutier.com/x86/SHUFPS.html) — Перестановка значений в упакованных операндах. +* [**UNPCKHPS**](http://www.felixcloutier.com/x86/UNPCKHPS.html) — Распаковка и чередование двух старших значений из двух операндов. +* [**UNPCKLPS**](http://www.felixcloutier.com/x86/UNPCKLPS.html) — Распаковка и чередование двух младших значений из двух операндов. + +## Преобразования SSE + +* [**CVTPI2PS**](http://www.felixcloutier.com/x86/CVTPI2PS.html) — Преобразование упакованных двойных слов в упакованные числа одиночной точности. +* [**CVTSI2SS**](http://www.felixcloutier.com/x86/CVTSI2SS.html) — Преобразование двойного слова в скаляр одиночной точности. +* [**CVTPS2PI**](http://www.felixcloutier.com/x86/CVTPS2PI.html) — Преобразование упакованных чисел одиночной точности в упакованные двойные слова. +* [**CVTTPS2PI**](http://www.felixcloutier.com/x86/CVTTPS2PI.html) — То же с усечением. +* [**CVTSS2SI**](http://www.felixcloutier.com/x86/CVTSS2SI.html) — Преобразование скаляра одиночной точности в двойное слово. +* [**CVTTSS2SI**](http://www.felixcloutier.com/x86/CVTTSS2SI.html) — То же с усечением. + +## Управление MXCSR (SSE) + +* [**LDMXCSR**](http://www.felixcloutier.com/x86/LDMXCSR.html) — Загрузка регистра MXCSR. +* [**STMXCSR**](http://www.felixcloutier.com/x86/STMXCSR.html) — Сохранение состояния MXCSR. + +## SSE: 64‑битные целые (расширения MMX) + +* [**PAVGB / PAVGW**](http://www.felixcloutier.com/x86/PAVGB:PAVGW.html) — Среднее значение упакованных беззнаковых байтов. +* [**PEXTRW**](http://www.felixcloutier.com/x86/PEXTRW.html) — Извлечь слово. +* [**PINSRW**](http://www.felixcloutier.com/x86/PINSRW.html) — Вставить слово. +* [**PMAXUB**](http://www.felixcloutier.com/x86/PMAXUB:PMAXUW.html) — Максимум упакованных беззнаковых байтов. +* [**PMAXSW**](http://www.felixcloutier.com/x86/PMAXSB:PMAXSW:PMAXSD:PMAXSQ.html) — Максимум упакованных знаковых слов. +* [**PMINUB**](http://www.felixcloutier.com/x86/PMINUB:PMINUW.html) — Минимум упакованных беззнаковых байтов. +* [**PMINSW**](http://www.felixcloutier.com/x86/PMINSB:PMINSW.html) — Минимум упакованных знаковых слов. +* [**PMOVMSKB**](http://www.felixcloutier.com/x86/PMOVMSKB.html) — Маска байтов (перенос знаков в маску). +* [**PMULHUW**](http://www.felixcloutier.com/x86/PMULHUW.html) — Умножение упакованных беззнаковых слов, сохранение старшей части. +* [**PSADBW**](http://www.felixcloutier.com/x86/MPSADBW.html) — Сумма абсолютных разностей. +* [**PSHUFW**](http://www.felixcloutier.com/x86/PSHUFW.html) — Перестановка слов в регистре MMX. + +## SSE: кэшируемость, предвыборка и упорядочивание + +* [**MASKMOVQ**](http://www.felixcloutier.com/x86/MASKMOVQ.html) — Нетемпоральная запись выбранных байтов из MMX в память. +* [**MOVNTQ**](http://www.felixcloutier.com/x86/MOVNTQ.html) — Нетемпоральная запись квадрослова из MMX в память. +* [**MOVNTPS**](http://www.felixcloutier.com/x86/MOVNTPS.html) — Нетемпоральная запись четырёх упакованных чисел одиночной точности из XMM в память. +* [**PREFETCHh**](http://www.felixcloutier.com/x86/PREFETCHh.html) — Загрузка 32 и более байт из памяти в выбранный уровень кэша. +* [**SFENCE**](http://www.felixcloutier.com/x86/SFENCE.html) — Сериализация операций записи. + +## Обзор SSE2 + +* Упакованные и скалярные 128‑битные числа двойной точности. +* Дополнительные инструкции для 64‑ и 128‑битных упакованных байтов/слов/двойных слов/квадрослов. +* 128‑битные версии целочисленных инструкций из MMX и SSE. +* Дополнительные инструкции управления кэшируемостью и упорядочиванием инструкций. + +## SSE2: перемещение данных FP64 + +* [**MOVAPD**](http://www.felixcloutier.com/x86/MOVAPD.html) — Перемещение двух выровненных упакованных чисел двойной точности между XMM и памятью. +* [**MOVUPD**](http://www.felixcloutier.com/x86/MOVUPD.html) — Перемещение двух невыровненных упакованных чисел двойной точности между XMM и памятью. +* [**MOVHPD**](http://www.felixcloutier.com/x86/MOVHPD.html) — Перемещение старшего элемента двойной точности из/в старшую часть XMM и память. +* [**MOVLPD**](http://www.felixcloutier.com/x86/MOVLPD.html) — Перемещение младшего элемента двойной точности из/в младшую часть XMM и память. +* [**MOVMSKPD**](http://www.felixcloutier.com/x86/MOVMSKPD.html) — Извлечь маску знаков из двух упакованных чисел двойной точности. +* [**MOVSD**](http://www.felixcloutier.com/x86/MOVSD.html) — Перемещение скалярного числа двойной точности между XMM и памятью. + +## SSE2: арифметика FP64 + +* [**ADDPD**](http://www.felixcloutier.com/x86/ADDPD.html) — Сложение упакованных чисел двойной точности. +* [**ADDSD**](http://www.felixcloutier.com/x86/ADDSD.html) — Сложение скалярных чисел двойной точности. +* [**SUBPD**](http://www.felixcloutier.com/x86/SUBPD.html) — Вычитание упакованных чисел двойной точности. +* [**SUBSD**](http://www.felixcloutier.com/x86/SUBSD.html) — Вычитание скалярных чисел двойной точности. +* [**MULPD**](http://www.felixcloutier.com/x86/MULPD.html) — Умножение упакованных чисел двойной точности. +* [**MULSD**](http://www.felixcloutier.com/x86/MULSD.html) — Умножение скалярных чисел двойной точности. +* [**DIVPD**](http://www.felixcloutier.com/x86/DIVPD.html) — Деление упакованных чисел двойной точности. +* [**DIVSD**](http://www.felixcloutier.com/x86/DIVSD.html) — Деление скалярных чисел двойной точности. +* [**SQRTPD**](http://www.felixcloutier.com/x86/SQRTPD.html) — Квадратные корни упакованных чисел двойной точности. +* [**SQRTSD**](http://www.felixcloutier.com/x86/SQRTSD.html) — Квадратный корень скалярного числа двойной точности. +* [**MAXPD**](http://www.felixcloutier.com/x86/MAXPD.html) — Максимумы упакованных чисел двойной точности. +* [**MAXSD**](http://www.felixcloutier.com/x86/MAXSD.html) — Максимум скаляра двойной точности. +* [**MINPD**](http://www.felixcloutier.com/x86/MINPD.html) — Минимумы упакованных чисел двойной точности. +* [**MINSD**](http://www.felixcloutier.com/x86/MINSD.html) — Минимум скаляра двойной точности. + +## SSE2: логические операции FP64 + +* [**ANDPD**](http://www.felixcloutier.com/x86/ANDPD.html) — Побитовое И упакованных чисел двойной точности. +* [**ANDNPD**](http://www.felixcloutier.com/x86/ANDNPD.html) — Побитовое И‑НЕ упакованных чисел двойной точности. +* [**ORPD**](http://www.felixcloutier.com/x86/ORPD.html) — Побитовое ИЛИ упакованных чисел двойной точности. +* [**XORPD**](http://www.felixcloutier.com/x86/XORPD.html) — Побитовое XOR упакованных чисел двойной точности. + +## SSE2: сравнения FP64 + +* [**CMPPD**](http://www.felixcloutier.com/x86/CMPPD.html) — Сравнение упакованных чисел двойной точности. +* [**CMPSD**](http://www.felixcloutier.com/x86/CMPSD.html) — Сравнение скаляров двойной точности. +* [**COMISD**](http://www.felixcloutier.com/x86/COMISD.html) — Упорядоченное сравнение скаляров двойной точности с установкой `rflags`. +* [**UCOMISD**](http://www.felixcloutier.com/x86/UCOMISD.html) — Неупорядоченное сравнение скаляров двойной точности с установкой `rflags`. + +## SSE2: перестановки и распаковка FP64 + +* [**SHUFPD**](http://www.felixcloutier.com/x86/SHUFPD.html) — Перестановка значений в упакованных операндах двойной точности. +* [**UNPCKHPD**](http://www.felixcloutier.com/x86/UNPCKHPD.html) — Распаковка и чередование старших значений из двух операндов. +* [**UNPCKLPD**](http://www.felixcloutier.com/x86/UNPCKLPD.html) — Распаковка и чередование младших значений из двух операндов. + +## SSE2: преобразования + +* [**CVTPD2PI**](http://www.felixcloutier.com/x86/CVTPD2PI.html) — Преобразование упакованных чисел двойной точности в упакованные двойные слова. +* [**CVTTPD2PI**](http://www.felixcloutier.com/x86/CVTTPD2PI.html) — То же с усечением. +* [**CVTPI2PD**](http://www.felixcloutier.com/x86/CVTPI2PD.html) — Преобразование упакованных двойных слов в упакованные числа двойной точности. +* [**CVTPD2DQ**](http://www.felixcloutier.com/x86/CVTPD2DQ.html) — Преобразование упакованных чисел двойной точности в упакованные двойные слова. +* [**CVTTPD2DQ**](http://www.felixcloutier.com/x86/CVTTPD2DQ.html) — То же с усечением. +* [**CVTDQ2PD**](http://www.felixcloutier.com/x86/CVTDQ2PD.html) — Преобразование упакованных двойных слов в упакованные числа двойной точности. +* [**CVTPS2PD**](http://www.felixcloutier.com/x86/CVTPS2PD.html) — Преобразование упакованных чисел одиночной в двойную точность. +* [**CVTPD2PS**](http://www.felixcloutier.com/x86/CVTPS2PD.html) — Преобразование упакованных чисел двойной в одиночную точность. +* [**CVTSS2SD**](http://www.felixcloutier.com/x86/CVTSS2SD.html) — Преобразование скаляра одиночной в двойную точность. +* [**CVTSD2SS**](http://www.felixcloutier.com/x86/CVTSD2SS.html) — Преобразование скаляра двойной в одиночную точность. +* [**CVTSD2SI**](http://www.felixcloutier.com/x86/CVTSD2SI.html) — Преобразование скаляра двойной точности в двойное слово. +* [**CVTTSD2SI**](http://www.felixcloutier.com/x86/CVTTSD2SI.html) — То же с усечением. +* [**CVTSI2SD**](http://www.felixcloutier.com/x86/CVTSI2SD.html) — Преобразование двойного слова в скаляр двойной точности. + +## SSE2: FP32 (расширения SSE) + +* [**CVTDQ2PS**](http://www.felixcloutier.com/x86/CVTDQ2PS.html) — Преобразование упакованных двойных слов в упакованные числа одиночной точности. +* [**CVTPS2DQ**](http://www.felixcloutier.com/x86/CVTPS2DQ.html) — Преобразование упакованных чисел одиночной точности в упакованные двойные слова. +* [**CVTTPS2DQ**](http://www.felixcloutier.com/x86/CVTTPS2DQ.html) — То же с усечением. + +## SSE2: целочисленные инструкции + +* [**MOVDQA**](http://www.felixcloutier.com/x86/MOVDQA:VMOVDQA32:VMOVDQA64.html) — Перемещение выровненного двойного квадрослова. +* [**MOVDQU**](http://www.felixcloutier.com/x86/MOVDQU:VMOVDQU8:VMOVDQU16:VMOVDQU32:VMOVDQU64.html) — Перемещение невыровненного двойного квадрослова. +* [**MOVQ2DQ**](http://www.felixcloutier.com/x86/MOVQ2DQ.html) — Перемещение квадрослова из MMX в XMM. +* [**MOVDQ2Q**](http://www.felixcloutier.com/x86/MOVDQ2Q.html) — Перемещение квадрослова из XMM в MMX. +* [**PMULUDQ**](http://www.felixcloutier.com/x86/PMULUDQ.html) — Умножение упакованных беззнаковых двойных слов. +* [**PADDQ**](http://www.felixcloutier.com/x86/PADDB:PADDW:PADDD:PADDQ.html) — Сложение упакованных квадрослов. +* [**PSUBQ**](http://www.felixcloutier.com/x86/PSUBQ.html) — Вычитание упакованных квадрослов. +* [**PSHUFLW**](http://www.felixcloutier.com/x86/PSHUFLW.html) — Перестановка младших слов. +* [**PSHUFHW**](http://www.felixcloutier.com/x86/PSHUFHW.html) — Перестановка старших слов. +* [**PSHUFD**](http://www.felixcloutier.com/x86/PSHUFD.html) — Перестановка двойных слов. +* [**PSLLDQ**](http://www.felixcloutier.com/x86/PSLLDQ.html) — Логический сдвиг двойного квадрослова влево. +* [**PSRLDQ**](http://www.felixcloutier.com/x86/PSRLDQ.html) — Логический сдвиг двойного квадрослова вправо. +* [**PUNPCKHQDQ**](http://www.felixcloutier.com/x86/PUNPCKHBW:PUNPCKHWD:PUNPCKHDQ:PUNPCKHQDQ.html) — Распаковка старших квадрослов. +* [**PUNPCKLQDQ**](http://www.felixcloutier.com/x86/PUNPCKLBW:PUNPCKLWD:PUNPCKLDQ:PUNPCKLQDQ.html) — Распаковка младших квадрослов. + +## SSE2: кэшируемость и упорядочивание + +* [**CLFLUSH**](http://www.felixcloutier.com/x86/CLFLUSH.html) — Сброс линии кэша. +* [**LFENCE**](http://www.felixcloutier.com/x86/LFENCE.html) — Сериализация операций чтения. +* [**MFENCE**](http://www.felixcloutier.com/x86/MFENCE.html) — Сериализация операций чтения и записи. +* [**PAUSE**](http://www.felixcloutier.com/x86/PAUSE.html) — Улучшает производительность «циклов активного ожидания» (spin‑wait). +* [**MASKMOVDQU**](http://www.felixcloutier.com/x86/MASKMOVDQU.html) — Нетемпоральная запись выбранных байтов из XMM в память. +* [**MOVNTPD**](http://www.felixcloutier.com/x86/MOVNTPD.html) — Нетемпоральная запись двух упакованных чисел двойной точности из XMM в память. +* [**MOVNTDQ**](http://www.felixcloutier.com/x86/MOVNTDQ.html) — Нетемпоральная запись двойного квадрослова из XMM в память. +* [**MOVNTI**](http://www.felixcloutier.com/x86/MOVNTI.html) — Нетемпоральная запись двойного слова из регистра общего назначения в память. + +## Ссылки + +* https://software.intel.com/sites/default/files/managed/39/c5/325462-sdm-vol-1-2abcd-3abcd.pdf +* http://www.agner.org/optimize/optimizing_assembly.pdf +* https://www.nasm.us/xdoc/2.13.03/nasmdoc.pdf +* https://godbolt.org/ +* https://www.lri.fr/~filliatr/ens/compil/x86-64.pdf +* https://0xax.github.io/categories/assembler/ + +## Таблицы инструкций + +* http://www.agner.org/optimize/instruction_tables.pdf + +## Примеры + +* https://github.com/torvalds/linux/tree/master/arch/x86 +* https://gist.github.com/rygorous/bf1659bf6cd1752ed114367d4b87b302 +* https://www.csee.umbc.edu/portal/help/nasm/sample_64.shtml + +## Утилиты + +* https://software.intel.com/sites/landingpage/IntrinsicsGuide/ +* https://git.ffmpeg.org/gitweb/ffmpeg.git/blob_plain/HEAD:/libavutil/x86/x86inc.asm +* https://gist.github.com/rygorous/f729919ff64526a46e591d8f8b52058e diff --git a/minimal/.vscode/launch.json b/minimal/.vscode/launch.json index bd9019d..cc80f6f 100644 --- a/minimal/.vscode/launch.json +++ b/minimal/.vscode/launch.json @@ -36,14 +36,6 @@ "preLaunchTask": "asm64", - }, - { - "name": "lldb+GCC x64", - "type": "lldb", - "request": "launch", - "program": "${workspaceFolder}/build/minimal", - "cwd": "${workspaceFolder}/build", - "preLaunchTask": "asm64+gcc", } ] } \ No newline at end of file diff --git a/minimal/.vscode/settings.json b/minimal/.vscode/settings.json new file mode 100644 index 0000000..9ddf6b2 --- /dev/null +++ b/minimal/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.ignoreCMakeListsMissing": true +} \ No newline at end of file diff --git a/minimal/.vscode/tasks.json b/minimal/.vscode/tasks.json index c362ad7..7f4beed 100644 --- a/minimal/.vscode/tasks.json +++ b/minimal/.vscode/tasks.json @@ -9,7 +9,7 @@ "mkdir -p $builddir;", "rawfilename=$builddir/minimal;", "nasm -gdwarf -f elf64 -o $rawfilename.o ${workspaceFolder}/minimal.asm;", - "ld -g -m elf_x86_64 -o $rawfilename $rawfilename.o;" + "gcc -g -o $rawfilename $rawfilename.o;" ], "problemMatcher": { "pattern": { @@ -26,28 +26,6 @@ "kind": "build", "isDefault": true } - }, - { - "label": "asm64+gcc", - "type": "shell", - "command": [ - "builddir=${workspaceFolder}/build;", - "mkdir -p $builddir;", - "rawfilename=$builddir/minimal;", - "nasm -gdwarf -f elf64 -o $rawfilename.o ${workspaceFolder}/minimal.asm;", - "gcc -o $rawfilename $rawfilename.o;" - ], - "problemMatcher": { - "pattern": { - "regexp": "error" - } - }, - "presentation": { - "focus": true, - "panel": "dedicated", - "reveal": "silent", - "clear": true - }, } ] } \ No newline at end of file diff --git a/minimal/minimal.asm b/minimal/minimal.asm index 2ca7986..b1d8214 100644 --- a/minimal/minimal.asm +++ b/minimal/minimal.asm @@ -1,11 +1,20 @@ global _start -section .data -nums dq 112, 113, 114, 115, 116 ; массив чисел типа qword -currentAddr dq $ - section .text _start: - mov rdi, [currentAddr - 8] ; rdi = 116 + ; Передаём два числа для суммирования + mov rsi, 12 + mov rdi, 7 + call calculate_sum + + ; Используем результат + mov rbx, rax + + ; Завершение программы mov rax, 60 - syscall \ No newline at end of file + syscall + +; Функция складывает два значения, переданных в RDI и RSI +calculate_sum: + lea rax, [rdi + rsi] + ret \ No newline at end of file diff --git a/nasm.code-workspace b/nasm.code-workspace index 8cd5dac..0e9177a 100644 --- a/nasm.code-workspace +++ b/nasm.code-workspace @@ -13,5 +13,6 @@ "settings": { "debug.allowBreakpointsEverywhere": true, "debug.inlineValues": "on", + "editor.codeLens": false, } } \ No newline at end of file