Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Прямое обращение к памяти и портам ввода-вывода




В Турбо Паскале имеется пять предварительно объявленных массивов: MEM, MEMW, MEML, PORT и PORTW. Первые три обеспечивают доступ к любому участку оперативной памяти по абсолютному адресу, два других - доступ к портам ввода-вывода.

Компонентами массива MEM являются данные типа BYTE, массива MEMW - типа WORD, массива MEML - типа LONGINT. Обращение к элементам этих массивов, т.е. их индексация, имеет специальный вид: каждый индекс представляет собой абсолютный адрес и состоит из двух выражений типа WORD; первое дает сегментную часть адреса, второе - смещение; выражения разделяются двоеточием. Например:

Меm[$0000:$1000]:= 0;

DataMem:= MemWfSeg(p):0fs(p)];

MemLong:.= MemL [64: i*SizeOf (real) ];

Как следует из технического описания операционной системы MS-DOS, в памяти по адресу $F000:$FFFE располагается байт-указатель типа компьютера. Следующая программа (пример 11.5) прочтет этот байт и выведет на экран тип Вашего ПК.

Пример 11.5

begin

Write (' Тип компьютера: ');

case Mem [$FOOO:$FFFE] of

$FF: WriteLn ('PC');

$FE: WriteLn('XT');

$FD: WriteLn('PCjr');

$FC: WriteLn('AT');

$F9: WriteLn('совместимый с PC')

end

end.

Компонентами массива PORT являются байты (тип BYTE), а массива PORTW - слова (тип WORD). Индексами этих массивов должно быть выражение типа BYTE, указывающее номер нужного порта. Присвоение значения элементу массива PORT или PORTW приведет к записи в порт, упоминание элемента в выражении - к чтению из порта. Компоненты массивов PORT и PORTW нельзя передавать в качестве параметров процедурам или функциям. Эти идентификаторы не употребляются без индексных выражений.

ДЛИННЫЕ СТРОКИ

Среда Турбо Паскаль 7.0 обладает весьма интересным новшеством: в ней введена поддержка длинных строк, т.е. строк, длина которых может превышать 255 байт. Как известно, тип String в Турбо Паскале имеет максимальную длину 255 байт. Это связано с тем, что истинная длина строки в этом типе указывается первым байтом, мощность которого не позволяет определять строки большей длины. В то же время в языке С используется другой подход к заданию текстовых строк: первый байт строки является ее первым символом, второй байт - вторым символом и т.д. пока не встретится байт с символом #0. Таким образом, длина строки не указывается явно, как в типе String, а определяется по замыкающему символу #0. Ясно, что такие строки могут иметь произвольную длину, ограничиваемую лишь объемом оперативной памяти или принятой схемой ее адресации: в MS-DOS такой границей является длина сегмента, поэтому максимально возможная длина С-строки для ПК составляет 65535 символов. Такие строки в дальнейшем будем называть ASCIIZ-строками.

Для реализации операций над ASCIIZ-строками в язык введен новый тип PChar, определяемый как указатель на символ:

type

PChar =^Char;

Однако такой обычный для Паскаля тип-указатель в рамках Турбо Паскаля 7.0 трактуется необычным способом: считается, что он указывает на цепочку символов, заканчивающуюся терминальным нулем, т.е. на ASCIIZ-строку. Более того, с этим типом совместим любой одномерный символьный массив с нулевой левой границей, а переменные типа PChar можно индексировать, как если бы они были массивами символов. Следующая программа напечатает все заглавные буквы английского алфавита:

{$Х+} {Включаем расширенный синтаксис}

var

Chars: array [0..26] of Char; {Массив символов}

PChars: PChar; {Указатель на символ}

k: Integer;

begin

for k:= 0 to 25 do

Chars[k]:= Chr(k+ord('A'); {Наполняем массив}

PChars:= Chars; {Указателю присваиваем массив!}

PChars[26]:= #0; {Индексируем указатель!}

WriteLn(PChars) {Печатаем указатель!}

end.

Три последние оператора программы недопустимы в стандартном Паскале и в ранних версиях Турбо Паскаля, но возможны в версии 7.0, если включен расширенный синтаксис (директивой {$Х+} или опцией Options/Compiler/Extended syntax). Обратите внимание: процедура WriteLn этой версии умеет работать с ASCIIZ-строками.

Для поддержки ASCIIZ-строк разработан модуль Strings, в котором реализованы необходимы процедуры и функции.

Функция StrCat. Объединяет строки. Заголовок:

Function StrCat(Dest, Source: PChar): PChar;

Копирует строку Source в конец строки Dest и возвращает указатель на начало Dest.

Функция StrComp. Сравнивает строки. Заголовок:

Function StrComp(Strl, Str2: PChar): Integer;

Побайтно сравнивает строку Strl со строкой Strl и возвращает следующий результат:

=0 Strl=Str2;

>0 Strl>Str2;

<0 Strl<Str2.

Функция StrCopy. Копирует строку. Заголовок:

Function StrCopy(Dest, Source: PChar): PChar;

Копирует строку Source в строку Dest и возвращает указатель на Dest. StrCopy не проверяет реальный размер памяти, связанный с Dest (он должен быть не меньше StrLen(Source)+1).

Процедура StrDispose. Удаляет строку из кучи. Заголовок:

Procedure StrDispose(Str: PChar);

Строка Str должна быть предварительно помещена в кучу функцией StrNew. Если Str=NIL, процедура ничего не делает.

Функция StrECopy. Объединяет строки. Заголовок:

Function StrECopy(Dest, Source: PChar): PChar;

Эта функция работает в точности как StrCat, но возвращает указатель на конец сцепленных строк, т.е. на терминальный ноль.

Функция StrEnd. Возвращает конец строки. Заголовок:

Function StrEnd(Str: PChar): PChar;

Функция возвращает указатель на терминальный ноль ASCIIZ-строки Str.

Функция StrlComp. Сравнивает строки. Заголовок:

Function StrlComp(Strl, Str2: PChar): PChar;.

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

Функция StrLCat. Объединяет строки. Заголовок:

Function StrLCat(Dest, Source: PChar; MaxLen: Word): PChar;

Копирует символы строки Source в конец строки Dest до тех пор, пока не будут скопированы все символы или когда длина сцепленной строки Dest не достигнет MaxLen. Возвращает указатель на сцепленную строку.

В отличие от StrCopy эта функция блокирует возможное переполнение области памяти, связанной с Dest. Обычно в качестве MaxLen используется выражение SizeOf (Dest) -1. Например:

{$Х+}

Uses Strings;

var

S: array [0..9] of Char;

begin

StrCopy(S, 'Turbo');

StrLCat(S, ' ', SizeOf(S)-1);

StrLCat(S, 'Pascal', SizeOf(S)-1);

WriteLn(S) {Напечатает "Turbo Pas"}

end;

Функция StrLComp. Сравнивает строки. Заголовок:

Function StrLComp(Dest, Source: PChar; MaxLen: Word): PChar;

В отличие от StrComp сравнивает не более MaxLen символов строк. Возвращаемый результат такой же, как и у StrComp.

Функция StrLCopy. Заголовок:

Function StrLCopy(Dest, Source: PChar; MaxLen: Word): PChar;

Копирует символы из строки Source в строку Dest до тех пор, пока не будет скопирована вся строка или пока не будет скопировано MaxLen символов. В отличие от StrCopy блокирует возможное переполнение области памяти, связанной с Dest. В качестве MaxLen обычно используется выражение SizeOf (Dest) -1. Например:

{$Х+}

Uses Strings;

var

S: array [0..9] of Char;

begin

StrLCopy(S, 'Turbo Pascal', SizeOf(S)-1);

WriteLn(S) {Напечатает "Turbo Pas"}

end;

Функция StrLen. Возвращает длину строки. Заголовок:

Function StrCattStr: PChar): Word;

Функция StrLIComp. Сравнивает строки с учетом регистра. Заголовок:

Function StrLIComp(Str1, Str2: PChar; MaxLen: Word): PChar;

Сравнивает не более MaxLen символов строк, проверяя точное соответствие высоты букв. Возвращаемый результат см. StrComp. Функция правильно работает только с латиницей.

Функция StrLower. Преобразует в строчные буквы. Заголовок:

Function StrLower(Str: PChar): PChar;

Преобразует заглавные буквы строки Str к строчным и возвращает указатель на результат. Функция правильно работает только с латиницей.

Функция StrMove. Копирует строку. Заголовок:

Function StrMove(Dest, Source: PChar; Count: Word): PChar;

Копирует точно Count символов строки Source в строку Dest и возвращает указатель на результат. Функция игнорирует действительные размеры строк и может выйти за их пределы.

Функция StrNew. Помещает строку в кучу. Заголовок:

Function StrNew(Str: PChar): PChar;

Функция Str Pas. Преобразует ASCHZ-строку в строку String. Заголовок:

Function StrPas(Str: PChar,): String;

Функция StrPCopy. Преобразует строку String в ASCIIZ-строку. Заголовок:

Function StrPCopy(Str: PChar; S: String): PChar;

Возвращает указатель на Str.

Функция StrPos. Ищет подстроку. Заголовок:

Function StrPos(Strl, Str2: PChar): PChar;

Ишет подстроку Str2 в строке Strl и возвращает указатель на первое вхождение Str2 или NIL, есди подстрока не найдена.

Функция StrRScan. Ищет последний символ. Заголовок:

Function StrRScan(Str: PChar; Ch: Char): PChar;

Ищет символ Ch в строке Str и возвращает указатель на последний обнаруженный символ Ch или NIL, если символ не найден.

Функция StrScan. Ищет первый символ. Заголовок:

Function StrScan(Str: PChar; Ch: Char): PChar;

Ищет символ Ch в строке Str и возвращает указатель на первый обнаруженный символ Ch или NIL, если символ не найден.

Функция StrUpper. Заголовок:

Function StrLower(Str: PChar): PChar;

Преобразует строчные буквы строки Str к заглавным и возвращает указатель на результат. Функция правильно работает только с латиницей.

Четыре функции модуля Strings (StrLower, StrUpper, StrlComp и StrLIComp) используют преобразование высоты букв и работают корректно только для букв латинского алфавита (латиницы). Для русских букв эти функции можно изменить следующим образом:

{Этот модуль содержит модификацию функций стандартного модуля Strings для работы с кириллицей (альтернативный вариант кодировки}

{$Х+}

Unit StringsR;

INTERFACE

Function LoCase(Ch: Char): Char;

Function UpCase(Ch: Char): Char;

Function StrLower(Str: PChar): PChar;

Function StrUpper(Str: PChar): PChar;

Function StrlComp(Strl, Str2: PChar): Integer;

Function StrLIComp(Strl, Str2: PChar; MaxLen: Word): Integer;

IMPLEMENTATION

Uses Strings;

Function LoCase(Ch: Char): Char;

{Преобразует латинскую или русскую букву Ch к строчной}

begin

case Ch of

'A'..'Z':LoCase:= Chr(ord('a')+ord(Ch)-ord('A'));

'A'..'П':LoCase:= Chr(ord('a')+ord(Ch)-ord('A'));

'P'..'Я':LoCase:= Chr(ord('p')+ord(Ch)-ord('P'));

else

LoCase:= Ch

end

end;

{-------------------}

Function UpCase(Ch: Char): Char;

{Преобразует латинскую или русскую букву Ch к заглавной}

begin

case Ch of

'a'..'z': UpCase:= Chr(ord('A')+ord(Ch)-ord('a'));

'a'..'n': UpCase:= Chr(ord('A')+ord(Ch)-ord('a'));

'p'..'я': UpCase:= Chr(ord('P')+ord(Ch)-ord('p'));

else

UpCase:= Ch

end

end;

{-------------}

Function StrLower(Str: PChar): PChar;

{Преобразует латинские и русские буквы строки Str к строчным}

var

k: Word;

begin

for k:= 0 to StrLen(Str)-1 do

Str[k]:= LoCase(Str[k]);

StrLower:= Str

end;

{-----------}

Function StrUpper(Str: PChar): PChar;

{Преобразует латинские и русские буквы строки Str к заглавным}

var

k: Word;

begin

for k:=0 to StrLen(Str)-1 do

Str[k]:= UpCase(Str[k]);

StrUpper:= Str

end;

{------------}

Function StrlComp (Str1, Str2: PChar): Integer;

{Сравнивает две строки, игнорируя возможную разницу в высоте латинских или русских букв}

var

k: Word;

Max: Word;

begin

{Определяем максимальное количество сравниваемых символов как минимум длин строк}

Мах:= StrLen(Str1);

if StrLen (Str2).<Max then

Max:= StrLen(Str2);

{Проверяем символы до первого несовпадения.Буквы преобразуем к заглавным}

for k:= 0 to Max-1 do

if UpCase(Strl[k])<>UpCase(Str2[k]) then

begin

{Строки не равны}

StrIComp:= ord(UpCase(StrlCk]))-ord(UpCase(Str2[k]));

Exit

end;

{Разницы нет - результат зависит от совпадения длин}

StrIComp:= StrLen(Str1)-StrLen(Str2)

end;

{--------------}

Function StrLIComp(Str1, Str2: PChar; MaxLen: Word): Integer;

{Сравнивает не более MaxLen символов строк, проверяя точное соответствие высоты букв}

var

k. Max: Word;

begin

{Определяем максимальное количество сравниваемых символов как минимум длин строк и MaxLen}

Мах:= MaxLen;

if StrLen(Strl)<Max then Max:= StrLen(Strl);

if StrLen(Str2)<Max then Max:= StrLen(Str2);

{Проверяем символы до первого несовпадения.Буквы преобразуем к заглавным}

for k:= 0 to Max do

if UpCase(Str1 [k])<>UpCase(Str2[k]) then

begin

StrLIComp:= ord(UpCase(Str1[k]))-ord(UpCase(Str2[k]));

Exit

end;

{Разницы нет. Если проверено MaxLen символов, строки считаются равными, в противном случае результат зависит от совпадения длин строк}

if Max=MaxLen then

StrLIComp:= 0

else

StrLIComp:= StrLen(Str1)-StrLen(Str2)

end;

end.

Если Вы будете использовать этот модуль, ссылайтесь на него в предложении Uses после ссылки на стандартный модуль Strings:

Uses Strings, StringsR,...

· Глава 12. ВСТРОЕННЫЙ АССЕМБЛЕР

o 12.1. Общее описание МП 8086/8088

§ 12.1.1. Регистры

§ 12.1.2. Адресация

§ 12.1.3. Система команд

o 12.2. Специфика встроенного ассемблера

§ 12.2.1. Оператор ASM

§ 12.2.2. Синтаксис ассемблерных команд

§ 12.2.3. Директивы ассемблера

§ 12.2.4. Ассемблерные подпрограммы

Глава 12

ВСТРОЕННЫЙ АССЕМБЛЕР

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

В этой главе рассматриваются приемы программирования с помощью ассемблера, встроенного в компилятор Турбо Паскаля. Встроенный ассемблер имеется в версиях 6.0 и 7.0 Турбо Паскаля и в руках опытного программиста представляет собой мощный инструмент, позволяющий «выжать» из ПК все возможное.

Поделиться:





Читайте также:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...