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

📄 getput.c

📁 计算机系统结构的讲义,浓缩了一本一千多页的书.真的是好东西.
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * Go on to the next value, if there are any more.	 */	count -= 1;	if (count == 0) {	    break;	}	if (isReg) {	    address += length / 4;	    if (address >= TOTAL_REGS) {		break;	    }	} else {	    address += length;	    if (ADDR_TO_INDEX(address) >= machPtr->numWords) {		break;	    }	}	*p = '\n';	p++;    }    return TCL_OK;}/* *---------------------------------------------------------------------- * * Gp_PutCmd -- * *	This procedure is invoked to process the "put" Tcl command. *	See the user documentation for details on what it does. * * Results: *	A standard Tcl result. * * Side effects: *	See the user documentation. * *---------------------------------------------------------------------- */intGp_PutCmd(clientData, interp, argc, argv)    ClientData clientData;    Tcl_Interp *interp;			/* Current interpreter. */    int argc;				/* Number of arguments. */    char **argv;			/* Argument strings. */{    DLX *machPtr = (DLX *) clientData;	    unsigned int address;    int isReg, value, result;    char *end;    if (argc != 3) {	sprintf(interp->result,		"wrong # args:  should be \"%.50s location value\"",		argv[0]);	return TCL_ERROR;    }    result = GetAddress(machPtr, argv[1], &address, &isReg);    if (result != TCL_OK) {	return result;    }    result = Sym_EvalExpr(machPtr, (char *) NULL, argv[2], 0,	    &value, &end);    if (result != TCL_OK) {	return result;    }    if (*end != 0) {	sprintf(interp->result,		"bad value \"%.50s\" in \"%.50s\" command",		argv[2], argv[0]);	return TCL_ERROR;    }    if (isReg) {	if (address == 0) {	    sprintf(interp->result, "can't modify %s", Asm_RegNames[address]);	    return TCL_ERROR;	}	if ((address == PC_REG) || (address == NEXT_PC_REG)) {	    if (value & 0x3) {		sprintf(interp->result,			"address 0x%x not properly aligned for pc or npc",			value);		return TCL_ERROR;	    }	    value = ADDR_TO_INDEX(value);	}	machPtr->regs[address] = value;    } else {	if (ADDR_TO_INDEX(address) < machPtr->numWords) {	    MemWord *wordPtr;	    wordPtr = &machPtr->memPtr[ADDR_TO_INDEX(address)];	    wordPtr->value = value;	    wordPtr->opCode = OP_NOT_COMPILED;	} else if (Io_Write(machPtr, (address & ~0x3), value, 4) == 0) {	    sprintf(interp->result,		    "location \"%.50s\" doesn't exist in memory",		    argv[1]);	    return TCL_ERROR;	}    }    return TCL_OK;}/* *---------------------------------------------------------------------- * * Gp_FPutCmd -- * *	This procedure is invoked to process the "fput" Tcl command. *	See the user documentation for details on what it does. * * Results: *	A standard Tcl result. * * Side effects: *	See the user documentation. * *---------------------------------------------------------------------- */intGp_FPutCmd(clientData, interp, argc, argv)    ClientData clientData;    Tcl_Interp *interp;			/* Current interpreter. */    int argc;				/* Number of arguments. */    char **argv;			/* Argument strings. */{    DLX *machPtr = (DLX *) clientData;	    unsigned int address;    int isReg, result, value[2];    float *pf = (float *)&(value[0]);    double *pd = (double *)&(value[0]), atof();    enum {FLOAT, DOUBLE} format = FLOAT;    if ((argc != 3) && (argc != 4)) {	sprintf(interp->result,		"wrong # args:  should be \"%.50s location value [f|d]\"",		argv[0]);	return TCL_ERROR;    }    result = GetAddress(machPtr, argv[1], &address, &isReg);    if (result != TCL_OK) {	return result;    }    if (argc == 4) {	if (*argv[3] == 'f')	    format = FLOAT;	else if (*argv[3] == 'd')	    format = DOUBLE;	else {	    sprintf(interp->result, "invalid type flag, must be f or d");	    return TCL_ERROR;	}    }    if (!isReg) {	address = address & ~3;    } else if (format == FLOAT) {	if (address > 63) {	    sprintf(interp->result, "illegal register");	    return TCL_ERROR;	}    } else {	/* format == DOUBLE */	if ((address < 32) || (address > 63) || (address %2)) {	    sprintf(interp->result, "illegal register for double");	    return TCL_ERROR;	}    }    if (format == FLOAT) {	*pf = atof(argv[2]);    } else {	/* format == DOUBLE */	*pd = atof(argv[2]);    }    if (isReg) {	if (address == 0) {	    sprintf(interp->result, "can't modify %s", Asm_RegNames[address]);	    return TCL_ERROR;	}	machPtr->regs[address] = value[0];	if (format == DOUBLE) {	    machPtr->regs[address+1] = value[1];	}    } else {	if (ADDR_TO_INDEX(address) < machPtr->numWords) {	    MemWord *wordPtr;	    wordPtr = &machPtr->memPtr[ADDR_TO_INDEX(address)];	    wordPtr->value = value[0];	    wordPtr->opCode = OP_NOT_COMPILED;	    if (format == DOUBLE) {		wordPtr = &machPtr->memPtr[ADDR_TO_INDEX(address+4)];		wordPtr->value = value[1];		wordPtr->opCode = OP_NOT_COMPILED;	    }	} else if (Io_Write(machPtr, (address & ~0x3), value[0], 4) == 0) {	    sprintf(interp->result,		    "location \"%.50s\" doesn't exist in memory",		    argv[1]);	    return TCL_ERROR;	}    }    return TCL_OK;}/* *---------------------------------------------------------------------- * * GetAddress -- * *	Convert a string to information about an address, suitable for *	reading or writing the location. * * Results: *	Returns a standard Tcl result. * * Side effects: *	Generates an error in interp if string can't be parsed into *	an address. * *---------------------------------------------------------------------- */static intGetAddress(machPtr, string, addressPtr, regPtr)    DLX *machPtr;			/* Machine address will be used with.					 * Also used for error reporting. */    char *string;			/* Specification of address. */    unsigned int *addressPtr;		/* Store address of value here. */    int *regPtr;			/* Store 1 here if address refers to					 * a register, 0 for memory location. */{    unsigned int result;    char *end;    result = Sym_GetSym(machPtr, (char *) NULL, string, SYM_PSEUDO_OK,	    addressPtr);    if (result == SYM_FREG_FOUND) {	*regPtr = 1;	*addressPtr += 32;	return TCL_OK;    }    if (result == SYM_REGISTER) {	*regPtr = 1;	return TCL_OK;    }    if (result == SYM_FOUND) {	*regPtr = 0;	return TCL_OK;    }    result = Sym_EvalExpr(machPtr, (char *) NULL, string, 0,	    (int *) addressPtr, &end);    if (result != TCL_OK) {	return result;    }    if (*end != 0) {	sprintf(machPtr->interp->result,		"mistyped expression \"%.50s\"", string);	return TCL_ERROR;    }    *regPtr = 0;    return TCL_OK;}/* *---------------------------------------------------------------------- * * GetString -- * *	Given an address, return the ASCII string at that address. * * Results: *	The return value is a pointer to ASCII string that's at *	"address" in machPtr's memory.  The integer at *countPtr *	is overwritten with the number of bytes in the string, *	including the terminating NULL character.  If the string *	is very long, the return value may be truncated to hold only *	the first few characters of the string (*countPtr will also *	be truncated).  The return value is stored in a static buffer *	that will be overwritten on the next call to this procedure. * * Side effects: *	None. * *---------------------------------------------------------------------- */static char *GetString(machPtr, address, countPtr)    register DLX *machPtr;	/* Machine whose memory is to be examined. */    unsigned int address;	/* Address of string. */    int *countPtr;		/* Fill in string length (including NULL				 * character, if any) here. */{#define MAX_LENGTH 200    static char buffer[(4*MAX_LENGTH)+20];    char *p;    unsigned int index;    int value, count;    buffer[0] = '"';    p = buffer+1;    for (count = 0; ; count++, address++) {	index = ADDR_TO_INDEX(address);	if (index >= machPtr->numWords) {	    break;	}	value = machPtr->memPtr[index].value;	switch (address & 0x3) {	    case 0:		value >>= 24;		break;	    case 1:		value >>= 16;		break;	    case 2:		value >>= 8;		break;	}	value &= 0xff;	if (value == 0) {	    *countPtr = count+1;	    break;	}	if (count == MAX_LENGTH) {	    *countPtr = MAX_LENGTH;	    strcpy(p, "...");	    p += 3;	    break;	}	if (value == '\\') {	    strcpy(p, "\\\\");	    p += 2;	} else if (value == '"') {	    strcpy(p, "\\\"");	    p += 2;	} else if (isascii(value) && isprint(value)) {	    *p = value;	    p++;	} else if (value == '\n') {	    strcpy(p, "\\n");	    p += 2;	} else if (value == '\t') {	    strcpy(p, "\\t");	    p += 2;	} else if (value == '\b') {	    strcpy(p, "\\b");	    p += 2;	} else if (value == '\r') {	    strcpy(p, "\\r");	    p += 2;	} else {	    sprintf(p, "\\x%02x", value);	    p += 4;	}    }    *p = '"';    p[1] = 0;    return buffer;}/* *---------------------------------------------------------------------- * * Gp_PutString -- * *	Given an ASCII string, store it in the memory of a machine. * * Results: *	The return value is the number of bytes actually stored *	in machPtr's memory.  If endPtr isn't NULL, *endPtr is *	filled in with the address of the character that terminated *	the string (either term or 0). * * Side effects: *	The bytes of "string" are stored in machPtr's memory starting *	at "address".  Standard Tcl backslash sequences are interpreted. * *---------------------------------------------------------------------- */intGp_PutString(machPtr, string, term, address, addNull, endPtr)    register DLX *machPtr;		/* Machine whose memory is to					 * be modified. */    register char *string;		/* String to store. */    char term;				/* Character that terminates string. */    unsigned int address;		/* Where in machPtr's memory to store.*/    int addNull;			/* If non-zero, add a terminating					 * NULL character to memory after					 * the string. */    char **endPtr;			/* If non-NULL, fill in with address					 * of terminating character. */{    int backslashCount;    int size;    size = 0;    while (1) {	if (*string == '\\') {	    Gp_PutByte(machPtr, address,		    Tcl_Backslash(string, &backslashCount));	    string += backslashCount;	} else if ((*string == 0) || (*string == term)) {	    break;	} else {	    Gp_PutByte(machPtr, address, *string);	    string++;	}	address += 1;	size += 1;    }    if (addNull) {	Gp_PutByte(machPtr, address, 0);	size += 1;    }    if (endPtr != 0) {	*endPtr = string;    }    return size;}/* *---------------------------------------------------------------------- * * Gp_PutByte -- * *	Store a particular byte at a particular address in memory. * * Results: *	None. * * Side effects: *	MachPtr's memory gets modified. * *---------------------------------------------------------------------- */voidGp_PutByte(machPtr, address, value)    register DLX *machPtr;		/* Machine whose memory to modify. */    unsigned int address;		/* Where to store value. */    int value;				/* Value to store as byte at address. */{    MemWord *wordPtr;    int index;    char msg[20], start[20], end[20];    index = ADDR_TO_INDEX(address);    if (index < machPtr->numWords) {	wordPtr = &machPtr->memPtr[index];	switch (address & 0x3) {	    case 0:		wordPtr->value = (wordPtr->value & 0xffffff)			| (value << 24);		break;	    case 1:		wordPtr->value = (wordPtr->value & 0xff00ffff)			| ((value << 16) & 0xff0000);		break;	    case 2:		wordPtr->value = (wordPtr->value & 0xffff00ff)			| ((value << 8) & 0xff00);		break;	    case 3:		wordPtr->value = (wordPtr->value & 0xffffff00)			| (value & 0xff);		break;	}/*	sprintf(msg, "%08x; ", wordPtr->value);	sprintf(start, "%d.%d ", 1+index/4, 20+index%4*15);	sprintf(end, "%d.%d; ", 1+index/4, 28+index%4*15);	Tcl_VarEval(machPtr->interp, ".data.t delete ", start, end, 		             ".data.t insert ", start, msg, 			     ".data.t yview ", start, (char *)NULL);    */	wordPtr->opCode = OP_NOT_COMPILED;    }}

⌨️ 快捷键说明

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