Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КР АВМиС заочное ввод-вывод, стек.doc
Скачиваний:
9
Добавлен:
01.04.2014
Размер:
145.92 Кб
Скачать

Написать и отладить программу, которая демонстрирует выполнение операций со стеком Листинг

#include "stdafx.h"

#include <iostream>

#include <string>

#include <windows.h>

#include <conio.h>

using namespace std;

int RSP,RBP,buf,bSP,bBP,pVal;

int *mstack;

class CInfoWindow{

private:

int count;

_COORD Crd;

HANDLE hConsole;

void ASCII(char *Ch)

{//метод перевода символов в дос кодировку

if (Ch == NULL) return;

int Len = strlen(Ch);

char *newCh = new char[Len+1];

for (int i = 0;i<Len;i++)

{

if ((int(Ch[i]) >= -64)&&(int(Ch[i]) <= -1))

{

if (Ch[i]+192 >=176) newCh[i] = Ch[i]+240;

else newCh[i] = Ch[i]+192;

}else newCh[i] = Ch[i];

}

newCh[Len] = '\0';

cout<<newCh;

}

public:

CInfoWindow()

{

hConsole = GetStdHandle(STD_OUTPUT_HANDLE);//получения контекста консоли

HideCursor();

SetTextColor(26);

count = 0;

}

~CInfoWindow()

{

}

void HideCursor()

{//метод выключает отображение курсора консоли

_CONSOLE_CURSOR_INFO MyCurSor;

MyCurSor.dwSize = 20;

MyCurSor.bVisible = FALSE;//курсор становится "не видимым":)

SetConsoleCursorInfo(hConsole,&MyCurSor);

}

void ShowCursor()

{//метод включает отображение курсора консоли

_CONSOLE_CURSOR_INFO MyCurSor;//объявление структуры

MyCurSor.dwSize = 20;//установка параметров курсора - размер (вертикальный)

MyCurSor.bVisible = TRUE;//состояние "Видимость" тру - видимый...

SetConsoleCursorInfo(hConsole,&MyCurSor);//вызов метода установки параметров курсора

}

void SetTextColor(int Color)

{

SetConsoleTextAttribute(hConsole,(WORD)Color);

}

void SetXY(int X,int Y)

{//метод установки курсора в позицию с координатами Х и У

Crd.X = X;

Crd.Y = Y;

SetConsoleCursorPosition(hConsole,Crd);

}

void clrscr(void)

{

system("cls");

}

void DrawRegInfo()

{

SetXY(67,5);

cout<<hex<<RSP;

SetXY(67,6);

cout<<hex<<RBP;

}

void Push(int Value)

{

if (count<17)

{

__asm{

mov bSP,ESP

mov bBP,EBP

mov ESP,RSP

mov EBP,RBP

push pVal

mov RSP,ESP

mov RBP,EBP

mov ESP,bSP

mov EBP,bBP

}

count++;

}else

throw new int(0);

}

int Pop()

{

pVal = 0;

if (count>0)

{

count--;

__asm{

mov bSP,ESP

mov bBP,EBP

mov ESP,RSP

mov EBP,RBP

pop pVal

mov RSP,ESP

mov RBP,EBP

mov ESP,bSP

mov EBP,bBP

}

}

return pVal;

}

void DrawStack()

{

int j,i;

for (i=count-1, j = 0;i>=0;i--,j++)

{

SetXY(5,7+j);

cout<<hex<<&mstack[17-i];

SetXY(29,7+j);

cout<<dec<<mstack[17-i];

}

}

void Draw()

{

clrscr();

SetXY(0,0);

cout<<"|------------------------------------------------------------------------------|";

ASCII("| Программа демонстрации работы стека (push/pop) |");

cout<<"|------------------------------------------------------------------------------|";

ASCII("|1-Push|2-Pop|3-Выход| Выбор: число: | Регистр | Значение |");

cout<<"|------------------------------------------------------------------------------|";

ASCII("| Адрес | Значение | ESP | |");

cout<<"|--------------------------------------------| EBP | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"| | | | |";

cout<<"|------------------------------------------------------------------------------|";

SetXY(0,0);

DrawRegInfo();

DrawStack();

ShowCursor();

SetXY(30,3);

}

};

void main()

{//суть идеи:

// 1 - выделяем 20*4 байт под стек

// 2 - сохраняем во временные переменные стековые регистры ESP и EBP

// 3 - заносим в регистры ESP и EBP адреса конца выделенного участка памяти

// 4 - используя команды ассемблера push и pop выполняем операции со стеком

// 5 - на экран выводим адреса и значения внесенных в стек элементов и отображаем содержимое регистров

mstack = new int[20];//размер памяти для нашего "виртуального" стека

for (int i=0;i<20;i++) mstack[i]=0;

mstack[19]=2;

__asm{

mov EAX,4 //получаем индекс последнего элемента

mov EBX,19 //4 байта для типа данных int

mul EBX //умножаем на 20 элем. - получаем смещение от начала в байтах

mov EBX,mstack //получаем адрес начала сегм памяти стека

add EBX,EAX //адрес последнего элемента mstack

mov EAX,EBX

sub EBX,4

mov dword ptr [EAX],EBX

mov RSP,EBX

sub EAX,4

mov dword ptr [EAX],EBX

mov RBP,EBX

}

CInfoWindow Wnd;

int i;

Wnd.Draw();

cin>>i;

while (i!=3)

{

switch(i){

case 1:{

Wnd.SetXY(40,3);

cin>>pVal;

Wnd.Push(i);

};break;

case 2:{Wnd.Pop();};break;

default:break;

}

Wnd.Draw();

cin>>i;

}

delete mstack;

return;

}