Re[15]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 04:32
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Сколько раз писал mov eax, 0 — ошибок, связанных с тем, что при этом меняется EIP — не было. Другие были


GN>Вопрос в решаемых задачах.


А можно пример, когда при mov eax, 0 я должен учитывать изменениие EIP ? Не просто помнить, а вот... если забуду про его изменение, то эта команда или следующая за ней неправильно (в любом смысле) сработает ?

GN>>>Из известных примеров — Windows при обработке 2х байтного int 3.


PD>>М.б. Я честно сказать, не в курсе — вроде он был однобайтный. Мне такое самому писать не доводилось.


GN>здесь


Спасибо.

PD>>За нашу и вашу свободу!


GN>


GN>>>При этом, в зависимости от размера my_subroutine, может быть сделан "автоматический" выбор — инлайн, или call.


PD>>Ну и прекрасно. То же, что и с inline в С — то ли будет, то ли нет, в зависимости от опций и настроения компилятора и фазы Луны. Еще есть __forceinline


GN>Это все подконтрольно на самом деле.


Относительно.

MSDN:

The compiler treats the inline expansion options and keywords as suggestions. There is no guarantee that functions will be inlined. You cannot force the compiler to inline a particular function, even with the __forceinline keyword.

GN>Потому что макросы якобы не есть Дзен и ведут к Немерло


Я убежденный атеист . Это раз. А в Немерло они вести не могут — когда они появились, его и в зародыше не было.

>>>и писать всё как настоящий джедай руками


PD>>В кодах ?


GN>На чистом ассемблере.


В кодах лучше


GN>Кстати, о ret. Мнемоника у неё retn. MASM понимает ret и автоматом подставит retn 8 при 2х входных параметрах stdcall подпрограммы. Говоря другими словами, команда перегружена В случае proc MASM ведёт себя как компилятор, можно даже представить себе транслятор который пойдёт дальше и будет инлайнить Хотя вряд ли кто будет писать — можно на макросах делать.


+1

PD>>Не увиливай. Я ничего не говорил о вызове и размере. Может, конечно. Только вот если код встраивается вместо вызова — это просто встраивание кода, а не вызов.


GN>Я дополняю условия задачи до разумных, подпрограмма без вызова никому не нужна. А куда её встроит гипотетический транслятор — 80% его пользователей даже и не заметят


Ну и пусть не заметят. Кому надо — заметит. Да и остальные тоже — им отладку вести-то надо ?

PD>>Scheme я не знаю и маргинальными языками не интересуюсь.


GN>Хм. Ну... тогда следует читать "LISP". Кстати создавали его что бы записывать алгоритмы для ассемблера. СОвременные макросы являются его жалким наследием


Можешь не соглашаться, но ИМХО это тоже маргинал. При всем моем уважении к нему и к пишущим на нем.

PD>> Можно пример из какого-нибудь известного большинству языка? Pascal, C, C++, Java, C#, Basic, Fortran ...


GN>А к чему ограничиваться этим списком?


А все же ? Я привел почти все "большие" языки. Думаю, 95 , если не 99% ПО написано на них. И если уж в них пример тебе найти не удается, а надо привлекать оставшиеся 1-5%, то это значит, что прием, мягко говоря, не слишком популярный.

GN>Ок, возмём С: setjmp, CreateFiber, atexit() да и вообще разные колбэки. В С++ добавляются try {} catch {} Но это конечно цветочки...


И что тут за трюки ? Вызов функции по указателю (колбэк) или же SEH (на базе которой реализован try-catch) ?

PD>>Может. При условии, что в том языке/системе это принято. В свое время (Win16) была calling conention Pascal (слева направо, стек очищает вызываемая). Если кто-то сейчас решится ее использовать -это будет ничем не оправданный трюк.


GN>Этот — да. И это не отменяет возможную полезность других. На ассемблере каждый... пишет как он хочет (как лучше для решения задачи).


Да бога ради, я согласен. Пока нет стыковки с модулями на ЯВУ.

> Всё это "как принято" должно изучаться и писаться на других языках.


Не получится.

>Иначе на ассемблере не научиться, и писать смысла тоже нет — разве что времени куча.


Смысл написания (для меня) чего-то на асме — ускорение некоего кода. И только. Хакерством я переболел давно.

PD>>Я так подозреваю, что Hello, World в твоем определении тоже рекурсивна


GN>Это вызов API (с побочным эффектом).


With best regards
Pavel Dvorkin
Re[13]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 04:36
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


GN>>>Да, новой не является. Пример с ASCIIZ — широко известный из учебников частный случай. И, что странно — зная про ASCIIZ, люди продолжают писать первый вариант цикла обработки битов. Попробу найти хоть одного человека, кто напишет 2й (можно изменить условия задачи, что бы было решабельно на ЯВУ).


PD>>Ну посмотри, например, ассемблерный код strlen. Зная про ASCIIZ, люди из MS тем не менее не стали реализовать тупой проход (зато простой и понятный! ах как хорошо понятный , а устроили работу с DWORDами, далеко не столь ясную, да еще и на ассемблере. Из чего следует, что не все так просто, как тебе кажется. Как минимум — надо померить и тот,и другой алгоритмы по скорости.


GN>Эх забыл я что тут любят уводить разговор в сторону и купился.


Тут и не такое любят

>Ответа на мой вопрос нет. Лаконичного императивного описания 2го кода отсюда
Автор: gear nuke
Дата: 28.09.09
нет и не будет. Ну и не надо: отрицательный результат — тоже результат


Смотреть весь тред лень, да и при одновременной дискуссии с тобой и FR я не всегда уже помню, кто из вас что сказал . Здесь я вопроса не вижу, только твое высказывание и мой ответ. Повтори, пожалуйста, вопрос.
With best regards
Pavel Dvorkin
Re[23]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 04:41
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Это многое говорит о твоих задачах.


Ты прав, как всегда . Не бывает сложных задач без рекурсии, ну не бывает, и все
With best regards
Pavel Dvorkin
Re[30]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 01.10.09 04:49
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Неубедительно. Платформы разные, но и библиотеки тоже разные. Я не знаю Unix, но сомневаюсь, что код strcpy берется там из *.lib файла


А какая разница откуда берется если транслируется из си.

PD>Ассемблер был еще в Турбо Паскале.


В те времена он везде был. Сейчас необходимости в нем нет.

PD>Наоборот. Это самый быстрый код. Быстрее, чем std::string. На эту тему в форуме C++ много было.


И string.h и std::string непроходимые тормоза. Первый из-за asciiz, второй из-за динамического выделения памяти. И рекламировать их все-равно что рекламировать супер оптимизированную написанную на ассемблере сортировку пузырьком.
Re[21]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 05:07
Оценка:
Здравствуйте, gandjustas, Вы писали:

PD>>Есть набор байтов, заканчивающийся нулем, найти сколько там байтов до нуля. Абстрактно, никакие не строки.

G>Ну покажи хоть одну реальную структуру, кроме asciiz строк, которая так выглядит.

Линейный список. Количество элементов неизвестно, последний элемент имеет .pNext == 0. Логически то же самое.
Строка в текстовом файле. Завершающий символ, правда, не один, а два — CR/LF.

G>А вот если еще более общий случай рассмотерть, такой как список, у которого голова и хвост, то именно на таких структурах используется рекурсия.


Упаси боже меня от рекурсии на линейных списках. Мне только стек дергать на ровном месте не хватало. Еще, чего доброго, его переполнишь.

Кстати, в дотнете разве в классах коллекций для IList используется рекурсия для основных действий ? Нет. Вот тебе пример. Класс LinkedList


public LinkedListNode<T> Find(T value)
{
    LinkedListNode<T> head = this.head;
    EqualityComparer<T> comparer = EqualityComparer<T>.Default;
    if (head != null)
    {
        if (value != null)
        {
            do
            {
                if (comparer.Equals(head.item, value))
                {
                    return head;
                }
                head = head.next;
            }
            while (head != this.head);
        }
        else
        {
            do
            {
                if (head.item == null)
                {
                    return head;
                }
                head = head.next;
            }
            while (head != this.head);
        }
    }
    return null;
}


А уж казалось бы, как красиво можно поиск рекурсивно организовать! Но что-то они не стали. Правильно не стали

G>Кстати asciiz строка и является таким списком:

G>если p — char*, то получение головы — *p, хвоста — p+1, пустой список *p == NULL.

PD>>Такая задача может возникнуть, или же, коль скоро в С такое используют для С-строк, надо эту задачу анафеме предать ?

G>Ну покажи хоть один реальный пример, иначе анафеме предаем.

Показал. Твой же пример
With best regards
Pavel Dvorkin
Re[31]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 05:16
Оценка: :)
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Неубедительно. Платформы разные, но и библиотеки тоже разные. Я не знаю Unix, но сомневаюсь, что код strcpy берется там из *.lib файла


FR>А какая разница откуда берется если транслируется из си.


А ты в этом уверен ? У тебя же исходников нет

PD>>Ассемблер был еще в Турбо Паскале.


FR>В те времена он везде был. Сейчас необходимости в нем нет.


Для кого нет, для кого есть

PD>>Наоборот. Это самый быстрый код. Быстрее, чем std::string. На эту тему в форуме C++ много было.


FR>И string.h и std::string непроходимые тормоза. Первый из-за asciiz, второй из-за динамического выделения памяти.


А можно поинтересоваться, в каких системах и библиотеках умеют создавать строки произвольной длины без динамического выделения памяти ? В С# ?

Это раз. А во-вторых, тебе не кажется, что ты слишком много голословных утверждений делаешь ? Приведи данные с измерением времени, из которых следует, что char* медленнее, чем нечто иное, пусть и не в С/C++, тогда и поговорим.

>И рекламировать их все-равно что рекламировать супер оптимизированную написанную на ассемблере сортировку пузырьком.


В огороде бузина, а в Киеве дядька.
With best regards
Pavel Dvorkin
Re[7]: Зачем нужны циклы если есть рекурсивные функции
От: LaptevVV Россия  
Дата: 01.10.09 05:26
Оценка: +1
Здравствуйте, gear nuke, Вы писали:

LVV>>Не... Это не совсем регистр ОБЩЕГО назначения.

GN>Я говорю не о 80286, а о 32ти битном режиме. Он ничем не хуже EDX.
Я тоже. Но EDX не изменяется автоматически при выполнении команды CALL, a ESP — изменяется.
LVV>> Он является СПЕЦИАЛИЗИРОВАННЫМ регистром для указания именно вершины стека, поскольку и при выполнении команд CALL и ret,
GN>Не "поскольку", а "в случаях, когда используются".
А используется он как раз при обращении к стеку — во всех стековых командах, при вызове подпрограмме и возврате из нее, при прерываниях и возврате из него.
LVV>> Мы не можем задать ДРУГОЙ регистр, который вел бы себя аналогичным образом.
GN>Если не вызывать внешнее API — можем.
Нет. Похожим образом АВТОМАТИЧЕСКИ ведут себя еще индексные регистры. Но при использовании остальных мы должны ЯВНО программировать поведение.
LVV>> И именно это неявное изменение и позволяет реализовать рекурсивные вызовы непосредственно на ассемблере. Таким образом, механизм поддержки рекурсии заложен непосредственно в архитектуру.
GN>Не вижу связи. "Неявное" (то есть описанное в доке) изменение можно всегда заменить не более чем парой отдельных команд. Intel C++ так делает при вызове stdcall API
Промоделировать. естественно, можно все. На машине без стека вполне можно выделить один регистр для этого дела и моделировать стек — нефиг делать. Но это означает, что в архитектуре отсутствуют некоторые возможности.
LVV>>То, что параметры при рекурсии складываются в стек, это необходимость для повторного входа. Но в архитектуре это не поддерживается и возлагается на программиста.
GN>Параметры при рекурсии могут передаваться в регистрах. Как в моих примерах. И если есть call — то же могут.
Только при этом придется моделировать стек в виде сохранения предыдущих значений переменных.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[32]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 01.10.09 05:38
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А ты в этом уверен ? У тебя же исходников нет


Да мне пофиг


PD>Для кого нет, для кого есть


Тогда он был необходим, сейчас нет, это очень большая разница.

FR>>И string.h и std::string непроходимые тормоза. Первый из-за asciiz, второй из-за динамического выделения памяти.


PD>А можно поинтересоваться, в каких системах и библиотеках умеют создавать строки произвольной длины без динамического выделения памяти ? В С# ?


То что в других системах тоже надо выделять память никак ни отменяет того факта что для std::string это сделано бездарно.
Ну и даже в C++ на типичных задачах парсинга можно почти полностью обходится без выделения памяти, срезы рулят.

PD>Это раз. А во-вторых, тебе не кажется, что ты слишком много голословных утверждений делаешь ? Приведи данные с измерением времени, из которых следует, что char* медленнее, чем нечто иное, пусть и не в С/C++, тогда и поговорим.


Я писал парсеры на C++. Использовал срезы типа этих http://rsdn.ru/forum/src/2287365.1.aspx
Автор: c-smile
Дата: 02.01.07
, до этого были два не мной написанных варианта сначала на std::string, потом ускорили этот вариант переписав часть алгоритмов практически на чистый си. Я писал заново сразу на срезах ускорение на больших файлах почти в 10 раз.
Данные привести не могу, писать заново тесты интереса нет.
Re[22]: Зачем нужны циклы если есть рекурсивные функции
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.10.09 05:48
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, gandjustas, Вы писали:


PD>>>Есть набор байтов, заканчивающийся нулем, найти сколько там байтов до нуля. Абстрактно, никакие не строки.

G>>Ну покажи хоть одну реальную структуру, кроме asciiz строк, которая так выглядит.

PD>Линейный список. Количество элементов неизвестно, последний элемент имеет .pNext == 0. Логически то же самое.

Да, но это уже не последовательность байтов, а следовательно супер-пупер оптимизированный ассемблерный вариант, типа strlen не подойдет.

PD>Строка в текстовом файле. Завершающий символ, правда, не один, а два — CR/LF.

Ну опять вернулись к строкам...

G>>А вот если еще более общий случай рассмотерть, такой как список, у которого голова и хвост, то именно на таких структурах используется рекурсия.

PD>Упаси боже меня от рекурсии на линейных списках. Мне только стек дергать на ровном месте не хватало. Еще, чего доброго, его переполнишь.
Ты уже забыл что даже компиляторы C умеют оптимизировать хвостовую рекурсию?

PD>Кстати, в дотнете разве в классах коллекций для IList используется рекурсия для основных действий ? Нет. Вот тебе пример. Класс LinkedList

PD>А уж казалось бы, как красиво можно поиск рекурсивно организовать! Но что-то они не стали. Правильно не стали
Потому что в компиляторе C# оптимизации хвостовой рекурсии нет.
Вот в F# есть, там многие операции так реализованы.

G>>Кстати asciiz строка и является таким списком:

G>>если p — char*, то получение головы — *p, хвоста — p+1, пустой список *p == NULL.

PD>>>Такая задача может возникнуть, или же, коль скоро в С такое используют для С-строк, надо эту задачу анафеме предать ?

G>>Ну покажи хоть один реальный пример, иначе анафеме предаем.
PD>Показал. Твой же пример
Какой?
Re[16]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 05:57
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А можно пример, когда при mov eax, 0 я должен учитывать изменениие EIP ? Не просто помнить, а вот... если забуду про его изменение, то эта команда или следующая за ней неправильно (в любом смысле) сработает ?


Модификация кода во время выполнения. Да вот свежий пример. Ладно бы только в таком контексте втстречалось... Проблема настолько серьёзна, что MS придумали hotpatchable images. Кстати решается на любом языке имеющем interlocked операции, или способном вызывать WinAPI.

PD>MSDN:


PD>The compiler treats the inline expansion options and keywords as suggestions. There is no guarantee that functions will be inlined. You cannot force the compiler to inline a particular function, even with the __forceinline keyword.


Случаи, когда __forceinline не будет работать (например, когда есть взятие адреса функции) описаны в том же MSDN.

PD>Я убежденный атеист .


Атеизм — всего лишь другая вера.

PD>И что тут за трюки ? Вызов функции по указателю (колбэк) или же SEH (на базе которой реализован try-catch) ?


Да, в том-то и дело, что это не трюки Почему же это трюки когда речь идёт об асме

GN>>Этот — да. И это не отменяет возможную полезность других. На ассемблере каждый... пишет как он хочет (как лучше для решения задачи).


PD>Да бога ради, я согласен. Пока нет стыковки с модулями на ЯВУ.


Это говорит лишь об ограниченности взгляда на реальное положение вещей. Сейчас асм используется разве что в малваре, а там API может запросто вызываться через хитрый переходник, который найдёт экспорт по хешу имени, достанет через задницу откуда-то параметры, поксорит дворды и вызовет функцию посредством retn. Потому что авторы знают — аналитик, изучавший ассемблер на примере masm'овского while — будет смотреть на код как баран на новые ворота.

>> Всё это "как принято" должно изучаться и писаться на других языках.


PD>Не получится.


Хм. Ну... я могу привести пример, что нельзя сделать в рамках С++ и придётся использовать ассемблер — зарегистрировать хендлер как safeseh в таблице PE. Какие есть еще варианты?

>>Иначе на ассемблере не научиться, и писать смысла тоже нет — разве что времени куча.


PD>Смысл написания (для меня) чего-то на асме — ускорение некоего кода. И только. Хакерством я переболел давно.


В 99% случаев это бесполезная трата времени. Пока счёт 1:0
Автор: gear nuke
Дата: 30.09.09
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[14]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 05:57
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Смотреть весь тред лень, да и при одновременной дискуссии с тобой и FR я не всегда уже помню, кто из вас что сказал . Здесь я вопроса не вижу, только твое высказывание и мой ответ. Повтори, пожалуйста, вопрос.


Прошу прощения, забыл про почтовых клиентов

Есть 32 бита в регистре (не конь в вуккуме, а, например, маска пикселей) нужно их как-то обработать по-одному. Как будет решаться задача императивно, циклом? В лоб:
    mov eax, [pixels]  
    mov ecx, 32  
@@: shr eax, 1  ; копируем очередной бит в Carry Flag
    ;
    ; тут что-то делаем с битом
    ;
    dec ecx  ; итерируем цикл
    jnz @b

Если немного подумать, то на ассемблере это делается так:
    mov eax, [pixels]
    stc    ; используем Carry Flag как "маркер" конца битовой последовательности.
@@: rcr eax, 1 ; копируем очередной бит в Carry Flag. за счёт цикличности сдвига, меркер перейдёт в младший бит на первом проходе.
    ;
    ; тут что-то делаем с битом
    ;
    or  eax, eax  ; проверяем, остался ли бит маркера.
    jnz @b

Счётчик цикла убран за не надобностью тратить лишний регистр. Как бы так "императивно" объяснить вышепроисходящее, без упоминаний о битах? С другой стороны, можно сказать что здесь рекурсивный вызов, где параметром передаётся "остаток" последовательности.

Если есть возможность — попробуйте провести экспеимент на студентах, как много способны написать 2й вариант. Можно даже на ЯВУ, если изменить условия задачи. Мой прогноз: без подсказок — 0.1%. Со strlen на самом деле мало общего.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[33]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 06:01
Оценка:
Здравствуйте, FR, Вы писали:

FR>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>А ты в этом уверен ? У тебя же исходников нет


FR>Да мне пофиг





PD>>Для кого нет, для кого есть


FR>Тогда он был необходим, сейчас нет, это очень большая разница.


Для кого необходим, а для кого и нет

FR>>>И string.h и std::string непроходимые тормоза. Первый из-за asciiz, второй из-за динамического выделения памяти.


PD>>А можно поинтересоваться, в каких системах и библиотеках умеют создавать строки произвольной длины без динамического выделения памяти ? В С# ?


FR>То что в других системах тоже надо выделять память никак ни отменяет того факта что для std::string это сделано бездарно.


Согласен. Но я его и не использую. Мне char* хватит. Он не сделан бездарно

FR>Ну и даже в C++ на типичных задачах парсинга можно почти полностью обходится без выделения памяти, срезы рулят.


Я и не для парсинга обхожусь .

PD>>Это раз. А во-вторых, тебе не кажется, что ты слишком много голословных утверждений делаешь ? Приведи данные с измерением времени, из которых следует, что char* медленнее, чем нечто иное, пусть и не в С/C++, тогда и поговорим.


FR>Я писал парсеры на C++. Использовал срезы типа этих http://rsdn.ru/forum/src/2287365.1.aspx
Автор: c-smile
Дата: 02.01.07
, до этого были два не мной написанных варианта сначала на std::string, потом ускорили этот вариант переписав часть алгоритмов практически на чистый си. Я писал заново сразу на срезах ускорение на больших файлах почти в 10 раз.


Я что-то не понял, что ты этим хочешь сказать ? Что std::string барахло ? Согласен. Что можно сделать умнее, чем просто аллоцировать новую строку каждый раз, когда она нужна ? Тоже согласен. Есть еще, кстати, strtok, она как раз делит строку на фрагменты без выделения новой памяти вообще, правда, портит исходную строку. Но какое это отношение имеет к твоему утверждению, что ASCIIZ очень медленный ?


Не надо открывать Америки. strtok — почти та же идея.


FR>Данные привести не могу, писать заново тесты интереса нет.
With best regards
Pavel Dvorkin
Re[22]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 01.10.09 06:05
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:


PD>Упаси боже меня от рекурсии на линейных списках. Мне только стек дергать на ровном месте не хватало. Еще, чего доброго, его переполнишь.


Вся функциональщина живет на рекурсивных алгоритмах на линейных списках, стек при этом никуда не дергается.


PD>А уж казалось бы, как красиво можно поиск рекурсивно организовать! Но что-то они не стали. Правильно не стали


Если язык и рантайм позволяют то организуют:

let rec find p = function
  | [] -> raise Not_found
  | x :: l -> if p x then x else find p l




_camlFind000__find_59:
    subl    $12, %esp
L102:
    movl    %eax, %edx
    cmpl    $1, %ebx
    je    L100
    movl    %ebx, 0(%esp)
    movl    %edx, 4(%esp)
    movl    (%ebx), %eax
    movl    %eax, 8(%esp)
    movl    (%edx), %ecx
    movl    %edx, %ebx
    call    *%ecx
L103:
    cmpl    $1, %eax
    je    L101
    movl    8(%esp), %eax
    addl    $12, %esp
    ret
    .align    16
L101:
    movl    0(%esp), %eax
    movl    4(%eax), %ebx
    movl    4(%esp), %eax
    jmp    L102
    .align    16
L100:
L104:    movl    _caml_young_ptr, %eax
    subl    $8, %eax
    movl    %eax, _caml_young_ptr
    cmpl    _caml_young_limit, %eax
    jb    L105
    leal    4(%eax), %eax
    movl    $1024, -4(%eax)
    movl    $_caml_exn_Not_found, (%eax)
    movl    _caml_exception_pointer, %esp
    popl    _caml_exception_pointer
    ret
L105:    call    _caml_call_gc
L106:    jmp    L104
    .text
    .align    16
    .globl    _camlFind000__fun_72
_camlFind000__fun_72:
L107:
    pushl    %ebx
    pushl    %eax
    movl    $_caml_equal, %eax
    call    _caml_c_call
L108:
    addl    $8, %esp
    ret
Re[17]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 06:21
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>А можно пример, когда при mov eax, 0 я должен учитывать изменениие EIP ? Не просто помнить, а вот... если забуду про его изменение, то эта команда или следующая за ней неправильно (в любом смысле) сработает ?


GN>Модификация кода во время выполнения.


Ну я же говорю, что тебя трюки в основном и привлекают



PD>>MSDN:


PD>>The compiler treats the inline expansion options and keywords as suggestions. There is no guarantee that functions will be inlined. You cannot force the compiler to inline a particular function, even with the __forceinline keyword.


PD>>Я убежденный атеист .


GN>Атеизм — всего лишь другая вера.


Это в СВ

PD>>И что тут за трюки ? Вызов функции по указателю (колбэк) или же SEH (на базе которой реализован try-catch) ?


GN>Да, в том-то и дело, что это не трюки Почему же это трюки когда речь идёт об асме


Ей-богу, ничего не понял.

GN>>>Этот — да. И это не отменяет возможную полезность других. На ассемблере каждый... пишет как он хочет (как лучше для решения задачи).


PD>>Да бога ради, я согласен. Пока нет стыковки с модулями на ЯВУ.


GN>Это говорит лишь об ограниченности взгляда на реальное положение вещей. Сейчас асм используется разве что в малваре, а там API может запросто вызываться через хитрый переходник, который найдёт экспорт по хешу имени, достанет через задницу откуда-то параметры, поксорит дворды и вызовет функцию посредством retn. Потому что авторы знают — аналитик, изучавший ассемблер на примере masm'овского while — будет смотреть на код как баран на новые ворота.





GN>Хм. Ну... я могу привести пример, что нельзя сделать в рамках С++ и придётся использовать ассемблер — зарегистрировать хендлер как safeseh в таблице PE.


Хм, а почему это нельзя ? Указатели вроде не отменили, запись по ним тоже.

>Какие есть еще варианты?


Скорость. Остальное меня мало интересует. Я не исследую малваре, а поэтому не буду искать переходники по хешу, доставть параметры из ... , ксорить дворды и вызывать функцию посредством ret . Я предпочту созерцать новые ворота вместо этого . А вот скорость меня интересует, когда ее можно улучшить.

>>>Иначе на ассемблере не научиться, и писать смысла тоже нет — разве что времени куча.


PD>>Смысл написания (для меня) чего-то на асме — ускорение некоего кода. И только. Хакерством я переболел давно.


GN>В 99% случаев это бесполезная трата времени. Пока счёт 1:0
Автор: gear nuke
Дата: 30.09.09


Ну и аргумент. Ты хоть посмотри, что __readfsdword делает. Это же встраивание машинных команд и есть
With best regards
Pavel Dvorkin
Re[32]: Зачем нужны циклы если есть рекурсивные функции
От: Klapaucius  
Дата: 01.10.09 06:23
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А можно поинтересоваться, в каких системах и библиотеках умеют создавать строки произвольной длины без динамического выделения памяти ? В С# ?


Вопрос во-первых, в том, сколько динамической памяти выделяется. Выделить подстроку можно, например, выделяя константное кол-во памяти, а не линейное. И результат конкатенации строк длинной N и K можно получить выделяя константное или логарифмическое кол-во памяти, а не N+K.
А во-вторых в том, что выделение памяти в разных менеджерах памяти будет стоить разного времени.

>>И рекламировать их все-равно что рекламировать супер оптимизированную написанную на ассемблере сортировку пузырьком.

PD>В огороде бузина, а в Киеве дядька.

Да нет, намек достаточно прозрачен. Есть мнение, что асимптотика алгоритма имеет значение. И при больших N как не оптимизируй, но вычисление длинны за линейное время не обгонит вычисление длинны за время константное.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[34]: Зачем нужны циклы если есть рекурсивные функции
От: FR  
Дата: 01.10.09 06:23
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Согласен. Но я его и не использую. Мне char* хватит. Он не сделан бездарно


Тоже ничего хорошего

PD>Я что-то не понял, что ты этим хочешь сказать ? Что std::string барахло ? Согласен. Что можно сделать умнее, чем просто аллоцировать новую строку каждый раз, когда она нужна ? Тоже согласен. Есть еще, кстати, strtok, она как раз делит строку на фрагменты без выделения новой памяти вообще, правда, портит исходную строку. Но какое это отношение имеет к твоему утверждению, что ASCIIZ очень медленный ?


Такое что даже переписанные на ASCIIZ алгоритмы (второй вариант) были на порядок тормознее чем срезы.

PD>Не надо открывать Америки. strtok — почти та же идея.


Нет это совсем другое.
Re[8]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 06:24
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>>>Не... Это не совсем регистр ОБЩЕГО назначения.

GN>>Я говорю не о 80286, а о 32ти битном режиме. Он ничем не хуже EDX.
LVV>Я тоже. Но EDX не изменяется автоматически при выполнении команды CALL, a ESP — изменяется.

Intel Architecture Software Developer's Manual, Volume 1: Basic Architecture

3.6.1. General-Purpose Data Registers
The 32-bit general-purpose data registers EAX, EBX, ECX, EDX, ESI, EDI, EBP, and ESP are
provided for holding the following items:
• Operands for logical and arithmetic operations
• Operands for address calculations
• Memory pointers
Although all of these registers are available for general storage of operands, results, and
pointers, caution should be used when referencing the ESP register. The ESP register holds the
stack pointer and as a general rule should not be used for any other purpose.


LVV>>> Он является СПЕЦИАЛИЗИРОВАННЫМ регистром для указания именно вершины стека, поскольку и при выполнении команд CALL и ret,

GN>>Не "поскольку", а "в случаях, когда используются".
LVV>А используется он как раз при обращении к стеку — во всех стековых командах, при вызове подпрограмме и возврате из нее, при прерываниях и возврате из него.

Используется оно когда захочет автор.

LVV>>> Мы не можем задать ДРУГОЙ регистр, который вел бы себя аналогичным образом.

GN>>Если не вызывать внешнее API — можем.
LVV>Нет. Похожим образом АВТОМАТИЧЕСКИ ведут себя еще индексные регистры. Но при использовании остальных мы должны ЯВНО программировать поведение.

It is possible, in some cases, to temporarily reuse ESP as a general purpose register. Since the x86 architecture is so register-starved, adding an eighth register can eliminate the need to spill variables to memory and boost the speed of a critical inner loop. I've used this in a couple of places in VirtualDub when I really needed it, and some have asked if it is actually safe to do this. The answer is yes...

здесь

GN>>Параметры при рекурсии могут передаваться в регистрах. Как в моих примерах. И если есть call — то же могут.

LVV>Только при этом придется моделировать стек в виде сохранения предыдущих значений переменных.

"Стек значений" от eax до нуля:
f:  dec eax
    jz @f
    call f
@@: retn
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[18]: Зачем нужны циклы если есть рекурсивные функции
От: gear nuke  
Дата: 01.10.09 06:33
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

GN>>Модификация кода во время выполнения.


PD>Ну я же говорю, что тебя трюки в основном и привлекают


Мне лишь приходится с этим иметь дело. Желающих пропатчить код Винды сейчас пруд пруди.

PD>>>И что тут за трюки ? Вызов функции по указателю (колбэк) или же SEH (на базе которой реализован try-catch) ?


GN>>Да, в том-то и дело, что это не трюки Почему же это трюки когда речь идёт об асме


PD>Ей-богу, ничего не понял.


Континуации на асме были названы трюками. А на С — обычным делом С первым я и не согласен.

GN>>Хм. Ну... я могу привести пример, что нельзя сделать в рамках С++ и придётся использовать ассемблер — зарегистрировать хендлер как safeseh в таблице PE.


PD>Хм, а почему это нельзя ? Указатели вроде не отменили, запись по ним тоже.


Это процесс времени трансляции. Компилятор С++ помещает нужную информацию в объектник не для всех случаев. Решается линковкой оттранслированного асм файла (не содержащего кстати ни одной мнемоники)

PD>Ну и аргумент. Ты хоть посмотри, что __readfsdword делает. Это же встраивание машинных команд и есть


Многие другие конструкции С++ приводят к встраиванию команд, об этом и речь, что нет нужды писать их руками.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[15]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 06:48
Оценка:
Здравствуйте, gear nuke, Вы писали:


GN>Есть 32 бита в регистре (не конь в вуккуме, а, например, маска пикселей) нужно их как-то обработать по-одному. Как будет решаться задача императивно, циклом? В лоб:

GN>
GN>    mov eax, [pixels]  
GN>    mov ecx, 32  
GN>@@: shr eax, 1  ; копируем очередной бит в Carry Flag
GN>    ;
GN>    ; тут что-то делаем с битом
GN>    ;
GN>    dec ecx  ; итерируем цикл
GN>    jnz @b
GN>

GN>Если немного подумать, то на ассемблере это делается так:
GN>
GN>    mov eax, [pixels]
GN>    stc    ; используем Carry Flag как "маркер" конца битовой последовательности.
GN>@@: rcr eax, 1 ; копируем очередной бит в Carry Flag. за счёт цикличности сдвига, меркер перейдёт в младший бит на первом проходе.
GN>    ;
GN>    ; тут что-то делаем с битом
GN>    ;
GN>    or  eax, eax  ; проверяем, остался ли бит маркера.
GN>    jnz @b
GN>

GN>Счётчик цикла убран за не надобностью тратить лишний регистр. Как бы так "императивно" объяснить вышепроисходящее, без упоминаний о битах?

Двумя словами — проход с барьером. Если хочешь пример аналога без битов — проход циклического списка с псевдоначалом (неким выбранным элементом, с которого стартуем и который содержит, скажем, NULL в поле данных). Другое дело, что это лишнее, проход и без этого "маркера" можно провести.

Или ты что-то другое хочешь ? Но твою задачу как она есть я без упоминаний о битах не могу объяснить, коль скоро там именно биты.

>С другой стороны, можно сказать что здесь рекурсивный вызов, где параметром передаётся "остаток" последовательности.


Поиск льва в Африке помнишь ?

New programmer : Двигаясь от Кейптауна к Каиру и при этом с запада на восток и с востока на запад, ловит первое попавшееся животное и сравнивает его с известным львом.
Advanced programmer : То же, но предварительно помещает льва в зоопарк в Каире , чтобы поиск гарантированно окончился



GN>Если есть возможность — попробуйте провести экспеимент на студентах, как много способны написать 2й вариант. Можно даже на ЯВУ, если изменить условия задачи. Мой прогноз: без подсказок — 0.1%. Со strlen на самом деле мало общего.


Не так уж мало. И там и тут проход с барьером. Только ты (и я в варианте со списком) этот барьер заносишь явно, а для char* его занесли до нас.
With best regards
Pavel Dvorkin
Re[23]: Зачем нужны циклы если есть рекурсивные функции
От: Pavel Dvorkin Россия  
Дата: 01.10.09 06:55
Оценка:
Здравствуйте, gandjustas, Вы писали:

PD>>Линейный список. Количество элементов неизвестно, последний элемент имеет .pNext == 0. Логически то же самое.

G>Да, но это уже не последовательность байтов

Кто мне про общие принципы толковал ? Общий принцип тут один и тот же — структура с терминатором.

>а следовательно супер-пупер оптимизированный ассемблерный вариант, типа strlen не подойдет.


То тебе подай хоть одну еще такую же структуру. Дал — теперь она тебя не устраивает по совсем другим причинам. Я что, так и буду на все твои новые возражения из другой оперы отвечать ?


PD>>Строка в текстовом файле. Завершающий символ, правда, не один, а два — CR/LF.

G>Ну опять вернулись к строкам...

А ты предложи заменить текстовые файлы на что-то иное. Например, хранить длину каждой строки перед самой строкой

PD>>Упаси боже меня от рекурсии на линейных списках. Мне только стек дергать на ровном месте не хватало. Еще, чего доброго, его переполнишь.

G>Ты уже забыл что даже компиляторы C умеют оптимизировать хвостовую рекурсию?

Упаси меня бог от рекурсии на списках, как хвостовой, так и безхвостой, как оптимизированной, так и нет.

PD>>Кстати, в дотнете разве в классах коллекций для IList используется рекурсия для основных действий ? Нет. Вот тебе пример. Класс LinkedList

PD>>А уж казалось бы, как красиво можно поиск рекурсивно организовать! Но что-то они не стали. Правильно не стали
G>Потому что в компиляторе C# оптимизации хвостовой рекурсии нет.

Слава богу.

G>Вот в F# есть, там многие операции так реализованы.


Ну и прекрасно. Подождем появления G#, может , там и бесхвостую соптимизируют

PD>>>>Такая задача может возникнуть, или же, коль скоро в С такое используют для С-строк, надо эту задачу анафеме предать ?

G>>>Ну покажи хоть один реальный пример, иначе анафеме предаем.
PD>>Показал. Твой же пример
G>Какой?

Список.

Все, закончил. Иначе этому конца не будет. За тобой право последнего ответа
With best regards
Pavel Dvorkin
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.