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

📄 long.s

📁 this is aes algorithm
💻 S
字号:
/*- * Copyright (c) 2007-2008 *      Bill Paul <wpaul@windriver.com>.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *      This product includes software developed by Bill Paul. * 4. Neither the name of the author nor the names of any co-contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. *//* * This module handles switching back and forth between real mode and * long mode. The assumption is that we'll be running in long * mode most of the time, and will thunk into real mode only long enough * to call a BIOS or PXE routine. During the thunk, we'll preserve most * of the registers on the protected mode stack (except for %rax, which * is generally assumed to be volatile). * * When entering real mode, we set up a special real mode stack and * data segment. This is so that the real mode code (primarily PXE) * can use stack and data space without potentially colliding with * the stack and data used in protected mode. The protected mode stack * is located at 0x6C00. The real mode stack is placed at 0x7C00. * The real mode data segment is placed at 0x4000. We leave the %fs * segment register set to segment 0 so that we can use it from * real mode to access storage used from long mode. The assumption * The assumption is that the real mode code won't use this segment * register. I don't know if this is guaranteed, but there haven't * been any problems with it so far. */#define _ASM#include "data.h"	.globl long_to_real	.globl real_to_long	.text/* * Switch to real mode from protected mode. * %rax is destroyed, all other registers are preserved. */long_to_real:	/* Grab the return address off the stack. */	pop	%rax	/* Save all registers */	push	%rax	push	%rbx	push	%rcx	push	%rdx	push	%rsi	push	%rdi	push	%rbp	/* Save protected mode stack pointer. */	mov	%rsp, EXT(saved_stack)	mov	%rax, %rsi /* Save return address here */	/* Do an intersegment jump to enter compatibility mode. */	mov	$compat_addr, %rax	ljmp	*(%rax)c1:	.code32		/* Turn off paging */	mov	%cr0, %eax	and	$~(CR0_PG), %eax	mov	%eax, %cr0	/* Disable PAE */	movl	%cr4, %eax	and	$~(CR4_PAE | CR4_PSE), %eax	movl	%eax, %cr4	/* Turn off long mode */	movl	$MSR_EFER, %ecx	rdmsr	andl	$~(EFER_LME|EFER_SCE|EFER_NXE), %eax	wrmsr	/* Now running in protected mode with no paging. */	/* Get rid of references to page tables */	xorl	%eax, %eax	mov	%eax, %cr3	/* Switch to real mode segment */	ljmpw	$GDT_RCODE, $real1real1:	/*	 * Set segments for real mode.	 * Note: this is required, because the CPU caches the	 * segment/selector register values and will retain them	 * even after we've switched back to running in a 16-bit	 * code segment. (This is known as "unreal mode," and can	 * be used to allow real mode code to access 4GB of	 * address space.)	 */	mov	$GDT_RDATA, %ax        mov	%ax, %ds        mov	%ax, %es        mov	%ax, %fs        mov	%ax, %gs        mov	%ax, %ss	/* Clear PE bit in CR0 */	mov	%cr0, %eax	and	$~CR0_PE, %eax	mov	%eax, %cr0	/* Switch to real mode */	ljmp	$0, $real2real2:	.code16	/* Give real mode its own data segment */	mov	$DATA_REAL, %ax        mov	%ax, %ds        mov	%ax, %es        mov	%ax, %gs	/* Leave %fs alone so we can use it. */	xorw	%ax, %ax        mov	%ax, %fs	/* Set up the real mode stack. */	mov	$STACK_REAL_SEG, %ax        mov	%ax, %ss	mov	$STACK_REAL_OFF, %sp	/* Put the return address onto the real mode stack. */	push	%si	ret	/* 	 * The following two NOP instructions are here to work	 * around what appears to be a bug in the Cygwin assembler	 * and/or linker. For some reason, code in the bios.S and	 * pxecall.S modules that calls the real_to_long() function	 * below ends up branching to an address two bytes _before_         * the start of real_to_long(). This corresponds to the	 * 'push %si' instruction above. It's unclear why this	 * happens, but the two NOP instructions mitigate the	 * problem (even though the branch destination is still         * wrong, the code falls through to the real_to_long()	 * entry below).	 *	 * When building the code with an assembler/linker that	 * calculates the branch offset correctly, these two NOPs	 * are never executed.	 */	nop	nop/* * Switch from protected mode to real mode. * %rax is destroyed, all other registers preserved. */real_to_long:	cli	/* Grab return address off the stack */	pop	%si	/* Reload GDT, in case it's been modified. */	lgdtw	%fs:EXT(GDESC)        /* Set PE bit in CR0 */        mov     %cr0, %eax        or      $CR0_PE, %eax        mov     %eax, %cr0        /* Do a jump to flush the instruction pipe */        jmp     prot1prot1:	/* Load segments for protected mode */	mov	$GDT_PDATA, %ax        mov	%ax, %ds        mov	%ax, %es        mov	%ax, %fs        mov	%ax, %gs        mov	%ax, %ss	/* Return to protected mode (sets %cs) */	ljmp	$GDT_PCODE, $prot2prot2:	.code32        /* Turn on EFER.LME in the EFER machine specific register */	movl    $MSR_EFER, %ecx	rdmsr	orl     $EFER_LME, %eax	wrmsr        /* Turn on PAE and enable paging */        movl    %cr4, %eax        orl     $(CR4_PAE | CR4_PSE), %eax        movl    %eax, %cr4        /* Set %cr3 to point to our page tables */        movl    $PT4, %eax        movl    %eax, %cr3	/* Turn on paging (implicitly sets EFER.LMA) */	movl    %cr0, %eax	orl     $CR0_PG, %eax	movl    %eax, %cr0	/* Now switch to the long mode segment */	ljmp	$GDT_LCODE, $prot3prot3:	.code64	/* Restore the protexted mode stack */	mov	EXT(saved_stack), %rsp	/* Temporarily save return address. */	mov	%rsi, EXT(saved_stack)	/* Restore all registers */	pop	%rbp	pop	%rdi	pop	%rsi	pop	%rdx	pop	%rcx	pop	%rbx	pop	%rax	mov	EXT(saved_stack), %rax	push	%rax	retq	.datacompat_addr:	.long	c1	.word	GDT_PCODE

⌨️ 快捷键说明

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