Автор Тема: Прекъсване 80 - int $0x80  (Прочетена 4644 пъти)

LinC

  • Участници
  • ***
  • Публикации: 5
    • Профил
Прекъсване 80 - int $0x80
« -: Jun 17, 2013, 17:55 »
Здравейте,
Има ли някой който може да ми даде линкове и насоки за въпросното прекъсване. Опитвам се да вграждам асемблерски код в C под линукс. Намерих информация на френски, но няма много примери. Опитвам се да направя простичка програма, която приема въвеждане от клавиатурата само на цифри, примерно. Под Windows има много информация и нещата могат да станат, но под линукс удрам на камък.
Благодаря!
Активен

laskov

  • Напреднали
  • *****
  • Публикации: 3166
    • Профил
Re: Прекъсване 80 - int $0x80
« Отговор #1 -: Jun 17, 2013, 18:11 »
Хич не съм наясно с това, но прекъсване 80 не е ли софтуерно прекъсване, което го има в MS-DOS и вероятно в Windows. Ако е така, в Линукс не би трябвало да търсиш такова. Има прекъсвания, които се обслужват от BIOS-а, но не съм сигурен, че Линукс ги ползва въобще ...
ПС Ама като питах гугъл, попаднах на едни такива работи: http://asm.sourceforge.net/intro/hello.html
« Последна редакция: Jun 17, 2013, 18:19 от laskov »
Активен

Не си мислете, че понеже Вие мислите правилно, всички мислят като Вас! Затова, когато има избори, идете и гласувайте, за да не сте изненадани после от резултата, и за да не твърди всяка партия, че тя е спечелила, а Б.Б. (С.С., ...) е загубил, а трети да управлява.  Наздраве!  [_]3

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: Прекъсване 80 - int $0x80
« Отговор #2 -: Jun 17, 2013, 19:50 »
int 80h е софтуерно прекъсване и handler-а се инсталира от ядрото при boot-ване. Това е системното прекъсване в линукс, нещо като int 21h в DOS.
Активен

"Knowledge is power" - France is Bacon

LinC

  • Участници
  • ***
  • Публикации: 5
    • Профил
Re: Прекъсване 80 - int $0x80
« Отговор #3 -: Jun 18, 2013, 19:52 »
Това е системното прекъсване в линукс, нещо като int 21h в DOS.
За съжаление, обаче, откривам и съществени разлики. Например не мога да го накарам да чете от клавиатурата без ехо. >:( Под линукс нещо не мога да се оттърва от линейното буфериране и това започва да става досадно. Ще се радвам някой да даде съвет.  ::)
Активен

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: Прекъсване 80 - int $0x80
« Отговор #5 -: Aug 13, 2013, 08:17 »
Предполагам ползваш read syscall-а за да четеш от стандартния вход. Нещото което първо трябва да разбереш е че ти дефакто не четеш директно от клавиатурата, четеш от някакъв терминал, по стечение на обстоятелствата там ходи клавиатурния вход, можеше да е примерно през ssh отдалечено и тогава това няма общо с клавиатурата на машината. В ядрото има отделна tty подсистема. Конкретно поведението, което те интересува се контролира с ioctl-та. На малко по-високо ниво виж линковете по-горе. Аз бих постъпил по следния начин: написвам си на C един прост пример с termios дето си играе с флаговете на терминала (и съответно забранява echo-то). Компилирам я и strace-вам, за да видя какви syscall-ове вика. Съответно си ги имплементирам на асемблер.

Тук да вметна един коментар за безсмислието на цялата работа, но ти си знаеш, пък и не е лошо да си играеш. Само да не забравиш да върнеш флаговете обратно после, че ще си осереш терминала иначе.
Активен

"Knowledge is power" - France is Bacon

zxz

  • Напреднали
  • *****
  • Публикации: 615
  • Distribution: Linux Mint 18.2
  • Window Manager: XFCE
    • Профил
Re: Прекъсване 80 - int $0x80
« Отговор #6 -: Aug 13, 2013, 09:09 »
Ползвай прекъсванията от биос-а, те са за всякакви ОС и работят бързо.
http://www.ctyme.com/intr/int.htm
« Последна редакция: Aug 13, 2013, 09:12 от zxz »
Активен

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: Прекъсване 80 - int $0x80
« Отговор #7 -: Aug 13, 2013, 22:32 »
Пробвал ли си, да видиш какво ще стане :)

BIOS прекъсвания в защитен режим....има някакъв минимален шанс все пак някоя функция да мине, но много силно ме съмнява. BIOS-ките handler-и са предвидени да се изпълняват в real mode и съответно са 16-битов код. Най-вероятното което ще се случи е програмата да гръмне със segfault.
Активен

"Knowledge is power" - France is Bacon

zxz

  • Напреднали
  • *****
  • Публикации: 615
  • Distribution: Linux Mint 18.2
  • Window Manager: XFCE
    • Профил
Re: Прекъсване 80 - int $0x80
« Отговор #8 -: Aug 14, 2013, 20:52 »
Преди време исках да си правя ОС, стигнах до накъде и се отказах, там съм ги ползвал, ама все пак, там не са в защитен режим и няма какво да ги ограничава. Може и да работят някои от тях трябва да пробвам. Аз под бозата със фасм ползвах това за вход :
   mov cx,12h ; това някъде в програмата където искаш да ползваш функцията 12h е дължината на стринга
   jmp readkey
 
   readkey:
   mov ah,01h ;getchar
   int 21h
   dec cx
   cmp cx,6h
   jg readkey
   ret
« Последна редакция: Aug 14, 2013, 20:56 от zxz »
Активен

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: Прекъсване 80 - int $0x80
« Отговор #9 -: Aug 15, 2013, 01:03 »
Мисля все пак че ако е за четене от клавиатурата, няма нужда от BIOS-ки прекъсвания, може да се чете от порта (60 и нещо беше, не знам, трябва да се провери). Разбира се,  това няма как да стане от ring3, но има един фокус, поне на x86 архитектура, има една системна функция, iopl(), която сетва IOPL-то. iopl(3) и си в джаза, можеш директно да четеш/пишеш по портове, дори да забраниш прекъсванията (който твърди че даден процес не може да забие системата, мога да го опровергая с 5-6 реда код на C, ехех). За това обаче трябват root права. Допълнително, така се месиш в работата на клавиатурния драйвер прескачаш tty слоя и ще си имаш проблеми (като например ще прихващаш натиснати клавиши от произволно друго tty, което е активно в момента). И като цяло е идиотско занимание.

Това също така би следвало да работи само за PS/2 клавиатури, USB клавиатурите минават по други пътища. Ако имаш права над usb устройството, предполагам можеш да си напишеш прост userspace-ски драйвер за клавиатурата с libusb, но това е също толкова извратено ако цялата идея е просто да чакаш вход от клавиатура без echo.

Като цяло не виждам смисъл за такива неща да се хабиш да го правиш на асемблер (аз и не виждам почти никакъв смисъл в 99.99% от случаите да вграждаш асемблерски код в C такъв, резултатът в 99.99% от случаите са скъсани нерви и краен ефект, който не оправдава очакванията).


П.П сега като се замисля има и (вероятно) начин да ползваш BIOS-ките прекъсвания, но не съм 100% сигурен. Принципно съществува "виртуален" 8086 режим, който се използва от разни емулатори и (предполагам) от уиндоус-а, за да подкарва ДОС програми. Как се влиза в него нямам идея, май ставаше с някакво системно извикване, но може и да греша. В този режим, адресирането на паметта става по същия начин там със сегмента и отместването и real mode код би трябвало да работи (въпреки че за прекъсванията не знам). Още повече че не знам веднъж влезеш ли в този режим дали можеш да се върнеш обратно. Като се има предвид обаче че искаш да пишеш native линукс код, а не нещо осакатено, което насилваш процесора да емулира, не знам дали е добра идея. Ама все пак би било забавно :)
« Последна редакция: Aug 15, 2013, 01:18 от gat3way »
Активен

"Knowledge is power" - France is Bacon

zxz

  • Напреднали
  • *****
  • Публикации: 615
  • Distribution: Linux Mint 18.2
  • Window Manager: XFCE
    • Профил
Re: Прекъсване 80 - int $0x80
« Отговор #10 -: Aug 15, 2013, 10:29 »
Това може да се пробва с досбокс, понеже върви виртуално и не вярвам да прави проблем ако нещо по кода е усрано. Или пък на една виртулка със виртуалбокс. Като цяло аз дори като пробвах да взема от клавиатурата със бозовскине интеръпти усещам забавяне.. не знам на какво се дължи това, но има известно забавяне около 0.5сек докато се появи символът, който си написал. Ако се цели бързодействие, няма да стане по този начин.
Активен

kifavi8024

  • Новаци
  • *
  • Публикации: 0
    • Профил
Re: Прекъсване 80 - int $0x80
« Отговор #11 -: Aug 15, 2013, 13:10 »
Ама аз пак не мога да разбере, каква е целта?
Търси се независимост на приложението от гледна точка на OS/библиотеки ли?
Ако е така може би има някакъв смисъл от такава реализация, но ако аргумента е бързодействие, просто тотално не си заслужава...
Активен

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: Прекъсване 80 - int $0x80
« Отговор #12 -: Aug 17, 2013, 01:43 »
Няма никакъв смисъл, независимостта се постига с езици от по-високо ниво, примерно Java или Python. Отделно бързодействието (в случаят с четене от клавиатурата няма никакво значение) е нещо много забавно. Винаги много ме е кефило когато някой ми обясни как нещо щял да го пренапише на асемблер и щяло да бъде 10000 пъти по-бързо и накрая го състезаваме с C кода, който генерира gcc и се оказва че последния е няколко пъти по-бърз. Истинското изкуство е да накараш C компилатора да ти генерира качествен код. В днешно време, C компилаторите са ужасно хитри копеленца и особено ако им знаеш изпълненията, можеш да докаращ доволно  бързо нещо, което асемблаторите няма въобще да докарат лесно и все ще забравят някоя подробност. Има редки частни случаи когато нещата може да са различни, но в общият случай когато чуя как някой щял нещо да направи на асемблер с порядъци по-добре, обикновено ми светва червената лампа "гавра".

Типичният пример с един колега от старата фирма, който много силно желае да разбере как работи всичко и да има пълен контрол над всичко, веднъж ми беше разправял как спорил с един идиот като мен за нещо просто (от сорта на strcpy()). Та пичът го реализирал на асемблер от-до както трябвало там с зареждането в регистър,проверката къде е нулевия байт, установяването на брояча, REP MOVSW и т.н. и накрая се оказало че все пак gcc генерирал по-бърз код. Тръгнали да го дизасемблират и се оказало че gcc генерира абсолютно същият код, само че с няколко NOP операции в повече, които на всичкото отгоре били "мъртъв" код, демек не се изпълнявали изобщо. Нямало никаква логика да работи по-бързо, докато не се сетили че имало near call, който при gcc-то бил чудесно align-нат на 32 бита заради pad-ването с NOP-ове, докато в асемблерския код това не било така. Само "наказанието" от процесора за прескачане на unaligned адрес било достатъчно да осере състезанието.. И такива неща.
« Последна редакция: Aug 17, 2013, 02:02 от gat3way »
Активен

"Knowledge is power" - France is Bacon

ivo1204

  • Напреднали
  • *****
  • Публикации: 987
    • Профил
Re: Прекъсване 80 - int $0x80
« Отговор #13 -: Aug 18, 2013, 22:57 »
Доколко си спомням /беше отдавна като се рових в това/ Линукс не пипа биоските прекъсвания, само ги проверява, но не ги променя. Въпреки че може изцяло да ги подмени.Но си ползва биоса както си е.
ПП. Все пак това е в конфигурацията на ядрото и някой мозък от убунтувците  например може да я щракне, така че избягвай да работиш директво с тях,а и според мен не е това решението.
« Последна редакция: Aug 18, 2013, 23:08 от ivo1204 »
Активен