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

📄 os.cs

📁 用C编写的一个微操作系统
💻 CS
📖 第 1 页 / 共 4 页
字号:
		}

		/// <summary>
		/// Outputs a view of memory from the Process's point of view
		/// </summary>
		/// <param name="p">The Process to Dump</param>
		public void DumpProcessMemory(Process p)
		{
			int address = 0; byte b;
			for (uint i = 0; i < p.PCB.processMemorySize; i++)
			{
				b = this.memoryMgr[p.PCB.pid,i];
				if (address == 0 || address%16==0)
					Console.Write(System.Environment.NewLine + "{0,-4:000} ", address);
				address++;
				if (b == 0)
					Console.Write("{0,3}","-");
				else
					Console.Write("{0,3}",(int)b);
				if (address%4==0 && address%16!=0) Console.Write("  :");
			}
			Console.WriteLine();
		}

		/// <summary>
		/// Called on a context switch. Copy the CPU's <see cref="CPU.registers"/> to the <see cref="currentProcess"/>'s <see cref="CPU.registers"/>
		/// </summary>
		private void SaveCPUState()
		{
			CPU.registers.CopyTo(currentProcess.PCB.registers,0);
			currentProcess.PCB.zf = CPU.zf;
			currentProcess.PCB.sf = CPU.sf;
			currentProcess.PCB.ip = CPU.ip;
		}

		/// <summary>
		/// Called on a context switch. Copy the <see cref="currentProcess"/>'s <see cref="Process.ProcessControlBlock.registers"/> to the CPU's <see cref="CPU.registers"/> 
		/// </summary>
		private void LoadCPUState()
		{
			currentProcess.PCB.registers.CopyTo(CPU.registers,0);
			CPU.zf = currentProcess.PCB.zf;
			CPU.sf = currentProcess.PCB.sf;
			CPU.ip = currentProcess.PCB.ip;
		}

		/// <summary>
		/// Take as a <see cref="Program"/> and creates a Process object, adding it to the <see cref="runningProcesses"/>
		/// </summary>
		/// <param name="prog">Program to load</param>
		/// <param name="memorySize">Size of memory in bytes to assign to this Process</param>
		/// <returns>The newly created Process</returns>
		public Process createProcess(Program prog, uint memorySize)
		{
			// Get an array represting the code block
			byte[] processCode = prog.GetMemoryImage();

			// Create a process with a unique id and fixed memory size
			Process p = new Process(++processIdPool, memorySize);
			
			// Map memory to the Process (if available, otherwise freak out)
			this.memoryMgr.MapMemoryToProcess(p.PCB.processMemorySize,p.PCB.pid);
			
			// Set the initial IP to 0 (that's where exectution will begin)
			p.PCB.ip = 0; 

			//
			// SETUP CODE SECTION
			//
			// Copy the code in one byte at a time
			uint index = 0;
			foreach (byte b in processCode)
				memoryMgr[p.PCB.pid, index++] = b;

			//
			// SETUP STACK SECTION
			//
			// Set stack pointer at the end of memory
			//
			p.PCB.sp = memorySize-1;
			p.PCB.stackSize = uint.Parse(ConfigurationSettings.AppSettings["StackSize"]);

			//
			// SETUP CODE SECTION
			//
			// Set the length of the Code section
			//
			uint roundedCodeLength = CPU.UtilRoundToBoundary((uint)processCode.Length, CPU.pageSize);
			//uint roundedCodeLength = (uint)(CPU.pageSize * ((processCode.Length / CPU.pageSize) + ((processCode.Length % CPU.pageSize > 0) ? 1: 0)));
			p.PCB.codeSize = roundedCodeLength;

			//
			// SETUP DATA SECTION
			//
			// Point Global Data just after the Code for now...
			//
			p.PCB.registers[9] = (uint)roundedCodeLength; 
			p.PCB.dataSize = uint.Parse(ConfigurationSettings.AppSettings["DataSize"]);

			//
			// SETUP HEAP SECTION
			//
			p.PCB.heapAddrStart = p.PCB.codeSize + p.PCB.dataSize;
			p.PCB.heapAddrEnd = p.PCB.processMemorySize - p.PCB.stackSize;
		

			this.memoryMgr.CreateHeapTableForProcess(p);

			// Add ourselves to the runningProcesses table
			runningProcesses.Add(p);
			return p;
		}
		
		/// <summary>
		/// Releases any locks held by this process.  
		/// This function is called when the process exits.
		/// </summary>
		/// <param name="pid">Process ID</param>
		public void ReleaseLocksOfProccess(uint pid)
		{	
			for (int i = 0; i < this.locks.Length; i++)
				if (this.locks[i] == pid) 
					this.locks[i] = 0;
		}


		/// <summary>
		/// Utility function to fetch a 4 byte unsigned int from Process Memory based on the current <see cref="CPU.ip"/>
		/// </summary>
		/// <returns>a new uint</returns>
		public unsafe uint FetchUIntAndMove()
		{
			uint retVal = memoryMgr.getUIntFrom(currentProcess.PCB.pid,CPU.ip);
			CPU.ip += sizeof(uint);
			return retVal;
		}

		/// <summary>
		/// Increments register
		/// <pre>1 r1</pre>
		/// </summary>
		public void Incr()
		{
			//get the instruction and make sure we should be here
			InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];	
			Debug.Assert(InstructionType.Incr == instruction);
			
			//move to the param
			CPU.ip++;
			uint register = FetchUIntAndMove();

			if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2}",currentProcess.PCB.pid, instruction, register);

			//increment the register pointed to by this memory
			CPU.registers[register]++;
		}

		/// <summary>
		///  Adds constant 1 to register 1
		/// <pre>
		/// 2 r1, $1
		/// </pre>
		/// </summary>
		public void Addi()
		{
			//get the instruction and make sure we should be here
			InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
			Debug.Assert(InstructionType.Addi == instruction);
			
			//move to the param containing the register
			CPU.ip++;
			uint register = FetchUIntAndMove();
			uint param1 = FetchUIntAndMove();

			if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2} {3}",currentProcess.PCB.pid, instruction, register, param1);

			//increment the register pointed to by this memory by the const next to it
			CPU.registers[register]+= param1;
		}

		/// <summary>
		/// Adds r2 to r1 and stores the value in r1
		/// <pre>
		/// 3 r1, r2
		/// </pre>
		/// </summary>
		public void Addr()
		{
			//get the instruction and make sure we should be here
			InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
			Debug.Assert(InstructionType.Addr == instruction);
			
			//move to the param containing the 1st register
			CPU.ip++;
			uint register = FetchUIntAndMove();
			uint param1 = FetchUIntAndMove();

			if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2} {3}",currentProcess.PCB.pid, instruction, register, param1);

			//add 1st register and 2nd register and put the result in 1st register
			CPU.registers[register] = CPU.registers[register] + CPU.registers[param1];
		}

		/// <summary>
		/// Compare contents of r1 with 1.  If r1 &lt; 9 set sign flag.  If r1 &gt; 9 clear sign flag.
		/// If r1 == 9 set zero flag.
		/// <pre>
		/// 14 r1, $9
		/// </pre>
		/// </summary>
		public void Cmpi()
		{
			//get the instruction and make sure we should be here
			InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
			Debug.Assert(InstructionType.Cmpi == instruction);
			
			//move to the param containing the 1st register
			CPU.ip++;
			uint register = FetchUIntAndMove();
			uint param1 = FetchUIntAndMove();

			if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2} {3}",currentProcess.PCB.pid, instruction, register, param1);

			//compare register and const
			CPU.zf = false;
			if (CPU.registers[register] < param1) 
				CPU.sf = true;
			if (CPU.registers[register] > param1) 
				CPU.sf = false;
			if (CPU.registers[register] == param1)
				CPU.zf = true;
		}

		/// <summary>
		/// Compare contents of r1 with r2.  If r1 &lt; r2 set sign flag.  If r1 &gt; r2 clear sign flag.
		/// If r1 == r2 set zero flag.
		/// <pre>
		/// 15 r1, r2
		/// </pre>
		/// </summary>
		public void Cmpr()
		{
			//get the instruction and make sure we should be here
			InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
			Debug.Assert(InstructionType.Cmpr == instruction);
			
			//move to the param containing the 1st register
			CPU.ip++;
			uint register1 = FetchUIntAndMove();
			uint register2 = FetchUIntAndMove();

			if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2} r{3}",currentProcess.PCB.pid, instruction, register1, register2);

			//compare register and const
			CPU.zf = false;
			if (CPU.registers[register1] < CPU.registers[register2]) 
				CPU.sf = true;
			if (CPU.registers[register1] > CPU.registers[register2]) 
				CPU.sf = false;
			if (CPU.registers[register1] == CPU.registers[register2])
				CPU.zf = true;
		}

		/// <summary>
		/// Call the procedure at offset r1 bytes from the current instrucion.  
		/// The address of the next instruction to excetute after a return is pushed on the stack
		/// <pre>
		/// 19 r1
		/// </pre>		
		/// </summary>
		public void Call()
		{
			//get the instruction and make sure we should be here
			InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
			Debug.Assert(InstructionType.Call == instruction);
			
			//move to the param containing the 1st register
			CPU.ip++;
			uint register = FetchUIntAndMove();
		
			if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2}",currentProcess.PCB.pid, instruction, register);

			StackPush(currentProcess.PCB.pid, CPU.ip);

			CPU.ip+= CPU.registers[register];
		}

		/// <summary>
		/// Call the procedure at offset of the bytes in memory pointed by r1 from the current instrucion.  
		/// The address of the next instruction to excetute after a return is pushed on the stack
		/// <pre>
		/// 20 r1
		/// </pre>		
		/// </summary>
		public void Callm()
		{
			//get the instruction and make sure we should be here
			InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
			Debug.Assert(InstructionType.Callm == instruction);
			
			//move to the param containing the 1st register
			CPU.ip++;
			uint register = FetchUIntAndMove();
		
			if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1} r{2}",currentProcess.PCB.pid, instruction, register);

			StackPush(currentProcess.PCB.pid, CPU.ip);

			CPU.ip+= this.memoryMgr[currentProcess.PCB.pid,CPU.registers[register]];
		}

		/// <summary>
		/// Pop the return address from the stack and transfer control to this instruction
		/// <pre>
		/// 21
		/// </pre>		
		/// </summary>
		public void Ret()
		{
			//get the instruction and make sure we should be here
			InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
			Debug.Assert(InstructionType.Ret == instruction);
			
			CPU.ip++;
		
			if (bDumpInstructions) Console.WriteLine(" Pid:{0} {1}",currentProcess.PCB.pid, instruction);

			CPU.ip = StackPop(currentProcess.PCB.pid);
		}



		/// <summary>
		/// Control transfers to the instruction whose address is r1 bytes relative to the current instruction. 
		/// r1 may be negative.
		/// <pre>
		/// 13 r1
		/// </pre>
		/// </summary>
		public void Jmp()
		{
			//get the instruction and make sure we should be here
			InstructionType instruction = (InstructionType)memoryMgr[currentProcess.PCB.pid,CPU.ip];
			Debug.Assert(InstructionType.Jmp == instruction);
			
			//move to the param containing the 1st register
			CPU.ip++;
			uint register = FetchUIntAndMove();
		

⌨️ 快捷键说明

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