сокращая длинную историю, это означает, что инструкции DO IT для инструкции были раньше.
Юда Правира
2
@YudaPrawira: вы должны думать о более ранних инструкциях как о настройке аргументов в регистрах и int 0x80как об особом виде callфункции в ядре (выбранной eax).
Питер Кордес
Почему вы сказали "БЫЛО использовано?" Он больше не используется?
Лига,
129
intозначает прерывание, а число 0x80- это номер прерывания. Прерывание передает поток программы тому, кто обрабатывает это прерывание, которое 0x80в данном случае является прерыванием . В Linux 0x80обработчиком прерывания является ядро, и оно используется для выполнения системных вызовов ядра другими программами.
Ядро уведомляется о том, какой системный вызов программа хочет сделать, проверяя значение в регистре %eax(синтаксис AT&T и EAX в синтаксисе Intel). Каждый системный вызов предъявляет разные требования к использованию других регистров. Например, значение 1in %eaxозначает системный вызов exit(), а значение in %ebxсодержит значение кода состояния для exit().
Вы можете увидеть здесь , что INTэто только один из многих инструкций ( на самом деле представление ассемблера (или я должен сказать «Мнемоника») из нее) , которая существует в наборе команд x86. Вы также можете найти дополнительную информацию об этой инструкции в собственном руководстве Intel, которое можно найти здесь .
Подведем итоги из PDF:
INT n / INTO / INT 3 - вызов процедуры прерывания
Инструкция INT n генерирует вызов обработчика прерывания или исключения, указанного в операнде назначения. Операнд-адресат определяет вектор от 0 до 255, закодированный как 8-битовое промежуточное значение без знака. Инструкция INT n - это общая мнемоника для выполнения программного вызова обработчика прерывания.
Как видите, 0x80 - это операнд назначения в вашем вопросе. На этом этапе ЦП знает, что он должен выполнить некоторый код, который находится в ядре, но какой код? Это определяется вектором прерывания в Linux.
Одним из наиболее полезных программных прерываний DOS было прерывание 0x21. Вызывая его с разными параметрами в регистрах (в основном ah и al), вы можете получить доступ к различным операциям ввода-вывода, строковому выводу и многому другому.
Большинство систем Unix и их производных не используют программные прерывания, за исключением прерывания 0x80, используемого для выполнения системных вызовов. Это достигается путем ввода 32-битного значения, соответствующего функции ядра, в регистр EAX процессора и последующего выполнения INT 0x80.
Взгляните на это, пожалуйста, где показаны другие доступные значения в таблицах обработчиков прерываний:
Как вы можете видеть, таблица указывает ЦП на выполнение системного вызова. Вы можете найти здесь таблицу системных вызовов Linux .
Таким образом, переместив значение 0x1 в регистр EAX и вызвав INT 0x80 в своей программе, вы можете заставить процесс выполнять код в ядре, который остановит (завершит) текущий запущенный процесс (в Linux, x86 Intel CPU).
Не следует путать аппаратное прерывание с программным прерыванием. Вот очень хороший ответ на этот счет.
Ссылка на таблицу системных вызовов Linux не работает = \
Мигель Анджело
1
Большинство систем Unix и их производных не используют программные прерывания (за исключением int 0x80). Это может показаться странным. int 0x80I386 Linux системного вызова ABI очень похож на DOS int 0x21ABI. Поместите номер вызова в регистр (AH для DOS, EAX для Linux) и другие аргументы в другие регистры, затем запустите инструкцию программного прерывания. Основное различие заключается в том, что системные вызовы позволяют вам делать (доступ к оборудованию непосредственно в DOS, но не в Linux), а не в том, как вы их вызываете.
Питер Кордес
Вот ссылка на неразрывную таблицу системных вызовов. syscalls.kernelgrok.com Просто разверните его, чтобы все вызовы отображались вверху.
Оллин,
При использовании 64-битной Linux вы можете увидеть системный вызов, доступный по адресу/usr/include/x86_64-linux-gnu/asm/unistd_64.h
ton
12
Пример минимального запускаемого системного вызова Linux
Linux настраивает обработчик прерывания 0x80таким образом, чтобы он реализовывал системные вызовы, способ взаимодействия программ пользовательского уровня с ядром.
.data
s:
.ascii "hello world\n"
len = . - s
.text
.global _start
_start:
movl $4, %eax /* write system call number */
movl $1, %ebx /* stdout */
movl $s, %ecx /* the data to print */
movl $len, %edx /* length of the buffer */
int $0x80
movl $1, %eax /* exit system call number */
movl $0, %ebx /* exit status */
int $0x80
Скомпилируйте и запустите с:
as -o main.o main.S
ld -o main.out main.o
./main.out
Результат: программа выводит на стандартный вывод:
hello world
и выходит чисто.
Вы не можете установить свои собственные обработчики прерываний непосредственно из пользовательской среды, потому что у вас есть только кольцо 3, а Linux не позволяет вам это сделать .
Теперь вы можете работать в 16-битном реальном режиме:
movw $handler0, 0x00
mov %cs, 0x02
movw $handler1, 0x04
mov %cs, 0x06
int $0
int $1
hlt
handler0:
/* Do 0. */
iret
handler1:
/* Do 1. */
iret
Это будет по порядку:
Do 0.
Do 1.
hlt: прекратить выполнение
Обратите внимание, как процессор ищет первый обработчик по адресу 0, а второй - по адресу 4: это таблица обработчиков, называемая IVT , и каждая запись имеет 4 байта.
Современные операционные системы работают в так называемом защищенном режиме.
Управление в этом режиме имеет больше возможностей, поэтому он более сложный, но дух тот же.
Ключевым шагом является использование инструкций LGDT и LIDT, которые указывают адрес структуры данных в памяти (таблица дескрипторов прерываний), которая описывает обработчики.
Простой ответ: проще говоря, прерывание - это событие, которое прерывает работу ЦП и сообщает ему о необходимости выполнения определенной задачи.
Подробный ответ :
ЦП имеет таблицу программ обслуживания прерываний (или ISR), хранящуюся в памяти. В реальной (16-бит) режиме, это сохраняется как IVT , или я nterrupt В Ector Т состоянии. IVT обычно располагается по 0x0000:0x0000(физическому адресу 0x00000) и представляет собой серию адресов со смещением сегмента, которые указывают на ISR. ОС может заменить существующие записи IVT своими собственными ISR.
(Примечание: размер IVT фиксирован и составляет 1024 (0x400) байтов.)
В защищенном (32-битном) режиме ЦП использует IDT. IDT - это структура переменной длины, состоящая из дескрипторов (иначе называемых воротами), которые сообщают ЦП об обработчиках прерываний. Структура этих дескрипторов намного сложнее, чем простые записи смещения сегмента в IVT; вот:
bytes 0, 1: Lower 16 bits of the ISR's address.
bytes 2, 3: A code segment selector (in the GDT/LDT)
byte 4: Zero.
byte 5: A type field consisting of several bitfields.
bit 0: P (Present): 0 for unused interrupts, 1 for used interrupts.*
bits 1, 2: DPL (Descriptor Privilege Level): The privilege level the descriptor (bytes 2, 3) must have.
bit 3: S (Storage Segment): Is 0 for interrupt and trap gates. Otherwise, is one.
bits 4, 5, 6, 7: GateType:
0101: 32 bit task gate
0110: 16-bit interrupt gate
0111: 16-bit trap gate
1110: 32-bit interrupt gate
1111: 32-bit trap gate
* IDT может иметь переменный размер, но он должен быть последовательным, т.е. если вы объявляете IDT от 0x00 до 0x50, вы должны иметь каждое прерывание от 0x00 до 0x50. ОС не обязательно использует их все, поэтому бит «Присутствует» позволяет процессору правильно обрабатывать прерывания, которые ОС не намерена обрабатывать.
Когда происходит прерывание (либо внешним триггером (например, аппаратным устройством) в IRQ, либо intинструкцией из программы), ЦП нажимает EFLAGS, затем CS, а затем EIP. (Они автоматически восстанавливаются командой iretвозврата из прерывания.) ОС обычно хранит дополнительную информацию о состоянии машины, обрабатывает прерывание, восстанавливает состояние машины и продолжает работу.
Во многих ОС * NIX (включая Linux) системные вызовы основаны на прерываниях. Программа помещает аргументы системного вызова в регистры (EAX, EBX, ECX, EDX и т. Д.) И вызывает прерывание 0x80. Ядро уже установило IDT, чтобы содержать обработчик прерывания на 0x80, который вызывается, когда он получает прерывание 0x80. Затем ядро считывает аргументы и соответственно вызывает функцию ядра. Он может хранить возврат в EAX / EBX. Системные вызовы в значительной степени заменены инструкциями sysenterand sysexit(или syscalland sysretна AMD), которые позволяют быстрее войти в кольцо 0.
Это прерывание могло иметь другое значение в другой ОС. Обязательно проверьте его документацию.
Интересный факт: системный вызов FreeBSD i386 ABI передает аргументы в стек пользовательского пространства. Только eaxиспользуется для номера системного вызова. asm.sourceforge.net/intro/hello.html
Питер Кордес
2
Как уже упоминалось, это вызывает переход управления к вектору прерывания 0x80. На практике это означает (по крайней мере, в Linux), что вызывается системный вызов; точный системный вызов и аргументы определяются содержимым регистров. Например, exit () можно вызвать, задав для% eax значение 1, за которым следует int 0x80.
Он сообщает процессору, что нужно активировать вектор прерывания 0x80, который в ОС Linux является прерыванием системного вызова, используемым для вызова системных функций, например open()для файлов и т. Д.
Строго говоря, он не сообщает ядру ... Он сообщает ЦП, который ищет обработчик в IDT, который в конечном итоге является указателем на некоторый код ядра.
asveikau
Правда. Я полагаю, что лучше было бы сказать, что ЦП активировал вектор, а вектор (как часть ядра) вызывает функцию.
Эмбер
который в конечном итоге делает это, который в конечном итоге делает то, что затем делает то, что затем сбивается с толку . : / У Эмбер есть понятный ответ .. вот оно что ..
Афзал Ахмад Зишан
1
int - это не что иное, как прерывание, т.е. процессор приостанавливает свое текущее выполнение.
0x80 - это не что иное, как системный вызов или вызов ядра. т.е. системная функция будет выполнена.
Чтобы быть конкретным, 0x80 представляет rt_sigtimedwait / init_module / restart_sys, он варьируется от архитектуры к архитектуре.
Ответы:
Передает управление вектору прерывания 0x80
См. Http://en.wikipedia.org/wiki/Interrupt_vector
В Linux посмотрите на это : он использовался для обработки
system_call
. Конечно, в другой ОС это могло означать совсем другое.источник
int 0x80
как об особом видеcall
функции в ядре (выбраннойeax
).int
означает прерывание, а число0x80
- это номер прерывания. Прерывание передает поток программы тому, кто обрабатывает это прерывание, которое0x80
в данном случае является прерыванием . В Linux0x80
обработчиком прерывания является ядро, и оно используется для выполнения системных вызовов ядра другими программами.Ядро уведомляется о том, какой системный вызов программа хочет сделать, проверяя значение в регистре
%eax
(синтаксис AT&T и EAX в синтаксисе Intel). Каждый системный вызов предъявляет разные требования к использованию других регистров. Например, значение1
in%eax
означает системный вызовexit()
, а значение in%ebx
содержит значение кода состояния дляexit()
.источник
Имейте в виду, что
0x80
=80h
=128
Вы можете увидеть здесь , что
INT
это только один из многих инструкций ( на самом деле представление ассемблера (или я должен сказать «Мнемоника») из нее) , которая существует в наборе команд x86. Вы также можете найти дополнительную информацию об этой инструкции в собственном руководстве Intel, которое можно найти здесь .Подведем итоги из PDF:
Как видите, 0x80 - это операнд назначения в вашем вопросе. На этом этапе ЦП знает, что он должен выполнить некоторый код, который находится в ядре, но какой код? Это определяется вектором прерывания в Linux.
Одним из наиболее полезных программных прерываний DOS было прерывание 0x21. Вызывая его с разными параметрами в регистрах (в основном ah и al), вы можете получить доступ к различным операциям ввода-вывода, строковому выводу и многому другому.
Большинство систем Unix и их производных не используют программные прерывания, за исключением прерывания 0x80, используемого для выполнения системных вызовов. Это достигается путем ввода 32-битного значения, соответствующего функции ядра, в регистр EAX процессора и последующего выполнения INT 0x80.
Взгляните на это, пожалуйста, где показаны другие доступные значения в таблицах обработчиков прерываний:
Как вы можете видеть, таблица указывает ЦП на выполнение системного вызова. Вы можете найти здесь таблицу системных вызовов Linux .
Таким образом, переместив значение 0x1 в регистр EAX и вызвав INT 0x80 в своей программе, вы можете заставить процесс выполнять код в ядре, который остановит (завершит) текущий запущенный процесс (в Linux, x86 Intel CPU).
Не следует путать аппаратное прерывание с программным прерыванием. Вот очень хороший ответ на этот счет.
Это тоже хороший источник.
источник
int 0x80
I386 Linux системного вызова ABI очень похож на DOSint 0x21
ABI. Поместите номер вызова в регистр (AH для DOS, EAX для Linux) и другие аргументы в другие регистры, затем запустите инструкцию программного прерывания. Основное различие заключается в том, что системные вызовы позволяют вам делать (доступ к оборудованию непосредственно в DOS, но не в Linux), а не в том, как вы их вызываете./usr/include/x86_64-linux-gnu/asm/unistd_64.h
Пример минимального запускаемого системного вызова Linux
Linux настраивает обработчик прерывания
0x80
таким образом, чтобы он реализовывал системные вызовы, способ взаимодействия программ пользовательского уровня с ядром.Скомпилируйте и запустите с:
Результат: программа выводит на стандартный вывод:
и выходит чисто.
Вы не можете установить свои собственные обработчики прерываний непосредственно из пользовательской среды, потому что у вас есть только кольцо 3, а Linux не позволяет вам это сделать .
GitHub вверх по течению . Проверено на Ubuntu 16.04.
Лучшие альтернативы
int 0x80
был заменен лучшими альтернативами для выполнения системных вызовов: сначалаsysenter
, затем VDSO.x86_64 появилась новая
syscall
инструкция .См. Также: Что лучше int 0x80 или syscall?
Минимальный 16-битный пример
Сначала узнайте, как создать ОС с минимальным загрузчиком и запустить ее на QEMU и реальном оборудовании, как я объяснил здесь: https://stackoverflow.com/a/32483545/895245
Теперь вы можете работать в 16-битном реальном режиме:
Это будет по порядку:
Do 0.
Do 1.
hlt
: прекратить выполнениеОбратите внимание, как процессор ищет первый обработчик по адресу
0
, а второй - по адресу4
: это таблица обработчиков, называемая IVT , и каждая запись имеет 4 байта.Минимальный пример, который выполняет некоторые операции ввода-вывода, чтобы сделать обработчики видимыми.
Пример минимально защищенного режима
Современные операционные системы работают в так называемом защищенном режиме.
Управление в этом режиме имеет больше возможностей, поэтому он более сложный, но дух тот же.
Ключевым шагом является использование инструкций LGDT и LIDT, которые указывают адрес структуры данных в памяти (таблица дескрипторов прерываний), которая описывает обработчики.
Минимальный пример
источник
http://www.linfo.org/int_0x80.html
источник
Инструкция "int" вызывает прерывание.
Что за прерывание?
Простой ответ: проще говоря, прерывание - это событие, которое прерывает работу ЦП и сообщает ему о необходимости выполнения определенной задачи.
Подробный ответ :
ЦП имеет таблицу программ обслуживания прерываний (или ISR), хранящуюся в памяти. В реальной (16-бит) режиме, это сохраняется как IVT , или я nterrupt В Ector Т состоянии. IVT обычно располагается по
0x0000:0x0000
(физическому адресу0x00000
) и представляет собой серию адресов со смещением сегмента, которые указывают на ISR. ОС может заменить существующие записи IVT своими собственными ISR.(Примечание: размер IVT фиксирован и составляет 1024 (0x400) байтов.)
В защищенном (32-битном) режиме ЦП использует IDT. IDT - это структура переменной длины, состоящая из дескрипторов (иначе называемых воротами), которые сообщают ЦП об обработчиках прерываний. Структура этих дескрипторов намного сложнее, чем простые записи смещения сегмента в IVT; вот:
* IDT может иметь переменный размер, но он должен быть последовательным, т.е. если вы объявляете IDT от 0x00 до 0x50, вы должны иметь каждое прерывание от 0x00 до 0x50. ОС не обязательно использует их все, поэтому бит «Присутствует» позволяет процессору правильно обрабатывать прерывания, которые ОС не намерена обрабатывать.
Когда происходит прерывание (либо внешним триггером (например, аппаратным устройством) в IRQ, либо
int
инструкцией из программы), ЦП нажимает EFLAGS, затем CS, а затем EIP. (Они автоматически восстанавливаются командойiret
возврата из прерывания.) ОС обычно хранит дополнительную информацию о состоянии машины, обрабатывает прерывание, восстанавливает состояние машины и продолжает работу.Во многих ОС * NIX (включая Linux) системные вызовы основаны на прерываниях. Программа помещает аргументы системного вызова в регистры (EAX, EBX, ECX, EDX и т. Д.) И вызывает прерывание 0x80. Ядро уже установило IDT, чтобы содержать обработчик прерывания на 0x80, который вызывается, когда он получает прерывание 0x80. Затем ядро считывает аргументы и соответственно вызывает функцию ядра. Он может хранить возврат в EAX / EBX. Системные вызовы в значительной степени заменены инструкциями
sysenter
andsysexit
(илиsyscall
andsysret
на AMD), которые позволяют быстрее войти в кольцо 0.Это прерывание могло иметь другое значение в другой ОС. Обязательно проверьте его документацию.
источник
eax
используется для номера системного вызова. asm.sourceforge.net/intro/hello.htmlКак уже упоминалось, это вызывает переход управления к вектору прерывания 0x80. На практике это означает (по крайней мере, в Linux), что вызывается системный вызов; точный системный вызов и аргументы определяются содержимым регистров. Например, exit () можно вызвать, задав для% eax значение 1, за которым следует int 0x80.
источник
Он сообщает процессору, что нужно активировать вектор прерывания 0x80, который в ОС Linux является прерыванием системного вызова, используемым для вызова системных функций, например
open()
для файлов и т. Д.источник
int - это не что иное, как прерывание, т.е. процессор приостанавливает свое текущее выполнение.
0x80 - это не что иное, как системный вызов или вызов ядра. т.е. системная функция будет выполнена.
Чтобы быть конкретным, 0x80 представляет rt_sigtimedwait / init_module / restart_sys, он варьируется от архитектуры к архитектуре.
Для получения дополнительной информации см. Https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md.
источник