首页 > 其他分享 >切换栈操作

切换栈操作

时间:2024-04-07 11:33:51浏览次数:16  
标签:movl esp mov eax 切换 memory 操作 edx

1. 何时需要切换栈:

  上下文切换,如:

  当需要切换进程时,需要保存正在运行的进程并切换到新的进程。

  当从一个函数切换到另一个函数时,需要保存原有的栈寄存器

2. 切换栈需要有哪些基本操作:

  1. 切换进程时,什么可以表示一个正在运行的程序?

    程序中各个寄存器的值表示程序的运行状态。

    其中ESP和EBP表示栈指针。ESP是当前运行的栈指针,EBP表示进程初始化时的栈指针。

 

 

 

 

 

 

  2. call convention: 

    in X86, 在调用子函数时,IA32 and X64 有不同的参数传递规则。参考x86 calling conventions - Wikipedia

3. 示例演示:

主要流程如下:

  switch:
    save all old process's register
    load new process's register
    load new process's ESP->完成切换栈操作

  3.1 操作系统导论:Chapter 6

  对于xv6中的进程切换代码函数定义如下:

  其中struct context是进程上下文数据,有[context ptr, esp, ebx, ecx, edx, edi, esi, ebp]

void switch (struct context **old, struct context *new);

 具体汇编代码:(使用的是IA32 的cdecl calling convention: "In cdecl, subroutine arguments are passed on the stack."即函数的参数从右往左一次存到ESP中)

xv6:
switch:
   # 4(%esp) save **old, 8(%esp) save *new # #save old context's registers: # #load old context ptr(*old) to eax movl 4(%esp), eax # save all old context's register popl 0(%eax) #eax[0](old[0]) save the old context ptr movl %esp, 4(%eax) movl %ebx, 8(%eax) movl %ecx, 12(%eax) movl %edx, 16(%eax) movl %esi, 20(%eax) movl %edi, 24(%eax) movl %ebp, 28(%eax) # #load new context's registers: # #load new context ptr movl 4(%esp), eax # load all new context's register movl 28(%eax), %ebp movl 24(%eax), %edi movl 20(%eax), %esi movl 16(%eax), %edx movl 12(%eax), %ecx movl 8(%eax), %ebx movl 4(%eax), %esp #new stack point has been set pushl 0(%eax) # return into new context ret

  3.2 UEFI FSP SwitchStack

  这里涉及到从CAR(cach as Ram)即TemporaryMemory搬到PermanentMemory的操作,

  因此这个情况下,把栈空间原封不动的搬到PermanentMemoryBase对应的地方就好,操作如下:

NewRsp = OldRsp - TemporaryMemoryBase + PermanentMemoryBase
NewRbp = OldRbp - TemporaryMemoryBase + PermanentMemoryBase //新的Rbp就是旧的Rbp的一个fixup(从旧的memorybase 往新的memorybase般)
//其它的register复制到新的栈空间

  下面分别是x64和IA32的示例:他们的calling convention 不一样(line38, line39)

  3.2.1 x64 calling convention, rcx(1st parameter), rdx, r8, r9

15 ; VOID
16 ; EFIAPI
17 ; SecSwitchStack (
18 ;   UINT32   TemporaryMemoryBase,
19 ;   UINT32   PermanentMemoryBase
20 ;   );
21 ;------------------------------------------------------------------------------
22 global ASM_PFX(SecSwitchStack)
23 ASM_PFX(SecSwitchStack):
24     ;
25     ; Save four register: rax, rbx, rcx, rdx
26     ;
27     push  rax
28     push  rbx
29     push  rcx
30     push  rdx
31 
32     ;
33     ; !!CAUTION!! this function address's is pushed into stack after
34     ; migration of whole temporary memory, so need save it to permanent
35     ; memory at first!
36     ;
37 
38     mov   rbx, rcx                 ; Save the first parameter rbx = rcx
39     mov   rcx, rdx                 ; Save the second parameter
40 
41     ;
42     ; Save this function's return address into permanent memory at first.
43     ; Then, Fixup the esp point to permanent memory
44     ;
45     mov   rax, rsp
46     sub   rax, rbx
47     add   rax, rcx
48     mov   rdx, qword [rsp]         ; copy pushed register's value to permanent memory
49     mov   qword [rax], rdx
50     mov   rdx, qword [rsp + 8]
51     mov   qword [rax + 8], rdx
52     mov   rdx, qword [rsp + 16]
53     mov   qword [rax + 16], rdx
54     mov   rdx, qword [rsp + 24]
55     mov   qword [rax + 24], rdx
56     mov   rdx, qword [rsp + 32]    ; Update this function's return address into permanent memory
57     mov   qword [rax + 32], rdx
58     mov   rsp, rax                 ; From now, rsp is pointed to permanent memory
59 
60     ;
61     ; Fixup the rbp point to permanent memory
62     ;
63     mov   rax, rbp
64     sub   rax, rbx
65     add   rax, rcx
66     mov   rbp, rax                 ; From now, rbp is pointed to permanent memory
67 
68     pop   rdx
69     pop   rcx
70     pop   rbx
71     pop   rax
72     ret

  3.2.2 IA32 calling convention

 

15 ; VOID
16 ; EFIAPI
17 ; SecSwitchStack (
18 ;   UINT32   TemporaryMemoryBase,
19 ;   UINT32   PermanentMemoryBase
20 ;   );
21 ;------------------------------------------------------------------------------
22 global ASM_PFX(SecSwitchStack)
23 ASM_PFX(SecSwitchStack):
24     ;
25     ; Save four register: eax, ebx, ecx, edx
26     ;
27     push  eax
28     push  ebx
29     push  ecx
30     push  edx
31 
32     ;
33     ; !!CAUTION!! this function address's is pushed into stack after
34     ; migration of whole temporary memory, so need save it to permanent
35     ; memory at first!
36     ;
37 
38     mov   ebx, [esp + 20]          ; Save the first parameter
39     mov   ecx, [esp + 24]          ; Save the second parameter
40 
41     ;
42     ; Save this function's return address into permanent memory at first.
43     ; Then, Fixup the esp point to permanent memory
44     ;
45     mov   eax, esp
46     sub   eax, ebx
47     add   eax, ecx
48     mov   edx, dword [esp]         ; copy pushed register's value to permanent memory
49     mov   dword [eax], edx
50     mov   edx, dword [esp + 4]
51     mov   dword [eax + 4], edx
52     mov   edx, dword [esp + 8]
53     mov   dword [eax + 8], edx
54     mov   edx, dword [esp + 12]
55     mov   dword [eax + 12], edx
56     mov   edx, dword [esp + 16]    ; Update this function's return address into permanent memory
57     mov   dword [eax + 16], edx
58     mov   esp, eax                 ; From now, esp is pointed to permanent memory
59 
60     ;
61     ; Fixup the ebp point to permanent memory
62     ;
63     mov   eax, ebp
64     sub   eax, ebx
65     add   eax, ecx
66     mov   ebp, eax                 ; From now, ebp is pointed to permanent memory
67 
68     pop   edx
69     pop   ecx
70     pop   ebx
71     pop   eax
72     ret
73 

 

标签:movl,esp,mov,eax,切换,memory,操作,edx
From: https://www.cnblogs.com/nipper/p/18118726

相关文章

  • UOS:统信操作系统UOS上的包管理器
    UOS是统信开发的基于Linux内核的操作系统。包管理器Linux系统基本上分为两大类:RedHat和Debian。RedHat系列:RedHat、Centos、Fedora;Debian系列(也称为GNU/Linux):Debian、Ubuntu。可以通过指令uname-a查看自己电脑上Linux版本。yum和apt-get都是包管理工具,只是yum用于RedHat,apt......
  • C# 文件、文件夹常规创建删除操作实例
    原文链接:https://blog.csdn.net/weixin_45023644/article/details/121951840C#的文件操作的功能是非常丰富的。他们大多来自System.IO类,比如:File、Directory、BinaryReader、BinaryWriter、DirectoryInfo、FileStream、MemoryStream、Path、StringWriter等等。当然,其它很多类中也......
  • .net学生选课系统功能操作说明
    ​学生选课系统分为三种用户角色登录,管理员,教师,学生操作,系统配置完成后,首先使用管理员账号密码登录默认是admin 密码admin1234登录成功后左侧可以看到管理员可以管理院系信息,专业管理,教师管理,学生管理,课程管理五大板块,分别可以对其进行增删改查操作,按照功能顺序,我们需......
  • Replication Controller、ReplicaSet和Deployment(Kubernetes调度系列,结合操作命令讲解
    目录一、概述二、ReplicationController2.1ReplicationController说明2.2ReplicationController举例三、ReplicaSet3.1ReplicaSet说明3.2ReplicaSet举例四、无状态应用管理Deployment4.1概述4.2创建Deployment4.2.1Deployment标签内容解析4.2.2ku......
  • Django框架之ORM操作
    一、选择数据库1、默认数据库Django默认的数据库是sqlite3数据库DATABASES={'default':{'ENGINE':'django.db.backends.sqlite3','NAME':BASE_DIR/'db.sqlite3',}}2、指定数据库修改连接到MySQL数据库DATABASES......
  • 无人值守安装(Unattended Installation) 是指在没有用户交互的情况下,自动完成操作系统或
    无人值守安装(UnattendedInstallation)是指在没有用户交互的情况下,自动完成操作系统或软件的安装过程。在Windows中,你可以使用XML文件来配置无人值守安装。这些XML文件通常称为无人值守答案文件(UnattendAnswerFiles),其中包含了安装过程中所需的各种配置选项。无人值守安装(Una......
  • linux后台运行及任务挂后台-linux亲测有效操作001
    由于命令行耗时太久,突然想把进程挂后台走人怎么办?01前台转到后台1.输入ctrl+z将该前台任务挂起^Z[1]+StoppedXXXXXXXX2.运行jobs命令,查看任务号(可以看到run.sh对应的任务号是1)jobs-l#-l显示pid......
  • 数据结构:实验四:队列的操作
    一、实验目的领会队列的存储结构特点掌握环形队列中的各种基本运算算法设计熟悉利用队列解决实际问题二、实验要求实现环形队列的定义,头文件命名”SqQueue.h”。利用所定义的环形队列,设计一个算法实现下面问题的求解:问题描述:设有n个人站成一排,从左向右的编号分别为1—n,......
  • 文件操作详解
    1.为什么使用文件目录1.为什么使用文件2.什么是文件2.1程序文件2.2数据文件2.3文件名字3.二进制文件与文本文件4.文件的打开和关闭4.1流 4.2标准流4.3文件指针 4.4 文件的打开和关闭fopenfclose5.文件的顺序读写5.1文件读取结束原因的判定5.2顺序读写函数......
  • 红黑树的平衡之道:深入解析右旋操作的原理与实践
    红黑树的平衡之道:深入解析右旋操作的原理与实践一、红黑树旋转的背景二、右旋(RIGHT-ROTATE)的原理三、右旋(RIGHT-ROTATE)的算法步骤四、右旋(RIGHT-ROTATE)的伪代码五、右旋(RIGHT-ROTATE)的C代码实现五、结论红黑树作为一种高效的平衡搜索树,其插入和删除操作的时间复杂度......