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

📄 i16_crt0.s

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 S
字号:
/*  * Copyright (c) 1995-1994 The University of Utah and * the Computer Systems Laboratory at the University of Utah (CSL). * All rights reserved. * * Permission to use, copy, modify and distribute this software is hereby * granted provided that (1) source code retains these copyright, permission, * and disclaimer notices, and (2) redistributions including binaries * reproduce the notices in supporting documentation, and (3) all advertising * materials mentioning features or use of this software display the following * acknowledgement: ``This product includes software developed by the * Computer Systems Laboratory at the University of Utah.'' * * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS * IS" CONDITION.  THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * CSL requests users of this software to return to csl-dist@cs.utah.edu any * improvements that they make and grant CSL redistribution rights. * *      Author: Bryan Ford, University of Utah CSL */#include <mach/machine/asm.h>#include "config.h"#include "i16_crt0.h"	.code16	.textENTRY(i16_entry)	/* DOS starts us up with our stack pointer pointing	   to the very top of our BSS segment.	   ds and es point to the PSP.  */#define DELAY jmp 1f; 1: jmp 1f; 1: jmp 1f; 1:	/* Check to make sure we're running on a 386 or higher -	   _without_ using any 32-bit instructions of course.	   Tricky, since gas doesn't support 16-bit addressing modes. :-)	   We can't produce any 16-bit relocations either,	   because ELF doesn't support them.	   This code is basically straight out of the Pentium manual,	   except gassed of coursed.  */	pushfw	DELAY	popw	%bx	movw	$0xfff,%ax	andw	%bx,%ax	pushw	%ax	DELAY	popfw	DELAY	pushfw	DELAY	popw	%ax	and	$0xf000,%ax	cmpw	$0xf000,%ax	je	1f	orw	$0xf000,%bx	pushw	%bx	DELAY	popfw	DELAY	pushfw	DELAY	popw	%ax	andw	$0xf000,%ax	jnz	4f1:	/* Gak!  We're running on an 8086/8088/80286!  */	callw	5f	.ascii	"This program requires a 386 or better.\r\n\0"5:	popw	%si	movw	%cs,%ax	movw	%ax,%ds	cld2:	lodsb	orb	%al,%al	jz	3f	movb	$0x02,%ah	movb	%al,%dl	int	$0x21	jmp	2b3:	movw	$0x4c02,%ax	int	$0x214:	/* Now we can use 32-bit instructions all we want.  */	/* Save the PSP segment address (dx).  */	movw	%ds,%dx	/* Find our real-mode code segment (ax).  */	movw	%cs,%ax#ifdef ENABLE_PAGE_ALIGNED_KERNEL	/* Move our code and data so that everything is on a page boundary.	   Theoretically we _could_ go past the end of available memory,	   since we're not checking, but it's enormously unlikely.  */	std	movw	%ax,%ds	addw	$0xff,%ax	andw	$0xff00,%ax	movw	%ax,%es	movl	$EXT(edata),%ecx	subl	$EXT(i16_entry_2),%ecx	movl	$EXT(edata)-1,%esi	movw	%si,%di	rep	movsb	/* Start running at the new address.  */	pushl	$EXT(i16_entry_2)	movw	%ax,2(%esp)	lretwENTRY(i16_entry_2)	/* We're now page aligned.  */#endif ENABLE_PAGE_ALIGNED_KERNEL	/* Load the data segment registers appropriately.  */	movw	%ax,%es	movw	%ax,%ss	/* Start using a real stack.  */	movl	$EXT(crt0_stack)+CRT0_STACK_SIZE,%esp	/* Clear our BSS segment.  */	movl	$EXT(edata),%edi	movl	$EXT(end),%ecx	subw	%di,%cx	xorb	%al,%al	cld	rep	stosb	/* Find the size of the environment array (si) 	   and the number of environment variables plus one (bx).	   The PSP segment is still in dx.  */	movw	%dx,%ds	movw	0x2c,%ds	xorw	%si,%si1:	lodsb	orb	%al,%al	jnz	1b	lodsb	orb	%al,%al	jnz	1b	/* Allocate space for the environment array on the stack.	   Also make sure the top 16 bits of ESP are cleared,	   and that the stack pointer is longword aligned.  */	subw	%si,%sp	andl	$0x0000fffc,%esp	/* Copy the environment array to the local stack.	   We present it backwards, but big deal - shouldn't matter.  */	xorl	%edi,%edi	movw	%sp,%di	xorl	%esi,%esi	pushl	%esi	jmp	3f2:	pushl	%edi	stosb1:	lodsb	stosb	orb	%al,%al	jnz	1b3:	lodsb	orb	%al,%al	jnz	2b	movl	%esp,%cs:EXT(environ)	/* Copy the program name to the local stack;	   it will be used as argv[0].  */	lodsw	movw	%si,%bx1:	pushw	$0	lodsb	orb	%al,%al	jz	2f	lodsb	orb	%al,%al	jnz	1b2:	movw	%bx,%si	movw	%sp,%di3:	lodsb	stosb	orb	%al,%al	jnz	3b	movl	%esp,%ebp	/* Build argv[1..n] from the command tail in the PSP.	   Count the arguments in ebx.  */	movw	%dx,%ds	xorl	%ecx,%ecx	xorl	%ebx,%ebx	movb	0x80,%cl	/* get size of command tail */	incw	%cx		/* plus the return character */	movw	$0x80,%si	addw	%cx,%si		/* si = ptr to return character */	movw 	%sp,%di	decw	%di	subw	%cx,%sp		/* allocate space on the stack */	andw	$0xfffc,%sp	pushl	%ebx	std1:	xorb	%al,%al		/* store a null terminator for this arg */	stosb	incl	%ebx2:	cmpw	$0x80,%si	je	5f	lodsb			/* scan backwards for the end of an arg */	cmpb	$0x20,%al	jbe	2b3:	stosb			/* copy the arg */	cmpw	$0x80,%si	je	4f	lodsb	cmpb	$0x20,%al	ja	3b4:	movw	%di,%cx		/* push an arg pointer */	incw	%cx	pushl	%ecx	jmp	1b5:	/* Push the argv[0] pointer.  */	pushl	%ebp	/* Push the argument and envirnonment parameters on the stack.  */	movl	%esp,%eax	pushl	%cs:EXT(environ)	pushl	%eax	pushl	%ebx	/* Release all conventional memory above the top of our BSS.	   The PSP segment is still in dx.  */	movl	$EXT(end)+15,%ebx	shrw	$4,%bx	movw	%cs,%ax	addw	%ax,%bx	subw	%dx,%bx	movw	%dx,%es	movb	$0x4a,%ah	int	$0x21	/* Load the normal data segment registers.  */	movw	%cs,%ax	movw	%ax,%ds	movw	%ax,%es	/* GCC wants the direction flag cleared at all times.  */	cld	/* Initialize the bss and run the program.  */	call	EXT(i16_main)	.globl	EXT(crt0_stack)	.comm	EXT(crt0_stack),CRT0_STACK_SIZE	.globl	EXT(environ)	.comm	EXT(environ),4	.data	.section .anno,"aw",@progbits	P2ALIGN(4)	.globl	__ANNO_START____ANNO_START__:

⌨️ 快捷键说明

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