arctg
-- Вычисляет сумму k слагаемых ряда Тейлора арктангенса, учитывая, что формула имеет смысл, только при |x| <= 1.
float __cdecl arctan(float x, uint k);
arctg_scalar
-- скалярная версия на xmmarctg_vector
-- векторная версия на xmm
Написать функцию, выполняющую преобразование числа из шестнадцатеричной записи в десятичную отформатированную.
Прототип функции:
void print(char *out_buf, const char *format, const char *hex_number);
Входное шестнадцатеричное число 128-битное, со знаком в двоичном дополнительном коде. Перед числом может быть символ '-', который следует интерпретировать строго как "инвертировать все биты входного числа и добавить 1", что полезно для ввода отрицательных чисел. Буквы могут быть любого регистра.
Строка формата подобна формату функции sprintf
, но необходимо реализовать только небольшое подмножество: флаги '-', '+', ' ', '0' и поле ширины (width).
В выходной буфер должна быть записана ноль-терминированная строка результата без переводов строки или ещё каких-либо лишних символов.
Конвенция вызова: cdecl
. Название функции в .asm
файле: _print
. Не забывайте сохранять нужные регистры, если вы их изменяете.
Функция должна быть реализована в одном .asm
файле и не использовать каких-либо внешних функций, один только .asm
файл должен быть приложен к письму.
Пример входных данных: "-5"
, "10"
. Результат: "16 "
.
Для проверки на небольших числах можете использовать следующий код на C:
int x;
sscanf("<hex_number>", "%x", &x);
printf("%<format>i", x);
Мир: x86
Преобразование Фурье -- вещь, которая позволяет перейти из частотной в импульсную форму. Оно часто применяется для обработки звука и изображения. А также важно, что его можно написать быстро.
Требуется написать 2 функции: выполняющие прямое и обратное DCT преобразование размером 16x16.
Прототипы функций:
void fdct(const float *in, float *out);
void idct(const float *in, float *out);
in
- указатель на входные данные,
out
- указатель на выходные данные.
Можно писать как 32-битный, так и 64-битный код.
32-битный код: конвенция вызова cdecl
, к именам нужно добавлять символ _
, то есть называться они у вас будут _fdct
и _idct
.
64-битный код: конвенция вызова fastcall64
, к именам не нужно добавлять символ _
, то есть называться они у вас будут fdct
и idct
.
Обе функции должны быть реализованы в одном .asm
файле и не использовать каких-либо внешних функций.
Из SIMD расширений разрешается использовать всё вплоть до SSE4.2 включительно.
Входные и выходные данные в памяти не пересекаются и их начала выравнены на границу, кратную 16.
Оцениваться будет как правильность реализации, так и скорость работы.
Функции будут вызываться много раз, так что если вам требуется какая-то начальная инициализация - позаботьтесь, чтобы она не повторялась при каждом вызове.
Написать прямое и обратное преобразование Фурье (двухмерное 16x16) DCT2, DCT3
- Не нужно писать перемножение матриц, можно сделать это быстрее или удобнее.
- Есть быстрое преобразование.
- Нужно попасть с нормировкой.
- Лучше всего начать с написания кода на C. Тогда можно сравниться с ним по скорости.
- Не нужно делить ответ на 4, т. к. преобразование линейное можно просто домножить коэффициентны
- Примеры входных и выходных данных:
input_fdct.txt
,output_fdct.txt
.
Требуется написать функцию, выполняющую преобразование числа в формате double precision в текстовую десятичную запись.
Прототип функции:
void dbl2str(const double *in, char *out_buf);
В результате выполнения функции в буфере должно быть записано текстовое 0-терминированное представление числа в виде:
+0.12345e5
То есть: знак числа, затем "0.", 1+ знаков мантиссы, "e", значение экспоненты (0 для нуля).
Должны также поддерживаться денормализованные и не-числа, которые выводятся в виде: +Inf
, -Inf
, NaN
.
Полученная запись должна удовлетворять требованию корректности: обратное преобразование должно дать исходное число при округлении к ближайшему чётному. А также требованию минимальной длины мантиссы. В случае нескольких минимальных вариантов - выбрать ближайший к центру диапазона. Лишние нули и знак "+" в экспоненте выводить не следует.
Конвенция вызова: fastcall64
. Не забывайте сохранять нужные регистры, если вы их изменяете.
Функция должна быть реализована в одном .asm
файле и не использовать каких-либо внешних функций, .asm
файл должен быть приложен к письму.
Использовать FPU
запрещается (не заморачивайтесь - он там совсем не нужен).
В буфер должно быть записано не больше 32 байт.
Оцениваться будет как правильность реализации (в частности, допускается несоответствие требованию минимальной длины для небольшого процента чисел), так и скорость работы.
На вход подается вещественное число с плавающей точной двойной точности. Известно, что оно задает диапазон чисел. Из этого диапазон нужно найти число, которое записывается кратчайшим способом в десятичной системе.
- Регистры общего назначения, сегментные, FPU, MMX, SSE, арифметические и логические команды (сложение, xor, сдвиги...), управляющие структуры (if, циклы, switch).
- Команды передачи управления (переходы, вызов функций, возврат), стандартные конвенции вызова функций (cdecl, stdcall, pascal, fastcall, thiscall, fastcall64, unix64).
- Команды пересылки данных, система адресации в командах.
- Режимы работы процессора. Защищённый режим и страничная адресация, их применение.
- SIMD расширения набора команд x86 (MMX и типы данных всех подробно; SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, SSE4A, AVX, AVX2, AVX512, FMA, AES-NI, BMI - обзорно).
- Новое и изменения в архитектуре x64 относительно x86.
Все вопросы подразумевают не только архитектуру x86, но и x64.
Кроме теоретического ответа я могу попросить вас написать небольшую программу, особенно в вопросе 5.