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

📄 lrmi.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 2 页
字号:
		}	else		{		if (size == 4)			asm volatile ("cld; outsl"			 : "=S" (esi) : "d" (edx), "0" (esi));		else if (size == 2)			asm volatile ("cld; outsw"			 : "=S" (esi) : "d" (edx), "0" (esi));		else			asm volatile ("cld; outsb"			 : "=S" (esi) : "d" (edx), "0" (esi));		}	esi -= (unsigned int)context.vm.regs.ds << 4;	context.vm.regs.esi &= 0xffff0000;	context.vm.regs.esi |= esi & 0xffff;	}static voidem_rep_outs(int size)	{	unsigned int ecx, edx, esi;	ecx = context.vm.regs.ecx & 0xffff;	edx = context.vm.regs.edx & 0xffff;	esi = context.vm.regs.esi & 0xffff;	esi += (unsigned int)context.vm.regs.ds << 4;	if (context.vm.regs.eflags & DIRECTION_FLAG)		{		if (size == 4)			asm volatile ("std; rep; outsl; cld"			 : "=S" (esi), "=c" (ecx)			 : "d" (edx), "0" (esi), "1" (ecx));		else if (size == 2)			asm volatile ("std; rep; outsw; cld"			 : "=S" (esi), "=c" (ecx)			 : "d" (edx), "0" (esi), "1" (ecx));		else			asm volatile ("std; rep; outsb; cld"			 : "=S" (esi), "=c" (ecx)			 : "d" (edx), "0" (esi), "1" (ecx));		}	else		{		if (size == 4)			asm volatile ("cld; rep; outsl"			 : "=S" (esi), "=c" (ecx)			 : "d" (edx), "0" (esi), "1" (ecx));		else if (size == 2)			asm volatile ("cld; rep; outsw"			 : "=S" (esi), "=c" (ecx)			 : "d" (edx), "0" (esi), "1" (ecx));		else			asm volatile ("cld; rep; outsb"			 : "=S" (esi), "=c" (ecx)			 : "d" (edx), "0" (esi), "1" (ecx));		}	esi -= (unsigned int)context.vm.regs.ds << 4;	context.vm.regs.esi &= 0xffff0000;	context.vm.regs.esi |= esi & 0xffff;	context.vm.regs.ecx &= 0xffff0000;	context.vm.regs.ecx |= ecx & 0xffff;	}static voidem_inb(void)	{	asm volatile ("inb (%w1), %b0"	 : "=a" (context.vm.regs.eax)	 : "d" (context.vm.regs.edx), "0" (context.vm.regs.eax));	}static voidem_inw(void)	{	asm volatile ("inw (%w1), %w0"	 : "=a" (context.vm.regs.eax)	 : "d" (context.vm.regs.edx), "0" (context.vm.regs.eax));	}static voidem_inl(void)	{	asm volatile ("inl (%w1), %0"	 : "=a" (context.vm.regs.eax)	 : "d" (context.vm.regs.edx));	}static voidem_outb(void)	{	asm volatile ("outb %b0, (%w1)"	 : : "a" (context.vm.regs.eax),	 "d" (context.vm.regs.edx));	}static voidem_outw(void)	{	asm volatile ("outw %w0, (%w1)"	 : : "a" (context.vm.regs.eax),	 "d" (context.vm.regs.edx));	}static voidem_outl(void)	{	asm volatile ("outl %0, (%w1)"	 : : "a" (context.vm.regs.eax),	 "d" (context.vm.regs.edx));	}static intemulate(void)	{	unsigned char *insn;	struct		{		unsigned int size : 1;		unsigned int rep : 1;		} prefix = { 0, 0 };	int i = 0;	insn = (unsigned char *)((unsigned int)context.vm.regs.cs << 4);	insn += context.vm.regs.eip;	while (1)		{		if (insn[i] == 0x66)			{			prefix.size = 1 - prefix.size;			i++;			}		else if (insn[i] == 0xf3)			{			prefix.rep = 1;			i++;			}		else if (insn[i] == 0xf0 || insn[i] == 0xf2		 || insn[i] == 0x26 || insn[i] == 0x2e		 || insn[i] == 0x36 || insn[i] == 0x3e		 || insn[i] == 0x64 || insn[i] == 0x65		 || insn[i] == 0x67)			{			/* these prefixes are just ignored */			i++;			}		else if (insn[i] == 0x6c)			{			if (prefix.rep)				em_rep_ins(1);			else				em_ins(1);			i++;			break;			}		else if (insn[i] == 0x6d)			{			if (prefix.rep)				{				if (prefix.size)					em_rep_ins(4);				else					em_rep_ins(2);				}			else				{				if (prefix.size)					em_ins(4);				else					em_ins(2);				}			i++;			break;			}		else if (insn[i] == 0x6e)			{			if (prefix.rep)				em_rep_outs(1);			else				em_outs(1);			i++;			break;			}		else if (insn[i] == 0x6f)			{			if (prefix.rep)				{				if (prefix.size)					em_rep_outs(4);				else					em_rep_outs(2);				}			else				{				if (prefix.size)					em_outs(4);				else					em_outs(2);				}			i++;			break;			}		else if (insn[i] == 0xec)			{			em_inb();			i++;			break;			}		else if (insn[i] == 0xed)			{			if (prefix.size)				em_inl();			else				em_inw();			i++;			break;			}		else if (insn[i] == 0xee)			{			em_outb();			i++;			break;			}		else if (insn[i] == 0xef)			{			if (prefix.size)				em_outl();			else				em_outw();			i++;			break;			}		else			return 0;		}	context.vm.regs.eip += i;	return 1;	}/* I don't know how to make sure I get the right vm86() from libc. The one I want is syscall # 113 (vm86old() in libc 5, vm86() in glibc) which should be declared as "int vm86(struct vm86_struct *);" in <sys/vm86.h>. This just does syscall 113 with inline asm, which should work for both libc's (I hope).*/#if !defined(USE_LIBC_VM86)static intlrmi_vm86(struct vm86_struct *vm)	{	int r;#ifdef __PIC__	asm volatile (	 "pushl %%ebx\n\t"	 "movl %2, %%ebx\n\t"	 "int $0x80\n\t"	 "popl %%ebx"	 : "=a" (r)	 : "0" (113), "r" (vm));#else	asm volatile (	 "int $0x80"	 : "=a" (r)	 : "0" (113), "b" (vm));#endif	return r;	}#else#define lrmi_vm86 vm86#endifstatic voiddebug_info(int vret)	{	int i;	unsigned char *p;	fputs("vm86() failed\n", stderr);	fprintf(stderr, "return = 0x%x\n", vret);	fprintf(stderr, "eax = 0x%08lx\n", context.vm.regs.eax);	fprintf(stderr, "ebx = 0x%08lx\n", context.vm.regs.ebx);	fprintf(stderr, "ecx = 0x%08lx\n", context.vm.regs.ecx);	fprintf(stderr, "edx = 0x%08lx\n", context.vm.regs.edx);	fprintf(stderr, "esi = 0x%08lx\n", context.vm.regs.esi);	fprintf(stderr, "edi = 0x%08lx\n", context.vm.regs.edi);	fprintf(stderr, "ebp = 0x%08lx\n", context.vm.regs.ebp);	fprintf(stderr, "eip = 0x%08lx\n", context.vm.regs.eip);	fprintf(stderr, "cs  = 0x%04x\n", context.vm.regs.cs);	fprintf(stderr, "esp = 0x%08lx\n", context.vm.regs.esp);	fprintf(stderr, "ss  = 0x%04x\n", context.vm.regs.ss);	fprintf(stderr, "ds  = 0x%04x\n", context.vm.regs.ds);	fprintf(stderr, "es  = 0x%04x\n", context.vm.regs.es);	fprintf(stderr, "fs  = 0x%04x\n", context.vm.regs.fs);	fprintf(stderr, "gs  = 0x%04x\n", context.vm.regs.gs);	fprintf(stderr, "eflags  = 0x%08lx\n", context.vm.regs.eflags);	fputs("cs:ip = [ ", stderr);	p = (unsigned char *)((context.vm.regs.cs << 4) + (context.vm.regs.eip & 0xffff));	for (i = 0; i < 16; ++i)		fprintf(stderr, "%02x ", (unsigned int)p[i]);	fputs("]\n", stderr);	}static intrun_vm86(void)	{	unsigned int vret;	while (1)		{		vret = lrmi_vm86(&context.vm);		if (VM86_TYPE(vret) == VM86_INTx)			{			unsigned int v = VM86_ARG(vret);			if (v == RETURN_TO_32_INT)				return 1;			pushw(context.vm.regs.eflags);			pushw(context.vm.regs.cs);			pushw(context.vm.regs.eip);			context.vm.regs.cs = get_int_seg(v);			context.vm.regs.eip = get_int_off(v);			context.vm.regs.eflags &= ~(VIF_MASK | TF_MASK);			continue;			}		if (VM86_TYPE(vret) != VM86_UNKNOWN)			break;		if (!emulate())			break;		}	debug_info(vret);	return 0;	}intLRMI_call(struct LRMI_regs *r)	{	unsigned int vret;	memset(&context.vm.regs, 0, sizeof(context.vm.regs));	set_regs(r);	context.vm.regs.cs = r->cs;	context.vm.regs.eip = r->ip;	if (r->ss == 0 && r->sp == 0)		{		context.vm.regs.ss = context.stack_seg;		context.vm.regs.esp = context.stack_off;		}	else		{		context.vm.regs.ss = r->ss;		context.vm.regs.esp = r->sp;		}	pushw(context.ret_seg);	pushw(context.ret_off);	vret = run_vm86();	get_regs(r);	return vret;	}intLRMI_int(int i, struct LRMI_regs *r)	{	unsigned int vret;	unsigned int seg, off;	seg = get_int_seg(i);	off = get_int_off(i);	/*	 If the interrupt is in regular memory, it's probably	 still pointing at a dos TSR (which is now gone).	*/	if (seg < 0xa000 || (seg << 4) + off >= 0x100000)		{		fprintf(stderr, "Int 0x%x is not in rom (%04x:%04x)\n", i, seg, off);		return 0;		}	memset(&context.vm.regs, 0, sizeof(context.vm.regs));	set_regs(r);	context.vm.regs.cs = seg;	context.vm.regs.eip = off;	if (r->ss == 0 && r->sp == 0)		{		context.vm.regs.ss = context.stack_seg;		context.vm.regs.esp = context.stack_off;		}	else		{		context.vm.regs.ss = r->ss;		context.vm.regs.esp = r->sp;		}	pushw(DEFAULT_VM86_FLAGS);	pushw(context.ret_seg);	pushw(context.ret_off);	vret = run_vm86();	get_regs(r);	return vret;	}

⌨️ 快捷键说明

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