Страница 53 из 56
равна смещению (в байтах) от начала структуры, содержащей этот
элемент. Рассмотрим следующий программный фрагмент:
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 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++)
; /* другой пустой оператор*/
}