Статус: Активный участник
Группы: Участники
Зарегистрирован: 12.10.2009(UTC) Сообщений: 42
Сказал(а) «Спасибо»: 4 раз Поблагодарили: 6 раз в 6 постах
|
Какая жесть. Такие касты - это UB в чистом виде. Ведь можно же поприличнее структуру заполнить, без привязок к платформе: Код:
fileTime.dwLowDateTime = (DWORD)offset_ft;
fileTime.dwHighDateTime = (DWORD)(offset_ft >> 32);
Отредактировано пользователем 20 октября 2021 г. 18:59:13(UTC)
| Причина: Не указана
|
 1 пользователь поблагодарил KDA за этот пост.
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602  Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 396 раз в 366 постах
|
Заполнить не вопрос. Нужно сложение. А его в данном случае удобно делать только на ассемблере иначе намучаетесь с переносом. Cложение FILETIME тоже вряд ли определено. Хотя, если перенести поля FILETIME в offset_ft, сложить и перенести обратно, то может пойти. Отредактировано пользователем 20 октября 2021 г. 19:06:44(UTC)
| Причина: Не указана
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 12.10.2009(UTC) Сообщений: 42
Сказал(а) «Спасибо»: 4 раз Поблагодарили: 6 раз в 6 постах
|
Обратно из двух 32-битных собрать одно в 64 бита и сложить с третьим, даже с контролем переноса - для этого нужен ассемблер?
Стесняюсь спросить, это в промышленном ПО так? Не могли бы Вы его обозначить, чтобы избегать его при эксплуатации? :)
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602  Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 396 раз в 366 постах
|
Там это проще всего, без разборов/сборов, напрямую, благо есть MMX даже на 32-разрядных процессорах уже много лет. Собственно, при чем тут промышленное ПО, если это просто тупо ограничения компилятора. Все эти извращения появляются когда компилятор считает что-то невозможным (не переносимым на другие платформы). А я лучше напишу под каждую архитектуру отдельный код и разделю ifdef - не люблю доверять тому что наколбасит компилятор в машинном коде, пытаясь найти универсальность под разными платформами. Уже то что компилятор автоматом вставляет вызовы небезопасных функций работы со строками без ограничения длины много стоит. Майкрософт такие - нет Вам эту функцию использовать низя, она устаревшая и т.п. Но наш компилятор ее Вам вставит, хотите или нет, потому что мы такие офигенные и предусмотрели вообще все случаи когда компилятор ее может вставить и проанализировали их. Потом они же: обновление нашего продукта исправляет ошибку переполнения буфера. Отредактировано пользователем 20 октября 2021 г. 19:18:25(UTC)
| Причина: Не указана
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 12.10.2009(UTC) Сообщений: 42
Сказал(а) «Спасибо»: 4 раз Поблагодарили: 6 раз в 6 постах
|
А потом еще делать разные реализации под разные платформы. И писать простыни про особенности представления чисел на Intel и борьбу с компиляторами :) Впрочем, как я уже поправил выше, Ваш пример на С++ демонстрирует неопределенное поведение, и никакой ассемблер этому не поможет. Кстати, хорошо, что Microsoft вспомнили: В Visual Studio при сборке под 64 бита встроенного ассемблера все равно не предусмотрено, нужно колхозить с раздельной компиляцией :) Отредактировано пользователем 20 октября 2021 г. 19:24:12(UTC)
| Причина: Не указана
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602  Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 396 раз в 366 постах
|
Цитата:Ваш пример на С++ демонстрирует неопределенное поведение, Тогда выдохните, на С++ я не пишу, о чем тоже сказано выше. Сама терминология UB и подразумевает, что подстраиваетесь под компилятор и его закидоны. Не спорю, что это правильно и удобно в большинстве случаев, однако так же есть и раздражающие моменты когда знаешь что типы одинаковы, а компилятор считает что у них разное формальное описание, которое на какой-то из кучи поддерживаемых платформ отличается в поведении. Мне просто та платформа не нужна. Пока еще. Но ведь нет, все равно надо еще 33 раза переменную по частям скопировать, чтобы соответствовала формальностям. Ассемблер поможет. Как не на ассемблере увидите перенос? Потому и вспомнил, что не предусмотрели и потому решение на ассемблере не в кассу в вопросе про С++. Но для полноты (ничего делить не надо и так по 4 байта поделено): Код:// на самом деле маленькие локальные переменные располагаются в стеке, вместо ecx/edx используется esp
push ebx
push edx
lea ecx, fileTime
lea edx, offset_ft
// на всякий переместим в регистр
push ebx
mov ebx, [ecx]
add ebx, [edx]
mov [ecx], ebx
mov ebx, [ecx+4]
adc ebx, [edx+4]
mov [ecx+4], ebx
pop ebx
pop ecx
pop edx
Отредактировано пользователем 20 октября 2021 г. 20:07:20(UTC)
| Причина: Не указана
|
|
|
|
Статус: Активный участник
Группы: Участники
Зарегистрирован: 12.10.2009(UTC) Сообщений: 42
Сказал(а) «Спасибо»: 4 раз Поблагодарили: 6 раз в 6 постах
|
Наверное, пример на С++ и советы совладать с компилятором давал второй владелец аккаунта :) Ну и зачем писать про закидоны, если не владеете предметом? Все это прописано в стандарте языка, на уровнях undefined, unspecified and implementation-defined. Цитата:Мне просто та платформа не нужна. А вот автору нужна другая плаформа. Что, в принципе, было ясно по самому первому посту. С приведенным куском не понял, чем он лучше (ну, кроме желания блеснуть знаниями): - некомпилябельный. - неясный ABI - ошибок переполнения не ловит - offset из секунд надо считать отдельно. - нормальный С/C++ компилятор под эту платформу соберет практически как же или лучше. Собственно, демо к последнему. Обработка переполнения так же опущена, как и в остальных примерах Код:void __declspec(noinline) adjust_filetime(FILETIME& ft, int offset_secs)
{
ULONGLONG u_ft = (ULONGLONG(ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
LONGLONG i_off = (LONGLONG)offset_secs * 10000000;
u_ft += i_off;
ft.dwLowDateTime = (DWORD)u_ft;
ft.dwHighDateTime = (DWORD)(u_ft >> 32);
}
Выхлоп с MSVC 14.29.30133. И это без встраивания и с умножением Код:
mov eax,edx
mov edx,989680h
imul edx
add eax,0
adc edx,dword ptr [ecx+4]
add dword ptr [ecx],eax
adc edx,0
mov dword ptr [ecx+4],edx
ret
Отредактировано пользователем 20 октября 2021 г. 22:09:49(UTC)
| Причина: Не указана
|
 1 пользователь поблагодарил KDA за этот пост.
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 14.10.2021(UTC) Сообщений: 13  Сказал(а) «Спасибо»: 9 раз
|
Теперь уж точно разобрался, спасибо)
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close