Калькулятор с использованием 2 стеков - PullRequest
3 голосов
/ 14 декабря 2008

У меня есть назначение сборки Intel. Мне нужно написать калькулятор, который использует 2 стека. Например, у меня есть выражение типа 23 + 4/2 ^ 4 $. Так что $ указывает на конец выражения. Я сделаю два стека, один для чисел, один для операторов, и вытолкну их в соответствии с приоритетом оператора.

Что мне нужно, так это как я могу использовать 2 стека для двух разных целей одновременно. Насколько я знаю, регистр esp указывает место для переменных в стеке, чтобы выталкивать последние или выдвигать новые. Но если у меня есть только один регистр esp, как я могу иметь два стека?

Заранее спасибо ...

Ответы [ 6 ]

4 голосов
/ 14 декабря 2008

Я думаю, что вы ищете алгоритм шунтирования Дейкстры.

Я решил это без использования стеков во время интерпретации, только во время выполнения, как описано в моем блоге.

Что касается создания дополнительных стеков, это довольно просто. Весь стек - это просто область памяти с указателем вверху и внизу. Каждый раз, когда вы нажимаете, вы увеличиваете верхний указатель, каждый раз, когда вы нажимаете, уменьшаете верхний указатель.

2 голосов
/ 14 декабря 2008

Или вы можете сделать это самым простым способом, который мог бы работать и торговать; и реализовать оба ваших стека выполнения в памяти; как указано выше, вам нужен только указатель TOP и некоторая арифметика.

1 голос
/ 14 декабря 2008

Все эти ответы предполагают, что не существует такого понятия, как приоритет оператора. Ясно, что использование стеков, упомянутых в вопросе, намекает на правильный ответ, связанный с вычислениями, использующими приоритет операторов.

Вот ссылка, объясняющая, чего вы пытаетесь достичь. http://epaperpress.com/oper/index.html

0 голосов
/ 14 декабря 2008

предположим, что выражение имеет длину L, тогда каждый из ваших стеков будет максимум L, поэтому вам потребуется максимум 2L памяти.
увеличьте ESP на 2 л, в ESP у вас будет начало вашего первого стека, в ESP + L у вас будет начало вашего второго стека (следует отметить, что ни один из этих стеков никогда не превысит L, поскольку выражение имеет длину L).
Алгоритм маневрового двора можно найти в разных местах. Для этого используется преобразование из инфиксной записи
постфиксировать запись. После этого оценка постфиксной нотации не составит труда.

Редактировать: также, для манипулирования двумя стеками вам нужно где-то хранить указатели их стеков.
Для этого вы можете использовать 2 регистра по вашему выбору, EBX, ECX, например
заставить один иметь значение ESP, а другой ESP + L. Каждый раз, когда вы будете использовать один или другой стек, вам придется обновлять ESP с помощью соответствующего EBX или ECX или где угодно, где вы можете хранить свои 2 указателя стека, потому что push и pop изменят ESP, и вам нужно, чтобы они изменили версию ESP нужен, а не другой. Также, когда вы закончили pop / push, вы должны обновить EBX / ECX со значениями ESP.

0 голосов
/ 14 декабря 2008

Итак, могу ли я создать два стека следующим образом:

mov ecx,256
L1: call ReadInt
    push eax          ;push the integer to where esp=1 points
    add esp,ecx       ;esp=1+256=257, now esp points to 257.

    call ReadChar     ;read operand
    cmp al,endChar    ;compare with end sign=$
    je next       
    push al           ;push operand to where esp=257 points
    sub esp,ecx       ;esp=257-256=1, now esp is in the original position
    loop L1
next:
...

Конечно, комментарии относятся к первому циклу.

Кстати, я получил сообщение "1> .. \ main.asm (46): ошибка A2149: ошибка в регистре байтов не может быть первым операндом" (push al)? в чем дело?

спасибо ...

0 голосов
/ 14 декабря 2008

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


Редактировать: развивая идею в соответствии с просьбой в комментарии: я считаю, что каждый раз, когда вы нажимаете оператор, вы затем нажимаете число, следующее за ним (потому что за этим номером в свою очередь может следовать оператор более высокого приоритета ). Точно так же, каждый раз, когда вы используете pop и operator, вы собираете два операнда и выдвигаете результат. Таким образом, стек операторов и стек операндов растут и уменьшаются в тандеме, и, поскольку первоначальный вопрос заключался в том, как сделать это в коде сборки, я предложил, чтобы они могли совместно использовать чередующиеся слоты в одном стеке. (Если этого недостаточно, пожалуйста, дайте мне знать, и я буду редактировать снова.)

...