首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >x86保留的EFLAGS位1 == 0:这怎么会发生?

x86保留的EFLAGS位1 == 0:这怎么会发生?
EN

Stack Overflow用户
提问于 2014-04-01 05:44:35
回答 1查看 955关注 0票数 9

我使用Win32 API来停止/启动/检查/更改线程状态。一般效果都很好。有时候它失败了,我想找出原因。

我有一个线程通过以下方式强制上下文切换到其他线程上:

代码语言:javascript
复制
thread stop
fetch processor state into windows context block
read thread registers from windows context block to my own context block
write thread registers from another context block into windows context block
restart thread

效果非常好..。但是..。很少情况下,上下文切换似乎会失败。(症状:我的多线程系统高举天空,用奇怪的寄存器内容执行一个奇怪的地方)。

上下文控制通过以下方式完成:

代码语言:javascript
复制
if ((suspend_count=SuspendThread(WindowsThreadHandle))<0)
   { printf("TimeSlicer Suspend Thread failure");
      ...
   }
...
Context.ContextFlags = (CONTEXT_INTEGER | CONTEXT_CONTROL | CONTEXT_FLOATING_POINT);
if (!GetThreadContext(WindowsThreadHandle,&Context))
   {   printf("Context fetch failure");
       ...
   }

call ContextSwap(&Context); // does the context swap

if (ResumeThread(WindowsThreadHandle)<0)
   {  printf("Thread resume failure");
        ...
   }

所有的打印语句都不会被执行。我的结论是,Windows认为上下文操作都是可靠的。

哦,是的,我知道什么时候停止线程不是计算,例如,在一个系统函数中,并且不会尝试停止/上下文切换它。我之所以知道这一点,是因为除了计算之外,每个线程都设置了一个特定于线程的“不要碰我”的标志,而不是计算。(设备驱动程序程序员会将其识别为“中断禁用”指令)。

因此,我想知道上下文块内容的可靠性。我对从上下文块中提取的各种寄存器值添加了各种正常测试;您实际上可以确定ESP是否正常(在TIB中定义的堆栈区域的范围内),PC在我期望的程序中,或者在系统调用中,等等。

我决定检查条件代码位(EFLAGS)是否被正确读出;如果这是错误的,它将导致切换任务在恢复其状态时采取“错误的分支”。因此,我添加了以下代码,以验证据称的EFLAGS寄存器包含的内容只与英特尔参考手册(register)中的EFLAGS类似。

代码语言:javascript
复制
   mov        eax, Context.EFlags[ebx]  ; ebx points to Windows Context block
   mov        ecx, eax                ; check that we seem to have flag bits
   and        ecx, 0FFFEF32Ah         ; where we expect constant flag bits to be
   cmp        ecx, 000000202h         ; expected state of constant flag bits
   je         @f
   breakpoint                         ; trap if unexpected flag bit status
@@:

在我的胜利7 AMD现象II X6 1090 T(六角核),它偶尔陷阱与断点,与ECX =0200 h。同样的失败在我的胜利7英特尔i7系统。我会忽略这一点,除非它暗示EFLAGS没有像我所怀疑的那样被正确地存储。

根据我对Intel (以及AMD)参考手册的阅读,bit 1是保留的,并且始终具有"1“的值。不是我在这里看到的。

显然,MS通过在线程停止上执行复杂的操作来填充上下文块。我希望他们能准确地存储这个州。这个位没有被正确地存储。如果他们没有正确地存储这一点,他们还能储存什么呢?

为什么这个位的值有时会/应该是零,有什么解释吗?

编辑:我的代码在捕捉断点时转储寄存器和堆栈。

堆栈区域包含上下文块作为局部变量。EAX和上下文块中EFLAGS在适当偏移量处的堆栈中的值都包含0244个值。所以上下文块中的值确实是错误的。

EDIT2:我将掩码和比较值更改为

代码语言:javascript
复制
and        ecx, 0FFFEF328h         ; was FFEF32Ah where we expect flag bits to be
cmp        ecx, 000000200h   

这似乎运行可靠,没有任何抱怨。显然,Win7没有正确地执行eflags的第1位操作,而且它似乎并不重要。

仍然感兴趣的解释,但显然这不是我偶尔的上下文切换崩溃的来源。

EN

回答 1

Stack Overflow用户

发布于 2014-04-02 15:36:17

微软有着悠久的历史,在一些不被真正使用的地方储存了一些东西。雷蒙德·陈( Raymond )给出了很多例子,例如,使用指针的下位而不是字节对齐。

在这种情况下,Windows可能需要将其一些线程上下文存储在现有的CONTEXT结构中,并决定在EFLAGS中使用其他未使用的位。无论如何,您不能对该位做任何事情,当您调用SetThreadContext时,Windows将返回该位。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22777727

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档