linux 汇编 寄存器的值,汇编 – 为什么我不能更改段寄存器的值? (MASM)

你说你对原因感兴趣,所以:

在实模式中,段是物理存储器的64K“窗口”,这些窗口间隔16个字节.在受保护模式下,段是物理或虚拟内存的窗口,其大小和位置由操作系统确定,并且具有许多其他属性,包括进程必须具有的访问权限级别.

从这里开始,我所说的一切都是指保护模式.

内存中有一个称为全局描述符表(GDT)的表,它保存有关这些窗口大小和位置以及其他属性的信息.每个进程可能还有本地描述符表,它们的工作方式类似,所以我只关注GDT.

加载到段寄存器中的值称为段选择器.它是GDT或LDT的索引,带有一些额外的安全信息.当然,如果程序试图加载超出GDT范围的描述符,则会发生异常.此外,如果进程没有足够的权限来访问该段,或者其他内容无效,则会发生异常.

发生异常时,内核会处理它.这种异常可能被归类为分段错误.操作系统会杀死你的程序.

最后一点需要注意:在x86指令集中,您无法将立即值加载到段寄存器中.必须将中间寄存器或内存操作数或POP用于段寄存器.

MOV DS, 160 ;INVALID - won't assemble

MOV AX, 160 ;VALID - assembles, but will probably result in an

MOV DS, AX ;exception, and thus the death of your program

我认为应该指出,该架构允许大量的细分市场.但AFAIK,在主流x86操作系统方面,段寄存器仅用于几个目的:

>安全机制,例如防止用户空间进程相互伤害或操作系统

>处理多核/多核处理器

>线程本地存储:作为优化,某些操作系统(包括Linux和Windows)使用段寄存器进行线程本地存储(TLS).由于线程共享相同的地址空间,因此线程很难“知道”其TLS区域在何处不使用系统调用或浪费寄存器……但由于段寄存器实际上没用,所以“浪费”没有坏处它们是为了快速TLS.请注意,设置此操作时,操作系统可能会跳过段寄存器并直接写入描述符高速缓存寄存器,这是用于缓存由段寄存器引用触发的GDT / LDT查找的“隐藏”寄存器,在这种情况下,如果您尝试要从段寄存器中读取,您将看不到它.

除了用于TLS的每个线程的段之外,实际上只使用少数段(处理器的数量),并且仅由OS执行.应用程序可以完全忽略段寄存器.

这是由于OS设计,而不是任何技术限制.可能有嵌入式操作系统需要用户空间程序来处理段寄存器,尽管我不知道.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值