有人可以解释以下汇编代码的作用吗?
int 0x80
答案 0 :(得分:105)
int
表示中断,数字0x80
是中断号。
中断将程序流传输给处理该中断的任何人,在这种情况下是中断0x80
。
在Linux中,0x80
中断处理程序是内核,用于通过其他程序对内核进行系统调用。
通过检查寄存器%eax
中的值(气体语法和Intel语法中的EAX),通知内核程序想要进行哪个系统调用。每个系统调用对其他寄存器的使用有不同的要求。例如,1
中的%eax
值表示exit()
的系统调用,而%ebx
中的值表示exit()
的状态代码值
答案 1 :(得分:53)
它将控制传递给中断向量0x80
请参阅http://en.wikipedia.org/wiki/Interrupt_vector
在Linux上,查看this:它用于处理system_call
。当然,在另一个操作系统上,这可能意味着完全不同的东西。
答案 2 :(得分:35)
请记住,0x80 = 80h = 128
您可以看到here INT 只是众多指令中的一个(实际上是汇编语言表示(或者我应该说是'助记符'))存在于x86指令集中。您还可以在英特尔自己的手册here中找到有关此说明的更多信息。
总结PDF:
INT n / INTO / INT 3 - 调用中断程序
INT n指令生成对中断或异常的调用 使用目标操作数指定的处理程序。目的地 操作数指定0到255之间的向量,编码为8位无符号 中间价值。 INT n指令是for的通用助记符 执行软件生成的调用中断处理程序。
您可以在问题中看到 0x80 是目标操作数。此时CPU知道它应该执行一些驻留在内核中的代码,但是代码是什么?这是由Linux中的中断向量决定的。
最有用的DOS软件中断之一是中断0x21。通过在寄存器中调用不同的参数(主要是ah和al),您可以访问各种IO操作,字符串输出等。
大多数Unix系统和衍生产品不使用软件中断,但中断0x80除外,用于进行系统调用。这是通过在处理器的EAX寄存器中输入对应于内核函数的 32位值然后执行INT 0x80来实现的。
请看看中断处理程序表中其他可用值的显示位置:
如您所见,该表指向CPU执行系统调用。您可以找到Linux系统调用表here。
因此,通过将值0x1移动到EAX寄存器并在程序中调用INT 0x80,可以使进程执行内核中的代码,该代码将停止(退出)当前正在运行的进程(在Linux,x86 Intel CPU上)
硬件中断不得与软件中断混淆。 Here在这方面是一个非常好的答案。
This也是很好的来源。
您可以在行动here中看到 int 80h 。
答案 3 :(得分:9)
int 0x80是汇编语言 用于调用的指令 在x86上的Linux系统调用(即, 与英特尔兼容的处理器。
答案 4 :(得分:7)
最小可运行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
结果:程序打印到stdout:
hello world
然后干净利落地退出。
您无法直接从用户区设置自己的中断处理程序,因为您只有ring 3 and Linux prevents you from doing so。
GitHub upstream。在Ubuntu 16.04上测试过。
更好的替代方案
int 0x80
已被更好的系统调用替代方案所取代:首先是sysenter
,然后是VDSO。
x86_64有a new syscall
instruction。
另请参阅:What is better "int 0x80" or "syscall"?
最小16位示例
首先了解如何创建一个最小的引导加载程序操作系统并在QEMU和真实硬件上运行它,如我在此解释的那样:https://stackoverflow.com/a/32483545/895245
现在您可以在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个字节。
Minimal example that does some IO让处理程序可见。
最低保护模式示例
现代操作系统以所谓的保护模式运行。
在这种模式下处理有更多选项,所以它更复杂,但精神是一样的。
关键步骤是使用LGDT和LIDT指令,这些指令指向描述处理程序的内存数据结构(中断描述符表)的地址。
答案 5 :(得分:3)
“int”指令导致中断。
简单答案:简单地说,中断是一个中断CPU并告诉它运行特定任务的事件。
详细解答:
CPU有一个存储在内存中的中断服务程序(或ISR)表。在Real(16位)模式下,它存储为 IVT ,或 I nterrupt V ector T 能够。 IVT通常位于0x0000:0x0000
(物理地址0x00000
),它是一系列指向ISR的段偏移地址。操作系统可以用自己的ISR替换已存在的IVT条目。
(注意:IVT的大小固定为1024(0x400)字节。)
在受保护(32位)模式下,CPU使用IDT。 IDT是一个可变长度的结构,由描述符(也称为门)组成,它告诉CPU有关中断处理程序的信息。这些描述符的结构比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的每个中断。操作系统不一定全部使用,因此当前位允许CPU正确处理操作系统无意处理的中断。
当发生中断时(通过IRQ中的外部触发器(例如硬件设备)或来自程序的int
指令),CPU按下EFLAGS,然后按CS,然后按EIP。 (这些由中断返回指令iret
自动恢复。)OS通常存储有关机器状态的更多信息,处理中断,恢复机器状态,并继续。
在许多* NIX操作系统(包括Linux)中,系统调用都是基于中断的。程序将参数放入寄存器(EAX,EBX,ECX,EDX等)中的系统调用,并调用中断0x80。内核已经将IDT设置为在0x80上包含一个中断处理程序,当它接收到中断0x80时会被调用。然后内核读取参数并相应地调用内核函数。它可以在EAX / EBX中存储一个回报。系统调用已基本上由sysenter
和sysexit
(或AMD上的syscall
和sysret
)指令取代,这样可以更快地进入第0环。
此中断在不同的操作系统中可能有不同的含义。请务必查看其文档。
答案 6 :(得分:2)
如上所述,它会导致控制跳转到中断向量0x80。在实践中,这意味着(至少在Linux下)是调用系统调用;确切的系统调用和参数由寄存器的内容定义。例如,可以通过将%eax设置为1,然后设置为“int 0x80”来调用exit()。
答案 7 :(得分:1)
它告诉cpu激活中断向量0x80,它在Linux操作系统上是系统调用中断,用于调用文件等open()
之类的系统函数。
答案 8 :(得分:1)
int只是中断 即处理器将保留其当前执行。
0x80只是系统调用或内核调用。 即将执行系统功能。
具体来说,0x80代表rt_sigtimedwait / init_module / restart_sys,它随体系结构的不同而不同。
有关更多详细信息,请参阅 https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md