Dengan mempersingkat cerita panjang itulah instruksi berarti LAKUKAN untuk instruksi sebelumnya.
Yuda Prawira
2
@YudaPrawira: Anda harus memikirkan instruksi sebelumnya sebagai pengaturan args di register, dan int 0x80sebagai jenis khusus dari callfungsi di kernel (dipilih oleh eax).
Peter Cordes
Mengapa Anda mengatakan "SUDAH digunakan?" Apakah itu tidak digunakan lagi?
Liga
131
intberarti interupsi, dan nomor tersebut 0x80adalah nomor interupsi. Interupsi mentransfer aliran program ke siapa pun yang menangani interupsi tersebut, yang 0x80dalam kasus ini interupsi . Di Linux, 0x80interrupt handler adalah kernel, dan digunakan untuk membuat panggilan sistem ke kernel oleh program lain.
Kernel diberitahu tentang pemanggilan sistem mana yang ingin dibuat oleh program, dengan memeriksa nilai dalam register %eax(sintaks AT&T, dan EAX dalam sintaks Intel). Setiap panggilan sistem memiliki persyaratan berbeda tentang penggunaan register lainnya. Misalnya, nilai 1in %eaxberarti pemanggilan sistem exit(), dan nilai in %ebxmenyimpan nilai kode status untuk exit().
Anda dapat melihat di sini bahwa INThanya salah satu dari banyak instruksi (sebenarnya representasi Bahasa Assembly (atau harus saya katakan 'mnemonic') darinya) yang ada di set instruksi x86. Anda juga dapat menemukan informasi lebih lanjut tentang instruksi ini di manual Intel yang ditemukan di sini .
Untuk meringkas dari PDF:
INT n / INTO / INT 3 — Prosedur Panggilan untuk Menyela
Instruksi INT n menghasilkan panggilan ke interupsi atau penangan pengecualian yang ditentukan dengan operan tujuan. Operand tujuan menentukan vektor dari 0 sampai 255, dikodekan sebagai nilai antara 8-bit unsigned. Instruksi INT n adalah mnemonik umum untuk menjalankan panggilan yang dihasilkan perangkat lunak ke pengendali interupsi.
Seperti yang Anda lihat, 0x80 adalah operan tujuan dalam pertanyaan Anda. Pada titik ini CPU mengetahui bahwa ia harus mengeksekusi beberapa kode yang ada di Kernel, tetapi kode apa? Itu ditentukan oleh Vektor Interupsi di Linux.
Salah satu interupsi perangkat lunak DOS yang paling berguna adalah interupsi 0x21. Dengan memanggilnya dengan parameter yang berbeda di register (kebanyakan ah dan al) Anda dapat mengakses berbagai operasi IO, keluaran string dan banyak lagi.
Sebagian besar sistem Unix dan turunannya tidak menggunakan interupsi perangkat lunak, dengan pengecualian interupsi 0x80, yang digunakan untuk melakukan panggilan sistem. Ini dilakukan dengan memasukkan nilai 32-bit yang sesuai dengan fungsi kernel ke dalam register EAX prosesor dan kemudian menjalankan INT 0x80.
Silakan lihat ini, di mana nilai lain yang tersedia di tabel penangan interupsi ditampilkan:
Seperti yang Anda lihat, tabel menunjukkan CPU untuk menjalankan panggilan sistem. Anda dapat menemukan tabel Panggilan Sistem Linux di sini .
Jadi dengan memindahkan nilai 0x1 ke register EAX dan memanggil INT 0x80 di program Anda, Anda dapat membuat proses pergi menjalankan kode di Kernel yang akan menghentikan (keluar) proses yang sedang berjalan (di Linux, x86 Intel CPU).
Interupsi perangkat keras tidak boleh disamakan dengan interupsi perangkat lunak. Inilah jawaban yang sangat bagus tentang hal ini.
Kebanyakan sistem dan turunan Unix tidak menggunakan interupsi perangkat lunak (kecuali int 0x80) sepertinya cara yang aneh untuk menjelaskannya. Sistem int 0x80Linux i386 memanggil ABI sangat mirip dengan int 0x21ABI DOS . Masukkan nomor panggilan di register (AH untuk DOS, EAX untuk Linux), dan arg lainnya di register lain, kemudian jalankan instruksi interupsi perangkat lunak. Perbedaan utama adalah pada apa yang diizinkan oleh system call (mengakses perangkat keras secara langsung di DOS tetapi tidak di Linux), bukan pada cara Anda memanggilnya.
Peter Cordes
Berikut adalah tautan tabel syscall yang tidak rusak. syscalls.kernelgrok.com Perluas saja untuk menampilkan semua panggilan di bagian atas.
ollien
Saat menggunakan linux 64bits, Anda dapat melihat panggilan sistem tersedia di/usr/include/x86_64-linux-gnu/asm/unistd_64.h
ton
12
Contoh panggilan sistem Linux minimal yang dapat dijalankan
Linux menyiapkan pengendali interupsi 0x80sedemikian rupa sehingga ia mengimplementasikan panggilan sistem, sebuah cara bagi program-program userland untuk berkomunikasi dengan kernel.
.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
Kompilasi dan jalankan dengan:
as -o main.o main.S
ld -o main.out main.o
./main.out
Pertama pelajari cara membuat OS bootloader minimal dan menjalankannya di QEMU dan perangkat keras nyata seperti yang telah saya jelaskan di sini: https://stackoverflow.com/a/32483545/895245
Sekarang Anda dapat menjalankan mode real 16-bit:
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
Ini akan dilakukan secara berurutan:
Do 0.
Do 1.
hlt: berhenti mengeksekusi
Perhatikan bagaimana prosesor mencari penangan pertama di alamat 0, dan yang kedua di 4: itu adalah tabel penangan yang disebut IVT , dan setiap entri memiliki 4 byte.
Sistem operasi modern berjalan dalam apa yang disebut mode terlindungi.
Penanganannya memiliki lebih banyak opsi dalam mode ini, jadi lebih kompleks, tetapi semangatnya sama.
Langkah kuncinya adalah menggunakan instruksi LGDT dan LIDT, yang menunjukkan alamat struktur data dalam memori (Tabel Descriptor Interupsi) yang menjelaskan penangan.
Jawaban Sederhana: Sebuah interupsi, sederhananya, adalah peristiwa yang mengganggu CPU, dan menyuruhnya untuk menjalankan tugas tertentu.
Jawaban Rinci :
CPU memiliki tabel Interrupt Service Routines (atau ISRs) yang disimpan di memori. Dalam Real Mode (16-bit), ini disimpan sebagai IVT , atau saya nterrupt V ektor T mampu. IVT biasanya terletak di 0x0000:0x0000(alamat fisik 0x00000), dan merupakan rangkaian alamat offset segmen yang mengarah ke ISR. OS dapat mengganti entri IVT yang sudah ada dengan ISR-nya sendiri.
(Catatan: Ukuran IVT ditetapkan pada 1024 (0x400) byte.)
Dalam Mode Terproteksi (32-bit), CPU menggunakan IDT. IDT adalah struktur dengan panjang variabel yang terdiri dari deskriptor (atau dikenal sebagai gerbang), yang memberi tahu CPU tentang penangan interupsi. Struktur deskriptor ini jauh lebih kompleks daripada entri offset segmen sederhana IVT; ini dia:
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 mungkin berukuran variabel, tetapi harus berurutan, yaitu jika Anda mendeklarasikan IDT Anda dari 0x00 hingga 0x50, Anda harus memiliki setiap interupsi dari 0x00 hingga 0x50. OS tidak selalu menggunakan semuanya, jadi bit Present memungkinkan CPU untuk menangani interupsi yang tidak ingin ditangani OS.
Ketika interupsi terjadi (baik oleh pemicu eksternal (misalnya perangkat keras) di IRQ, atau dengan intinstruksi dari program), CPU mendorong EFLAGS, lalu CS, dan kemudian EIP. (Ini secara otomatis dipulihkan oleh iret, instruksi pengembalian interupsi.) OS biasanya menyimpan lebih banyak informasi tentang status mesin, menangani interupsi, memulihkan status mesin, dan melanjutkan.
Di banyak * NIX OS (termasuk Linux), panggilan sistem berbasis interupsi. Program ini menempatkan argumen ke panggilan sistem di register (EAX, EBX, ECX, EDX, dll ..), dan panggilan interupsi 0x80. Kernel telah menetapkan IDT untuk memuat penangan interupsi pada 0x80, yang dipanggil ketika menerima interupsi 0x80. Kernel kemudian membaca argumen dan menjalankan fungsi kernel yang sesuai. Ini mungkin menyimpan pengembalian dalam EAX / EBX. Panggilan sistem sebagian besar telah digantikan oleh sysenterdan sysexit(atau syscalldansysret instruksi pada AMD), yang memungkinkan untuk masuk lebih cepat ke ring 0.
Interupsi ini bisa memiliki arti berbeda di OS yang berbeda. Pastikan untuk memeriksa dokumentasinya.
Fakta menarik: Panggilan sistem i386 FreeBSD, ABI, meneruskan argumen pada tumpukan ruang pengguna. Hanya eaxdigunakan untuk nomor syscall. asm.sourceforge.net/intro/hello.html
Peter Cordes
2
Seperti disebutkan, itu menyebabkan kontrol melompat ke vektor interupsi 0x80. Dalam praktiknya, ini berarti (setidaknya di Linux) adalah bahwa panggilan sistem dipanggil; panggilan sistem dan argumen yang tepat ditentukan oleh konten register. Misalnya, exit () bisa dipanggil dengan menyetel% eax ke 1 diikuti dengan 'int 0x80'.
Ini memberitahu cpu untuk mengaktifkan vektor interupsi 0x80, yang pada OS Linux adalah interupsi panggilan sistem, digunakan untuk menjalankan fungsi sistem seperti open()untuk file, dan sebagainya.
Sebenarnya, ini tidak memberi tahu kernel ... Ini memberi tahu CPU, yang mencari penangan di IDT, yang akhirnya menjadi penunjuk ke beberapa kode kernel.
asveikau
Benar. Saya kira ungkapan yang lebih baik akan memberitahu CPU untuk mengaktifkan vektor, dan vektor (sebagai bagian dari kernel) memanggil fungsinya.
Amber
yang akhirnya melakukan ini, yang akhirnya melakukan itu, yang kemudian melakukan ini, yang kemudian pergi ke sana dengan bingung . : / Amber punya jawaban yang bisa dimengerti..yaitu ..
Afzaal Ahmad Zeeshan
1
int tidak lain adalah gangguan yaitu prosesor akan menahan eksekusi saat ini.
0x80 tidak lain adalah panggilan sistem atau panggilan kernel. yaitu fungsi sistem akan dijalankan.
Untuk lebih spesifiknya 0x80 mewakili rt_sigtimedwait / init_module / restart_sys, itu bervariasi dari satu arsitektur ke arsitektur lainnya.
Jawaban:
Ini melewati kontrol untuk mengganggu vektor 0x80
Lihat http://en.wikipedia.org/wiki/Interrupt_vector
Di Linux, lihat ini : ini digunakan untuk menangani
system_call
. Tentu saja di OS lain ini bisa berarti sesuatu yang sama sekali berbeda.sumber
int 0x80
sebagai jenis khusus daricall
fungsi di kernel (dipilih oleheax
).int
berarti interupsi, dan nomor tersebut0x80
adalah nomor interupsi. Interupsi mentransfer aliran program ke siapa pun yang menangani interupsi tersebut, yang0x80
dalam kasus ini interupsi . Di Linux,0x80
interrupt handler adalah kernel, dan digunakan untuk membuat panggilan sistem ke kernel oleh program lain.Kernel diberitahu tentang pemanggilan sistem mana yang ingin dibuat oleh program, dengan memeriksa nilai dalam register
%eax
(sintaks AT&T, dan EAX dalam sintaks Intel). Setiap panggilan sistem memiliki persyaratan berbeda tentang penggunaan register lainnya. Misalnya, nilai1
in%eax
berarti pemanggilan sistemexit()
, dan nilai in%ebx
menyimpan nilai kode status untukexit()
.sumber
Ingatlah bahwa
0x80
=80h
=128
Anda dapat melihat di sini bahwa
INT
hanya salah satu dari banyak instruksi (sebenarnya representasi Bahasa Assembly (atau harus saya katakan 'mnemonic') darinya) yang ada di set instruksi x86. Anda juga dapat menemukan informasi lebih lanjut tentang instruksi ini di manual Intel yang ditemukan di sini .Untuk meringkas dari PDF:
Seperti yang Anda lihat, 0x80 adalah operan tujuan dalam pertanyaan Anda. Pada titik ini CPU mengetahui bahwa ia harus mengeksekusi beberapa kode yang ada di Kernel, tetapi kode apa? Itu ditentukan oleh Vektor Interupsi di Linux.
Salah satu interupsi perangkat lunak DOS yang paling berguna adalah interupsi 0x21. Dengan memanggilnya dengan parameter yang berbeda di register (kebanyakan ah dan al) Anda dapat mengakses berbagai operasi IO, keluaran string dan banyak lagi.
Sebagian besar sistem Unix dan turunannya tidak menggunakan interupsi perangkat lunak, dengan pengecualian interupsi 0x80, yang digunakan untuk melakukan panggilan sistem. Ini dilakukan dengan memasukkan nilai 32-bit yang sesuai dengan fungsi kernel ke dalam register EAX prosesor dan kemudian menjalankan INT 0x80.
Silakan lihat ini, di mana nilai lain yang tersedia di tabel penangan interupsi ditampilkan:
Seperti yang Anda lihat, tabel menunjukkan CPU untuk menjalankan panggilan sistem. Anda dapat menemukan tabel Panggilan Sistem Linux di sini .
Jadi dengan memindahkan nilai 0x1 ke register EAX dan memanggil INT 0x80 di program Anda, Anda dapat membuat proses pergi menjalankan kode di Kernel yang akan menghentikan (keluar) proses yang sedang berjalan (di Linux, x86 Intel CPU).
Interupsi perangkat keras tidak boleh disamakan dengan interupsi perangkat lunak. Inilah jawaban yang sangat bagus tentang hal ini.
Ini juga merupakan sumber yang bagus.
sumber
int 0x80
Linux i386 memanggil ABI sangat mirip denganint 0x21
ABI DOS . Masukkan nomor panggilan di register (AH untuk DOS, EAX untuk Linux), dan arg lainnya di register lain, kemudian jalankan instruksi interupsi perangkat lunak. Perbedaan utama adalah pada apa yang diizinkan oleh system call (mengakses perangkat keras secara langsung di DOS tetapi tidak di Linux), bukan pada cara Anda memanggilnya./usr/include/x86_64-linux-gnu/asm/unistd_64.h
Contoh panggilan sistem Linux minimal yang dapat dijalankan
Linux menyiapkan pengendali interupsi
0x80
sedemikian rupa sehingga ia mengimplementasikan panggilan sistem, sebuah cara bagi program-program userland untuk berkomunikasi dengan kernel.Kompilasi dan jalankan dengan:
Hasil: program mencetak ke stdout:
dan keluar dengan bersih.
Anda tidak dapat mengatur penangan interupsi Anda sendiri langsung dari userland karena Anda hanya memiliki ring 3 dan Linux mencegah Anda melakukannya .
GitHub upstream . Diuji di Ubuntu 16.04.
Alternatif yang lebih baik
int 0x80
telah digantikan oleh alternatif yang lebih baik untuk melakukan panggilan sistem: pertamasysenter
, kemudian VDSO.x86_64 memiliki instruksi baru
syscall
.Lihat juga: Apa yang lebih baik "int 0x80" atau "syscall"?
Contoh minimal 16-bit
Pertama pelajari cara membuat OS bootloader minimal dan menjalankannya di QEMU dan perangkat keras nyata seperti yang telah saya jelaskan di sini: https://stackoverflow.com/a/32483545/895245
Sekarang Anda dapat menjalankan mode real 16-bit:
Ini akan dilakukan secara berurutan:
Do 0.
Do 1.
hlt
: berhenti mengeksekusiPerhatikan bagaimana prosesor mencari penangan pertama di alamat
0
, dan yang kedua di4
: itu adalah tabel penangan yang disebut IVT , dan setiap entri memiliki 4 byte.Contoh minimal yang melakukan beberapa IO untuk membuat penangan terlihat.
Contoh mode perlindungan minimal
Sistem operasi modern berjalan dalam apa yang disebut mode terlindungi.
Penanganannya memiliki lebih banyak opsi dalam mode ini, jadi lebih kompleks, tetapi semangatnya sama.
Langkah kuncinya adalah menggunakan instruksi LGDT dan LIDT, yang menunjukkan alamat struktur data dalam memori (Tabel Descriptor Interupsi) yang menjelaskan penangan.
Contoh minimal
sumber
http://www.linfo.org/int_0x80.html
sumber
Instruksi "int" menyebabkan interupsi.
Apa itu interupsi?
Jawaban Sederhana: Sebuah interupsi, sederhananya, adalah peristiwa yang mengganggu CPU, dan menyuruhnya untuk menjalankan tugas tertentu.
Jawaban Rinci :
CPU memiliki tabel Interrupt Service Routines (atau ISRs) yang disimpan di memori. Dalam Real Mode (16-bit), ini disimpan sebagai IVT , atau saya nterrupt V ektor T mampu. IVT biasanya terletak di
0x0000:0x0000
(alamat fisik0x00000
), dan merupakan rangkaian alamat offset segmen yang mengarah ke ISR. OS dapat mengganti entri IVT yang sudah ada dengan ISR-nya sendiri.(Catatan: Ukuran IVT ditetapkan pada 1024 (0x400) byte.)
Dalam Mode Terproteksi (32-bit), CPU menggunakan IDT. IDT adalah struktur dengan panjang variabel yang terdiri dari deskriptor (atau dikenal sebagai gerbang), yang memberi tahu CPU tentang penangan interupsi. Struktur deskriptor ini jauh lebih kompleks daripada entri offset segmen sederhana IVT; ini dia:
* IDT mungkin berukuran variabel, tetapi harus berurutan, yaitu jika Anda mendeklarasikan IDT Anda dari 0x00 hingga 0x50, Anda harus memiliki setiap interupsi dari 0x00 hingga 0x50. OS tidak selalu menggunakan semuanya, jadi bit Present memungkinkan CPU untuk menangani interupsi yang tidak ingin ditangani OS.
Ketika interupsi terjadi (baik oleh pemicu eksternal (misalnya perangkat keras) di IRQ, atau dengan
int
instruksi dari program), CPU mendorong EFLAGS, lalu CS, dan kemudian EIP. (Ini secara otomatis dipulihkan olehiret
, instruksi pengembalian interupsi.) OS biasanya menyimpan lebih banyak informasi tentang status mesin, menangani interupsi, memulihkan status mesin, dan melanjutkan.Di banyak * NIX OS (termasuk Linux), panggilan sistem berbasis interupsi. Program ini menempatkan argumen ke panggilan sistem di register (EAX, EBX, ECX, EDX, dll ..), dan panggilan interupsi 0x80. Kernel telah menetapkan IDT untuk memuat penangan interupsi pada 0x80, yang dipanggil ketika menerima interupsi 0x80. Kernel kemudian membaca argumen dan menjalankan fungsi kernel yang sesuai. Ini mungkin menyimpan pengembalian dalam EAX / EBX. Panggilan sistem sebagian besar telah digantikan oleh
sysenter
dansysexit
(atausyscall
dansysret
instruksi pada AMD), yang memungkinkan untuk masuk lebih cepat ke ring 0.Interupsi ini bisa memiliki arti berbeda di OS yang berbeda. Pastikan untuk memeriksa dokumentasinya.
sumber
eax
digunakan untuk nomor syscall. asm.sourceforge.net/intro/hello.htmlSeperti disebutkan, itu menyebabkan kontrol melompat ke vektor interupsi 0x80. Dalam praktiknya, ini berarti (setidaknya di Linux) adalah bahwa panggilan sistem dipanggil; panggilan sistem dan argumen yang tepat ditentukan oleh konten register. Misalnya, exit () bisa dipanggil dengan menyetel% eax ke 1 diikuti dengan 'int 0x80'.
sumber
Ini memberitahu cpu untuk mengaktifkan vektor interupsi 0x80, yang pada OS Linux adalah interupsi panggilan sistem, digunakan untuk menjalankan fungsi sistem seperti
open()
untuk file, dan sebagainya.sumber
int tidak lain adalah gangguan yaitu prosesor akan menahan eksekusi saat ini.
0x80 tidak lain adalah panggilan sistem atau panggilan kernel. yaitu fungsi sistem akan dijalankan.
Untuk lebih spesifiknya 0x80 mewakili rt_sigtimedwait / init_module / restart_sys, itu bervariasi dari satu arsitektur ke arsitektur lainnya.
Untuk detail selengkapnya, lihat https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md
sumber