Выполнить программное прерывание в реальном режиме
#include <x86/v86.h>int _intr_v86( int swi,struct _v86reg *regs,void *data,int datasize );
_v86reg
, со значениями, которые необходимо использовать в реальном режиме.libc
Функция _intr_v86() выполняет программное прерывание реального режима, указанное swi в виртуальном режиме 8086. Это дает доступ к функциям ROM BIOS, которые предназначены для запуска в 16-и битном режиме. Примеры:
Прерывание | Описание |
---|---|
int 10h | Видео BIOS |
int 1ah | PCI |
Вызовы BIOS (такие как int 13h
, ввод/вывод диска), которые требуют аппаратных прерываний, не поддерживаются.
После входа в реальный режим, регистры загружаются из regs. Сегментные регистры и указатели должны обращаться к 2 КБ области взаимодействия, расположенной со смещением 0:800h в реальной памяти. Буфер data, размером datasize скопируется в эту область, прямо перед входом в реальный режим, и скопируется обратно, когда вызов завершится. regs также обновятся, и будут содержать значения регистров реального режима.
Вы должны установить сегментные регистры DS, ES, FS и GS в 0. Значения в CS:IP, и SS:SP регистрах игнорируются и устанавливаются ядром. Доступный стек имеет размер около 500 байт.
Схема распределения памяти реального режима описывается структурой _v86_memory
в <x86/v86.h>
.
Когда поток входит в виртуальный режим 8086, все потоки в системе продолжают планироваться в соответствии с их приоритетом, включая вызвавший их поток. Находясь в виртуальном режиме 8086, поток имеет полный доступ к управлению портами ввода/вывода, а также включению или отключению прерываний. Одновременно только один поток может войти в виртуальный режим 8086.
Функция завершится с ошибкой, если вызывающий процесс не имеет эффективного ID пользователя root (euid 0
).
#include <stdio.h>#include <stdlib.h>#include <stddef.h>#include <errno.h>#include <x86/v86.h>struct _v86reg reg;int main( void ){char buf[4];/* Equipment call */printf( "int 12\n" );memset( ®, 0, sizeof( reg ) );_intr_v86( 0x12, ®, NULL, 0 );printreg();sleep( 5 );/* Enter 40 column text mode */printf( "int 10 ah=00h al=00h\n" );memset( ®, 0, sizeof( reg ) );_intr_v86( 0x10, ®, NULL, 0 );printreg();sleep( 5 );/* Enter 80 column text mode */printf( "int 10 ah=00h al=02h\n" );memset( ®, 0, sizeof( reg ) );reg.eax = 2;_intr_v86( 0x10, ®, NULL, 0 );printreg();sleep( 5 );/* Write a string from memory */printf( "int 10 ah=13h al=00h\n" );strcpy( buf, "Hi!" );memset( ®, 0, sizeof( reg ) );reg.eax = 0x1300;reg.es = 0;reg.ebp = offsetof( struct _v86_memory, userdata );reg.ecx = strlen( buf );reg.edx = 0;reg.ebx = 0x0007;_intr_v86( 0x10, ®, buf, strlen( buf ) );printreg();sleep( 5 );return (EXIT_SUCCESS);}void printreg(){printf( "eax=%-8x ebx=%-8x ecx=%-8x edx=%-8x\n",reg.eax, reg.ebx, reg.ecx, reg.edx );printf( "esi=%-8x edi=%-8x ebp=%-8x esp=%-8x\n",reg.esi, reg.edi, reg.ebp, reg.esp );printf( " ds=%-8x es=%-8x fs=%-8x gs=%-8x\n",reg.ds, reg.es, reg.fs, reg.gs );printf( "efl=%-8x\n\n", reg.efl );}
ЗОСРВ «Нейтрино»
Предыдущий раздел: Описание API системной библиотеки