<Int 16h> Прерывание BIOS при сборке GCC в Linux?

Я использую QTCreator 3.5.1 и виртуальную ОС Linux Mint 18.3 Cinnamon 32-bit, компилятор GCC.

Мне нужно написать код, который использует прерывания, получая нажатие клавиши на клавиатуре с помощью ассемблерных команд.

Код, который должен был работать в Windows, выглядит следующим образом:

#include <iostream>
unsigned char x;
int main()
{
 do {
 __asm {
 mov ah, 00h
 int 16h
 mov x, ah
 };
 std::cout <<"The pressed key code is "<< x << std::endl;
 } while (true);
}

Хотя он не работает ни в Windows 98, ни в скомпилированном с помощью Visual Studio 2003 в Windows 7x32, ни в любых других системах Windows, что приводит к ошибке во время выполнения или завершению работы моей системы (в Windows 98).

Поэтому я переключился на Linux, и следующий пример кода сборки из http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html (часть 7) работает очень хорошо:

#include <iostream>
using std::cout;
int main(void)
{
        int foo = 10, bar = 15;
        __asm__ __volatile__("addl  %%ebx,%%eax"
                             :"=a"(foo)
                             :"a"(foo), "b"(bar)
                             );
        printf("foo+bar=%d\n", foo);
        return 0;
}

(Чтобы он работал правильно, мне также пришлось указать версию компилятора (GCC x86 32bit в usr/bin) в «Desktop Kit» в QT Creator Tool-> Options и рабочую версию QT 4.8.7, последняя версия 5.5 .1 выдает ошибку "установлен неправильно, пожалуйста, запустите make install")

Хотя я изо всех сил пытаюсь понять концепцию прерываний и как прерывание «int 16h» должно работать в Linux со встроенной сборкой GCC, каков синтаксис и как я могу получить код любой нажатой клавиши клавиатуры?

Поскольку вы работаете с Qt (очевидно), не было бы более уместно использовать что-то вроде this, а не пытаться перехватывать события клавиатуры на уровне биоса (что вряд ли будет настроено на одно и то же прерывание в разных операционных системах). системы).

πάντα ῥεῖ 23.12.2020 02:42
int 16h — это служба BIOS. Он работает только в реальном режиме и обычно используется в загрузчиках или программах DOS. К нему нельзя получить доступ ни из Windows (любая версия, если только не выполняется программа DOS, в этом случае служба эмулируется), ни из Linux (любая версия), ни из любой другой операционной системы защищенного режима в этом отношении.
fuz 23.12.2020 02:43

В упражнении указано, что вы должны использовать int 16h? Какие еще подробности указаны? Вы можете читать входные данные, используя встроенный ассемблер в Linux (хотя я бы не рекомендовал делать это вне учебных занятий). В Windows это тоже возможно, но правильный вызов зависит от версии Windows.

fuz 23.12.2020 02:45

@fuz, да. В этом проблема, в моем академическом упражнении указано, что я должен использовать int 16h

Ivan Silkin 23.12.2020 02:57

@IvanSilkin Вы уверены, что они не хотят, чтобы вы написали программу для DOS или загрузчик? Вы можете писать программы на C для DOS с помощью встроенного ассемблера, используя некоторые старые наборы инструментов, что позволит вам выполнить это упражнение. Двумя недавними поддерживающими это являются ia16-gcc и Open Watcom, хотя требуется некоторая возня, чтобы заставить их выдавать рабочие двоичные файлы.

fuz 23.12.2020 02:59

По словам людей из #winapi в Freenode, возможно, действительно можно было вызвать int 16h из программы Win32 в Windows 98, но тогда вызов мог привести к зависанию в BIOS. Очень странно.

fuz 23.12.2020 03:39

@fuz, да, система зависает и ничего не распознает, кроме ctrl+alt+del.

Ivan Silkin 23.12.2020 04:06

@IvanSilkin Попробуйте уговорить Visual Studio создать приложение Win16 или DOS.

fuz 23.12.2020 04:19

Вы уверены, что вам не сказали использовать Turbo-C++ (или Borland C) для написания программы для DOS. У вас есть полная копия задания, которое вы можете опубликовать здесь, чтобы показать нам, в чем именно состоит ваше задание? Единственная другая вещь, о которой я могу думать, это если бы вы использовали что-то вроде MSVC 1.52, у которого была версия C++, которая все еще могла генерировать программы для DOS. Если у вас установлена ​​32-разрядная версия Windows, эта программа DOS будет работать внутри виртуальной машины WIndows DOS (NTVDM).

Michael Petch 23.12.2020 05:51

@fuz, ваш комментарий от «23 декабря в 1:43» дал мне статус завершения практической работы, не могли бы вы также записать его как ответ?

Ivan Silkin 27.12.2020 09:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
371
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Для современных систем; во время загрузки ОС берет на себя управление всем оборудованием из прошивки, и после этого прошивка становится непригодной для использования (поскольку нельзя предполагать, что ни одно из аппаратных средств не находится в состоянии, ожидаемом прошивкой). Затем ОС запускает свои собственные драйверы, которые предназначены для ОС, и используют IRQ, и работают с планировщиком операционной системы (и не тратят время на опрос ЦП), и работают для нескольких ЦП, и правильно поддерживают память (и не t ограничен 640 КиБ).

Это означает, что прерывание BIOS «int 0x16» может работать, только если:

а) Вы используете ОС, ставшую неактуальной более 20 лет назад (MS-DOS)

б) Вы используете ОС, которая выполняет много дополнительной работы для эмуляции ОС, которая стала неактуальной более 20 лет назад (например, «устаревшая совместимость с DOS», встроенная в Windows95, а не какой-либо исполняемый файл Windows, предназначенный для Windows).

c) Вы не используете операционную систему, а компьютер настолько старый, что в нем установлена ​​прошивка BIOS (вместо этого новые компьютеры перешли на UEFI).

Мне нужно написать код, который использует прерывания, получая нажатие клавиши на клавиатуре с помощью ассемблерных команд.

Я бы еще раз проверил, что ты должен делать. Например. «использует прерывание» может означать «использование старого 32-битного API-интерфейса ядра Linux (int 0x80), а не устаревших функций BIOS» (и это может означать «использование устаревшего чипа контроллера PS/2 IRQ (как это делает драйвер устройства)» , или что-то другое).

Более конкретно; Я предполагаю, что вы следовали инструкциям, которые включали «установить старую 32-разрядную версию Linux на виртуальную машину», потому что вы должны использовать старый API ядра Linux («int 0x80») для выполнения эквивалента « read(STDIN_FILENO, buffer, 1);" на языке ассемблера (чтобы получить байт из чего бы то ни было stdin, который может или не может быть получен с клавиатуры в зависимости от того, как ваш исполняемый файл запускается/используется).

Ответ принят как подходящий

Сервис int 16h — это сервис BIOS. Он работает только в реальном режиме и обычно используется в загрузчиках или программах DOS. К нему нельзя получить доступ ни из Windows (любая версия, если только не выполняется программа DOS, в этом случае служба эмулируется), ни из Linux (любая версия), ни из любой другой операционной системы защищенного режима в этом отношении.

По словам людей из #winapi в Freenode, возможно, было бы возможно вызвать int 16h из программы Win32 в Windows 98, но тогда вызов может привести к зависанию в BIOS. В любом случае, это не полезно для достижения вашей цели.

Чтобы решить вашу проблему, либо напишите программу для DOS, используя цепочку инструментов DOS, такую ​​как ia16-gcc, Open Watcom или старую версию MSVC, либо используйте службу защищенного режима, поддерживаемую операционной системой, для которой вы программируете.

Другие вопросы по теме