-
static inline void flush_write_buffers(void)
-
{
-
__asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory");
-
}
-
-
#define dma_cache_inv(_start,_size) flush_write_buffers()
-
#define dma_cache_wback(_start,_size) flush_write_buffers()
-
#define dma_cache_wback_inv(_start,_size) flush_write_buffers()
1、lock指令:对总线(什么总线?)加锁。为了在多处理器环境中,保证在当前指令执行期间禁止一切中断(只对当前核么?)。
这个前缀仅仅对ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG,DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD,XCHG指令
有效,如果将Lock前缀用在其它指令之前,将会引起异常。
2、 addl $0,0(%%esp)"
: : :"memory"
表示将0(%%esp)的内存单元加上0,然后再写入相应的内存单元。最后的memory很重要,有两个作用:
1、表示需要强制刷缓存,即同步cache,前面的add操作实际啥也没干,最终就是通过memory限制实现cache的同步。
2、防止编译器编译时对指令顺序进行重排优化。
之前理解错了,以为_start参数会压栈,然后会操作_start相应的内存单元,但实际没有,因为这里的flush_write_buffers
是内联函数,直接展开,没有压栈的过程,所以,实际上,这个函数的参数是没有使用的,无意义的。
另外,这里使用的地址应该是虚拟地址才对。因为保护模式下,汇编指令操作的实际也只能是虚拟地址,虚拟地址经硬件MMU自动转换为物理地址,然后在地址总线上传播。
对于软件来说,保护模式下,只能使用虚拟地址,软件只需准备好页表,并告知页表的位置(通过CR3寄存器),剩余的虚拟地址到物理地址的转换工作,就都由mmu硬件来完成了。
阅读(2322) | 评论(0) | 转发(0) |