Калкулатор, използващ 2 стека

Имам задание за сглобяване на информация. Трябва да напиша калкулатор, който използва 2 стека. Например, имам израз като 23+4/2^4$. Така че $ показва края на израза. Това, което ще направя, е да имам два стека, един за числа, един за оператори и да ги натискам и изваждам според приоритета на оператора.

Това, от което се нуждая, е как мога да използвам 2 стека за две различни цели едновременно. Доколкото знам регистърът на esp показва мястото за променливи в стека, за да изскочи последната или да натисне нова. Но ако имам само един esp регистър, как мога да имам два стека?

Благодаря предварително...


person israkir    schedule 13.12.2008    source източник


Отговори (6)


Мисля, че това, което търсите, е маневриращият алгоритъм на Дейкстра.

Реших го, без да използвам стекове по време на интерпретация, само по време на изпълнение, както е описано в моя блог.

Що се отнася до правенето на допълнителни стекове, това е доста лесно. Всичко, което е един стек, всъщност е просто област от паметта с указател към горната и долната част. Всеки път, когато натиснете, вие увеличавате горния показалец, всеки път, когато изскочите, намалявате горния показалец.

person Guge    schedule 13.12.2008

Или можете да го направите по най-простия начин, който евентуално би могъл да работи, и да внедрите и двата си стека за изпълнение в паметта; както по-горе, имате нужда само от TOP показалец и малко аритметика.

person Charlie Martin    schedule 13.12.2008

Всички тези отговори предполагат, че няма такова нещо като приоритет на оператора. Ясно е, че използването на стекове, споменати във въпроса, подсказва правилния отговор, свързан с изчислението, използващо приоритет на оператора.

Ето връзка, която обяснява какво се опитвате да постигнете. http://epaperpress.com/oper/index.html

person fasih.rana    schedule 13.12.2008
comment
Всички тези отговори предполагат, че няма такова нещо като приоритет на оператора? Какво ? Откъде го направи това заключение? - person xxxxxxx; 14.12.2008
comment
Този проблем е известният проблем с приоритета на оператора и се решава от известната Infix нотация. Отговорите по-горе изглежда не вземат под внимание стековете и говорят за премахване на стековете, което убива целта на горното упражнение. - person fasih.rana; 15.12.2008
comment
Мисля, че не знаеш какво говориш - person xxxxxxx; 10.03.2010

Тъй като вашите два стека не са независими, друга идея би била да преплитате данните в един стек. Например можете да използвате думи с четни номера за числа и думи с нечетни номера за оператори.


Редактиране: разработване на идеята, както е поискано в коментара: Вярвам, че всеки път, когато натиснете оператор, ще натиснете номера, който го следва (защото този номер на свой ред може да бъде последван от оператор с по-висок приоритет). По същия начин, всеки път, когато натиснете и оператор, ще извадите два операнда и ще натиснете резултат. Така операторният стек и операндният стек растат и се свиват в тандем и тъй като първоначалният въпрос беше как да се направи това в асемблерния код, аз предложих да споделят редуващи се слотове на един стек. (Ако това не е достатъчно обяснение, моля, уведомете ме и аз ще редактирам отново.)

person Norman Ramsey    schedule 13.12.2008
comment
Мисля, че това е много интересна идея, която трябва да се доразвие. - person Guge; 14.12.2008
comment
преплитане на стекове ... тази хитрост ще ви навлече проблеми - person xxxxxxx; 14.12.2008
comment
Ако OP имплементира това като RPN, тогава операторите и операндите няма да се преплитат 1:1. Например, 5 * (6 - 3) ще бъде {6,3,-,5,} или дори {5,6,3,-,}, което според мен е това, което маневрената площадка алгоритъмът ще генерира. - person P Daddy; 14.12.2008

да предположим, че изразът има дължина L, тогава всеки от вашите стекове ще бъде най-много L, така че ще имате нужда от най-много 2L памет.
увеличете ESP с 2L, при ESP ще имате началото на първия си стек, при ESP +L ще имате началото на вашия втори стек (трябва да се отбележи, че нито един от тези стекове никога няма да надхвърли L, тъй като изразът е с дължина L).
Алгоритъмът на маневрената площадка може да бъде намерен на различни места. Какво е е преобразуването от инфиксна нотация
към постфиксна нотация. След това оценката на постфиксната нотация няма да бъде трудна.

Редактиране: също така, за манипулиране на 2-та стека, ще трябва да съхранявате техните указатели на стека някъде.
Можете да използвате 2 регистъра по ваш избор за това, EBX, ECX например
накарайте един да има стойност ESP и други ESP+L. Всеки път, когато използвате единия или другия стек, ще трябва да актуализирате ESP със съответния EBX или ECX или където и да запазите вашите 2 указателя на стека, защото натискането и поп ще променят ESP и вие ще искате те да променят версията на ESP, която е необходим, а не друг. Освен това, когато приключите с изп/натискане, трябва да актуализирате EBX/ECX със стойностите на ESP.

person xxxxxxx    schedule 13.12.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)? какъв е проблема?

Благодаря...

person israkir    schedule 13.12.2008
comment
Ще имате проблеми, ако възникне прекъсване между add esp, ecx и sub esp, ecx. Вместо това ще трябва да поддържате два указателя към вашите стекове. Едното може да е esp, другото трябва да е ebp. - person P Daddy; 14.12.2008
comment
Що се отнася до грешката ви (байтовият регистър не може да бъде първи операнд), ще трябва да натиснете eax, а не al. Можете да натискате само регистри с пълна ширина. esp винаги трябва да бъде подравнен по границата на машинната дума. - person P Daddy; 14.12.2008