计算机系统要素:第十二章 操作系统

本文探讨了在Hack计算机架构中构建操作系统时遇到的关键问题,包括溢出处理、数组、字符串、内存管理、屏幕显示、输出编码和键盘交互。特别强调了16位计算机的溢出情况、内存分配算法、屏幕像素的存储方式以及字符显示的复杂性。
摘要由CSDN通过智能技术生成

终于来到了Hack计算机架构的最后一部分——操作系统的构建了!这一章的内容涉及了大量的逻辑架构、算法问题与细节处理,需要花很多精力才能够完成。我曾经与nand2tetris团队的一位工作人员有过联系,他就指出,这本书最后几个较难的章节介绍性的内容太少了,最后的OS章节如果作为正常的上课来学习的话,两周时间是绝对不够的(只要想想,计算机专业的学生得花一个学期学OS),其中涉及了太多问题。因此,在这篇文章中,我会将语言规范、溢出处理、特殊情况处理等几个重要的问题单独列出加以讨论。

 

Math

溢出(overflow)处理:

Math中各个算法的实现其实都不难,重要的是必须考虑溢出情况,因为这是一台16位的计算机,所以它能表示的数字范围在-32768~32767之间。而溢出情况就是指计算的数字超出了这个范围,如果不加以考虑的话,溢出部分的数字会出现混乱。这里,我给大家提供一篇参考文章,里面详细阐述了这方面的内容。

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/12/Math.jack

/**
 * A basic math library.
 */
class Math {

    /** Initializes the library. */
    function void init() {
		return;
    }

    /** Returns the absolute value of x. */
    function int abs(int x) {
		var int absNum;
		if (x < 0){
			let absNum = -x;
		}
		else{
			let absNum = x; 
		}
		return absNum;
    }

    /** Returns the product of x and y. */
    function int multiply(int x, int y) {
		var int sum;
		var int shiftedX,functionY;
		var int flag,j;
		var boolean WhetherNeg;
		let sum = 0;
		let shiftedX = Math.abs(x);
		let functionY= Math.abs(y);
		let flag=1;
		let j=0;
		if ((x=0)|(y=0)){
			return 0;
		}
		let WhetherNeg = ((x<0)=(y<0));
		while(j<16){
			if(functionY&flag=flag){
				let sum = sum + shiftedX;
			}
			let shiftedX=shiftedX+shiftedX;
			let flag=flag+flag;
			let j=j+1;
		}
		if (~WhetherNeg){
		let sum=-sum;
		}
		return sum;
	}

    /** Returns the integer part of x/y (x>0,y>0). */
	function int div(int x, int y) {
		var int q,qy;
		if((y<0)|(y>x)){
			return 0;
		}
		let q = Math.div(x,y+y);
		let qy = Math.multiply(q,y);
		if (x-qy-qy<y){
			return q+q;
		}
		else{
			return q+q+1;
		}
	}
	
    /** Returns the integer part of x/y. */
	function int divide(int x, int y) {
		var int answer;
		var int absX,absY;
		var boolean WhetherNeg;
		let absX = Math.abs(x);
		let absY= Math.abs(y);
		if(absY=0){
			return Sys.error(3);
		}
		let WhetherNeg = ((x<0)=(y<0));
		let answer = Math.div(absX, absY);
		if (~WhetherNeg){
			let answer=-answer;
		}
		return answer;
	}

	/** Returns to the exponent number n where x <= 2^n. */
	function int logTwo(int x){
		var int powerTwo,flag;
		if ((x>16384)&((x<32767)|(x=32767))){
			return 15;
		}
		let powerTwo = 1;
		let flag = 0;
		while (powerTwo<x){
			let powerTwo = powerTwo+powerTwo;
			let flag = flag + 1;
		}
		return flag;
	}
	
	/** Returns to x^y. */
	function int power(int x, int y){
		var int flag;
		var int result;
		let flag = y;
		let result = 1;
		if(y=0){
			return 1;
		}
		while ( flag>0 ){
			let result = Math.multiply(result,x);
			let flag=flag-1;
		}
		return result; 
	}	
	
    /** Returns the integer part of the square root of x. */
    function int sqrt(int x) {
		var int y,j,flag,powerJ;
		var int n,halfN;
		let y=0;
		let n = Math.logTwo(x);
		let halfN = Math.divide(n,2);
		let j=halfN;
		if (x<0){
			return Sys.error(3);
		}
		while (j>-1){
			let powerJ = Math.power(2,j);
			let flag = y+powerJ;
			let flag = Math.multiply(flag,flag);
			if (((flag < x) | (flag = x)) & (flag > 0)){
				let y = y + powerJ;
			}
			let j=j-1;
		}
		return y;
    }

    /** Returns the greater number. */
    function int max(int a, int b) {
		if (a>b){
			return a;
		}
		else{
			return b;
		}
    }

    /** Returns the smaller number. */
    function int min(int a, int b) {
		if (a<b){
			return a ;
		}
		else{
			return b;
		}
    }
}



Array

Array模块的实现非常简单,只需要注意,它调用了Memory模块中的相关函数,以实现动态分配内存。

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/12/Array.jack

/**
 * Represents an array. Can be used to hold any type of object.
 */
class Array {

    /** Constructs a new Array of the given size. */
    function Array new(int size) {
	var Array a;
	let a=Memory.alloc(size);
	return a;
    }

    /** De-allocates the array and frees its space. */
    method void dispose() {
	do Memory.deAlloc(this);
	return;
    }
}




String

语言规范:field变量的使用

String的本质是一个数组,在每一个String类中,都必须有四个全局参数,一个是数组a,代表了String的起始地址,一个是当前字符串长度stringLength和最大字符串长度allocLength(注意,这两个长度是不同的!),另外还有判断String是否为负数字符串的negFlag。

 

负数的处理:

1,String.new(0) 参数小于0时最好报错,参数等于0时,默认给它赋1的空间。

2,数字与字符串相转换时,若数字为负数,需要加符号,这里用negFlag来判别。

 此外,本书的字符串编码与ASCII有细微差异,例如,书中将backspace定义为129,换行定义为128,读者只需了解即可。

// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/12/String.jack

/**
 * Represents a String object. Implements the String type.
 */
class String {
    field Array a;
    field int stringLength; 
    field boolean negFlag;
    field int allocLength;

    /** Constructs a new empty String with a maximum length of maxLength. */
    constructor String new(int maxLength) {
        if (maxLength<1){
            let maxLength = 1;
        }
        let allocLength = maxLength;
        let negFlag = false;
        let a = Array.new(maxLength);
        let stringLength = 0;
        return this;
    }

    /** De-allocates the string and frees its space. */
    method void dispose() {
        do a.dispose();
        return;
    }

    /** Returns the current length of this String. */
    method int length() {
        return stringLength;
    }

    /** Returns the character at location j. */
    method char charAt(int j) {
        var char c;
        let c=a[j];
        return c;
    }

    /** Sets the j"th character of this string to be c. */
    method void setCharAt(int j, char c) {
        let a[j]=c;
        return;
    }

    /** Appends the character c to the end of this String.
     *  Returns this string as the return value. */
    method String appendChar(char c) {
        var int length;
        if(stringLength=allocLength){
            do Sys.error(17);
        }
        let length = stringLength;
        let a[len
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值