adfun.ru
| |
BIGLIB |
| большущая библиотека (9812 книг), можно не только прочитать но и скачать бесплатно |
|
| |
ФАНТАСТИКА |
| фентези,
фантастика, фантастические повести |
|
| |
ФИЛОСОФИЯ |
книги, которые заставляют
задуматься над окружающим тебя миром.
|
|
| |
МЕДИЦИНА |
медицинские книги,
методички,
народные лечебники |
|
| |
КУЛИНАРИЯ |
рецепты
тортов, консервирование,
все о спиртных
напитках. |
|
| |
СТИХИ |
| стихи популярных
и не очень авторов |
|
| |
ТВОРЧЕСТВО |
| народное творчество,
стихи, песни и т.д. |
|
| |
ЮМОР |
| анекдоты, приколы,
смешные истории |
|
| |
ЭРОТИКА |
| эротические рассказы,
книги о технике секса,
кама-сутра и др. |
|
|
| |
 |
равна смещению (в байтах) от начала структуры, содержащей этот
элемент. Рассмотрим следующий программный фрагмент:
struct myStruct (
int a_a;
int a_b;
int a_c;
) myA ;
myfunc()
(
...
asm mov ax,myA.a_b
- 435,436 -
asm mov bx,[di].a_c
...
)
Мы объявили тип структуры, названной myStruct, с 3 членами:
a_a, a_b, a_c, а также объявили переменную myA типа myStruct.
Первый оператор встроенного ассемблера заносит величину из
myA.a_b в регистр AX. Второй заносит величину по адресу [di] +
смещение (a_c) в регистр BX (оператор берет адрес, сохраненный в
DI, и добавляет к нему смещение а_с от начала myStruct). В этой
последовательнности ассемблеровские операторы производят следую-
щую программу:
mov ax, DGROUP : myA+2
mov bx, [di+4]
Для чего вам может это понадобиться сделать? Если вы загру-
жаете регистр (такой, как DI) адресом структуры типа myStruct, то
вы можете использовать имена, для того чтобы непосредственно ука-
зывать элементы. Имя элемента может быть использовано в любой по-
зиции, где численная константа разрешена в операнде утверждения
ассемблера.
Элемент структуры должен начинаться с точки (.) для того,
чтобы указывать, что используется имя члена структуры, а не нор-
мальный идентификатор Си. Имена элементов замещаются в ассембле-
ровском коде числовыми смещениями элементов в структуре (числовое
смещение а_с есть 4), но тип информации не сохраняется. Поэтому
элементы могут быть использованы только во время компиляции ас-
семблеровских операторов.
Однако, есть одно ограничение: если две структуры используют
одно и то же имя элемента, вы должны имя элемента заключить в
круглые скобки, сделав его как бы ядром.
- 437,438 -
Использование команд перехода и меток
-----------------------------------------------------------------
Во встроенном ассемблере вы можете использовать любые услов-
ные и безусловные команды перехода, а также команды цикла. Все
они имеют силу только внутри функции. Так как в операторах asm не
могут быть даны метки, команды перехода должны использовать
Си-метки операторов goto как объекты перехода. Прямые far-перехо-
ды не могут генерироваться.
Также допускаются косвенные переходы. Для того, чтобы ис-
пользовать косвенный переход, вы можете применить имя регистра
как операнд команды перехода. В следующей программе переход идет
к Си-метке "а" оператора goto.
int x()
{
a: /* Это goto метка "а" */
. . .
asm jmp a /* Переход к метке "а" */
. . .
}
Функции прерываний
-----------------------------------------------------------------
Микропроцессор 8086 резервирует первые 1024 байта памяти для
набора 256 удаленных указателей (называемых векторами прерываний)
на специальные системные подпрограммы обработки прерываний. Эти
подпрограммы вызываются выполнением команды
int <целое число>,
где <целое число> принимает значения от 0h до ffh. По этой коман-
де компьютер сохраняет программный сегмент (CS), указатель команд
(IP) и флажки состояния, запрещает прерывания и затем делает уда-
ленный переход к программе обработки, соответствующей вектору
прерывания. Например, прерывание
int 21h
вызывает большинство ДОС подпрограмм. Одако многие вектора преры-
ваний незадействованы. Вы можете написать свой собственный обра-
ботчик прерывания и установить удаленный указатель на него в од-
ном из неиспользуемых векторов.
- 439,440 -
Для того, чтобы написать обработчик прерывания на Турбо Си,
необходимо определить функцию типа interrupt. Более точно это
должно выглядеть так:
void interrupt myhandler (bp, di, si, es, dx, cx,bx, ax,
ip, cs, flags, ...);
Как вы можете видеть, все регистры передаются как параметры,
так что вы можете использовать и модифицировать их в программе
без применения псевдопеременных, рассмотренных ранее в этой гла-
ве. Также заметим, что вы можете иметь дополнительные параметры
(flags, ...), передаваемые обработчику. Они определяются соответ-
ственно.
Функции типа interrupt будут автоматически сохранять ( в до-
полнение к SI, DI и BP) регистры от AX до DX, ES и DS. Эти же ре-
гистры восстанавливаются при выходе из обработчика прерывания.
Во всех моделях памяти обработчики преревания могут исполь-
зовать арифметические операции с плавующей точкой. Всякий обра-
ботчик прерываний, который использует сопроцессор 8087/80287,
должен сохранять его состояние и при выходе восстанавливать его.
Функция прерывания может видоизменять свои параметры. Изменение
объявленных параметров будет модифицировать соответствующий ре-
гистр при выходе из обработчика. Это удобно, когда используется
обработчик прерывания для обслуживания запросов пользователя, то
есть аналогично сервисному запросу ДОСа INT 21. Также заметим,
что выход из обработчика прерываний осуществляется командой
IRET(возвращение из прерывания).
Зачем же вам писать свой собственный обработчик прерываний?
Прежде всего затем, чтобы он работал, как работают большинство
резидентных программ. Они устанавливают сами себя как обработчики
прерываний. Таким образом, всякий раз, когда происходят какие-ли-
бо специальные или периодические действия (переключение часов,
нажатие клавиши на клавиатуре и т.п.), эти программы перехватыва-
ют обращения к подпрограммам обработки прерываний и определяют,
какое действие необходимо произвести. Выполнив это, они затем мо-
гут передать управление исходной подпрограмме обработки прерыва-
ний.
- 441,442 -
Примеры программирования на низком уровне
-----------------------------------------------------------------
Вы уже видели несколько примеров того, как использовать раз-
личные приемы программирования на низком уровне в вашей програм-
ме; теперь пришло время заглянуть немного дальше. Для начала вы
будете писать реальный обработчик прерываний, который делает неч-
то безобидное и хорошо видимое (или, в данном случае, слышимое).
Это будет звуковой сигнал, вызванный откуда-нибудь.
Во-первых, вам нужно написать функцию как таковую. Она будет
выглядеть таким образом:
#include
void interrupt mybeep(unsigned bp, unsigned dl, unsigned si,
unsigned ds, unsigned es, unsigned dx,
unsigned cx, unsigned bx, unsigned ax)
{
int i,j;
char originalbits,bits;
unsigned char bcount = ax >> 8;
/* Получить текущие установки управляющего порта */
bits = originalbits = inportb (0x61);
for (i = 0; i <= bcount; i++){
/* На время отключить динамик */
outportb(0x61, bits & 0xfc);
for (j = 0; j <= 100; j++)
; /* пустой оператор*/
/* Теперь включить его на определенное время */
outportb(0x61, bits | 2);
for (j = 0; j <= 100; j++)
; /* другой пустой оператор*/
}
|
adfun.ru
|
|
|
|