在linux 0.11版本源代码中,在文件linux/include/asm/system.h中有一个宏定义  move_to_user_mode()

  1 #define move_to_user_mode() \
2 __asm__ ("movl %%esp,%%eax\n\t" \
3 "pushl $0x17\n\t" \
4 "pushl %%eax\n\t" \
5 "pushfl\n\t" \
6 "pushl $0x0f\n\t" \
7 "pushl $1f\n\t" \
8 "iret\n" \
9 "1:\tmovl $0x17,%%eax\n\t" \
10 "movw %%ax,%%ds\n\t" \
11 "movw %%ax,%%es\n\t" \
12 "movw %%ax,%%fs\n\t" \
13 "movw %%ax,%%gs" \
14 :::"ax")

  这个宏定义用于在内核初始化结束时“切换到”初始进程(任务0)。

  首先解释指令iret.

  iret 指令(interrupt return)中断返回,终端服务程序的最后一条指令。iret指令将推入堆栈的段地址和偏移地址弹出,使程序返回到原来中断发生的地方。它将产生以下三点效应:

1.恢复IP(instruction pointer):(IP)←((SP)+1:(SP)),(SP)←(SP)+2

2.恢复CS(code segment):(CS)←((SP)+1:(SP)),(SP)←(SP)+2

3.恢复中断前的PSW(program status word),即恢复中断前的标志寄存器的状态。
(FR)←((SP)+1:(SP)),(SP)←(SP)+2
以上操作按顺序进行。
  当使用IRET指令返回到相同保护级别的任务时,IRET会从堆栈弹出代码段选择子及指令指针分别到CS与IP寄存器,并弹出标志寄存器内容到EFLAGS寄存器。
  当使用IRET指令返回到一个不同的保护级别时,IRET不仅会从堆栈弹出以上内容,还会弹出堆栈段选择子及堆栈指针分别到SS与SP寄存器。
  
  因此,这段程序的大概意思是先将任务0所需要的各个寄存器的值压栈,压栈后执行IRET指令,利用该中断返回指令将各个寄存器设置为我们所理想的值。
  但是,程序中压入了几个常数,0x17,0x0f,1f是什么意思呢。
  分两类,0x17,0x0f是段选择子。段选择子用于保护模式下的寻址。0-1位表示请求的特权级,0表示系统级,3表示用户级。2位用于选择全局描述符表还是局部描述符表。
  3-15位是描述符表项索引。
  1f表示将下面标号1的程序段的偏移地址入栈。
 
  
 
   

linux源码阅读笔记 move_to_user_mode()解析的更多相关文章

  1. linux源码阅读笔记 数组定义

    在阅读linux源码的过程中遇到了下面的略显奇怪的结构体数组定义. static struct hd_struct{ long start_sect; long nr_sects; }hd[10]={ ...

  2. linux源码阅读笔记 asm函数

    在linux源码中经常遇到__asm__函数.它其实是函数asm的宏定义 #define __asm__ asm,asm函数让系统执行汇编语句. __asm__常常与__volatile__一起出现. ...

  3. linux源码阅读笔记 fork函数

    在阅读源码的过程中,发现找不到fork函数的定义.后来在linux/init/main.c中找到了这样一条语句 static inline _syscall0(int,fork) 原来这里就是fork ...

  4. linux源码阅读笔记 void 指针

    void 指针的步长为1,而其他类型的指针的步长与其所定义的数据结构有关. example: 1 #include<stdio.h> 2 main() 3 { 4 int a[10]; 5 ...

  5. linux源码阅读笔记 jmpi指令(转)

    jmpi是段间跳转指令,用于x86实模式下, 如:BOOTSEG = 0x0c70 jmpi    4, #BOOTSEG 假如当前段CS==00h,那么执行此指令后将跳转到段CS==0x0c70,当 ...

  6. linux源码阅读笔记 #define 语句的妙用

    #define 语句用于宏定义,在c中,我们可以用其实现函数的功能.如下语句 #define test(a,b)  a>b?a:b 很显然,这是一个比较大小的语句.这里a,b相当于函数中的参数. ...

  7. Linux 0.11源码阅读笔记-文件管理

    Linux 0.11源码阅读笔记-文件管理 文件系统 生磁盘 未安装文件系统的磁盘称之为生磁盘,生磁盘也可以作为文件读写,linux中一切皆文件. 磁盘分区 生磁盘可以被分区,分区中可以安装文件系统, ...

  8. Linux 0.11源码阅读笔记-中断过程

    Linux 0.11源码阅读笔记-中断过程 是什么中断 中断发生时,计算机会停止当前运行的程序,转而执行中断处理程序,然后再返回原被中断的程序继续运行.中断包括硬件中断和软件中断,硬中断是由外设自动产 ...

  9. Linux 0.11源码阅读笔记-总览

    Linux 0.11源码阅读笔记-总览 阅读源码的目的 加深对Linux操作系统的了解,了解Linux操作系统基本架构,熟悉进程管理.内存管理等主要模块知识. 通过阅读教复杂的代码,锻炼自己复杂项目代 ...

随机推荐

  1. startup.bat闪退---tomcat环境变量配置中遇到的问题

    常用的方法: 1.在已解压的tomcat的bin文件夹下找到startup.bat,右击->编辑.在文件头加入下面两行: SET JAVA_HOME=D:\Java\jdk1.6.0_10   ...

  2. 一些常用的字符串hash函数

    unsigned int RSHash(const std::string& str) { unsigned int b = 378551; unsigned int a = 63689; u ...

  3. javascript a=a||"" 表达式

    其实: a=a||"defaultValue"; 与: if(!a){ a="defaultValue"; } 和: if(a==null||a==" ...

  4. activiti搭建(二)与Spring集成

    转载请注明源地址:http://www.cnblogs.com/lighten/p/5876773.html 本文主要讲解如何将Activiti和Spring框架集成,再过一段时间将会将一个基础的de ...

  5. 【Qt】Qt之进程间通信(QProcess)【转】

    简述 前几节里,分享了进程通信的几种方式:Windows消息机制.Shared Memory(共享内存),本节讲解下关于进程通信的另外一种方式-QProcess. 简述 命令行参数启动 说明 实现 命 ...

  6. SQL中char,varchar,nvarchar等的异同

    比较这几个数据类型,总是忘记,可能比较细节的原因.先做个记号,回头完善.

  7. (二)使用log4net写入数据库自定义日志

    1.配置项目环境 1.1 本文只显示需要修改配置的操作,初次引入log4net环境的请参考上文. 1.2 安装mysql-connector-net.msi环境,下载地址.并手动生成数据库日志信息表. ...

  8. MVC 5.0(or5.0↓) Ajax.BeginForm 异步上传附件问题,答案是不能的!

    MVC 5.0(or5.0↓)  Ajax.BeginForm 异步上传附件问题,答案是不能的! (请注意我这里说的异步!) 来看一下下面这段一步提交file的代码 //前台 .cshtml 文件 & ...

  9. snmptrap使用

    SNMP简单网络管理协议,其中其支持的一个命令snmptrap命令,用于模拟向管理机发送trap消息.   启动陷阱方法: snmptrapd -C -c /etc/snmp/snmptrapd.co ...

  10. CSS3 transition 属性 过渡效果

    <!DOCTYPE html> <html> <head> <style> div { width:100px; height:100px; backg ...