Организацию прямого доступа к памяти с помощью указателей рассмотрим на примере обращения к памяти видеоадаптера в текстовом режиме монитора с разрешением экрана 80*25 позиций. Как известно, видеопамять при этом начинается с адреса B800:0000 и состоит из пар байт "символ‑атрибут", описывающих экранные позиции слева направо и затем сверху вниз.
static unsigned char far *s =
(unsigned char far *) 0xB8000000UL;
void putc (int x, int y, char c) {
*(s+y*160+x*2)=c;
}
void main () {
putc (0,0,'*'); putc (79,0,'*');
putc (0,24,'*'); putc (79,24,'*');
//вывели звездочки по краям
//текстового экрана
}
Модификатор far определяет "длинный" 4-байтовый указатель (см. п. 11).
Поскольку одна строка экрана консоли состоит из 80 символов и требует 160 байт памяти, конструкция *(s+y*160+x*2), где x – экранный столбец, а y – строка, адресует на экране позицию в y‑строке и x‑столбце.
Учитывая, что операции сдвига порождают более быстрый код, чем умножение, а 160=128+32=27+25, в функции putc лучше использовать присваивание вида
*(s+ (y<<7) + (y<<5) + (x<<1)) = c;