堆栈的切换

当目标代码执行完毕,需要返回控制权给原代码时,将产生返回控制权行为。返回控制权行为,比转移控制权行为简单得多。因为,一切条件已经在交出控制权之前准备完毕,返回时仅需出栈就行了。

 

1、 near call的返回

近调用情况下,段不改变,即 CS 不改变,权限级别不改变。从栈中pop返回地址到EIP寄存器时,需进行 limit 的检查。

 

2、 直接控制权转移的返回(far callfar jmp

直接转移返回到相同权限级别,发生跨段的返回,权限不变。这时,CS 被从栈中 pop 出来的 CS 值加载进去,处理器会检查 CPL 与这个 pop 出来的选择子(calling procedure CS)中的RPL进行检查,相等则属相级返回。

 

3、 利用各种门符进行向高权限代码转移后的返回

★    检查保存在 called procedure stack中的原calling procedure CSRPL域以确保是从高权限向低权限代码返回。

★    原 calling procedure CSEIP pop CS EIP 寄存器中。

★    若有参数时,called procedureESP需恢复栈结构(加上相应参数 size

★    原 calling procedure SS ESP pop SS ESP寄存器中。

★    若有参数时,原 calling procedure ESP 需恢复结构(加上相应参数 size)。

★    恢复原 calling procedureCS后,将检查每个segment selectorDSESFSGS),假如数据段权限高于CS,则被加载null segment selector



操作系统必须至少建立一个TSS4个权限级别的堆栈结构(stack segment selectorstack pointer)必须被定义。

 

一、 堆栈及栈指针的权限级别:

★    3 级:stack selectorstack pointer存储在SS寄存器及 ESP 寄存器中

★    012级:相应的stack selectorstack pointer存储在TSS相应的域中。

 

 

二、当发生向高权限级别代码转移时,发生堆栈的切换:

★    根据CPL(转移时CPL改变)在TSS得到相应级别的堆栈结构(SSESP

★    进行栈结构检查,包括limit检查、stack segment descriptor一系列的检查后,stack selector stack pointer加载到 SS ESP寄存器。

★    将原来级别的(权限低)stack selectorstack pointer压入新的堆栈中(权限高),这个过程是:加载新的SSESP时,先临时保存旧的SSESP,再将临时保存旧的SSESP压入新的堆栈中。

★    若有参数,则压入参数(参数个数定义在call gate中的param count域)

★    压入返回地址(CSEIP

★    若有错误码,则压入错误码。

 

 

注意事项:

★    call gate 允许最多31个参数,在调用者的堆栈里。发生切换时,将从调用者的堆栈里复制到新的堆栈里。

 
 

切换后堆栈结构图:

calling procedure         called procedure

… …

param1

Param2

Param3

… …

 

… …

calling SS

calling ESP

param1

param2

param3

calling CS

calling EIP

... ...

… …

 



0
0

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Freertos中的堆栈和启动文件中的堆栈是两个不同的概念。在Freertos中,堆栈是用来保存任务的上下文信息的内存区域,用于任务切换时保存和恢复任务的执行状态。而启动文件中的堆栈是用来为整个程序提供内存空间的,包括全局变量、静态变量等。 在Freertos中,的大小可以通过在FreeRTOSConfig.h文件中设置configTOTAL_HEAP_SIZE来指定。这个值决定了Freertos可以使用的的总大小。根据经验,的大小应该设置得足够大,以满足任务的内存需求。 而启动文件中的堆栈大小与Freertos中的大小没有直接关系。启动文件中的堆栈大小是用来为整个程序提供内存空间的,包括全局变量、静态变量等。在使用Freertos时,启动文件中的堆栈大小可以根据以下公式来设置:启动文件中的heap_size = mcu运行时的ram空间 - RW-Data - ZI-Data - Freertos中设置的大小。 总结起来,Freertos中的堆栈和启动文件中的堆栈是两个不同的概念,它们的大小设置是独立的。在使用Freertos时,需要根据任务的内存需求来设置Freertos中的大小,并根据公式来设置启动文件中的堆栈大小,以确保程序的正常运行。 #### 引用[.reference_title] - *1* *2* *3* [stm32以及freertos 堆栈解析](https://blog.csdn.net/sinat_36568888/article/details/124320985)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值