汇编指令中的 INT 与 CALL 的区别

4

我在网上搜索了一下,但是没有找到汇编语言中int和call之间的区别。那么int和call汇编指令有什么区别呢?

它们都可以调用某些函数。 "int"指令调用系统函数, "call"指令调用用户函数。

但是在实模式下它们是否相同? 我无法理解它们之间的区别。

此外,int指令是否调用了BIOS中定义的IVT(中断向量表)? 但是,call指令也可以执行相同的操作吗?为什么需要将其分开使用?


3
BIOS中断调用可以通过知道中断/函数号来实现 - 实际地址不需要知道。这是一种抽象,就像函数名称一样。 - Jonathon Reinhart
这是指令集文档中的内容,这些文档以无数种形式遍布于整个网络。 - old_timer
2个回答

9

表面上看,区别在于:

CALL获取过程地址,可以是近址或远址,并以常数或寄存器提供。而INT获取中断号,在实模式下用作中断向量表0000:0000中的索引,以查找地址。CALL将返回地址(近址或远址)压入堆栈;而INT则将标志寄存器和返回地址(始终为远址)压入堆栈。

在保护模式下,INT有所不同。它涉及用户到内核模式的切换。

INT用于消费BIOS和DOS的服务。CALL用于调用您自己的过程。您可以使中断向量指向您的一个过程,但这有什么意义呢?

一些具有供其他程序使用的服务的实模式DOS程序也用于挂接中断向量。例如,Microsoft鼠标驱动程序(一个常规的程序,而不是DOS的一部分)会挂接INT 33h向量,程序会使用它与鼠标交互。为了使向量保持有效,这些程序必须留驻在内存中。


你能否推荐其它阅读源,类似于Vlad Pirogov的《汇编程序设计大师书》?我回答这个问题的来源是哪里呢? - xmojmr
有一段时间了,我记不清了。可能是Jourdain的书。 - Seva Alekseyev
在保护模式下,int 并没有太大的区别。它仍然根据内核维护的表将控制权传递给中断处理程序。它仍然会将 EFLAGS 和 CS:EIP 推入内核堆栈(但这只是一个小差异)。它仍然主要用于调用内核中的函数,例如通过在寄存器中放置参数和系统调用代码来从 32 位 Linux 或 *BSD 用户空间使用 int 0x80,就像 DOS/BIOS int 调用的 ABI 一样。 - Peter Cordes
在保护模式下,可以将“调用门”段指定为“call”指令的目标地址。在这种情况下,还会发生到内核的上下文切换。一些旧的x86 SunOS版本使用此变体来进入系统调用,而不是使用“int”指令... - Martin Rosenau

1
我在网上搜索了int和call在asm中的区别,但没有找到任何差异。call和int asm指令有什么区别?
全面的答案会很长,简化的意见也不足够。所以我只回答:
我在网上搜索了int和call在asm中的区别,但没有找到任何差异。
在您的网络搜索中,请选择可信和专业的信息来源,您将找到您想要的答案。
我建议从Wikipedia: INT (x86 instruction)开始阅读,还要阅读链接和“另请参阅”文章(肯定包括Wikipedia: Interrupt descriptor tableWikipedia: System call,其他关键术语可能是call gateinterrupt gate...),并熟悉外部参考资料。

最重要的参考资料之一是Intel® 64和IA-32体系结构软件开发者手册,其中第6章→过程调用、中断和异常应该能够回答你想了解的所有信息。


2
通常情况下,您无法访问中断代码所在的内存特权级别。您只能触发中断,这会改变特权级别(包括从用户空间到系统空间的内存映射)。 - turboscrew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接