откуда прерывания знают адрес, куда им вернуть результат.
Прерывания не знают. Это работа ОС -- организовать информацию так, чтобы при получении прерывания разобраться, откуда оно, зачем, и что с ним делать.
Прерывание в коде int 21h и прочие Это какое?
Любое прерывание инициируемое инструкцией
int
-- программное. В отличие от прерывания, инициируемого уровнем или фронтом сигнала подключённого к контроллеру прерываний.
Вообще, кажется, если понять, что программные прерывания на x86 используются просто как удобный способ вызывать функции ядра, т.е. делать системные вызовы, то путаницы должно стать меньше. Не думай о них как о прерываниях, думай о них просто как о вызовах функций ядра. Ядро делает всё для того, чтобы для приложения это именно так и выглядело.
выполнение прерывания std::cin>>line; Может и сутки длиться.
Системного вызова.
std::cin >>line
в конце концов превращается в системный вызов
read
.
Вот как по пунктам для этой команды. (С условием что есть еще 1 поток жаждущий ЦП).
Можно запустить такую программу, узнать её PID, выполнить где-нибудь
cat /proc/<PID>/stack
и увидеть следующую картину:
[<0>] wait_woken+0x67/0x80
[<0>] n_tty_read+0x426/0x5a0
[<0>] tty_read+0x135/0x240
[<0>] new_sync_read+0x115/0x1a0
[<0>] vfs_read+0xf4/0x180
[<0>] ksys_read+0x5f/0xe0
[<0>] do_syscall_64+0x33/0x80
[<0>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
Т.е. поток выполнил системный вызов (ksys_read), зашёл в VFS, добрался до функции чтения в драйвере терминала (tty_read) и перешёл в состояние ожидания в глубине этой функции (wait_woken). Когда драйвер терминала получит данные для программы, он разбудит её поток и системный вызов завершится. До тех пор этот поток будет не готов к выполнению и скедулер ОС просто не будет выделять ему время.
Мне кажется, что тебе было бы полезно прочитать вторую и третью книжки (Understanding the Linux Kernel и Linux Kernel Developmen) из
моего списка.