简体   繁体   English

汇编代码中的“int 0x80”是什么意思?

[英]What does "int 0x80" mean in assembly code?

Can someone explain what the following assembly code does?有人可以解释以下汇编代码的作用吗?

 int 0x80  

int means interrupt, and the number 0x80 is the interrupt number. int表示中断,数字0x80是中断号。 An interrupt transfers the program flow to whomever is handling that interrupt, which is interrupt 0x80 in this case.中断将程序流传输给处理该中断的任何人,在本例中为中断0x80 In Linux, 0x80 interrupt handler is the kernel, and is used to make system calls to the kernel by other programs.在 Linux 中, 0x80中断处理程序是内核,用于其他程序对内核进行系统调用。

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).通过检查寄存器%eax (AT&T 语法和 Intel 语法中的 EAX)中的值,内核被告知程序想要进行哪个系统调用。 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() .例如, %eax的值1表示exit()的系统调用,而%ebx的值保存exit()的状态代码的值。

It passes control to interrupt vector 0x80它将控制权传递给中断向量 0x80

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

On Linux, have a look at this : it was used to handle system_call .在 Linux 上,看看这个:它被用来处理system_call Of course on another OS this could mean something totally different.当然,在另一个操作系统上,这可能意味着完全不同的东西。

Keep in mind that 0x80 = 80h = 128请记住, 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.您可以在这里看到INT只是 x86 指令集中存在的众多指令之一(实际上是汇编语言表示(或者我应该说它的“助记符”))。 You can also find more information about this instruction in Intel's own manual found here .您还可以在此处找到的英特尔自己的手册中找到有关此指令的更多信息。

To summarize from the PDF:从PDF总结:

INT n/INTO/INT 3—Call to Interrupt Procedure INT n/INTO/INT 3—调用中断程序

The INT n instruction generates a call to the interrupt or exception handler specified with the destination operand. INT n 指令生成对目标操作数指定的中断或异常处理程序的调用。 The destination operand specifies a vector from 0 to 255, encoded as an 8-bit unsigned intermediate value.目标操作数指定从 0 到 255 的向量,编码为 8 位无符号中间值。 The INT n instruction is the general mnemonic for executing a software-generated call to an interrupt handler. INT n 指令是执行软件生成的中断处理程序调用的通用助记符。

As you can see 0x80 is the destination operand in your question.如您所见, 0x80是您问题中的目标操作数 At this point the CPU knows that it should execute some code that resides in the Kernel, but what code?此时 CPU 知道它应该执行一些驻留在内核中的代码,但是什么代码呢? That is determined by the Interrupt Vector in Linux.这是由 Linux 中的中断向量决定的。

One of the most useful DOS software interrupts was interrupt 0x21.最有用的 DOS 软件中断之一是中断 0x21。 By calling it with different parameters in the registers (mostly ah and al) you could access various IO operations, string output and more.通过在寄存器中使用不同的参数(主要是 ah 和 al)调用它,您可以访问各种 IO 操作、字符串输出等。

Most Unix systems and derivatives do not use software interrupts, with the exception of interrupt 0x80, used to make system calls.大多数 Unix 系统及其衍生产品不使用软件中断,除了用于进行系统调用的中断 0x80。 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.这是通过将与内核函数对应32 位值输入处理器的 EAX 寄存器然后执行 INT 0x80 来实现的。

Take a look at this please where other available values in the interrupt handler tables are shown:请查看中断处理程序表中其他可用值的位置:

在此处输入图片说明

As you can see the table points the CPU to execute a system call.如您所见,该表指向 CPU 执行系统调用。 You can find the Linux System Call table here .您可以在此处找到 Linux 系统调用表。

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).因此,通过将值 0x1 移动到 EAX 寄存器并在您的程序中调用 INT 0x80,您可以让进程执行内核中的代码,这将停止(退出)当前正在运行的进程(在 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.也是很好的来源。

Minimal runnable Linux system call example最小的可运行 Linux 系统调用示例

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

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 .您不能直接从用户空间设置您自己的中断处理程序,因为您只有ring 3,而 Linux 阻止您这样做

GitHub upstream . GitHub 上游. Tested on Ubuntu 16.04.在 Ubuntu 16.04 上测试。

Better alternatives更好的选择

int 0x80 has been superseded by better alternatives for making system calls: first sysenter , then VDSO. int 0x80已被更好的系统调用替代方案取代:首先是sysenter ,然后是 VDSO。

x86_64 has a new syscall instruction . x86_64 有一个新的syscall指令

See also: What is better "int 0x80" or "syscall"?另请参阅: “int 0x80”或“syscall”哪个更好?

Minimal 16-bit example最小 16 位示例

First learn how to create a minimal bootloader OS and run it on QEMU and real hardware as I've explained here: https://stackoverflow.com/a/32483545/895245首先学习如何创建一个最小的引导加载程序操作系统并在 QEMU 和真实硬件上运行它,正如我在这里解释的: https : //stackoverflow.com/a/32483545/895245

Now you can run in 16-bit real mode:现在您可以在 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

This would do in order:这将按顺序执行:

  • Do 0.
  • Do 1.
  • hlt : stop executing hlt : 停止执行

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.请注意处理器如何在地址0处查找第一个处理程序,在4处查找第二个处理程序:这是一个称为IVT的处理程序表,每个条目有 4 个字节。

Minimal example that does some IO to make handlers visible. 执行一些 IO以使处理程序可见的最小示例

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.关键步骤是使用 LGDT 和 LIDT 指令,它们指向描述处理程序的内存数据结构(中断描述符表)的地址。

Minimal example 最小的例子

int 0x80 is the assembly language instruction that is used to invoke system calls in Linux on x86 (ie, Intel-compatible) processors. int 0x80 是汇编语言指令,用于在 x86(即 Intel 兼容)处理器上的 Linux 中调用系统调用。

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

The "int" instruction causes an interrupt. “int”指令导致中断。

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.简单回答:中断,简单地说,就是中断 CPU 并告诉它运行特定任务的事件。

Detailed Answer :详细解答

The CPU has a table of Interrupt Service Routines (or ISRs) stored in memory. CPU 有一个存储在内存中的中断服务程序(或 ISR)表。 In Real (16-bit) Mode, this is stored as the IVT , or I nterrupt V ector T able.在真实的(16位)的模式下,该被存储为IVT,nterrupt V厄克托Ť能。 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. IVT 通常位于0x0000:0x0000 (物理地址0x00000 ),它是一系列指向 ISR 的段偏移地址。 The OS may replace the pre-existing IVT entries with its own ISRs.操作系统可以用它自己的 ISR 替换预先存在的 IVT 条目。

(Note: The IVT's size is fixed at 1024 (0x400) bytes.) (注意:IVT 的大小固定为 1024 (0x400) 字节。)

In Protected (32-bit) Mode, the CPU uses an IDT.在保护(32 位)模式下,CPU 使用 IDT。 The IDT is a variable-length structure that consists of descriptors (otherwise known as gates), which tell the CPU about the interrupt handlers. IDT 是一个由描述符(也称为门)组成的可变长度结构,它告诉 CPU 有关中断处理程序的信息。 The structure of these descriptors is much more complex than the IVT's simple segment-offset entries;这些描述符的结构比 IVT 的简单段偏移条目复杂得多; 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, ie if you declare your IDT to be from 0x00 to 0x50, you must have every interrupt from 0x00 to 0x50. *IDT 可以是可变大小,但它必须是连续的,即如果你声明你的 IDT 是从 0x00 到 0x50,你必须有从 0x00 到 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. OS 不一定使用所有这些,因此 Present 位允许 CPU 正确处理 OS 不打算处理的中断。

When an interrupt occurs (either by an external trigger (eg a hardware device) in an IRQ, or by the int instruction from a program), the CPU pushes EFLAGS, then CS, and then EIP.当中断发生时(通过 IRQ 中的外部触发器(例如硬件设备),或程序中的int指令),CPU 推送 EFLAGS,然后是 CS,然后是 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. (这些由iret自动恢复,中断返回指令。)操作系统通常会存储更多关于机器状态的信息,处理中断,恢复机器状态,然后继续。

In many *NIX OSes (including Linux), system calls are interrupt based.在许多 *NIX 操作系统(包括 Linux)中,系统调用是基于中断的。 The program puts the arguments to the system call in the registers (EAX, EBX, ECX, EDX, etc..), and calls interrupt 0x80.程序将系统调用的参数放入寄存器(EAX、EBX、ECX、EDX 等),并调用中断 0x80。 The kernel has already set the IDT to contain an interrupt handler on 0x80, which is called when it receives interrupt 0x80.内核已经将 IDT 设置为在 0x80 上包含一个中断处理程序,当它接收到中断 0x80 时会调用该处理程序。 The kernel then reads the arguments and invokes a kernel function accordingly.然后内核读取参数并相应地调用内核函数。 It may store a return in EAX/EBX.它可以在 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.系统调用在很大程度上被换成了sysentersysexit (或syscallsysret上AMD)指令,允许更快的进入0环。

This interrupt could have a different meaning in a different OS.此中断在不同的操作系统中可能具有不同的含义。 Be sure to check its documentation.请务必检查其文档。

它告诉 cpu 激活中断向量 0x80,它在 Linux 操作系统上是系统调用中断,用于调用系统函数,如文件的open()等。

As mentioned, it causes control to jump to interrupt vector 0x80.如前所述,它会导致控制跳转到中断向量 0x80。 In practice what this means (at least under Linux) is that a system call is invoked;实际上,这意味着(至少在 Linux 下)是调用系统调用; 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'.例如,可以通过将 %eax 设置为 1 后跟“int 0x80”来调用 exit()。

int is nothing but an interruption ie the processor will put its current execution to hold. int 只是一个中断,即处理器将暂停其当前执行。

0x80 is nothing but a system call or the kernel call. 0x80 只不过是一个系统调用或内核调用。 ie the system function will be executed.即系统函数将被执行。

To be specific 0x80 represents rt_sigtimedwait/init_module/restart_sys it varies from architecture to architecture.具体来说,0x80 代表 rt_sigtimedwait/init_module/restart_sys,它因架构而异。

For more details refer https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md有关更多详细信息,请参阅https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 有人知道适用于 VS Code 的良好组装 x86 荧光笔扩展吗? - Does someone know good Assembly x86 highlighter extension for VS Code? getaddrinfo ENOTFOUND 是什么意思? - What does getaddrinfo ENOTFOUND mean? 部署Firebase云function时这个错误是什么意思 - What does this error mean when deploying Firebase cloud function glibc detected...httpd: double free or corruption 是什么意思? - What does glibc detected ...httpd: double free or corruption mean? DataFlow 中的管道“状态”是什么意思? - What does the pipeline "state" mean in DataFlow? amr在aws cognito中是什么意思 - What does amr mean in aws cognito ReceiveMessage中的ApproximateReceiveCount中的approximate是什么意思? - What does it mean by approximate in ApproximateReceiveCount in ReceiveMessage? Go Mod 需要什么意思 - What does the Go Mod require mean aws,loadbalancer,dns中的dualstack是什么意思? - aws, loadbalancer, what does dualstack mean in dns? PAGE_EXECUTE_READWRITE 作为 VirtualAlloc 中的一个选项的存在是否意味着 W^X 仅由 DEP 在 Windows 中提供便利? - Does the existence of PAGE_EXECUTE_READWRITE as an option in VirtualAlloc mean that the W^X is only facilitated in Windows by DEP?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM