⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bcopy.s

📁 一个嵌入式操作系统(microwindows)的源代码
💻 S
📖 第 1 页 / 共 3 页
字号:
	fistpq	56(%edi)	fistpq	48(%edi)	fistpq	40(%edi)	fistpq	32(%edi)	fistpq	24(%edi)	fistpq	16(%edi)	fistpq	8(%edi)	fistpq	0(%edi)	addl	$64,%esi	addl	$64,%edi	subl	$64,%ecx	cmpl	$64,%ecx	jae	large_i586_bcopy_loop	popl	%eax	addl	%eax,%ecx	cmpl	$64,%ecx	jae	4b	cmpl	$0,_npxproc	je	i586_bc2	frstor	0(%esp)	addl	$108,%espi586_bc2:	lmsw	%dx	movb	$0xfe,kernel_fpu_lock/* * This is a duplicate of the main part of generic_bcopy.  See the comments * there.  Jumping into generic_bcopy would cost a whole 0-1 cycles and * would mess up high resolution profiling. */	ALIGN_TEXTsmall_i586_bcopy:	shrl	$2,%ecx	cld	rep	movsl	movl	20(%esp),%ecx	andl	$3,%ecx	rep	movsb	popl	%edi	popl	%esi	ret	ALIGN_TEXT1:	addl	%ecx,%edi	addl	%ecx,%esi	decl	%edi	decl	%esi	andl	$3,%ecx	std	rep	movsb	movl	20(%esp),%ecx	shrl	$2,%ecx	subl	$3,%esi	subl	$3,%edi	rep	movsl	popl	%edi	popl	%esi	cld	ret#endif /* I586_CPU && NNPX > 0 *//* * Note: memcpy does not support overlapping copies */ENTRY(memcpy)	pushl	%edi	pushl	%esi	movl	12(%esp),%edi	movl	16(%esp),%esi	movl	20(%esp),%ecx	movl	%edi,%eax	shrl	$2,%ecx				/* copy by 32-bit words */	cld					/* nope, copy forwards */	rep	movsl	movl	20(%esp),%ecx	andl	$3,%ecx				/* any bytes left? */	rep	movsb	popl	%esi	popl	%edi	ret/*****************************************************************************//* copyout and fubyte family                                                 *//*****************************************************************************//* * Access user memory from inside the kernel. These routines and possibly * the math- and DOS emulators should be the only places that do this. * * We have to access the memory with user's permissions, so use a segment * selector with RPL 3. For writes to user space we have to additionally * check the PTE for write permission, because the 386 does not check * write permissions when we are executing with EPL 0. The 486 does check * this if the WP bit is set in CR0, so we can use a simpler version here. * * These routines set curpcb->onfault for the time they execute. When a * protection violation occurs inside the functions, the trap handler * returns to *curpcb->onfault instead of the function. *//* copyout(from_kernel, to_user, len) */ENTRY(copyout)	MEXITCOUNT	jmp	*_copyout_vectorENTRY(generic_copyout)	movl	_curpcb,%eax	movl	$copyout_fault,PCB_ONFAULT(%eax)	pushl	%esi	pushl	%edi	pushl	%ebx	movl	16(%esp),%esi	movl	20(%esp),%edi	movl	24(%esp),%ebx	testl	%ebx,%ebx			/* anything to do? */	jz	done_copyout	/*	 * Check explicitly for non-user addresses.  If 486 write protection	 * is being used, this check is essential because we are in kernel	 * mode so the h/w does not provide any protection against writing	 * kernel addresses.	 */	/*	 * First, prevent address wrapping.	 */	movl	%edi,%eax	addl	%ebx,%eax	jc	copyout_fault/* * XXX STOP USING VM_MAXUSER_ADDRESS. * It is an end address, not a max, so every time it is used correctly it * looks like there is an off by one error, and of course it caused an off * by one error in several places. */	cmpl	$VM_MAXUSER_ADDRESS,%eax	ja	copyout_fault#if defined(I386_CPU)#if defined(I486_CPU) || defined(I586_CPU) || defined(I686_CPU)	cmpl	$CPUCLASS_386,_cpu_class	jne	3f#endif/* * We have to check each PTE for user write permission. * The checking may cause a page fault, so it is important to set * up everything for return via copyout_fault before here. */	/* compute number of pages */	movl	%edi,%ecx	andl	$PAGE_MASK,%ecx	addl	%ebx,%ecx	decl	%ecx	shrl	$IDXSHIFT+2,%ecx	incl	%ecx	/* compute PTE offset for start address */	movl	%edi,%edx	shrl	$IDXSHIFT,%edx	andb	$0xfc,%dl1:	/* check PTE for each page */	leal	_PTmap(%edx),%eax	shrl	$IDXSHIFT,%eax	andb	$0xfc,%al	testb	$PG_V,_PTmap(%eax)		/* PTE page must be valid */	je	4f	movb	_PTmap(%edx),%al	andb	$PG_V|PG_RW|PG_U,%al		/* page must be valid and user writable */	cmpb	$PG_V|PG_RW|PG_U,%al	je	2f4:	/* simulate a trap */	pushl	%edx	pushl	%ecx	shll	$IDXSHIFT,%edx	pushl	%edx	call	_trapwrite			/* trapwrite(addr) */	popl	%edx	popl	%ecx	popl	%edx	testl	%eax,%eax			/* if not ok, return EFAULT */	jnz	copyout_fault2:	addl	$4,%edx	decl	%ecx	jnz	1b				/* check next page */#endif /* I386_CPU */	/* bcopy(%esi, %edi, %ebx) */3:	movl	%ebx,%ecx#if defined(I586_CPU) && NNPX > 0	ALIGN_TEXTslow_copyout:#endif	shrl	$2,%ecx	cld	rep	movsl	movb	%bl,%cl	andb	$3,%cl	rep	movsbdone_copyout:	popl	%ebx	popl	%edi	popl	%esi	xorl	%eax,%eax	movl	_curpcb,%edx	movl	%eax,PCB_ONFAULT(%edx)	ret	ALIGN_TEXTcopyout_fault:	popl	%ebx	popl	%edi	popl	%esi	movl	_curpcb,%edx	movl	$0,PCB_ONFAULT(%edx)	movl	$EFAULT,%eax	ret#if defined(I586_CPU) && NNPX > 0ENTRY(i586_copyout)	/*	 * Duplicated from generic_copyout.  Could be done a bit better.	 */	movl	_curpcb,%eax	movl	$copyout_fault,PCB_ONFAULT(%eax)	pushl	%esi	pushl	%edi	pushl	%ebx	movl	16(%esp),%esi	movl	20(%esp),%edi	movl	24(%esp),%ebx	testl	%ebx,%ebx			/* anything to do? */	jz	done_copyout	/*	 * Check explicitly for non-user addresses.  If 486 write protection	 * is being used, this check is essential because we are in kernel	 * mode so the h/w does not provide any protection against writing	 * kernel addresses.	 */	/*	 * First, prevent address wrapping.	 */	movl	%edi,%eax	addl	%ebx,%eax	jc	copyout_fault/* * XXX STOP USING VM_MAXUSER_ADDRESS. * It is an end address, not a max, so every time it is used correctly it * looks like there is an off by one error, and of course it caused an off * by one error in several places. */	cmpl	$VM_MAXUSER_ADDRESS,%eax	ja	copyout_fault	/* bcopy(%esi, %edi, %ebx) */3:	movl	%ebx,%ecx	/*	 * End of duplicated code.	 */	cmpl	$1024,%ecx	jb	slow_copyout	pushl	%ecx	call	_fastmove	addl	$4,%esp	jmp	done_copyout#endif /* I586_CPU && NNPX > 0 *//* copyin(from_user, to_kernel, len) */ENTRY(copyin)	MEXITCOUNT	jmp	*_copyin_vectorENTRY(generic_copyin)	movl	_curpcb,%eax	movl	$copyin_fault,PCB_ONFAULT(%eax)	pushl	%esi	pushl	%edi	movl	12(%esp),%esi			/* caddr_t from */	movl	16(%esp),%edi			/* caddr_t to */	movl	20(%esp),%ecx			/* size_t  len */	/*	 * make sure address is valid	 */	movl	%esi,%edx	addl	%ecx,%edx	jc	copyin_fault	cmpl	$VM_MAXUSER_ADDRESS,%edx	ja	copyin_fault#if defined(I586_CPU) && NNPX > 0	ALIGN_TEXTslow_copyin:#endif	movb	%cl,%al	shrl	$2,%ecx				/* copy longword-wise */	cld	rep	movsl	movb	%al,%cl	andb	$3,%cl				/* copy remaining bytes */	rep	movsb#if defined(I586_CPU) && NNPX > 0	ALIGN_TEXTdone_copyin:#endif	popl	%edi	popl	%esi	xorl	%eax,%eax	movl	_curpcb,%edx	movl	%eax,PCB_ONFAULT(%edx)	ret	ALIGN_TEXTcopyin_fault:	popl	%edi	popl	%esi	movl	_curpcb,%edx	movl	$0,PCB_ONFAULT(%edx)	movl	$EFAULT,%eax	ret#if defined(I586_CPU) && NNPX > 0ENTRY(i586_copyin)	/*	 * Duplicated from generic_copyin.  Could be done a bit better.	 */	movl	_curpcb,%eax	movl	$copyin_fault,PCB_ONFAULT(%eax)	pushl	%esi	pushl	%edi	movl	12(%esp),%esi			/* caddr_t from */	movl	16(%esp),%edi			/* caddr_t to */	movl	20(%esp),%ecx			/* size_t  len */	/*	 * make sure address is valid	 */	movl	%esi,%edx	addl	%ecx,%edx	jc	copyin_fault	cmpl	$VM_MAXUSER_ADDRESS,%edx	ja	copyin_fault	/*	 * End of duplicated code.	 */	cmpl	$1024,%ecx	jb	slow_copyin	pushl	%ebx			/* XXX prepare for fastmove_fault */	pushl	%ecx	call	_fastmove	addl	$8,%esp	jmp	done_copyin#endif /* I586_CPU && NNPX > 0 */#if defined(I586_CPU) && NNPX > 0/* fastmove(src, dst, len)	src in %esi	dst in %edi	len in %ecx		XXX changed to on stack for profiling	uses %eax and %edx for tmp. storage *//* XXX use ENTRY() to get profiling.  fastmove() is actually a non-entry. */ENTRY(fastmove)	pushl	%ebp	movl	%esp,%ebp	subl	$PCB_SAVEFPU_SIZE+3*4,%esp	movl	8(%ebp),%ecx	cmpl	$63,%ecx	jbe	fastmove_tail	testl	$7,%esi	/* check if src addr is multiple of 8 */	jnz	fastmove_tail	testl	$7,%edi	/* check if dst addr is multiple of 8 */	jnz	fastmove_tail/* if (npxproc != NULL) { */	cmpl	$0,_npxproc	je	6f/*    fnsave(&curpcb->pcb_savefpu); */	movl	_curpcb,%eax	fnsave	PCB_SAVEFPU(%eax)/*   npxproc = NULL; */	movl	$0,_npxproc/* } */6:/* now we own the FPU. *//* * The process' FP state is saved in the pcb, but if we get * switched, the cpu_switch() will store our FP state in the * pcb.  It should be possible to avoid all the copying for * this, e.g., by setting a flag to tell cpu_switch() to * save the state somewhere else. *//* tmp = curpcb->pcb_savefpu; */	movl	%ecx,-12(%ebp)	movl	%esi,-8(%ebp)	movl	%edi,-4(%ebp)	movl	%esp,%edi	movl	_curpcb,%esi	addl	$PCB_SAVEFPU,%esi	cld	movl	$PCB_SAVEFPU_SIZE>>2,%ecx	rep	movsl	movl	-12(%ebp),%ecx	movl	-8(%ebp),%esi	movl	-4(%ebp),%edi/* stop_emulating(); */	clts/* npxproc = curproc; */	movl	_curproc,%eax	movl	%eax,_npxproc	movl	_curpcb,%eax	movl	$fastmove_fault,PCB_ONFAULT(%eax)4:	movl	%ecx,-12(%ebp)	cmpl	$1792,%ecx	jbe	2f	movl	$1792,%ecx2:	subl	%ecx,-12(%ebp)	cmpl	$256,%ecx	jb	5f	movl	%ecx,-8(%ebp)	movl	%esi,-4(%ebp)	ALIGN_TEXT3:	movl	0(%esi),%eax	movl	32(%esi),%eax	movl	64(%esi),%eax	movl	96(%esi),%eax	movl	128(%esi),%eax	movl	160(%esi),%eax	movl	192(%esi),%eax	movl	224(%esi),%eax	addl	$256,%esi	subl	$256,%ecx	cmpl	$256,%ecx	jae	3b	movl	-8(%ebp),%ecx	movl	-4(%ebp),%esi5:	ALIGN_TEXTfastmove_loop:	fildq	0(%esi)	fildq	8(%esi)	fildq	16(%esi)	fildq	24(%esi)	fildq	32(%esi)	fildq	40(%esi)	fildq	48(%esi)	fildq	56(%esi)	fistpq	56(%edi)	fistpq	48(%edi)	fistpq	40(%edi)	fistpq	32(%edi)	fistpq	24(%edi)	fistpq	16(%edi)	fistpq	8(%edi)	fistpq	0(%edi)	addl	$-64,%ecx	addl	$64,%esi	addl	$64,%edi	cmpl	$63,%ecx	ja	fastmove_loop	movl	-12(%ebp),%eax	addl	%eax,%ecx	cmpl	$64,%ecx	jae	4b/* curpcb->pcb_savefpu = tmp; */	movl	%ecx,-12(%ebp)	movl	%esi,-8(%ebp)	movl	%edi,-4(%ebp)	movl	_curpcb,%edi	addl	$PCB_SAVEFPU,%edi	movl	%esp,%esi	cld	movl	$PCB_SAVEFPU_SIZE>>2,%ecx	rep	movsl	movl	-12(%ebp),%ecx	movl	-8(%ebp),%esi	movl	-4(%ebp),%edi/* start_emulating(); */	smsw	%ax	orb	$CR0_TS,%al	lmsw	%ax/* npxproc = NULL; */	movl	$0,_npxproc	ALIGN_TEXT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -