Content #
每个输入/输出表达式都必须指定自身的操作约束。操作约束的类型可以细分为寄存器约束、内存约束和立即数约束。在输出表达式中,还有限定寄存器操作的修饰符。
寄存器约束 #
限定了表达式的载体是一个寄存器,这个寄存器可以明确指派,亦可模糊指派再由编译器自行分配。寄存器约束可使用寄存器的全名,也可以使用寄存器的缩写名称,如下所示:
__asm__ __volatile__("movl %0, %%cr0"::"eax"(cr0));
__asm__ __volatile__("movl %0, %%cr0"::"a"(cr0));
如果使用寄存器的缩写名称,那么编译器会根据指令部分的汇编代码来确定寄存器的实际位宽。
内存约束 #
限定了表达式的载体是一个内存空间,使用约束名m表示。例如以下内嵌汇编表达式:
__asm__ __volatile__ ("sgdt %0":"=m"(__gdt_addr)::);
__asm__ __volatile__ ("lgdt %0"::"m"(__gdt_addr));
立即数约束 #
只能用于输入部分,它限定了表达式的载体是一个数值,如果不想借助任何寄存器或内存,那么可以使用立即数约束,比如下面这行代码:
__asm__ __volatile__("movl %0, %%ebx"::"i"(50));
使用约束名i限定输入表达式是一个整数类型的立即数,如果希望限定输入表达式是一个浮点数类型的立即数,则使用约束名F。立即数约束只能使用在输入部分。
From #
一个64位操作系统的设计与实现