What does "int 0x80" mean in assembly code?
Asked Answered
A

9

135

Can someone explain what the following assembly code does?

 int 0x80  
Adames answered 30/11, 2009 at 2:17 Comment(1)
P
86

It passes control to interrupt vector 0x80

See http://en.wikipedia.org/wiki/Interrupt_vector

On Linux, have a look at this: it was used to handle system_call. Of course on another OS this could mean something totally different.

Preponderant answered 30/11, 2009 at 2:19 Comment(3)
by shorten long story that's instructions mean DO IT for instruction was before.Playgoer
@YudaPrawira: you should think of the earlier instructions as setting up args in registers, and int 0x80 as a special kind of call to a function in the kernel (selected by eax).Cecil
Why did you say "WAS used?" Is it used no longer?Candlewick
D
174

int means interrupt, and the number 0x80 is the interrupt number. An interrupt transfers the program flow to whomever is handling that interrupt, which is interrupt 0x80 in this case. In Linux, 0x80 interrupt handler is the kernel, and is used to make system calls to the kernel by other programs.

The kernel is notified about which system call the program wants to make, by examining the value in the register %eax (AT&T syntax, and EAX in Intel syntax). Each system call have different requirements about the use of the other registers. For example, a value of 1 in %eax means a system call of exit(), and the value in %ebx holds the value of the status code for exit().

Dustydusza answered 4/12, 2009 at 20:28 Comment(2)
You mean to say the kernel is just another program? i.e. programs get interrupted with other programs. And that program in this case happens to be the kernel?Deathlike
@Deathlike Yes the Kernel is a program.Ecclesiolatry
P
86

It passes control to interrupt vector 0x80

See http://en.wikipedia.org/wiki/Interrupt_vector

On Linux, have a look at this: it was used to handle system_call. Of course on another OS this could mean something totally different.

Preponderant answered 30/11, 2009 at 2:19 Comment(3)
by shorten long story that's instructions mean DO IT for instruction was before.Playgoer
@YudaPrawira: you should think of the earlier instructions as setting up args in registers, and int 0x80 as a special kind of call to a function in the kernel (selected by eax).Cecil
Why did you say "WAS used?" Is it used no longer?Candlewick
C
55

Keep in mind that 0x80 = 80h = 128

You can see here that INT is just one of the many instructions (actually the Assembly Language representation (or should I say 'mnemonic') of it) that exists in the x86 instruction set. You can also find more information about this instruction in Intel's own manual found here (page 626).

To summarize from the PDF:

INT n/INTO/INT 3—Call to Interrupt Procedure

The INT n instruction generates a call to the interrupt or exception handler specified with the destination operand. The destination operand specifies a vector from 0 to 255, encoded as an 8-bit unsigned intermediate value. The INT n instruction is the general mnemonic for executing a software-generated call to an interrupt handler.

As you can see 0x80 is the destination operand in your question. At this point the CPU knows that it should execute some code that resides in the Kernel, but what code? That is determined by the Interrupt Vector in Linux.

One of the most useful DOS software interrupts was interrupt 0x21. By calling it with different parameters in the registers (mostly ah and al) you could access various IO operations, string output and more.

Most Unix systems and derivatives do not use software interrupts, with the exception of interrupt 0x80, used to make system calls. This is accomplished by entering a 32-bit value corresponding to a kernel function into the EAX register of the processor and then executing INT 0x80.

Take a look at this please where other available values in the interrupt handler tables are shown:

enter image description here

As you can see the table points the CPU to execute a system call. You can find the Linux System Call table here.

So by moving the value 0x1 to EAX register and calling the INT 0x80 in your program, you can make the process go execute the code in Kernel which will stop (exit) the current running process (on Linux, x86 Intel CPU).

A hardware interrupt must not be confused with a software interrupt. Here is a very good answer on this regard.

This also is good source.

Clarethaclaretta answered 28/2, 2015 at 17:40 Comment(4)
Linux System Call table link is broken =\Aragats
Most Unix systems and derivatives do not use software interrupts (except int 0x80) seems like a weird way to put it. The int 0x80 i386 Linux system call ABI is extremely similar to the DOS int 0x21 ABI. Put a call number in a register (AH for DOS, EAX for Linux), and other args in other registers, then run a software-interrupt instruction. The main difference is in what the system calls let you do (access hardware directly in DOS but not Linux), not in how you invoke them.Cecil
Here is a non-broken syscall table link. syscalls.kernelgrok.com Just expand it to show all calls at the top.Cambridgeshire
When using linux 64bits, You can see the system call available at /usr/include/x86_64-linux-gnu/asm/unistd_64.hConduction
O
13

Minimal runnable Linux system call example

Linux sets up the interrupt handler for 0x80 such that it implements system calls, a way for userland programs to communicate with the 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

Compile and run with:

as -o main.o main.S
ld -o main.out main.o
./main.out

Outcome: the program prints to stdout:

hello world

and exits cleanly.

You cannot set your own interrupt handlers directly from userland because you only have ring 3 and Linux prevents you from doing so.

GitHub upstream. Tested on Ubuntu 16.04.

Better alternatives

int 0x80 has been superseded by better alternatives for making system calls: first sysenter, then VDSO.

x86_64 has a new syscall instruction.

See also: What is better "int 0x80" or "syscall"?

Minimal 16-bit example

First learn how to create a minimal bootloader OS and run it on QEMU and real hardware as I've explained here: https://mcmap.net/q/15004/-how-to-run-a-program-without-an-operating-system

Now you can run in 16-bit real mode:

    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

This would do in order:

  • Do 0.
  • Do 1.
  • hlt: stop executing

Note how the processor looks for the first handler at address 0, and the second one at 4: that is a table of handlers called the IVT, and each entry has 4 bytes.

Minimal example that does some IO to make handlers visible.

Minimal protected mode example

Modern operating systems run in the so called protected mode.

The handling has more options in this mode, so it is more complex, but the spirit is the same.

The key step is using the LGDT and LIDT instructions, which point the address of an in-memory data structure (the Interrupt Descriptor Table) that describes the handlers.

Minimal example

Ocd answered 5/8, 2015 at 15:40 Comment(0)
S
11

int 0x80 is the assembly language instruction that is used to invoke system calls in Linux on x86 (i.e., Intel-compatible) processors.

http://www.linfo.org/int_0x80.html

Sherrilsherrill answered 30/11, 2009 at 2:20 Comment(0)
H
6

The "int" instruction causes an interrupt.

What's an interrupt?

Simple Answer: An interrupt, put simply, is an event that interrupts the CPU, and tells it to run a specific task.

Detailed Answer:

The CPU has a table of Interrupt Service Routines (or ISRs) stored in memory. In Real (16-bit) Mode, this is stored as the IVT, or Interrupt Vector Table. The IVT is typically located at 0x0000:0x0000 (physical address 0x00000), and it is a series of segment-offset addresses that point to the ISRs. The OS may replace the pre-existing IVT entries with its own ISRs.

(Note: The IVT's size is fixed at 1024 (0x400) bytes.)

In Protected (32-bit) Mode, the CPU uses an IDT. The IDT is a variable-length structure that consists of descriptors (otherwise known as gates), which tell the CPU about the interrupt handlers. The structure of these descriptors is much more complex than the IVT's simple segment-offset entries; here it is:

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
 

*The IDT may be of variable size, but it must be sequential, i.e. if you declare your IDT to be from 0x00 to 0x50, you must have every interrupt from 0x00 to 0x50. The OS does not necessarily use all of them, so the Present bit allows the CPU to properly handle interrupts the OS does not intend to handle.

When an interrupt occurs (either by an external trigger (e.g. a hardware device) in an IRQ, or by the int instruction from a program), the CPU pushes EFLAGS, then CS, and then EIP. (These are automatically restored by iret, the interrupt return instruction.) The OS usually stores more information about the state of the machine, handles the interrupt, restores the machine state, and continues on.

In many *NIX OSes (including Linux), system calls are interrupt based. The program puts the arguments to the system call in the registers (EAX, EBX, ECX, EDX, etc..), and calls interrupt 0x80. The kernel has already set the IDT to contain an interrupt handler on 0x80, which is called when it receives interrupt 0x80. The kernel then reads the arguments and invokes a kernel function accordingly. It may store a return in EAX/EBX. System calls have largely been replaced by the sysenter and sysexit (or syscall and sysret on AMD) instructions, which allow for faster entry into ring 0.

This interrupt could have a different meaning in a different OS. Be sure to check its documentation.

Horseplay answered 16/6, 2017 at 19:26 Comment(1)
Fun fact: FreeBSD's i386 system call ABI passes args on the user-space stack. Only eax is used for the syscall number. asm.sourceforge.net/intro/hello.htmlCecil
J
2

It tells the cpu to activate interrupt vector 0x80, which on Linux OSes is the system-call interrupt, used to invoke system functions like open() for files, et cetera.

Jeffreyjeffreys answered 30/11, 2009 at 2:21 Comment(3)
Strictly speaking, it doesn't tell the kernel... It tells the CPU, which looks up the handler in the IDT, which ends up being a pointer to some kernel code.Rogan
True. I suppose the better phrasing would be it tells the CPU to activate the vector, and the vector (as part of the kernel) invokes the function.Jeffreyjeffreys
which ends up doing this, which inturn ends up doing that, which then does this, which then goes there confused. :/ Amber has an answer that is understandable..thats it..Kreager
K
2

As mentioned, it causes control to jump to interrupt vector 0x80. In practice what this means (at least under Linux) is that a system call is invoked; the exact system call and arguments are defined by the contents of the registers. For example, exit() can be invoked by setting %eax to 1 followed by 'int 0x80'.

Kannan answered 30/11, 2009 at 2:33 Comment(0)
A
2

int is nothing but an interruption i.e the processor will put its current execution to hold.

0x80 is nothing but a system call or the kernel call. i.e the system function will be executed.

To be specific 0x80 represents rt_sigtimedwait/init_module/restart_sys it varies from architecture to architecture.

For more details refer https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md

Artichoke answered 17/9, 2020 at 5:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.