[Программирование, Assembler] Перевод числа в строку с помощью FPU
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Каждый человек увлекающийся программированием обязан написать свой вариант решения этой задачи. Я решил не быть исключением.В соответствии с x64 software conventions будем считать что число подлежащие конвертированию расположено в XMM0.Будем использовать x64 битный код при x32 битной адресации. Такой способ адресации позволяет использовать преимущества обоих диалектов.Сохраняем значение стека и создаем точку размещения данных выровненную про параграфу для повышения быстродействия:
; старт процедуры
mov r9d, esp
lea r8d,[r9d - 70h]
and r8d, 0FFFFFFF0h
mov esp, r8d
Подготавливаем FPU освобождая его от данных и устанавливаем повышенную точность и округление к нулю:
fsave [esp]
finit
mov dword ptr[esp - dword], 037F0F7Fh
fldcw [esp - dword]
Перегружаем число из XMM0 в FPU:
movd qword ptr[esp - xmmword], xmm0
fld qword ptr[esp - xmmword]
Находим десятичный порядок Числа:
fld st(0)
fxtract
fldl2t
fst st(1)
fdivr st(0),st(2)
frndint
Устанавливаем округление к ближайшему числу:
fldcw [esp - word]
Сохраняем порядок Числа и находим десятичный порядок Множителя для перевода значащих цифр Числа в целую часть:
fist dword ptr[esp - dword]
movzx edx, word ptr[esp - dword]
mov dword ptr[esp - dword], 10h
fisubr dword ptr[esp - dword]
Находим десятичный Множитель и перемножаем его на Число:
fmulp st(1),st(0)
fst st(1)
frndint
fsub st(1),st(0)
fld1
fscale
fstp st(1)
fmulp st(2),st(0)
f2xm1
fld1
faddp st(1),st(0)
fmulp st(1),st(0)
frndint
Перегружаем полученное число из FPU в регистры AX и XMM0 в размере 2 первых и 8 последующих байтов соответственно. При загрузки 8 байт в регистр XMM0 одновременно меняем порядок расстановки байт за счет предварительного выравнивания указателя стека по параграфу:
fbstp tbyte ptr[esp - xmmword]
mov ax, word ptr[esp - qword]
pshuflw xmm0, xmmword ptr[esp - xmmword], 00011011b
Восстанавливаем состояние FPU:
frstor [esp]
Переставляем байты регистра ХММ0 до состояния их полного разворота с одновременным удвоением:
punpcklbw xmm0, xmm0
pshuflw xmm0, xmm0, 10110001b
pshufhw xmm0, xmm0, 10110001b
Загружаем маску и разделяем числовые тетрады:
mov dword ptr[esp], 0FF00FF0h
pshufd xmm1, xmmword ptr[esp], 0
pand xmm0, xmm1
psrlw xmm1, 4
movdqa xmm2, xmm1
pand xmm1, xmm0
psrlw xmm1, 4
pandn xmm2, xmm0
paddb xmm1, xmm2
Создаем маску и находим байты содержащие значащие цифры:
pxor xmm0, xmm0
pcmpeqb xmm0, xmm1
Преобразуем числа в соответствующие им символы:
mov dword ptr[esp], 30303030h
pshufd xmm2, xmmword ptr[esp], 0
paddb xmm1, xmm2
Преобразуем первые два байта числа в символы и сохраняем их в память:
mov byte ptr[esp],'-'
btr ax, 0Fh
adc esp, 0
add ax,'.0'
mov word ptr[esp], ax
Находим длину значащей части числа в регистре ХММ0 :
movdqu xmmword ptr[esp + word], xmm1
pmovmskb ecx, xmm0
bsf ecx, ecx
add esp, ecx
Проверка порядка Числа на нулевое значение и отрицательную величину:
mov ecx,(word + dword)
mov eax, edx
neg dx
jnc @f
cmovns eax, edx
setns dh
Преобразуем значение порядка числа в символы и сохраняем их в память:
cmp ax, 0Ah
sbb ecx, ecx
mov dl, 0Ah
div dl
cmp al, 0Ah
sbb ecx, 0
shl eax, 8
shr ax, 8
div dl
add eax, 303030h
lea edx,[edx * 2 + 2B51h]
mov dword ptr[esp + word + ecx + word], eax
mov word ptr[esp + word], dx
Вычисляем длину числа и сохраняем ее в регистрах EAX и ECX:
@@: lea ecx,[esp + ecx + qword]
sub ecx, r8d
mov eax,ecx
Сохраняем строку символов в паре регистров XMM1 и XMM2:
movdqa xmm1, xmmword ptr[r8d]
movdqa xmm2, xmmword ptr[r8d + xmmword]
Восстанавливаем значение стека:
mov esp, r9d
Выходим из процедуры.В своем коде я применяю недокументированное соглашение о передаче / возврате из функции множественных параметров. Соглашение абсолютно зеркально соглашению x64 software conventions за тем исключением что описывает правила размещения параметров при выходе из процедуры.Зачем писать этот код если уже есть готовые решения - потому что мое решение лучше.Чем оно лучше других - мой код прямой и не имеет циклов или ветвлений, а также содержит минимальное количество обращений к памяти.Зачем писать его на ассемблере если есть другие более удобные языки - потому что ассемблер лучше.Чем ассемблер лучше в данном случае - полным доступом к SIMD и FPU командам.Лишь часть данного кода векторная, вычисление числа скалярно - это не выполнимое требование так как при вызове процедуры ей передается только одно число.
===========
Источник:
habr.com
===========
Похожие новости:
- [Разработка веб-сайтов, PHP, Программирование] Enum в PHP 8.1 — для чего нужен enum, и как реализован в PHP
- [Разработка веб-сайтов, Программирование] Custom Elements из Angular в Angular
- [Программирование, Assembler, Научно-популярное, Старое железо, DIY или Сделай сам] Пишем программу для компьютера ALTAIR 8800 1975г выпуска
- [Программирование, Rust] Размышления о Rust
- [Программирование] Mutation Driven Development
- [Python, Программирование, Django] Конвертеры маршрутов в Django 2.0+ (path converters)
- [Программирование, Go] Создаем бессерверное приложение с помощью Azure Functions и Go (перевод)
- [Системное администрирование, Программирование, Кодобред, *nix, Оболочки] Консольный менеджер сертификатов для JKS/PCKS12
- [Open source, Программирование, Совершенный код, C++] Исследование COVID-19 и неинициализированная переменная
- [Open source, Программирование, Совершенный код, C++] COVID-19 Research and Uninitialized Variable
Теги для поиска: #_programmirovanie (Программирование), #_assembler, #_assembler (ассемблер), #_programiirovanie (програмиирование), #_programmirovanie (
Программирование
), #_assembler
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 25-Ноя 03:06
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Каждый человек увлекающийся программированием обязан написать свой вариант решения этой задачи. Я решил не быть исключением.В соответствии с x64 software conventions будем считать что число подлежащие конвертированию расположено в XMM0.Будем использовать x64 битный код при x32 битной адресации. Такой способ адресации позволяет использовать преимущества обоих диалектов.Сохраняем значение стека и создаем точку размещения данных выровненную про параграфу для повышения быстродействия: ; старт процедуры
mov r9d, esp lea r8d,[r9d - 70h] and r8d, 0FFFFFFF0h mov esp, r8d fsave [esp]
finit mov dword ptr[esp - dword], 037F0F7Fh fldcw [esp - dword] movd qword ptr[esp - xmmword], xmm0
fld qword ptr[esp - xmmword] fld st(0)
fxtract fldl2t fst st(1) fdivr st(0),st(2) frndint fldcw [esp - word]
fist dword ptr[esp - dword]
movzx edx, word ptr[esp - dword] mov dword ptr[esp - dword], 10h fisubr dword ptr[esp - dword] fmulp st(1),st(0)
fst st(1) frndint fsub st(1),st(0) fld1 fscale fstp st(1) fmulp st(2),st(0) f2xm1 fld1 faddp st(1),st(0) fmulp st(1),st(0) frndint fbstp tbyte ptr[esp - xmmword]
mov ax, word ptr[esp - qword] pshuflw xmm0, xmmword ptr[esp - xmmword], 00011011b frstor [esp]
punpcklbw xmm0, xmm0
pshuflw xmm0, xmm0, 10110001b pshufhw xmm0, xmm0, 10110001b mov dword ptr[esp], 0FF00FF0h
pshufd xmm1, xmmword ptr[esp], 0 pand xmm0, xmm1 psrlw xmm1, 4 movdqa xmm2, xmm1 pand xmm1, xmm0 psrlw xmm1, 4 pandn xmm2, xmm0 paddb xmm1, xmm2 pxor xmm0, xmm0
pcmpeqb xmm0, xmm1 mov dword ptr[esp], 30303030h
pshufd xmm2, xmmword ptr[esp], 0 paddb xmm1, xmm2 mov byte ptr[esp],'-'
btr ax, 0Fh adc esp, 0 add ax,'.0' mov word ptr[esp], ax movdqu xmmword ptr[esp + word], xmm1
pmovmskb ecx, xmm0 bsf ecx, ecx add esp, ecx mov ecx,(word + dword)
mov eax, edx neg dx jnc @f cmovns eax, edx setns dh cmp ax, 0Ah
sbb ecx, ecx mov dl, 0Ah div dl cmp al, 0Ah sbb ecx, 0 shl eax, 8 shr ax, 8 div dl add eax, 303030h lea edx,[edx * 2 + 2B51h] mov dword ptr[esp + word + ecx + word], eax mov word ptr[esp + word], dx @@: lea ecx,[esp + ecx + qword]
sub ecx, r8d mov eax,ecx movdqa xmm1, xmmword ptr[r8d]
movdqa xmm2, xmmword ptr[r8d + xmmword] mov esp, r9d
=========== Источник: habr.com =========== Похожие новости:
Программирование ), #_assembler |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 25-Ноя 03:06
Часовой пояс: UTC + 5