Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Системный Си.doc
Скачиваний:
3
Добавлен:
01.04.2025
Размер:
98.3 Кб
Скачать

2.2. Доступ к оперативной памяти

В Си-программе программист имеет возможность прочитать и записать данные по абсолютному адресу памяти, а также определить физические адреса памяти, по которым располагаются переменные его программы. Для чтения данных из памяти испольэуются функции:

int peek(unsigned int segm, unsigned int offs);

char peekb(unsigned int segm, unsigned int offs);

Для записи данных в память испольэуются функции:

void poke(unsigned int segm, unsigned int offs, int val);

void pokeb(unsigned int segm, unsigned int offs, char val);

Аргументы этих функций: segm - сегментный адрес памяти, offs - смещение в сегменте. Функции peek и peekb возвращают прочитанное значение, а в функциях poke и pokeb записываемое в память значение задается аргументом val. Функции peekb и pokeb работают с одним байтом, peek и poke - с двухбайтным словом. Следует помнить, что слово в памяти ПЭВМ хранится в двух последовательных байтах памяти, причем в байте с меньшим адресом - младшая часть слова. Поэтому при побайтном (peekb) чтении из двух последовательных адресов мы получим сначала младшую, а затем старшую часть слова, а при чтении слова (peek) - целое слово, в котором обе части находятся "на своих местах".

Определение физических адресов переменных возможно благодаря наличию в языке Си данных типа "указатели", представляющих собой адреса переменных. Указатель может быть преобразован в физический адрес при помощи макросов:

unsigned int FP_SEG(void far *ptr);

unsigned int FP_OFF(void far *ptr);

которые возвращают сегментную часть адреса и смещение соответственно. Обратное преобразование производится макросом:

void far *MK_FP(unsigned int segm, unsigned int offs);

Следует учитывать, что внутреннее представление указателей зависит от модели памяти, в которой транслируется программа или от явного описания. Указатель может быть либо ближним (явное описание: near) и представляться двухбайтным смещением в текущем сегменте, либо дальним (явное описание: far) и иметь четырехбайтное представление - сегментная часть адреса и смещение. Указанные макросы работают только с дальними указателями.

Программные примеры данного пособия компилируются в модели памяти large (если в тексте программы не указана другая модель). По умолчанию в этой модели все указатели являются far. При компиляции в той модели памяти, где указатель по умолчанию near необходимо включить в описания всех указателей явные описатели far.

2.3. Порты ввода-вывода

Для чтения данных из порта испольэуются функции:

int inport(int port);

unsigned char inportb(int port);

Для записи данных в порт испольэуются функции:

void outport(int port, int val);

void outportb(int port, unsigned char val);

Аргумент этих функций port - номер порта ввода-вывода. Функции inport и inportb возвращают прочитанное из порта значение, а в функциях outport и outportb записываемое в порт значение задается аргументом val. Функции inportb и outportb работают с однобайтными, а inport и outport - с двухбайтными портами. Программист должен точно знать, работает он с одно- или с двухбайтным портом. Применение функций inport, outport к однобайтным портам может привести к весьма неожиданным результатам. Так, например, оператор программы:

outport(0x20,0x11);

(а 0x20 - однобайтный порт) эквивалентен двум операторам: outportb(0x20,0x11); outportb(0x21,0);