LINUX.ORG.RU

asm & interupts


0

0

Решил немного изучить асемблер. Пишу например функию
getkey:
mov ah,00
int 0x16

компилю:
$nasm -f elf gk.s
$ld -s gk.o
$./a.out
и получаю сегфолт. через gdb вижу что сегфолт в вызове int.
Внимание вопрос: Что я делаю неправильно и если в коде все нормально то почему не работает? Желательно еще и ссылочки по теме.

tnx

P.S. nasm(версию непомню тк пост не из дома, но помоему 38 или 39 в конце),Slackware 10.0, 2.4.26

anonymous
Ответ на: комментарий от no1sm

Хмм... Мне нужно чтобы работало не под емулятором, хотя это тоже вариант. Проверю. Еще идеи есть? кстати погляньте в
$grep -R getkey /usr/src/linux/arch/i386/boot/

anonymous
()
Ответ на: комментарий от Begemoth

>А с чего ты решил, что в коде все правильно?

Ну так напиши что не так

anonymous
()
Ответ на: комментарий от anonymous

>Мне нужно чтобы работало не под емулятором

Говори как сказали. Когда доучишься до режимов процессора и 32-х битного кода - все поймешь сам. Либо учись на кошках (в винде) - там нужная тебе эмуляция встроена для поддержки dos-вских программ. Ты же dos-й код пишешь.

kosmonavt
()
Ответ на: комментарий от kosmonavt

ЗЫ

Для *.com файлов код должен начинаться со смещения 100h

kosmonavt
()

> и получаю сегфолт. через gdb вижу что сегфолт в вызове int.

потому, что команда привилегированная, даже root не поможет.

не говоря уже том, что getkey вы все равно никак не получили бы.

idle ★★★★★
()
Ответ на: комментарий от idle

Дело не том, что инструкция привилигированная (int кстати таковой не является), а том, что в linux он пытается использовать прерывания BIOS (его кажется, у DOS 21h).

ЗЫ: А syscall в linux вызываются прерыванием 80h (на х86)

Begemoth ★★★★★
()

ЗЗЫ: Язык ассемблера "немного" не изучают, это не Васик или Паскакаль.

Begemoth ★★★★★
()

>Что я делаю неправильно и если в коде все нормально то почему не
>работает?

1) native linux приложения не работают в 16-битном режиме
2) 0x16 скорее всего не соответствует шлюз прерывания(и не должен), поэтому попытка передать туда управление не имеет смысла

anonymous
()
Ответ на: комментарий от Begemoth

> Дело не том, что инструкция привилигированная (int кстати
> таковой не является)

верно, коряво я выразился.

> а том, что в linux он пытается использовать прерывания BIOS
> (его кажется, у DOS 21h).

точнее, наверное, будет все таки сказать, что для того, чтобы
"int N" сработало, нам нужно иметь idt_table[N].dpl == 3, я
это имел в виду под привилегиями.

хотя то, что вы сказали, конечно верно, а я был соврамши.

idle ★★★★★
()
Ответ на: комментарий от Begemoth

>что в linux он пытается использовать прерывания BIOS

Возникает вопрос, а это невозможно? потомучто именно это я и хочю проделать.

>чтобы "int N" сработало, нам нужно иметь idt_table[N].dpl == 3, я
>это имел в виду под привилегиями.

Тоесть если я правильно понимаю, то надо править файлы ядра и пересобирать ядро?

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от anonymous

>> что в linux он пытается использовать прерывания BIOS

> Возникает вопрос, а это невозможно? потомучто именно это я и хочю проделать.

1. Нет (по-хорошему). В принципе если находиться в кольце 0, то можно перейти в реальный режим вызвать прерывание, вернуться в защищенный режим. Но этого лучше не делать.

2. BIOS работатет в реальном режиме и поэтому устарела. Не нужно ее использовать в новых программах (кроме как bootloader'ах и коде ядра до перехода в защищенный режим).

> Тоесть если я правильно понимаю, то надо править файлы ядра и пересобирать ядро?

Надо читать Intel Architecture Software Developers Manual том 3 до полного просветления. Но тебе (поскольку ты еще учишь язык ассемблера х86) это рановато.

Вывод: 1. Если хочешь использовать прерывания BIOS пиши DOS-программы. 2. Если программы должны работать в Linux - use int 80h

Begemoth ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.