微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

什么时候esp寄存器设置在Linux?

在程序执行之前, esp寄存器何时被设置为指向有效地址? 在调用exec期间? 或者在用户空间本身? 我已经通过了内核代码,似乎无法find任何地方。

如何在一个确定的地址(gcc,linux)的可执行文件中创build一个“空”空间?

通过SSH启动一个长时间运行的程序

清除串口缓冲区

Google Chrome 61.0.3163.79中的canvas在Linux上速度太慢

如何使用期望与可选的提示

背景

x86 cpu有两个(实际上是四个)堆栈(每个任务):一个用于用户模式,一个用于内核模式。

当在用户模式下发生中断时,cpu将把esp设置为内核堆栈的地址(参见“TSS”以获取更多信息),并将esp (用户模式堆栈的位置)的原始值推送到(内核)堆栈。 当发生中断时, eip , cs和eflags总是被压入堆栈。

从中断返回时, iret指令将从(内核)堆栈弹出“旧”寄存器值,并且堆栈指针将再次指向用户的堆栈。

抢先式多任务操作系统通常以下列方式工作:

一些任务正在运行,这意味着这个任务在很短的时间内就会占用100%的cpu负载。 发生定时器中断时,当前正在运行的任务的寄存器值将被存储在堆栈中(由cpu)。 操作系统push所有其他寄存器的值,并将esp值更改为另一个任务的内核堆栈(在另一个定时器中断发生时保存)。 然后它pops寄存器并执行一个iret ,所有寄存器包含另一个任务的值,另一个任务正在运行。

在Linux(4.12.2)中,x86-32由组件源“entry_32.S”中的__switch_to_asm函数完成。

直接回答你的问题

一个新的任务被创建时,两个堆栈(用户和内核堆栈)被分配给该任务,并且在中断中被初始化的注册值被写入内核堆栈。 这包括用户模式的esp的初始值。

有些计时器会在第一次启动任务之后中断(与已经运行的任务重新启动的方式相同)。

在(旧版本的)Linux中,有两个命令用于创建新的任务:

fork()将简单地复制内核堆栈。 fork()会复制一个已经存在的任务,所以所有的寄存器值(包括esp )必须与已经存在的任务完全相同

execve()将不会分配一个新的内核堆栈(现在新的任务被创建,但另一个可执行文件正在当前任务中运行)。 execve将分配一个新的用户堆栈并覆盖内核堆栈上的esp值。 (Mark Plotnick的评论向你展示了完成这个任务的位置。)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐