内联汇编程序:标志 - 保存或不保存

时间:2013-12-24 10:27:48

标签: visual-c++ gcc assembly intel inline-assembly

问题是针对英特尔处理器的 GCC Visual Studio 内联汇编程序。

我不清楚是否应该以某种方式保存FLAGS(EFLAGS / RFLAGS)寄存器。编译器是否依赖于已设置的标志,例如,避免两次比较或某种情况(有或没有优化)?

2 个答案:

答案 0 :(得分:3)

对于GCC,逻辑非常直接 - 应该描述他的代码的副作用,这包括“cc”来表示标志被改变。这个例子只是说明了方法:


    asm("clc" : : : "cc");

编译器将检测到这一点并检查它是否需要一些标志以及如何。

但如果您更改的条件代码标志(例如DF)更多,则应在操作后恢复它们。

很抱歉,我不能在VS汇编程序上说任何内容,除非它一直看起来不一致(没有明确的输入/输出/效果声明),并最终从ix64版本中删除。

答案 1 :(得分:1)

EFLAGS寄存器中有3种类型的标志:

  • 状态标志
  • 控制标志
  • 系统标志

很明显,你不能改变系统标志,除非你正在写一个驱动程序,所以这里不太关心。

其他人提到了一个控制标志DF。你希望那个标志保持原样。 DF由“字符串”指令使用,例如MOVS(现在重命名为流指令)。

状态标志(OF,SF,ZF,AF,PF,CF),我还没有看到在返回时使用状态标志的C / C ++编译器。因此对于“标准函数”,状态标志可以是返回的任何内容。 (即内核中的低级别,在少数情况下,它们会在返回时使用状态标志,但不会在用户空间中使用。)

现在还有一个状态在英特尔处理器中非常时髦。如果您正在编写使用MMX寄存器的代码,则它与FPU不兼容。在返回之前必须使用EMMS指令恢复FPU的状态(因此FPU实际上有效!)并且您可能必须保存/恢复FPU寄存器。 (即如果你有一个使用FPU使用MMX调用函数的函数,那么在返回时,预期的浮点可能无效,除非你保护那些...)无论如何,你应该使用SSE代替。

P.S。 Netch提到的指令用于优化目的,编译器可以假设(或不)标志没有改变。我不知道它真的用得太多了(在那个上做错可能太容易了。)