今天看源码发现了一条以前没关注的汇编指令lock,查了一篇日志,解释比较清除,转来参考。
以下为转载内容:
转载地址:http://ooooooo.blogbus.com/logs/1357939.html
今天看L4的代码,其中一个名为L4_KernelInterface的API让我迷惑了很久。其实现如下:
void * L4_KernelInterface(
L4_Word_t *ApiVersion,
L4_Word_t *ApiFlags,
L4_Word_t *KernelId
)
{
void * base_address;
__asm__ __volatile__ (
" lock; nop"
: /* outputs */
"=a" (base_address),
"=c" (*ApiVersion),
"=d" (*ApiFlags),
"=S" (*KernelId)
/* no inputs */
/* no clobbers */
);
return base_address;
}
整个函数的核心就是一条内联汇编语句,而汇编指令只有一条:
lock; nop
我们知道,lock是一个指令前缀,Intel的手册上对其的解释是:
Causes the processor's LOCK# signal to be asserted during execution of the accompanying instruction (turns the instruction into an atomic instruction). In a multiprocessor environment, the LOCK# signal insures that the processor has exclusive use of any shared memory while the signal is asserted.
真正的指令是nop,nop指令是一条什么也不干的指令,意思是no operation,一般用来做指令对齐。
所以,从代码上看,你无论如何都不明白,为什么一条什么也不干的指令最后,可以通过eax来得到KernelInterface的基地址。
由于我们看到的是C语言语句,有可能编译器做了一些我们看不到的事情,所以我们应该检查一下生成的汇编:
push %ebp
mov %esp,%ebp
push %esi
push %ebx
sub $0xc,%esp #为base_address分配空间
lock nop #C代码中的内联汇编
mov %edx,%ebx
mov 0x8(%ebp),%edx
mov %ecx,(%edx) # *ApiVersion = %ecx
mov 0xc(%ebp),%edx
mov %ebx,(%edx) # *ApiFlags = %edx
mov 0x10(%ebp),%edx
mov %esi,(%edx) # *KernelId = %esi
add $0xc,%esp
pop %ebx
pop %esi
leave
ret # return %eax
mov %esi,%esi
从汇编代码中看不出任何倪端,因为生成的代码正是C语言所表达的意思。那问题到底出在哪儿?难道有鬼了不成?
仔细查看一下源代码,难道lock本身可能会导致异常?然后异常处理程序会改变%eax, %ecx, %edx和%esi的值?
赶紧再翻出IA-32的指令手册,果然,上面写着:
An undefined opcode exception will be generated if the LOCK prefix is used with any other instruction except ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG,DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG.
原来如此,赶紧搜索一个L4的异常处理程序,果然看到了下面代码段:
case 0xf0: /* lock prefix */
if (space->get_from_user(addr_offset(addr, 1)) == 0x90)
{
/* lock; nop */
frame->eax = (u32_t)space->get_kip_page_area().get_base();
frame->ecx = get_kip()->api_version;
frame->edx = get_kip()->api_flags;
frame->esi = get_kip()->get_kernel_descriptor()->kernel_id.get_raw();
frame->eip+= 2;
return;
}
真相终于大白。