以下是一个宏函数,包含了一段内联汇编,用于配置中断描述符表的中断门和陷阱门:
#define _set_gate(gate_selector_addr,attr,ist,code_addr) \
do \
{ unsigned long __d0,__d1; \
__asm__ __volatile__ ( "movw %%dx, %%ax \n\t" \
"andq $0x7, %%rcx \n\t" \
"addq %4, %%rcx \n\t" \
"shlq $32, %%rcx \n\t" \
"addq %%rcx, %%rax \n\t" \
"xorq %%rcx, %%rcx \n\t" \
"movl %%edx, %%ecx \n\t" \
"shrq $16, %%rcx \n\t" \
"shlq $48, %%rcx \n\t" \
"addq %%rcx, %%rax \n\t" \
"movq %%rax, %0 \n\t" \
"shrq $32, %%rdx \n\t" \
"movq %%rdx, %1 \n\t" \
:"=m"(*((unsigned long *)(gate_selector_addr))) , \
"=m"(*(1 + (unsigned long *)(gate_selector_addr))),"=&a"(__d0),"=&d"(__d1) \
:"i"(attr << 8), \
"3"((unsigned long *)(code_addr)),"2"(0x8 << 16),"c"(ist) \
:"memory" \
); \
}while(0)
请问这个内联汇编中输出部分的&修饰符是什么意思?在翻阅gcc手册时理解的是&修饰符表示修饰的操作数输入和输出不能使用同一个寄存器,但是看这个代码时候感觉理解错了,希望有人能仔细解释一下"=&a"(__d0),"=&d"(__d1)的意思。
另一个问题是输入部分的"3"和"2"是什么意思?是表示输入部分的第3个操作数吗?
最后希望能解释以下这段汇编的输入输出是什么,汇编代码在做什么?
一:&修饰符在这里表示该操作数既是输入也是输出,它可以保证该操作数在输入和输出之间的值相同。
二:"=&a"(__d0),"=&d"(__d1) 表示 __d0 和 __d1 是输出操作数,并且它们的值来自寄存器 ax 和 dx。 & 表示该操作数既是输入也是输出,它可以保证该操作数在输入和输出之间的值相同。
三:"3"((unsigned long *)(code_addr))是表示第3个输入操作数,"2"(0x8 << 16)表示第2个输入操作数。
四:这段汇编的输入是 "i"(attr << 8), "3"((unsigned long *)(code_addr)),"2"(0x8 << 16),"c"(ist)。其中,attr << 8 是一个属性值, (unsigned long *)(code_addr) 是代码地址,0x8 << 16 是代码段选择器,ist 是中断栈指针。
输出是 "=m"(*((unsigned long )(gate_selector_addr))), "=m"((1 + (unsigned long *)(gate_selector_addr))),"=&a"(__d0),"=&d"(__d1)。其中, *((unsigned long *)(gate_selector_addr)) 和 *(1 + (unsigned long *)(gate_selector_addr)) 是中断描述符表的对应位置, __d0 和 __d1 是辅助寄存器。
五:汇编代码的目的是将输入的属性值,中断栈指针,代码段选择器和代码地址组合成一个64位的值,并将其存储到中断描述符表的对应位置中。具体来说,它通过对寄存器 ax,dx,cx进行操作,将属性值,代码段选择器和代码地址组合成一个64位值,然后将该值存储到中断描述符表的对应位置中。
&表示操作数是输出也是输入。
: 分隔前面的汇编语句和后面的操作数;= 表示此操作数是输出操作数,_d0和_d1就是输出操作数,使用寄存器eax和edx
代码中2和3的意思就是你说的那个意思,表示是哪个操作数。
你能理解这些基本的知识,理解整个代码应该就不成问题了,我觉得你可以自己尝试去解读下,对自己的学习有帮助。