Leroi_1, Самое простое - по строкам. Надо исходное изображение расширить хотя бы на 7 байт в конце, чтобы не было чтения за границей массива, а ваше ядро добить тремя 0 до ширины в 8 байт.
Потом вы для каждой из 5 строк вы загружаете в регистр строку ядра и строку исходного изображения (всегда на 2 пикселя левее). Векторно их перемножаете, суммируете и эти 5 чисел складываете в ответ. У вас на самом деле загрузятся еще 3 лишних значения правее - это будут или пиксели со следующей строки, или вообще нули в самом конце массива. Но тут нет проблемы, ибо в ядре там стоят 0 и они умножатся на 0.
Тут вы 25 операций векторизовали пятерками. Это работает легче всего, потому что данные лежат вот так по строкам. если вы попытаетесь 4 раза по 8, или 2 по 16 элеменов как-то загружать сразу, у вас все будет очень сложно и скорее всего даже медленнее.
Тут, правда, будет проблема с первыми двумя столбцами изображения - у вас же нет никаких пикселей левее.
Для обработки этого случая, вам придется загружать Input не с позиции на 2 пикселя левее, а на 1 или 0, но тогда и kernel придется читать со столбца 1/2 а не 0.
Для обработки крайних строк надо будет пропускать какие-то из этих 5 итераций цикла.
Или сильно проще будет, если в при загрузке изображения поместите его в рамочку из нулей шириной 2. Т.е. у вас будет +4 толбца и +4 строки.
Ланской Кирилл, Еще остались проблемы с логикой. Вам в соседнем ответе правильно подсказали - если в первом слове буква встречается несколько раз, то вы ее в ответ несколько раз и выведете.
Вообще ваш подход очень не оптимален. Может даже не пройдет по времени, если есть какая-то система тестирования.
Надо вам завести массив на 26 (или 256, если буквы не только английские бывают в словах) элементов, где вы будете помечать, есть ли у вас какая-то буква в текущем слове. Это может быть bitmask<26>, например.
Во втором таком же массиве вы должны также хранить те буквы, которые встречались во все словах.
Тогда вам надо выполнять логическую операцию И над каждым элементом этих двух массивов.
floppa322, В зависимости от того, что вам на самом деле надо делать со структурой данных, она может быть строго O(1), а не чуть лучше логарифма в среднем на некоторых данных.
но в дереве отрезков запрос именно можно сказать по 2-му параметру узлов - порядковому номеру,
Если в качестве диапазоно взять ключи, то у вас будет запрос по ключам. Но вообще, надо конкретно вашу задачу узнать. Вы там говорили, что данные не меняются, так что возможно какой-нибудь сортированный массив с одним бинпоиском может быть даже быстрее любой другой структуры данных.
Дмитрий, Тогда можно использовать FF. Оно, вроде, есть и там и там. Правда, там не так просто адрес будет указать. его надо куда-то в память или регистры сначала засунуть и уже вот это указывать в команде.
Наверное, вы правы и ret будет попроще, хоть и как-то уж вывернуто.
w3w3w3w3w3, Ну тогда делайте примерно то, что и делали. Только проблема похоже в том, что у вас не тот jmp используется. E9 - это Jump near. Не факт, что разница адресов укладывается в огрангичения. Попробуйте jump far, который с EA начинается.
Так что мой ответ в силе: Он выдает кривой код, потому что его не просили код оптимизировать. Ну вот такой дефолт у него сделать "на отвали". Имеет право.
Действительно clang 15 выдает плохой код. Но только если отключить оптимизацию (-O0). Если же оптимизацию включить, то константа исчезает.
Но, если оптимизация отключена, то никаких проблем нет. Ну вот просто умеет компилятор переводить список инициализации через константы. Имеет право. Если его не попросить код соптимизировать.
8iKS, В настоящем, не игрушечном исполняемом файле, если функция вам важна для взлома, то она вряд ли будет заинлайнена. В крайнем случае, вам придется патчить ту функцию, куда проверка аутентификации вставлена.
8iKS, А вы код auth ассемблерный тоже покажите - интересно.
А найти вы его не могли именно из-за инлайнинга функции, как я и говорил пару комметариев назад. Компилятор видит, что функция мелкая, вызывается в одном месте. Можно тупо ее код вставить вместо вызова и сэкономить ресурсы. Все-таки вызов - не бесплатное удовольствие. Очень много чего надо сохранить и восстановить после. Отключение оптимизаций дало бы такой же результат.
А потом, поскольку компилятор заинлайнил все вызовы функции, можно ее и не генерировать вообще в исполняемом файле.
В изменном коде компиялтор видит, что надо получить адрес функции. Поэтому ее нельзя выкинуть, у нее же адреса не будет. Вот и пришлось, ворча и кряхтя, таки, вставить функцию в исполняемый файл.
8iKS, Прокрутите вниз дизассемблерный код. Там, вроде, выводится "CALLED FUNCTION auth()" в 00007FF60BFA112D. Но до этого есть какие-то циклы, вызов методов класса и еще какие-то выводы.
Вам не кажется странным, что ваша элементарная функция auth() вышла вот такой вот портянкой? Это уже пропатченная функция что ли?
Дайте-ка еще полный код main. Всего файла. И напишите, каким компилятором и версией оно у вас собирается. Хочу посмотреть ассемблерный выхлоп у себя.
Я все еще 100% уверен, что по смещению +140 у вас совсем не auth(), а что-то другое. И оно ждет параметров функции - какие-то указатели на классы. Вы их не передаете, поэтому эта функция и падает.
8iKS, Да, точно, адрес же можно тупо вывести. Например из main() и из dllmain(). Не вызывая функцию вообще.
В дизассемблере видно, что это начало какой-то функции, но я не вижу там никакого вывода в cout. Это точно auth() из поста? Еще, не видно, что там ниже происходит.
Я вижу, что функция по A1040 ожидает что-то полезное в rcx, кажется указатель на указатель на структуру, положенное туда вызывателем. Но там оказывается что-то не то. По смыслу, это какой-то указатель должен быть в параметрах функции. Но auth() не принимает никаких параметров! Сдается мне, что оптимизатор заинлайнил auth() и ее в екзешнике тупо нет. А нашли вы и вызываете что-то не то.
Попробуйте сначала без оптимизаций auth скомпилировать (-O0), тогда ассемблерный код будет понятнее и ее не заинлайнит.
P.s. Вы, вижу, вопрос отредактирвали. Ваш дизассемблер main() показывает, что auth точно заинлайнена. Там нет ее вызова, а сразу вызвыаются функции cout. Удивительно, что там что-то по A1040 вообще есть. Вряд ли это ваша auth().
Кстати, добавив вывод адреса auth в main вы, вероятно, тоже добъетесь, что оптимизатор ее не выкинет.
Потом вы для каждой из 5 строк вы загружаете в регистр строку ядра и строку исходного изображения (всегда на 2 пикселя левее). Векторно их перемножаете, суммируете и эти 5 чисел складываете в ответ. У вас на самом деле загрузятся еще 3 лишних значения правее - это будут или пиксели со следующей строки, или вообще нули в самом конце массива. Но тут нет проблемы, ибо в ядре там стоят 0 и они умножатся на 0.
Тут вы 25 операций векторизовали пятерками. Это работает легче всего, потому что данные лежат вот так по строкам. если вы попытаетесь 4 раза по 8, или 2 по 16 элеменов как-то загружать сразу, у вас все будет очень сложно и скорее всего даже медленнее.
Тут, правда, будет проблема с первыми двумя столбцами изображения - у вас же нет никаких пикселей левее.
Для обработки этого случая, вам придется загружать Input не с позиции на 2 пикселя левее, а на 1 или 0, но тогда и kernel придется читать со столбца 1/2 а не 0.
Для обработки крайних строк надо будет пропускать какие-то из этих 5 итераций цикла.
Или сильно проще будет, если в при загрузке изображения поместите его в рамочку из нулей шириной 2. Т.е. у вас будет +4 толбца и +4 строки.