Определение системных ресурсов ПЭВМ

Цель работы: изучение и использование функций BIOS и DOS, системных данных и таблиц для решения задачи определения состава, типов и параметров присоединенного оборудования и некоторых других системных ресурсов и данных ПЭВМ:

1. типа персонального компьютера;

2. размера основной и дополнительной памяти;

3. даты изготовления базовой системы ввода/вывода;

4. числа и типов накопителей на магнитных дисках;

5. типа и параметров видеосистемы;

6. типов и числа других периферийных устройств;

7. номера версии установленной операционной системы.

Краткие теоретические сведения:

Для решения указанных задач предлагается составить программу на языке Turbo Pascal с использованием его расширенных возможностей, таких как : размещение переменных по абсолютным адресам памяти, непосредственный доступ к ячейкам памяти и портам, организация программных прерываний и системных вызовов, программирование на низком уровне. Кратко рассмотрим эти возможности Turbo Pascal. В Turbo Pascal имеются средства размещения переменных по конкретным адресам оперативной памяти. Такие переменные называются абсолютными. Для описания абсолютных переменных предназначено зарезервированное слово Absolute. Формат описания переменных этого типа выглядит так :

Var <идентификатор> : <тип> Absolute BA:BS;

Здесь BA:BS - абсолютный адрес ячейки оперативной памяти (байта памяти), начиная с которой отводится место для хранения значения переменной <идентификатор> указанного типа <тип>;

BA - базовый адрес сегмента; BS - смещение внутри этого сегмента.

Для работы с абсолютными переменными (определения абсолютных адресов переменных, записи и считывания информации из конкретных ячеек памяти) в Turbo Pascal имеется ряд стандартных подпрограмм : Addr, CSeg, DSeg, Ofs, Ptr, Seg, SSeg.

В Turbo Pascal определены пять предварительно объявленных массивов : Mem, MemW, MemL, Port и PortW. Первые три массива обеспечивают непосредственный доступ (запись и чтение) к любому участку памяти по абсолютному адресу, два других массива - доступ к портам ввода/вывода.

Для осуществления работы с регистрами процессора ПЭВМ, организации программных прерываний, использования большинства возможностей операционной системы MS-DOS предназначен системный модуль DOS Turbo Pascal.

Реализация всех этих возможностей практически всегда предполагает обращение к регистрам центрального процессора.

Для этих целей в модуле DOS определен специальный тип данных Registers :

Type Registers = Record

Case Integer of 0 : (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : Word);

1 : (AL, AH, BL, BH, CL, CH, DL, DH : Byte)

End;

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

Для организации программных прерываний и выполнения системных функций MS-DOS в модуле DOS Turbo Pascal имеются две стандартные процедуры Intr и MsDos.

Первая процедура Intr инициирует программное прерывание с требуемым номером:

Intr(Num_Int : Byte; var Regs : Registers);

Здесь : Num_Int - номер программного прерывания, которое не обходимо вызвать (0..255);

Regs - запись, в которой процедуре обработки прерывания с номером Num_Int передаётся содержимое регистров и в ней же возвращается выходная информация.

Язык Turbo Pascal допускает три основные возможности для использования средств программирования на низком уровне (язык машинных команд и фрагменты на языке Ассемблера) :

1. Можно написать одну или несколько процедур на языке Ассемблера (вне среды Turbo Pascal), оттранслировать их, получив объектные модули этих процедур, и затем подключить эти модули к Pascal-программе. Для этого в Turbo Pascal существует служебное слово External, указываемое в заголовке процедуры, и директива компилятора $L.

2. Turbo Pascal позволяет непосредственно включать в текст программы фрагменты, написанные на машинном коде. Это достигается использованием inline-операторов и inline-процедур.

3. Начиная с шестой версии Turbo Pascal появилась возможность включения в текст Pascal-программы фрагментов на языке Ассемблера. Средства, поддерживающие эту возможность, называют "встроенный Ассемблер".

ТЕКСТ ПРОГРАММЫ:

program xyz;

uses crt,dos,art,PRINTER;

type zapis=record

OS_Pam,DOP_PAm,Video_Pam:word;

Tip_Kompa,data_biosa:string[20];

NZMD,GMDA,GMDB,Displai,so_proch,igr,_print,MSDOS:string;

posled_port,paral_port:integer;

end;

var st:array [1..4] of string;

ch:integer;

My:zapis;

function type_Pc:string;

var s:byte absolute $F000:$FFFE;

begin

case s of

$FF:type_Pc:='Тип компьютера IBM PC';

$FD:type_Pc:=' Тип компьютера IBM PCjr';

$FE:type_Pc:= Тип компьютера IBM PC/XT';

$FC:type_Pc:=' Тип компьютера IBM PC/AT';

end;

end;

function MS_DOS:string;

var Regs:Registers;

s1,s2:string;

begin

Regs.AH:=$30;

MsDos(Regs);

str(Regs.AL,s1);str(Regs.AH,s2);

MS_DOS:='Версия MS-DOS '+s1+'.'+s2;

end;

procedure SIZE_MEM(var os:word;var dp:word;var video:word);

var Regs:Registers;

begin

os:=memw[$0000:$0413];

Intr($15,Regs);

dp:=Regs.AX;

video:=memw[$40:$4C];

end;

function Date_Bios:string;

var i:integer;

stroka:string;

W:byte;

begin

stroka:='';

write('Дата создания биоса ');w:=$0004;

for i:=1 to 8 do

begin

w:=w+1;

stroka:=stroka+chr(mem[$ffff:w]);

end;

Date_Bios:=stroka;

end;

function video_sys:string;

var regs:Registers;

begin

Regs.AH:=$1A;Regs.AL:=$00;

intr($10,regs);

case Regs.BL of

$00:video_sys:='Монохромный дисплей';

$01:video_sys:='Монохромний адаптер - Монохромный дисплей';

$02:video_sys:='Адаптер CGA-цветной дисплей';

$04:video_sys:='Адаптер EGA-цветной дисплей';

$05:video_sys:='Адаптер EGA-монохромный дисплей';

$07:video_sys:='Адаптер VGA-монохромный аналоговый дисплей';

$08:video_sys:='Адаптер VGA- цветной аналоговый дисплей';

$0A:video_sys:='Адаптер VGA- цветной цифровой дисплей';

end;

end;

function Kol_GMD(var s:string):string;

var i:integer;

k:byte;

begin

for i:=1 to 2 do

begin

port[$70]:=$10;

k:=port[$71];

if i=1 then k:=k shr 4 else k:=k shl 4;

case k of

0:s:='Дисковода нет или его тип не известен';

1:s:=' на 360 Kb, для дискет диаметром 5.25';

2:s:=' на 1.2 Mb, для дискет диаметром 5.25';

3:s:=' на 720 Kb, для дискет диаметром 3.5';

4:s:=' на 1.44 Mb, для дискет диаметром 3.5';

5:s:=' на 2.88 Mb, для дискет диаметром 3.5';

6:s:=' не установлен’;

end;

if i=1 then Kol_GMD:=s;

end;

end;

function kol_ZMD:string;

var k:byte;

s:string;

begin

k:=mem[$45:$75];

str(k,s);

kol_ZMD:='Колличество жеских магнитных дисков-'+s;

end;

function soproch:string;

var k:word;

begin

k:=memw[$40:$10] and 2;

k:=k shr 1;

if k=1 then soproch:='есть математический сопроцессор'

else soproch:=' математический сопроцессор отсутсвует';

end;

function igr_adap:string;

var k:word;

begin

k:=memw[$40:$10] and 4096;

k:=k shr 13;

if k=1 then igr_adap:='есть игровой адаптер '

else igr_adap:='игровой адаптер отсутсвует';

end;

function Kol_posled_port:integer;

var k:word;

begin

k:=memw[$40:$10];

k:=k shl 4;k:=k shr 13;

Kol_posled_port:=k;

end;

function Kol_paral_port:integer;

var k:word;

begin

k:=memw[$40:$10];

k:=k shr 14;

Kol_paral_port:=k;

end;

function print:string;

var k:word;

begin

k:=memw[$40:$10] and 4096;

k:=k shr 14;

if k=1 then print:='установлен последовательный принтер'

else print:=' последовательный принтер не установлен’;

end;

procedure zopolnenie;

begin

with my do

begin

tip_kompa:=type_pc;

size_mem(os_pam,dop_pam,video_pam);

data_biosa:=Date_Bios;

GMDA:=Kol_GMD(GMDB);

displai:=video_sys;

NZMD:=kol_ZMD;

so_proch:=soproch;

igr:=igr_adap;

_print:=print;

posled_port:=Kol_posled_port;

paral_port:=Kol_paral_port;

MSDOS:=MS_DOS;

end;

end;

procedure vivod_disp;

begin

clrscr;

with my do

begin

textcolor(2);writeln(' ОБЩИЕ СВЕДЕНИЯ'); textcolor(7);

writeln(tip_kompa);writeln(MSDOS);

writeln('Дата создания BIOSa-',data_biosa);

textcolor(2);Writeln(' ПАМЯТЬ ');textcolor(7);

writeln('Колличество основной памяти (Kб)-',os_pam);

writeln('Колличество дополнительной памяти(Kб)-',dop_pam);

writeln('Память видео страницы(байт)-',video_pam);

textcolor(2);writeln(' ДИСКИ');textcolor(7);

writeln('Дисковод A:',GMDA);

writeln('Дисковод B:',GMDB);

writeln(NZMD);

textcolor(2);writeln(' ВИДЕО');textcolor(7);

writeln(displai);

textcolor(2);writeln(' ДОПОЛНИТЕЛЬНЫЕ СВЕДЕНИЯ');textcolor(7);

writeln(so_proch);

writeln(igr);

writeln(_print);

writeln('Колличество последовательных портов -',posled_port);

writeln(' Колличество паралельных портов -',paral_port);

end;

end;

procedure vivod_fail;

var f:text;

s:string;

begin

clrscr;

write('Введите путь к файлу -');readln(s);

assign(f,s);rewrite(f);

with my do

begin

writeln(f,' ОБЩИЕ СВЕДЕНИЯ');

writeln(f,tip_kompa);writeln(f,MSDOS);

writeln(f,'Дата создания BIOSa-',data_biosa);

Writeln(f,' ПАМЯТЬ');

writeln(f,'Колличество основной памяти (Kб)-',os_pam);

writeln(f,'Колличество дополнительной памяти (Kб)-',dop_pam);

writeln(f,'Память видео страницы (байт)-',video_pam);

writeln(f,' ДИСКИ');

writeln(f,'Дисковод A:',GMDA);

writeln(f,'Дисковод B:',GMDB);

writeln(f,NZMD);

writeln(f,' ВИДЕО');

writeln(f,displai);

writeln(f,' ДОПОЛНИТЕЛЬНЫЕ СВЕДЕНИЯ ');

writeln(f,so_proch);

writeln(f,igr);

writeln(f,_print);

writeln(f,'Колличество последовательных портов -',posled_port);

writeln(f,' Колличество паралельных портов -',paral_port);

end;

close(f);

end;

procedure vivod_print;

var Lst:text;

s:string;

begin

clrscr;

write('Введите путь к файлу -');readln(s);

assign(Lst,s);reset(lst);

while not eof(Lst) do

begin

readln(Lst,s);

writeln(Lst,s);

end;

close(Lst);

end;

BEGIN

clrscr;

st[1]:='Вивод информации на дисплей';st[2]:='Вывод информации в файл';

st[3]:='Вывод информации на принтер';st[4]:='Выход';

zopolnenie;

repeat

ch:=menu_s(st,4,0,0);

case ch of

1:begin vivod_disp;readln;end;

2:vivod_fail;

3:vivod_print;

end;

until ch=4 ;

END.

РЕЗУЛЬТАТЫ РАБОТЫ ПРОГРАММЫ:

OBCHIE SVEDENIYA

Tip kompa IBM PC/AT

Versiya MSDOS 5.0

data sozdaniya BIOSa-03/28/02

PAMYAT'

kollicestvo osnovnoi pamyati(Kb)-640

kollicestvo dopolnitel'noi pamyati(Kb)-34336

Pamyat' video stranichi(bait)-4096

DISKI

Diskovod A: na 1.44 Mb, dlya disket diametrom 3.5

Diskovod B:Diskovoda net ili ego tip neizvesten

Kolichestvo zhestkih magnitnih diskov-0

VIDEO

Adapter VGA-chvetnoi analogovii displai

DOPOLNITEL'NIE SVEDENIYA

est' matematicheskii soprochessor

igrovoi adapter otsytstvyet

posledovatel'nii printer ne ystanovlen

kolichestvo poslrdovatel'nih portov-4

kolichestvo paralel'nih portov-3

Общие сведения о языке GPSS и пакете GPSS/PC

Одним из наиболее распространенных языков имитационного моделирования является язык GPSS (от General Purpose Simulation System), разработанный в 1974 г. фирмой IBM. Язык применяется для моделирования дискретных процессов, реализует метод “по особым событиям” с целочисленным модельным временем.

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

Пакет состоит из двух загрузочных модулей с именами gpsspc.exe и gpssrept.exe. Первый содержит итнтерпретатор языка и основные интерактивные средства. Второй имеет вспомогательный характер и предназначен для выдачи на печать итогового отчета о результатах моделирования.

Ввод и редактирование программы моделирования

Работа с пакетом начинается с загрузки модуля gpsspc.exe, после чего в нижней части экрана высвечивается приглашение для ввода операторов языка в виде >.

Если программа моделирования набивается впервые, после приглашения > набираются последовательно строки программы или команды. Каждая строка при этом завершается нажатием клавиши “Возврат каретки” (ВК), после чего введенная строка переходит в верхнюю часть экрана, а в его нижней части вновь высвечивается приглашение >. Если набирается строка, содержащая синтаксическую ошибку, то в месте ошибки ввод прекращается, выдается звуковой сигнал, а под строкой высвечивается ^. Иногда имеют место ошибки, выявляемые в процессе интерпретации всей строки. В этом случае сообщение об ошибке появляется в верхней части экрана после нажатия клавиши ВК. Следует отметить, что возможны ошибки в процессе исполнения программы моделирования. В этом случае соответствующие сообщения появляются на экране вверху.

При наборе оператора GPSS следует строго выполнять синтаксические правила, в частности, разбиение оператора на поля. Для облегчения этого редактором GPSS/PC предоставляются удобные средства в виде подсказок. После набора первого поля следует нажать клавишу пробела. Тогда в нижней строке курсор перескочит к первой позиции следующего поля - поля меток, где временно высветится символ L. С началом набора имени метки этот символ “забьется” именем метки. Аналогичные подсказки высвечиваются и для других полей (V-для поля операций, X,A,B,C,D и т.д. - для полей операндов, ; - для поля комментариев). Для перехода к следующему полю необходимо нажимать клавишу пробела или клавишу с запятой.

В процессе набора строки ее можно исправлять, пользуясь клавишами передвижения курсора, клавишей Ins (вставки), клавишами Home,End,Ctrl. Для передвижения к началу следующего (предыдущего) слова удобно использовать комбинации клавиш Ctrl/-> (Ctrl/<-).

Если требуется исправить уже введенную строку, необходимо выполнить команду

EDIT <номер строки>

После исполнения этой команды в нижней части экрана появится та строка, номер которой указан в данной команде.

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

Если программа очень длинная, можно на экран вывести ее фрагмент. Для этого необходимо после приглашения > набрать команду

DISPLAY a,b

где a и b - начальная и конечная строки программы. Как a, так и b могут отсутствовать. Если не задано a, то на экран выведется фрагмент от начала программы до строки с номером b; если не задано b, то выведется строка с номером a; если не заданы ни a, ни b, то выведутся все строки программы (так же, как при нажатии F2).

Для удаления набранных строк используется команда

DELETE a,b

где a и b имеют тот же смысл, что и у команды DISPLAY, но аргумент a обязательно должен быть.

Для загрузки уже существующей на диске программы необходимо выполнить команду

@<спецификация файла с программой на GPSS>

например,

@GAUNETS.GPS

После исполнения такой команды начнется построчная загрузка программы на GPSS в память компьютера с одновременной ее трансляцией. После завершения загрузки введенную программу можно запускать на счет либо редактировать с помощью внутреннего редактора. Следует отметить, что программу на GPSS можно набирать с помощью любого текстового редактора, работающего с ASCII-файлами.

Введенную или отредактированную программу, как правило, необходимо сохранить в файле на диске, для чего следует набрать на клавиатуре и исполнить команду

SAVE <спецификация файла>, a, b

где аргументы a и b имеют тот же смысл и правила использования, что и в команде DISPLAY (см. выше).

3.3.Запуск на счет и управление процессом моделирования

Запуск на счет вновь введенной или прочитанной с диска программы осуществляется путем исполнения команды

START a,c ,

где a - начальное значение счетчика завершения, c - отсутствует или NP (NP - если не нужен выходной файл статистики).

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

Обычно для управления временем моделирования в программу вводится отдельный сегмент вида

GENERATE b

TERMINATE 1

Тогда время моделирования бутет определяться произведением указанных выше параметров a и b.

Для визуального контроля процесса моделирования в пакете предусмотрены окна и микроокна. Окна могут быть высвечены на экране с помощью функциональных клавиш F4,F5,...F10, Всего предусмотрено 7 окон - данных, блоков, устройств, таблиц, многоканальных устройств, позиций, матриц.

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

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

Особенно часто окно блоков используется совместно с нижним горизонтальным меню, в котором имеются пункты CONTINUE, STEP, STOP, UNSTOP, EDIT, INSERT, DELETE, позволяющие редактировать программу непосредственно по блок-схеме из окна блоков. Так, для удаления некоторого блока требуется с помощью клавиш передвижения курсора совместить курсор с данным блоком и нажать на клавишу Ins, затем вернуть курсор на горизонтальное меню, совместив его с пунктом DELETE и вновь нажать на клавишу Ins. Аналогично выполняются и другие пункты - останов и продолжение моделирования (STOP и CONTINUE), снятие условия останова (UNSTOP), редактирование оператора блока (EDIT), вставка блока (INSERT).

В окне устройств (facilities) помещается информация о текущем состоянии устройств - их имена, интегральные коэффициенты загрузки (Ut), величины очереди к устройствам (Q), средние времена пребывания сообщений в устройстве Av.time) и некоторая другая информация. Эти данные приведены частично в графическом виде, что облегчает визуальный контроль за процессом моделирования.

В окне многоканальных устройств (storages) помещается информация о многоканальных устройствах (МУ). Информация приводится в форме, близкой к форме представления в окне устройств. Поскольку МУ в данный момент времени может быть занято частично, то помимо интегрального коэффициента загрузки Ut и длины очереди к устройству Q, здесь также выводится информация о проценте загрузки МУ в текущий момент времени (Part Used) и количество сообщений в устройстве в текущий момент времени(Content).

В окне таблиц (Tables) выводятся гистограммы выходных данных модели, формируемые пользователем в программе моделирования с помощью описаний TABLE или QTABLE и оператора- блока TABULATE.

В окне матриц (matrices) отображаются текущие значения элементов матриц.

В окне позиций при необходимости отображается процесс моделирования в виде совокупности неподвижных и перемещающихся объектов (мультипликация)

Микроокна заводятся с помощью команды MICROWINDOWS непосредственно с клавиатуры или при исполнении программы, если среди ее операторов имеется такая команда. В последнем случае микроокно откроется только при загрузке такой программы с диска, но не после внесения команды MICROWINDOWS в программу с помощью внутреннего редактора. Микроокно представляет собой прямоугольную рамку, внутри которой указывается номер микроокна, задаваемый короткий текст (до 8 символов) и отображаемое значение (стандартный числовой атрибут - СЧА или СЧА$параметр). Максимальное количество микроокон - 4. Микроокна располагаются в правой части всех окон, кроме окна данных. Указанная команда имеет синтаксис:

MICROWINDOWS a,b;c ,

где a - номер микроокна (от 1 до 4),

b - отображаемый СЧА или СЧА$параметр,

c - короткий текст (до 8 символов).

Для вывода значений СЧА и выражений в текущий момент модельного времени используется также команда SHOW. Для этого необходимо приостановить процесс моделирования путем нажатия клавиши ESC или другим способом (например, с помощью нижнего горизонтального меню) и с клавиатуры набрать команду

SHOW a ,

где a - выражение GPSS.

Имеются и некоторые другие средства вывода информации - команды EVENTS, ANOVA, GROUPS, USERCHAINS, PLOT, с которыми можно ознакомиться по технической документации [1].

3.4.Вывод итоговых результатов моделирования

В отличие от других языков программирования, в языке GPSS нет специальных средств для формирования отчетов об итогах моделирования. Здесь имеются две возможности - воспользоваться стандартным файлом отчета либо формировать нестандартный отчет в подпрограмме HELP на языке FORTRAN. Последнее требует наличия компилятора FORTRAN в составе программного обеспечения персональной ЭВМ. В большинстве случаев стандартный отчет удовлетворяет потребности пользователей.

Он формируется автоматически в файле REPORT.GPS либо в файле с заданным именем с помощью команды REPORT. Кроме того, имеются средства (команды RESULT и ANOVA) для вывода и статистической обработки значений ячеек сохраняемых величин.

Так, если требуется получить математическое ожидание и стандартное отклонение ячеек сохраняемых величин с именами NAME1 и NAME2, необходимо в программе моделирования в нужном месте поместить операторы

RESULT FILE.RES,NAME1,1

...

RESULT FILE.RES,NAME2,2

...

ANOVA FILE.RES .

Первые два оператора помещаются в тех местах программы, где уже известны значения NAME1 и NAME2, последний оператор обычно задают в виде команды с клавиатуры терминала либо в конце программы моделирования. Здесь FILE.RES - спецификация файла результатов моделирования, числа 1 и 2 задают так называемые уровни обработки. Уровни обработки позволяют различать выборки различных случайных величин в одном файле результатов. После работы команды ANOVA на экране терминала для каждого уровня обработки будут выведены математическое ожидание (Mean) и стандартное отклонение (Std.Dev).

Изучение методов трансляции выражений в польскую инверсную запись (ПОЛИЗ).

Постановка задачи

Разработать программу для трансляции выражений в ПОЛИЗ логического выражения в языке Pascal.

Таблица приоритетов.

Метод построения ПОЛИЗА основан на использовании стека с приоритетами, позволяющего изменить порядок следования знаков операций в выражении так, что получается ПОЛИЗ. При этом каждому ограничителю, входящему в выражение, присваивается приоритет. Для знаков операции приоритеты возрастают в порядке, обратном старшинству операций. Скобки имеют низший приоритет.

В логических выражениях языка Pascal приоритеты у операций следующие:

1. not

2. *, /, and

3. +, -, or, xor

4. =, <>, <, >,<=, >=

Для программы приоритеты у знаков будут следующие:

0. (

1. )

2. =, <>, <, >, <=, >=

3. +, -, or, xor

4. *, /, and

5. not

Описание входных и выходных данных

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

Операция

Код

+

+

-

-

*

*

/

/

=

=

<>

 

!

<

 

<

 

>

 

>

 

<=

l

>=

g

not

n

and

a

or

o

xor

x

Выходными данными является строка, содержащая ПОЛИЗ. Кодирование в ней такой же, как и во входной строке.

Также в программе применяется внутреннее кодирование символов для удобства построения ПОЛИЗА. Кодирование следующее: если символ операнд, то он не кодируется (остаётся таким же), если символ знак операции, то первый бит его кода принимает значение ‘1’, следующие три бита содержат приоритет, а последние четыре номер в массиве знаков операции. (const char ChInSt[]={'(', ')', 'n', '*', '/', 'a', '+', '-', 'o', 'x', '=', '!', '<', '>', 'g', 'l', '#'};)

Для работы используется стек с элементами типа char.

Описание алгоритма

Арифметическое или логическое выражение рассматривается как входная строка символов. Входная строка рассматривается слева направо. Операнды переписываются в выходную строку, а знаки операций помещаются вначале в стек операций.

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

Особенности имеет лишь обработка скобок. Открывающаяся круглая скобка, имеющая "особый" приоритет нуль, просто записывается в вершину стека и не выталкивает ни одного знака. В то же время ее не может вытолкнуть ни один знак, кроме закрывающей скобки.

Закрывающая скобка имеет приоритет 1, не превосходящий приоритет любой операции. Поэтому появление закрывающей скобки вызывает выталкивание всех знаков до ближайшей открывающей скобки включительно. В стек закрывающая скобка не записывается. Открывающая и закрывающая скобки как бы взаимно уничтожаются и в выходную строку не переносятся.

После просмотра всех символов входной cтроки происходит выталкивание всех оставшихся в стеке символов и дописывание их к выходной строке.

Тестовые примеры

1. Входная строка – “A+B”

Result:

AB+

2. Входная строка – “A+B!3”

Result:

AB+3!

3. Входная строка – “A+B=3*ZaC!2”

Result:

AB+3Z*Ca=2!

4. Входная строка – “A*(B+C)<7”

Result:

ABC+*7<

5. Входная строка – “A*(B-C/(L-9))gM”

Result:

ABCL9-/-*Mg

Текст программы

stack.h

template <class T> class Stack;

template <class T>

class Node

{

friend class Stack<T>;

private:

T *node;

Node<T> *p;

public:

Node (const T &t);

~Node();

};

template <class T>

class Stack

{

private:

Node<T> *lp;

public:

Stack();

~Stack();

void Push(T);

bool Pop(T *);

};

stack.cpp

//---------------------------------------------------------------------------

#include "stack.h"

#include <stddef.h>

//---------------------------------------------------------------------------

template <class T>

Node<T>::Node (const T &t): node(new T(t)), p(NULL){}

//---------------------------------------------------------------------------

template <class T>

Node<T>::~Node()

{

if (p)

delete p;

delete node;

}

//---------------------------------------------------------------------------

template <class T>

Stack<T>::Stack(): lp(NULL){}

//---------------------------------------------------------------------------

template <class T>

Stack<T>::~Stack()

{

if (lp)

delete lp;

}

//---------------------------------------------------------------------------

template <class T>

void Stack<T>::Push(T n)

{

Node<T> *new_node=new Node<T>(n);

new_node->p=lp;

lp=new_node;

}

//---------------------------------------------------------------------------

template <class T>

bool Stack<T>::Pop(T *n)

{

if (lp)

{

*n=*(lp->node);

Node<T> *del_node=lp;

lp=lp->p;

del_node->p=NULL;

delete del_node;

}

else return 0;

return 1;

}

//---------------------------------------------------------------------------

lab5.cpp

//---------------------------------------------------------------------------

#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused

//---------------------------------------------------------------------------

#include <iostream.h>

#include <conio.h>

#include "stack.cpp"

#include <string.h>

//---------------------------------------------------------------------------

const char ChInSt[]={'(', ')', 'n', '*', '/', 'a', '+', '-', 'o', 'x', '=', '!', '<', '>', 'g', 'l', '#'};

char *POLIZ(char *);

char *Code(char *);

char *Decode(char *);

//---------------------------------------------------------------------------

void main()

{

clrscr();

char st[200], *resP, *res;

cout<<"Input string"<<endl;

cin>>st;

res=Code(st);

resP=POLIZ(res);

delete res;

res=Decode(resP);

cout<<"Result:"<<endl<<res<<endl;

getch();

delete res, resP;

}

//---------------------------------------------------------------------------

char *POLIZ(char *st)

{

Stack<char> s;

char n;

int prior, j=0;

char *res=new char[strlen(st)];

for (unsigned int i=0; i<strlen(st); i++)

{

if (!(st[i]&0x80))

{

res[j++]=st[i];

continue;

}

if (st[i]&0x0F)

{

prior=st[i]&0x70;

while (s.Pop(&n))

if ((n&0x70)>=prior)

res[j++]=n;

else

{

if (prior!=0x10)

s.Push(n);

break;

}

}

if (prior!=0x10)

s.Push(st[i]);

}

while (s.Pop(&n))

res[j++]=n;

res[j]=0;

return res;

}

//---------------------------------------------------------------------------

char *Code(char *st)

{

char *res=new char[strlen(st)+1];

strnset(res, 0, strlen(st)+1);

int j;

for (unsigned int i=0; i<strlen(st); i++)

{

for (j=0; j<17; j++)

if (st[i]==ChInSt[j])

break;

switch (j)

{

case 0: res[i]=0x80; break;

case 1: res[i]=j+0x90; break;

case 2: res[i]=j+0xD0; break;

case 3: case 4: case 5: res[i]=j+0xC0; break;

case 6: case 7: case 8: case 9: res[i]=j+0xB0; break;

case 10: case 11: case 12: case 13: case 14: case 15: res[i]=j+0xA0; break;

case 17: res[i]=st[i];

}

}

return res;

}

//---------------------------------------------------------------------------

char *Decode(char *st)

{

char *res=new char[strlen(st)+1];

for (unsigned int i=0; i<strlen(st); i++)

{

if (st[i]&0x80)

res[i]=ChInSt[st[i]&0x0F];

else res[i]=st[i];

}

res[strlen(st)]=0;

return res;

}

//---------------------------------------------------------------------------

Изучение команд языка Ассемблер, предназначенных для обработки строк символов.

 

Постановка задачи

Разработать программу формирования информационного кадра для передачи по локальной вычислительной сети. Формат кадра следующий:

    ПП

Данные

КС

КК

ПП - преамбула (4 байта с кодом 55Н);

Данные - поле данных (16 байт);

КС - контрольная сумма (2 байта);

КК - конец кадра (1 байт с кодом 1FН).

Под формированием понимается заполнение поля данных кадра и формирование контрольной суммы. Данные для передачи хранятся в области памяти с именем SDATA и представляют собой последовательность 16 символов из набора от A до Z и от 0 до 9. При формировании кадра данные необходимо зашифровать согласно таблице кодировки.

Контрольная сумма формируется как арифметическая сумма всех байт поля данных.

В лабораторной работе использовать команды работы со строками:

LODS,STOS и др.

Таблицы кодировки:

A

Q

K

3

U

R

3

M

B

L

L

D

V

9

4

V

C

O

M

X

W

B

5

N

D

T

N

7

X

H

6

E

E

W

O

4

Y

5

7

Y

F

G

P

U

9

0

8

J

G

Z

Q

P

Z

8

 

 

H

C

R

6

0

I

 

 

I

1

S

Z

1

F

 

 

J

A

T

S

2

K

 

 

Описание алгоритма

  1. В строку-результат записывается преамбула.
  2. Далее в цикле, который повторяется 16 раз, выполняются следующие действия:
    1. загрузка очередного символа из строки с данными;
    2. поиск соответствующего символа в первой строке таблицы кодировки;
    3. вычисление адреса соответствующего закодированного символа (к адресу второй строки таблицы прибавляется значение регистра СХ) и сохранение его в регистре АL;
    4. запись этого символа в строку-результат.
  3. Установка значения регистра SI на адрес начала данных в выходной строке.
  4. Подсчёт контрольной суммы (в цикле загружается каждый символ строки и складывается с значением в регистре ВХ в результате в ВХ будет храниться контрольная сумма).
  5. Запись контрольной суммы в выходную строку.
  6. Запись признака конца кадра в выходную строку.

Описание входных и выходных данных

Входными данными являются исходная строка данных, таблица кодирования, преамбула и признак конца кадра. Исходная строка данных представляется как обычная строка, преамбула и признак конца кадра задаются как обычные последовательности байт, а таблица кодирования представляется двумя строками.

Выходными данными является кадр. Для него резервируется место в 23 байта.

Текст программы

;------------------------------------------------------

LAB6 SEGMENT

ASSUME CS:LAB6,DS:LAB6,SS:LAB6

ORG 100H

BEGIN: JMP MAIN

;------------------------------------------------------

SDATA DB 'SDFSD12YGVF6RT92'

PP DB 4 DUP(55H)

KK DB 1FH

ABC DB 'ABCDEFGHIJKLMNOPQRSTUVWXY9Z012345678'

ABC_C DB 'QLOTWGZC1A3DX74UP6ZSR9BH508IFKMVNEYJ'

RES DB 23 DUP(?)

;------------------------------------------------------

MAIN: CLD

LEA SI,PP

LEA DI,RES

MOV CX,2

REP MOVSW

LEA SI,SDATA

MOV CX,16

CYCLE: LODSB

MOV DX,DI

LEA DI,ABC+35

MOV BX,CX

STD

MOV CX,36

REPNE SCASB

MOV BP,CX

ADD BP,OFFSET ABC_C

MOV AL,[BP]

MOV DI,DX

CLD

STOSB

MOV CX,BX

LOOP CYCLE

XOR BX,BX

XOR AX,AX

MOV CX,16

LEA SI,RES+4

CHECK: LODSB

ADD BX,AX

LOOP CHECK

MOV AX,BX

STOSW

MOV AL,KK

STOSB

INT 20H

LAB6 ENDS

END BEGIN

;------------------------------------------------------

Результаты тестирования

В результате работы программы вы из строки 'SDFSD12YGVF6RT92' должны получить следующее

55Н 55Н 55Н 55Н

‘ZTGZTFK5Z9GE6S0K’

8CH 04H (1164)

1FH

В результате работы получено:

clip_image002

Результата находится по адресам [0160]-[0177]

Вывод

В результате работы мною были изучены команд языка Ассемблер, предназначенных для обработки строк символов.