Content #
损坏部分描述了在指令部分执行的过程中,将被修改的寄存器、内存空间或标志寄存器,并且这些修改部分并未在输出部分和输入部分出现过,格式为:
“损坏描述”, “损坏描述”, ……
如果需要声明多个寄存器,则必须使用逗号“, ”将它们分隔开,这点与输入/输出部分一致。
■ 寄存器修改通知。这种情况一般发生在寄存器出现于指令部分,又不是输入/输出操作表达式指定的寄存器,更不是编译器为r或g约束选择的寄存器。如果该寄存器被指令部分所修改,那么就应该在损坏部分加以描述,比如下面这行代码:
__asm__ __volatile__ ("movl %0, %%ecx"::"a"(__tmp):"cx");
这段汇编表达式的指令部分修改了寄存器ECX的值,却未被任何输入/输出部分所记录,那么必须在损坏部分加以描述,一旦编译器发现后续代码还要使用它,便会在内嵌汇编语句的过程中做好数据保存与恢复工作。如果未在损坏部分描述,则很可能会影响后续程序的执行结果。
注意,已在损坏部分声明的寄存器,不能作为输入/输出操作表达式的寄存器约束,也不会被指派为q 、 r 、 g约束的寄存器。如果在输入/输出操作表达式中已明确选定寄存器,或者使用q 、 r 、 g约束让编译器指派寄存器时,编译器对这些寄存器的状态非常清楚,它知道哪些寄存器将会被修改。除此之外,编译器对指令部分修改的寄存器却一无所知。
■ 内存修改通知。除了寄存器的内容会被篡改外,内存中的数据同样会被修改。如果一个内嵌汇编语句的指令部分修改了内存数据,或者在内嵌汇编表达式出现的地方,内存数据可能发生改变,并且被修改的内存未使用m约束。此时,应该在损坏部分使用字符串memory,向编译器声明内存会发生改变。
如果损坏部分已经使用memory对内存加以约束,那么编译器会保证在执行汇编表达式之后,重新向寄存器装载已引用过的内存空间,而非使用寄存器中的副本,以防止内存与副本中的数据不一致。
■ 标志寄存器修改通知。当内嵌汇编表达式中包含影响标志寄存器R|EFLAGS的指令时,必须在损坏部分使用cc来向编译器声明这一点。
From #
一个64位操作系统的设计与实现