首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么` `write()`是通过`call`指令而不是中断来执行的?

write()是通过call指令而不是中断来执行的原因如下:

  1. write()函数是一个系统调用,用于将数据写入文件或设备。系统调用是用户程序与操作系统之间的接口,用于访问操作系统提供的服务和资源。在执行系统调用时,用户程序需要切换到内核态,这需要一些特殊的处理。
  2. 中断是一种由硬件或软件触发的事件,用于打断正在执行的程序,转而执行相应的中断处理程序。中断通常用于处理硬件设备的输入/输出操作,例如键盘输入、磁盘读写等。中断处理程序通常是事先定义好的,用于处理特定的中断事件。
  3. 在执行系统调用时,用户程序需要切换到内核态,这是因为系统调用需要访问操作系统的内部资源和功能。为了实现这种切换,操作系统提供了特殊的指令,例如call指令。
  4. call指令用于在程序中调用一个子程序或函数,并将控制权转移到该子程序中执行。当用户程序调用write()函数时,通过call指令将控制权转移到操作系统内核中的相应系统调用处理程序。这样可以确保在执行系统调用时,用户程序能够正确地切换到内核态,并且操作系统能够提供相应的服务。

总结起来,write()是通过call指令而不是中断来执行的,是因为系统调用需要用户程序切换到内核态,并且操作系统提供了特殊的指令来实现这种切换。中断通常用于处理硬件设备的输入/输出操作,而系统调用是用户程序与操作系统之间的接口,用于访问操作系统提供的服务和资源。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

详解linux系统调用原理

库函数 与 系统调用处理函数 之间,由于涉及用户态与内核态切换,要复杂一些。 Linux 通过中断 实现从 用户态 到 内核态 切换。...用户态 与 内核态 独立执行流,因此在切换时,需要准备 执行栈 并保存 寄存器 。 内核实现了很多不同系统调用(提供不同功能), 系统调用处理函数 只有一个。...因此,用户进程必须传递一个参数用于区分,这便是 系统调用号 ( system call number )。 在 Linux 中, 系统调用号 一般通过 eax 寄存器 传递。...总结起来, 执行态切换 过程如下: 应用程序 在 用户态 准备好调用参数,执行 int 指令触发 软中断中断号为 0x80 ; CPU 被软中断打断后,执行对应 中断处理函数 ,这时便已进入 内核态...并从 内核栈 中恢复 寄存器 ; 系统调用处理函数 执行 ret 指令切换回 用户态 ; 编程实践 下面,通过一个简单程序,看看应用程序如何在 用户态 准备参数并通过 int 指令触发 软中断

4.2K43

操作系统接口和调用--02

即用户怎么用操作系统?.. ---- 会学习从会问问题开始… 操作系统接口并不是直接暴露给用户使用,用户通过应用软件间接调用到操作系统接口。 ---- 命令行怎么回事?...因此就有了IEEE制定统一操作系统相关接口。 例如上面讲到printf函数,底层就是通过调用操作系统提供write接口完成对屏幕输出操作。...---- 硬件提供了“主动进入内核方法” 硬件提供了中断功能,让程序可以调用操作系统相关接口,当调用int指令进行中断时候,会将CS中CPL设置为0,然后去调用内核区中系统接口。...当中断程序执行结束后,会将CPL重新设置为3,回到用户态 如果还不清楚,也可以看看下面这篇文章分析: 系统调用:用户级函数如何通过INT 80中断进入操作系统内核 ---- 中断处理程序: system_call...) 执行system_call内核函数,通过传入系统调用号,去函数表中定位到对应函数,然后执行函数 ----

39020

从一个简单汇编程序学习linux下系统调用机制

(system call),其类似C语言中函数,可在程序中直接调用,也即 write(1,msg,len)和 exit(0)。...系统中断-操控内核关键 1、什么系统中断?...任何CPU在检测到从外部发来或内部产生中断信息时候,都需要立即处理所接受到信息,CPU在不再接着向下执行刚才指令,转而去处理中断信息过程就叫中断中断有内中断和外中断之分。...内中断又有以下几种情况: 除法错误 单步执行 执行into指令 执行int指令 2、 int0x80是什么? 在CPU设计之初,中断信息中包含有标识中断类型码。...中断类型码作用是用来定位中断处理程序执行int指令, intnn为中断类型码,其功能为引发中断过程。 int0x80,即中断号为0x80,其上层应用程序与内核进行交互通信唯一接口。

83520

Go 语言汇编入门

为什么要学 Go 语言汇编 首先是要破除迷信,同一个问题网上答案众说纷纭,比如到底传值还是传引用争论不休,不如静下心看一下汇编踏实。...学习 Go 语言汇编不是为了以后用汇编做开发,只是可以用通过阅读汇编深刻理解 Go 语言背后实现细节,真正精通这门语言,在使用过程中可以更加安心。...接下来指令 .globl _start,这里并没有拼错,不是 global,_start 一个标签。接下来真正汇编指令部分了。...接下来指令 int $0x80,前面介绍过,这是一条中断触发指令,把执行流程交给内核继续处理,应用程序不用关心内核如何处理,内核处理完会把执行流程还给应用程序,同时根据执行成功与否设置全局变量 errno...接下来指令实际上执行 exit(0) 退出程序,指令和逻辑与之前一样,不再赘述。 下面编译和执行上面的汇编代码。

92020

MIT 6.S081 (BOOK-RISCV-REV1)教材第四章内容 --Trap -- 中

通过getCmd函数汇编源码,可以看到调用write函数对应汇编指令,这段汇编指令主要作了参数准备,最后跳转到write函数地址执行write汇编代码如下所示: 通过上图可知write汇编程序入口地址...ecall并不会为我们做这里任何一件事。 当然,我们可以通过修改硬件让ecall为我们完成这些工作,不是交给软件完成。并且,我们也将会看到,在软件中完成这些工作并不是特别简单。...另一个问题为什么这些寄存器保存在trapframe,不是用户代码栈中?...所以内核需要自己管理这些寄存器保存,这就是为什么内核将这些内容保存在属于内核内存trapframe中,不是用户内存。...我们之前在系统调用过程中打开了中断,这里关闭中断是因为我们将要更新STVEC寄存器指向用户空间trap处理代码,之前在内核中时候,我们指向内核空间trap处理代码。

27040

什么系统调用?

当谈到系统调用(system call)时,我们首先映入脑海差不多就是软中断、内核态、用户态。开宗明义第一章,我想让大家先要重新认识一下『系统调用』这个词。...中断本身一个硬件概念,就是打断CPU,让其执行一下其他任务,比如键盘中断、打印机中断、定时器中断等。软中断本就是从软件层面模拟了这一中断操作。...网上很多资料大多会提到使用128号软中断指令(int 0x80)来使进程从用户态陷入内核态,执行完毕后调用iret指令重回用户态。但其实这是比较传统、比较老做法。...后来随着 ( 和 )升级, 内核一般会使用快速系统调用( ) 指令代替int 0x80,使用sysexit/sysret代替iret。...在运行软中断指令时候,会用一个寄存器存储具体系统调用号,比如在Linux上read和write系统调用号分别为0和1。 单内核与微内核上系统调用有什么不同呢?

1.5K30

进入Linux内核前准备

我们把为什么给ds赋值说清楚了,那ds为什么0x07c0呢?之前我们不是说Bios将数据复制到内存中0x7c00吗,这里为为什么刚好差了16倍呢?...这个中断发起后,CPU会通过这个中断号,去寻找对应中断处理程序入口地址,并跳转过去执行,逻辑上就想到那个与执行了一个函数,0x13号中断BIOS提前写好一个读取磁盘相关功能函数。...继续看head.s,两个call语句设置了中断描述符表IDT和全局描述符表GDT,然后后面又是重新执行了一遍前面的代码,为什么要重新设置段寄存器值呢?...idt里面存储中断描述符,每个中断号对应一个中断描述符,中断描述符里面存储着主要是中断程序地址,这样CPU就可以根据中断号寻找到对应中断程序并且执行。...因此上面几句执行完后,会把esp寄存器(栈顶元素)值赋值给eip寄存器,cs:eipCPU执行下一条指令地址,此时栈顶刚好我们压入栈main.c里面main函数内存地址,这样我们就使用压栈指令和返回指令

5.5K20

操作系统进程实现---中---05

然后,通过系统调用号,去system_call_table定位到某个具体内核函数地址,然后执行 这里具体定位到sys_fork函数 在执行sys_fork时候,可能会引起切换,例如: 如果产生了阻塞或者时间片到期了...,即PCB切换,因为用户态状态在产生中断时候,就已经保存到了内核栈中 然后再通过counter判断时间片是否到期,如果到期了,也需要进行切换 当reschedule函数执行结束后,会去执行ret_from_sys_call...---- 这里先来看一下中断返回,即执行完_schedule函数后,执行ret_from_sys_call 恢复现场,将保存相关寄存器状态从栈中弹出 此时esp指向栈,已经不是原内核级线程对应栈了...当段间指令jmp所含指针选择符指示一个可用任务状态段TSS描述符时,将造成任务切换。那么CPU怎么识别描述符TSS描述符不是其他描述符呢?...,其使用就是父进程用户栈空间,下面ss和esp参数,就是函数从栈中获取实参值 最后还有一点需要说明,因为这里使用tss完成内核级线程切换,不是内核栈方式,因此不需要将eip压入两个栈中

81860

16汇编第十讲完结Call变为函数以及指令最后讲解

整体这样,这里为什么要一开始把bp和sp相等,有原因,我们不妨这样想,如果我们申请局部变量空间 时候,是不是参数偏移也要改动,这样每次都要自己计算偏移,相当麻烦,所以只能这样, 我们以后找参数就...返回 ,retf下面详细讲 在这里主要是掌握bp所在位置即可,就能明白为什么这样写了,不信的话自己写个程序,看下反汇编,大体就是这个套路,这里讲解为什么这样做,不是和市面的汇编视频一样,你看到...4到栈底才可以 二丶中断指令 1.什么中断指令 中断,有一种改变程序执行顺序方法 中断具有很多中断类型 中断指令有3条   1.INT i8(i8代表一个八位立即数)   2.IRET  IRET...比如显示一个字符串 mov ah,09h int 21h 其中参数09,int 21h代表执行,还有很多 介绍下指令   INT I8:  中断调用指令: 产生I8号中断,就是调用int代表我要调用了...,其中指令是什么使我们给,一个八位立即数比如 09   IRET:  中断返回指令,理解为返回,可以进行下一条指令执行   INTO:  不常用,不讲解. 3.21h中断,到底个啥玩意 我们每次都调用

895100

ROP基本原理和实战教学,看这一篇就够了!

通过上一篇文章栈溢出漏洞原理详解与利用,我们可以发现栈溢出控制点ret处,那么ROP核心思想就是利用以ret结尾指令序列把栈中应该返回EIP地址更改成我们需要值,从而控制程序执行流程。...时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,不是执行恶意指令。...sys_write(unsigned int fd, const char __user *buf, size_t count); 可以发现前三个mov指令把该函数需要参数放进相应寄存器中,然后把sys_write...,&system_call),设置中断向量号0x80中断描述符,也就是说实现了系统调用 (处理过程system_call)和 int 0x80中断对应,进而通过中断号用EAX实现不同子系统调用...、通过ret指令使得EIP指向pop eax;地址 3、执行pop eax;栈顶值0xb成功出栈,栈顶指针下移 4、通过ret指令使得EIP指向pop ebx;地址 .....

1.9K30

Linux系统调用原理

由于某些指令(如设置时钟、关闭/打开中断和I/O操作等)只能运行在内核态,所以操作系统必须提供一种能够进入内核态方式,系统调用 就是这样一种机制。...系统调用 Linux 内核提供一段代码(函数),其实现了一些特定功能,用户可以通过 int 0x80 中断(x86 CPU)或者 syscall 指令(x64 CPU)调用 系统调用。...二、进入系统调用 本文主要介绍 x86 CPU 进入系统调用方式 Linux 提供了 int 0x80 中断让用户程序进入 系统调用,我们来看看 Linux 对 int 0x80 中断处理初始化过程...因为 用户态 和 内核态 使用栈不同,调用 系统调用 在用户态调用进入 系统调用 后会变成内核态,所以参数就不能通过传递。... Linux 进入中断处理程序时,会把这些寄存器值保存到内核栈中,这样 系统调用 就能通过内核栈获取到参数。

4.2K30

xv6(6) 系统调用

$xv6$ 系统调用是用 INT n 指令实现,INT n 作用就是触发一个 $n$ 号中断中断过程应该很熟悉了吧,不熟悉可以看看前文中断代码部分。...指令触发中断。...上面只是说一般大致情况,如果看过前文中断机制应该知道,$xv6$ 对所有中断(包括系统调用)处理执行共同中断入口程序,主要就是保护现场压栈寄存器,然后根据向量号不同执行不同中断处理程序。...问题很多,咱们一个一个解决,首先从 IDT, GDT 中获取到中断入口程序地址之后,执行中断入口程序压栈寄存器保存上下文,这个上下文中包括了向量号。...$c$ 语言中这个过程可能看起来不是那么真切,如果用汇编来写,或者查看编译之后程序,会有下面的大致过程: push size push buf push fd call writecall

27710

深入探索 perf CPU Profiling 实现原理

CPU cycles (周期) CPU 执行指令时间单位,时钟频率表示 CPU 每秒执行 CPU 周期数。每个 CPU 指令执行可能需要一个或多个 CPU 周期。...Brendan Gregg 在大量例子中都使用了 99 Hertz 这个采样频率,至于为什么这样设置,他在文章 perf Examples 中给出了解释,大意:选择 99 Hertz 不是100...我们知道,PC 寄存器存放下一条指令地址,这时 PC 寄存器中函数调用指令call)后紧跟着那条指令地址。...返回地址函数调用指令call)后下一条指令,即 Calc 调用完 Sum 后紧跟着下一条指令,把这个指令地址恢复到 PC 寄存器中,实际上将控制权返回给了 Calc ,让 Calc 剩余部分接着执行...在 x86 架构中,每个中断或异常都通过一个 0 到 255 范围内数字识别,这个数字一个 8 位无符号数,被称为“向量(vector)”。

1.6K73

操作系统篇-进程管理和中断

进程和线程区别 进程就是一个程序运行起来状态,线程一个进程中不同执行路径。 进程OS分配资源基本单位,线程执行调度基本单位。...纤程线程中线程,对应图最上面蓝色框,在用户空间,不需要向操作系统申请。 纤程处于线程内部,非常轻量级,可以在线程中快速切换。JVM自己管理,自己实现调度,自己切换,与操作系统无关。...(下半场) 软中断(80中断中断向量表特殊符号 系统调用:int 0x80 (INT用于x86处理器汇编指令) 或者 sysenter原语(现在cpu在硬件级别直接支持,汇编码) 通过ax...寄存器填入调用号(比如1代表exit函数,2代表fork函数) 参数通过bx cx dx si di传入内核 返回值通过ax返回 系统调用实现hello world代码: ;以下例子主要调用了内核空间...注:eax 32位,ax16位 java中例子 java读网络 – jvm read() – c库read() - > 内核空间 -> system_call() (系统调用处理程序)-> sys_read

1.2K00

为什么 Linux 系统调用会消耗较多资源

多数编程语言函数调用只需要分配新栈空间、向寄存器写入参数并执行 CALL 汇编指令跳转到目标地址执行函数,在函数返回时通过栈或者寄存器返回参数[^3]。...图 4 - 硬件中断和软件中断 根据事件发出者不同,我们可以将中断分成硬件和软件中断两种,硬件中断由处理器外部设备触发电子信号;软件中断由处理器在执行特定指令时触发,某些特殊指令也可以故意触发软件中断...在 32 位 x86 系统上,我们可以使用 INT 指令触发软件中断,早期 Linux 会使用 INT 0x80 触发软件中断、注册特定中断处理器 entry_INT80_32 来处理系统调用...等架构上仍然会使用中断执行系统调用[^12] 汇编指令 因为使用软件中断实现系统调用在 Pentium 4 处理器上表现非常差[^13]。...与 INT 0x80 通过触发软件中断实现系统调用不同,SYSENTER 和 SYSCALL 专门为系统调用设计汇编指令,它们不需要在中断描述表(Interrupt Descriptor Table

1.9K40

Linux系统调用过程

应用程序和文件系统接口系统调用。 ?...我们经常看到比如fork、open、write 等等函数实际上并不是真正系统调用函数,他们都只是c库,在这些函数里将执行一个软中断 swi 指令,产生一个软中断,使CPU 陷入内核态,接着在内核中进行一系列判断...,判断出哪个系统调用,再转到真正系统调用函数,完成相应功能。...但是因为用户程序运行在用户空间,系统调用运行在内核空间,因此用户程序不能直接调用系统调用函数,我们经常看到比如fork、open、write 等等函数实际上并不是真正系统调用函数,他们都只是c库,...在这些函数里将执行一个软中断 swi 指令,产生一个软中断,使CPU 陷入内核态,接着在内核中进行一系列判断,判断出哪个系统调用,再转到真正系统调用函数,完成相应功能。

4.8K70

逆向工程——汇编基础

调用子程序指令CALL,对应返回指令RET,另外还有ENTER和LEAVE,她们可以帮助进行堆栈维护。 CALL指令参数被调用子程序地址。使用宏汇编时候,这通常是一个标号。...CPU向DMA控制器发出指令,要求外设和内存直接交换数据,通过CPU。...子程序一个不错主意,不过,CALL指令需要指定地址,让外设强迫CPU执行一条CALL指令也违背了CPU作为核心控制单元设计初衷。考虑到这些,这x86系统中引入了中断向量概念。...操作系统随时可能升级,这样,通过CALL调用操作系统服务(如果说每个程序都包含对于文件系统、进程表这些应该由操作系统管理数据直接操作的话,不仅会造成程序臃肿,而且不利于系统安全)就显得不太合适了...CPU将保存当前程序状态字,清除Trap和Interrupt两个标志,将即将执行指令地上压入堆栈,并调用中断服务(根据中断向量表)。 编写中断服务程序不是一件容易事情。

1.1K10

程序编译、链接、装载与运行

装载 在上一节我们已经通过链接得到了可执行文件,在可执行文件中包含了很多段(section),但是一旦这些段被加载到内存中之后,我们就不在乎他到底是什么类型数据,只在乎这份数据在内存中读写权限。...由于现代操作系统均采用分页方式管理内存,所以操作系统只需要读取可执行文件文件头,之后建立起可执行文件到虚拟内存注5映射关系,不需要真正将程序载入内存。...运行 开始执行 操作系统jmp到进程第一条指令不是main方法,而是别的代码。...x86下使用中断(interrupt)发送信息给CPU,一旦CPU收到了中断信息,就会停止执行当前任务转而根据中断编号去执行中断处理函数。...= 2 对应 fork,等等 参数设置完毕之后,用户程序执行 int 0x80 指令,CPU收到中断信息 CPU将控制权限交给操作系统内核,进程栈从用户栈切换到内核栈注8 中断向量表中 0x80 号中断中断处理函数开始执行

1.3K10
领券