Как начать выполнение процедуры с определенного момента.

Тема в разделе "WASM.BEGINNERS", создана пользователем LIKAN, 14 дек 2011.

  1. LIKAN

    LIKAN New Member

    Публикаций:
    0
    Регистрация:
    10 дек 2011
    Сообщения:
    8
    Как начать выполнение процедуры с определенного момента без использования меток.
    Задача следующая, при определенных условиях процедура завершает своё выполнение не закончив алгоритм, есть ли возможность при следующем её вызове не начинать код с начала, а продолжить выполнение алгоритма. Желательно что то вроде запомнить адрес последней команды ,а потом передать его как аргумент, возможно ли такое?
     
  2. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    LIKAN
    Код (Text):
    1. switch(номер_стадии_которую_процедура_ещё_не_успела_выполнить)
    2. {
    3.    case алгоритм_ещё_не_начат:
    4.       ...
    5.       if (алгоритм_нужно_срочно_прервать)
    6.       {
    7.          номер_стадии_которую_процедура_ещё_не_успела_выполнить = алгоритм_уже_выполнил_треть;
    8.          break;
    9.       }
    10.    case алгоритм_уже_выполнил_треть:
    11.      ...
    12.       if (алгоритм_нужно_срочно_прервать)
    13.        {
    14.          номер_стадии_которую_процедура_ещё_не_успела_выполнить = алгоритм_уже_выполнил_две_трети;
    15.          break;
    16.       }
    17.    case алгоритм_уже_выполнил_две_трети:
    18.      ...
    19.       if (алгоритм_нужно_срочно_прервать)
    20.        {
    21.          номер_стадии_которую_процедура_ещё_не_успела_выполнить = алгоритм_ещё_не_начат;
    22.          break;
    23.       }
    24. }
     
  3. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    Легко.
    mov eax, $-2 ; в eax адресс предудыщей команды
    И сохраняй куда-нибудь. Хотя идея какая-то некошерная.
     
  4. Dmitry_Milk

    Dmitry_Milk Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2007
    Сообщения:
    540
    В Питоне (и еще нескольких языкаъ) такая вещь есть. В Питоне называется генератором :)

    А вообще такое надо реализовать в виде объекта, имеющего поля состояния и, собственно, саму функцию, в которой все использования локальных переменных заменены на использование полей состояния.
     
  5. LIKAN

    LIKAN New Member

    Публикаций:
    0
    Регистрация:
    10 дек 2011
    Сообщения:
    8
    наародд, питон и си это конечно круто, но форум про ассемблер, соответственно вопрос к асму
     
  6. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    С чего ты взял? А вообще алгоритм тот же. И читай пост #3
     
  7. Dmitry_Milk

    Dmitry_Milk Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2007
    Сообщения:
    540
    Конкретно я бы наверное реализовал так:
    Основная функция (обычная, с аргументами) и две вспомогательных, назовем их, скажем, Interrupt и Continue.
    В самом начале основной функции сохраняется указатель начала ее стекового кадра в определенной глобальной переменной или в поле объекта (если это метод). Далее функция выполняется как обычно, а в нужном месте вызывается фукнция Interrupt(с аргументом для возврата), которая, ориентируясь на сохраненное значение указателя стека, сохраняет содержимое стека от указанной позиции (тоже глобально или в полях, если метод), а потом откатывает стек так, чтоб остался только адрес возврата, запихивает аргумент в eax и совершает возврат, вылетая таким образом сразу в то место программы, где вызывалась основная функция. Далее программа работает и в некоторый момент вызывает Continue, которая совершает действия, обратные тому, что совершала Interrupt - восстанавливает содержимое стека и снова делает возврат, возвращаясь таким образом к тому месту в основной функции, откуда вызывалась Interrupt, при этом имея значения всех локальных переменных в таком состоянии, какое было на момент вызова Interrupt.

    Правда слишком уж опасная вещь руками так играться со стеком, тот еще рассадник ошибок. Но идеологически такое программирование вполне обоснованно - при написании такой функции вы можете думать только о том, что и в каких местах функция должна возвращать. Удобно для программирования функций, генерирующих последовательности "на выдачу".
     
  8. moderhi

    moderhi New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2011
    Сообщения:
    189
    питон- мрачная хрень какаято, одно слово уже ужас наводит. И сто пудов есть на форме горстка засланцев которые пытаются не прямо а намеками, вскользь расхваливать, пропиарить это чудище.
     
  9. Dmitry_Milk

    Dmitry_Milk Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2007
    Сообщения:
    540
    Вот блин. Точно рассадник ошибок. Забыл учесть, что аргументы кладутся в стек до того, как положится адрес возврата. Так что вышенаписанное можно применить только для основной функции без аргументов.
     
  10. Dmitry_Milk

    Dmitry_Milk Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2007
    Сообщения:
    540
    moderhi, я не засланец, но Питон мне нравится :)
     
  11. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    moderhi-еретик. Cжечь.
     
  12. moderhi

    moderhi New Member

    Публикаций:
    0
    Регистрация:
    11 окт 2011
    Сообщения:
    189
    не выйдет :) острый клинок асма пронзит сердце огнедышащего питона!)
     
  13. Sholar

    Sholar New Member

    Публикаций:
    0
    Регистрация:
    16 окт 2011
    Сообщения:
    189
    Ну насчет асма никто не спорит (:
    *Капитулирую*
     
  14. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    LIKAN
    Очень крутой комментарий в контексте условия задачи:
    Где Вы видели код на ассемблере без использования меток? Естесственно, что ни одному уважающему себя телепату ассемблер в кофейную гущу не взбредёт.
     
  15. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    сами себе ответили и алгоритм придумали. Значит возможно. Проблема записать то что придумали на ассемблере?

    Something:
    mov cx, LastStop
    add cx, <размер комманд>
    jmp cx
    ...
    ; какие-то действия процедуры
    ; проверка условия
    ; если да, то
    db 0e8h, 0,0 ;это call на следующую команду, фактически push ip
    pop cx
    mov LastStop, cx
    ret
    ...
    и дорабатывайте )
     
  16. LIKAN

    LIKAN New Member

    Публикаций:
    0
    Регистрация:
    10 дек 2011
    Сообщения:
    8
    А можно немного откоментировать ваш код? И код по разным сегментам раскидан, сегмент тоже запомнить?
    Что такое LastStop, а главное зачем мне размер команды? И что за жесть "db 0e8h, 0,0 ", а главное как эта процедура должна вызваться из внешней программы?
     
  17. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    жесть 0E8h, 00, 00 - это машинный код команды call с относительным смещением 0. Если написать вот так:

    Код (Text):
    1. ...
    2.    call @Next
    3. @Next:
    4. ...
    то как раз такой машинный код и сгенерится. Это чтобы с $ и метками не заморачиваться.

    LastStop - это некая переменная, которую надо естественно где-то в сегменте данных упомянуть:

    Код (Text):
    1. LastStop dw (offset Start0)-Size   ; первоначально указует на действительное начало процедуры. Size = 6, см. далее
    Зачем нужна переменная? Это вместо "запомнить адрес последней команды ,а потом передать его как аргумент"

    Теперь, если вы вызываете процедуру Something (а вызывать всегда будете именно ее, не используя меток внутри), то берется сохраненный в переменной адрес, к нему прибавляется размер команд

    Код (Text):
    1. pop cx
    2. mov LastStop, cx
    3. ret
    (это 6 байт)

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

    А Start0, которую я ввел при задании первоначального значения LastStop, это вот что:

    Код (Text):
    1. Something:
    2.    mov cx, LastStop
    3.    add cx, <размер комманд>
    4.    jmp cx
    5. Start0:
    6. ; здесь начинается собственно процедура, выполняющая эти загадочные действия.
    7. ...
    Без понятия, какова должна быть задача. И если упомянутые "определенные условия" заключаются в нажатии клавиши или ином IRQ, возможно, надо делать обработчик прерываний, что решит все проблемы. Но формально, предложенное решение отвечает условиям :)

    Насчет сегментов: а ради бога. Но тогда да, еще и сегмент записывать. Но... Судя по сегментам (и вопросу в соседней теме), у вас 16-битный код. Размер сегмента (кода, который умещается в 1 сегмент) - 64К. 64К на ассемблере - это небольшая операционная система типа DOS, вместе с интепретатором команд, бейсиком, и текстовым редактором. И еще туда же можно тетрис запихнуть. И как-то не вяжутся ваши вопросы и процедура в несколько сегментов
     
  18. kejcerfcrv

    kejcerfcrv New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2011
    Сообщения:
    320
    Есть такая не годная фича в нт как фиберы. А есчо шедулер есть. И в прочих осях примитивных были таймеры, которые задачами рулили.
     
  19. iamlamer

    iamlamer New Member

    Публикаций:
    0
    Регистрация:
    20 июн 2005
    Сообщения:
    273
    Адрес:
    Russia
    Ага, в примитивных осях типа Вындоуз и Уних (линухи там всякие, макоси и фрибзди) задачами, действительно, рулили таймеры. А в современных осях (жаль, названий не помню) задачами рулит святой дух. :)

    З.Ы. По теме. Не понятно, _почему_ и _как_ (с точки зрения ТС) процедура может не выполнить алгоритм до конца. Вот как только ТС приведет конкретный пример "недовыполонения до конца", так сразу ему и будет адекватный ответ. :)
     
  20. kejcerfcrv

    kejcerfcrv New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2011
    Сообщения:
    320
    iamlamer
    В досе псевдомультизадачность реализовалась через таймеры. И на спеки тоже. И на ниндендо для спрайтов отводилась своя задача. И святой дух тоже задача. А на нт уже таймеры не рулят.