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

📄 asm.c

📁 计算机系统结构的讲义,浓缩了一本一千多页的书.真的是好东西.
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  * asm.c -- * *  The procedures in this file do assembly and dis-assembly of *  DLX assembler instructions. * *  This file is part of DISC.  It was modified by Yinong Zhang  *  (yinong@ecn.purdue.edu) from the file "asm.c" in the distribution *  of "dlxsim" available at: *     ftp://max.stanford.edu/pub/hennessy-patterson.software/dlx.tar.Z * *  The original source code is copyright as follows: * * Copyright 1989 Regents of the University of California * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies.  The University of California * makes no representations about the suitability of this * software for any purpose.  It is provided "as is" without * express or implied warranty. * */#include <ctype.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <tcl.h>#include "dlx.h"#include "sym.h"/* * The following structure type encapsulates the state of loading one * or more assembler files, and is used for communication between the * procedures that do assembly. */typedef struct {    char *file;			/* Name of file currently being assembled				 * (none means info to assemble comes from				 * some source other than file). */    int lineNum;		/* Line number within file (-1 if info being				 * assembled doesn't come from file). */    char *line;			/* Contents of entire line being assembled				 * (useful for error messages). */    unsigned int codeAddr;	/* Next address to place information in				 * code area. */    unsigned int dataAddr;	/* Next address to place information in				 * data area. */    unsigned int dot;		/* Address at which to place information				 * (can be either code or data). */    /*     * Information used to build up a concatenated version of all the     * error strings that occur while reading the files:     */    char *message;		/* Pointer to current message (calloc-ed).				 * NULL means no error has occurred so far. */    char *end;			/* Address of NULL byte at end of message;				 * append new messages here. */    int totalBytes;		/* # of bytes allocated at message. 0 means				 * no error has occurred yet. */    int errorCount;		/* If too many errors occur, give up. */    int flags;			/* Various flags:  see below for values. */} LoadInfo;/* * Flags for LoadInfo structures: * * ASM_CODE -			1 means currently assembling into code *				area;  0 means currently assembling into *				data area. * ASM_SIZE_ONLY -		1 means this is the first pass, where the *				only important thing is size (suppress *				all error messages). * ASM_ALIGN_0 -		1 means that an "align 0" command is in *				effect. */#define ASM_CODE	1#define ASM_SIZE_ONLY	2#define ASM_ALIGN_0	4#define ASM_MAX_ERRORS	20/* * The #defines below specify the different classes of instructions, * as defined on pp. D-4 to D-6 of Kane's book.  These classes are used * during assembly, and indicate the different formats that may be taken * by operand specifiers for a particular opcode. *  * NO_ARGS -		no operands * LOAD -		(register, address) * STORE -		(address, register) * LUI -		(dest, 16-bit expression) * ARITH -		(dest, src1, sr2c) OR (dest/src1, src2) *			OR (dest, src1, 16-bit immediate) *			OR (dest/src1, 16-bit immediate) * MULDIV -		same as ARITH (special subset to handle *			mult/divide/rem instructions because they *                      operate on floating point registers) * SHIFT -		same as ARITH (special subset to handle *			shifting instructions) * BRANCH_0_OP -	(label) the source register is implied * BRANCH_1_OP -	(src1, label) * JUMP -		(label) OR (src1) * SRC1 -		(src1) * LABEL -		(label) * MOVE -		(dest,src1) * FLOAD -		like LOAD, for floating/double * FSTORE -		like STORE, for floating/double * FARITH -		like ARITH, for floating point * FCOMPARE -		compare two floating point numbers * TRAP -		(trap number) */#define NO_ARGS		0#define LOAD		1#define STORE		2#define LUI		3#define ARITH		4#define MULDIV		5#define SHIFT		6#define BRANCH_0_OP	7#define BRANCH_1_OP	8#define JUMP		9#define SRC1		10#define LABEL		11#define MOVE		12#define FLOAD		13#define FSTORE		14#define FARITH		15#define FCOMPARE	16#define TRAP		17/* * The tables below give the maximum and minimum # of arguments * permissible for each class above. */static int minArgs[] =    {0, 3, 3, 2, 3, 3, 3, 1, 2, 1, 1, 1, 2, 3, 3, 3, 2, 1};static int maxArgs[] =    {0, 3, 3, 2, 3, 3, 3, 1, 2, 1, 1, 1, 2, 3, 3, 3, 2, 1};/* * Structures of the following type are used during assembly and * disassembly.  One such structure exists for each defined op code. */typedef struct {    char *name;			/* Opcode name, e.g. "add". */    int class;			/* Class of instruction (see table above). */    int op;			/* Bit pattern corresponding to this				 * instruction. */    int mask;			/* Used for disassembly:  if these bits match				 * op, then use this opcode for disassembly.				 * 0 means this is a synthesized instruction				 * that doesn't exist in native form, so				 * it should be ignored during disassembly. */    int other;			/* This field is used when the assembler				 * is generating multiple instructions for				 * a single opcode, or when different				 * instructions may be generated for the				 * same opcode (e.g. add -> addi).  The				 * meaning of the field depends on class;				 * see the code in Asm_Assemble. */    int flags;			/* OR-ed combination of bits, giving various				 * information for use during assembly, such				 * as for range checking.  See below for				 * values. */    int rangeMask;		/* Mask for use in range check:  for unsigned				 * check, none of these bits must be set.  For				 * sign-extended check, either all or none				 * must be set. */} OpcodeInfo;/* * Bits for "flags" field, used for range checking: * * CHECK_FIRST -		1 means check first argument, if it is an immediate * CHECK_LAST -			1 means check last argument, if it is *				an immediate. * CHECK_NEXT_TO_LAST -		1 means check next-to-last argument, if it *				is an immediate. * IMMEDIATE_REQ -		1 means the argument given above MUST be *				an immediate. * SIGN_EXTENDED -		1 means the immediate will be sign-extended. * FIRST_F * SECOND_F * THIRD_F			Must the 1st/2nd/3rd be a single or double prec. *				floating point register * FIRST_D * SECOND_D * THIRD_D			Must the 1st/2nd/3rd be a double prec. register? */#define CHECK_LAST		0x1#define CHECK_NEXT_TO_LAST	0x2#define IMMEDIATE_REQ		0x4#define SIGN_EXTENDED		0x8#define CHECK_FIRST		0x10#define FIRST_INT		0x20#define SECOND_INT		0x40#define THIRD_INT		0x80#define FIRST_F			0x100#define SECOND_F		0x200#define THIRD_F			0x400#define FIRST_D			0x800#define SECOND_D		0x1000#define THIRD_D			0x2000/* * The following value for "other" is used in the SHIFT class to * indicate that this instruction must always take the variable * form. */#define ALWAYS_VAR 0xfffffffe/* * Table of all known instructions: */OpcodeInfo opcodes[] = {    {"add", ARITH, 0x20, 0xfc00003f, 0x20000000,	    CHECK_LAST|SIGN_EXTENDED, 0xffff8000},    {"addd", FARITH, 0x04000004, 0xfc00003f, 0, FIRST_D|SECOND_D|THIRD_D, 0},    {"addf", FARITH, 0x04000000, 0xfc00003f, 0, FIRST_F|SECOND_F|THIRD_F, 0},    {"addi", ARITH, 0x20000000, 0xfc000000, 0,	    CHECK_LAST|SIGN_EXTENDED|IMMEDIATE_REQ, 0xffff8000},    {"addu", ARITH, 0x21, 0xfc00003f, 0x24000000, CHECK_LAST, 0xffff0000},    {"addui", ARITH, 0x24000000, 0xfc000000, 0,	    CHECK_LAST|IMMEDIATE_REQ, 0xffff0000},    {"and", ARITH, 0x24, 0xfc00003f, 0x30000000, CHECK_LAST, 0xffff0000},    {"andi", ARITH, 0x30000000, 0xfc000000, 0,	    CHECK_LAST|IMMEDIATE_REQ, 0xffff0000},    {"beqz", BRANCH_1_OP, 0x10000000, 0xfc000000, 0, 0, 0},    {"bfpf", BRANCH_0_OP, 0x18000000, 0xfc000000, 0, 0, 0},    {"bfpt", BRANCH_0_OP, 0x1c000000, 0xfc000000, 0, 0, 0},    {"bnez", BRANCH_1_OP, 0x14000000, 0xfc000000, 0, 0, 0},    {"cvtd2f", MOVE, 0x0400000a, 0xfc00003f, 0, FIRST_F|SECOND_D, 0},    {"cvtd2i", MOVE, 0x0400000b, 0xfc00003f, 0, FIRST_F|SECOND_D, 0},    {"cvtf2d", MOVE, 0x04000008, 0xfc00003f, 0, FIRST_D|SECOND_F, 0},    {"cvtf2i", MOVE, 0x04000009, 0xfc00003f, 0, FIRST_F|SECOND_F, 0},    {"cvti2d", MOVE, 0x0400000d, 0xfc00003f, 0, FIRST_D|SECOND_F, 0},    {"cvti2f", MOVE, 0x0400000c, 0xfc00003f, 0, FIRST_F|SECOND_F, 0},    {"div", MULDIV, 0x0400000f, 0xfc00003f, 0, FIRST_F|SECOND_F|THIRD_F, 0},    {"divd", FARITH, 0x04000007, 0xfc00003f, 0, FIRST_D|SECOND_D|THIRD_D, 0},    {"divf", FARITH, 0x04000003, 0xfc00003f, 0, FIRST_F|SECOND_F|THIRD_F, 0},    {"divu", MULDIV, 0x04000017, 0xfc00003f, 0, FIRST_F|SECOND_F|THIRD_F, 0},    {"eqd", FCOMPARE, 0x04000018, 0xfc00003f, 0, FIRST_D|SECOND_D, 0},    {"eqf", FCOMPARE, 0x04000010, 0xfc00003f, 0, FIRST_F|SECOND_F, 0},    {"ged", FCOMPARE, 0x0400001d, 0xfc00003f, 0, FIRST_D|SECOND_D, 0},    {"gef", FCOMPARE, 0x04000015, 0xfc00003f, 0, FIRST_F|SECOND_F, 0},    {"gtd", FCOMPARE, 0x0400001b, 0xfc00003f, 0, FIRST_D|SECOND_D, 0},    {"gtf", FCOMPARE, 0x04000013, 0xfc00003f, 0, FIRST_F|SECOND_F, 0},    {"j", JUMP, 0x08000000, 0xfc000000, 0x48000000, 0, 0},    {"jal", JUMP, 0x0c000000, 0xfc000000, 0x4c000000, 0, 0},    {"jalr", SRC1, 0x4c000000, 0xfc000000, 0, 0, 0},    {"jr", SRC1, 0x48000000, 0xfc000000, 0, 0, 0},    {"lb", LOAD, 0x80000000, 0xfc000000, 0,	    CHECK_NEXT_TO_LAST|IMMEDIATE_REQ|SIGN_EXTENDED, 0xffff8000},    {"lbu", LOAD, 0x90000000, 0xfc000000, 0,	    CHECK_NEXT_TO_LAST|IMMEDIATE_REQ|SIGN_EXTENDED, 0xffff8000},    {"ld", FLOAD, 0x9c000000, 0xfc000000, 0,	    CHECK_NEXT_TO_LAST|IMMEDIATE_REQ|SIGN_EXTENDED|FIRST_D, 0xffff8000},    {"led", FCOMPARE, 0x0400001c, 0xfc00003f, 0, FIRST_D|SECOND_D, 0},    {"lef", FCOMPARE, 0x04000014, 0xfc00003f, 0, FIRST_F|SECOND_F, 0},    {"lf", FLOAD, 0x98000000, 0xfc000000, 0,	    CHECK_NEXT_TO_LAST|IMMEDIATE_REQ|SIGN_EXTENDED|FIRST_F, 0xffff8000},    {"lh", LOAD, 0x84000000, 0xfc000000, 0,	    CHECK_NEXT_TO_LAST|IMMEDIATE_REQ|SIGN_EXTENDED, 0xffff8000},    {"lhi", LUI, 0x3c000000, 0xfc000000, 0,	    CHECK_LAST|IMMEDIATE_REQ, 0xffff0000},    {"lhu", LOAD, 0x94000000, 0xfc000000, 0,	    CHECK_NEXT_TO_LAST|IMMEDIATE_REQ|SIGN_EXTENDED, 0xffff8000},    {"ltd", FCOMPARE, 0x0400001a, 0xfc00003f, 0, FIRST_D|SECOND_D, 0},    {"ltf", FCOMPARE, 0x04000012, 0xfc00003f, 0, FIRST_F|SECOND_F, 0},    {"lw", LOAD, 0x8c000000, 0xfc000000, 0,	    CHECK_NEXT_TO_LAST|IMMEDIATE_REQ|SIGN_EXTENDED, 0xffff8000},    {"movd", MOVE, 0x00000033, 0xfc00003f, 0, FIRST_D|SECOND_D, 0},    {"movf", MOVE, 0x00000032, 0xfc00003f, 0, FIRST_F|SECOND_F, 0},    {"movfp2i", MOVE, 0x00000034, 0xfc00003f, 0, SECOND_F, 0},    {"movi2fp", MOVE, 0x00000035, 0xfc00003f, 0, FIRST_F, 0},    {"movi2s", MOVE, 0x00000030, 0xfc00003f, 0, 0, 0},    {"movs2i", MOVE, 0x00000031, 0xfc00003f, 0, 0, 0},    {"mult", MULDIV, 0x0400000e, 0xfc00003f, 0, FIRST_F|SECOND_F|THIRD_F, 0},    {"multd", FARITH, 0x04000006, 0xfc00003f, 0, FIRST_D|SECOND_D|THIRD_D, 0},    {"multf", FARITH, 0x04000002, 0xfc00003f, 0, FIRST_F|SECOND_F|THIRD_F, 0},    {"multu", MULDIV, 0x04000016, 0xfc00003f, 0, FIRST_F|SECOND_F|THIRD_F, 0},    {"ned", FCOMPARE, 0x04000019, 0xfc00003f, 0, FIRST_D|SECOND_D, 0},    {"nef", FCOMPARE, 0x04000011, 0xfc00003f, 0, FIRST_F|SECOND_F, 0},    {"nop", NO_ARGS, 0x0, 0xffffffff, 0, 0, 0},    {"or", ARITH, 0x25, 0xfc00003f, 0x34000000, CHECK_LAST, 0xffff0000},    {"ori", ARITH, 0x34000000, 0xfc000000, 0,	    CHECK_LAST|IMMEDIATE_REQ, 0xffff0000},    {"rfe", LABEL, 0x40000000, 0xfc000000, 0, 0, 0xfe000000},    {"sb", STORE, 0xa0000000, 0xfc000000, 0,	    CHECK_FIRST|IMMEDIATE_REQ|SIGN_EXTENDED, 0xffff8000},    {"sd", FSTORE, 0xbc000000, 0xfc000000, 0,	    CHECK_FIRST|IMMEDIATE_REQ|SIGN_EXTENDED|THIRD_D, 0xffff8000},    {"seq", ARITH, 0x00000028, 0xfc00003f, 0x60000000,	    CHECK_LAST|SIGN_EXTENDED, 0xffff8000},    {"seqi", ARITH, 0x60000000, 0xfc000000, 0,	    CHECK_LAST|SIGN_EXTENDED|IMMEDIATE_REQ, 0xffff8000},    {"sequ", ARITH, 0x00000010, 0xfc00003f, 0xc0000000,            CHECK_LAST, 0xffff0000},    {"sequi", ARITH, 0xc0000000, 0xfc000000, 0,            CHECK_LAST|IMMEDIATE_REQ, 0xffff0000},    {"sf", FSTORE, 0xb8000000, 0xfc000000, 0,	    CHECK_FIRST|IMMEDIATE_REQ|SIGN_EXTENDED|THIRD_F, 0xffff8000},    {"sge", ARITH, 0x0000002d, 0xfc00003f, 0x74000000,	    CHECK_LAST|SIGN_EXTENDED, 0xffff8000},    {"sgei", ARITH, 0x74000000, 0xfc000000, 0,	    CHECK_LAST|SIGN_EXTENDED|IMMEDIATE_REQ, 0xffff8000},    {"sgeu", ARITH, 0x00000015, 0xfc00003f, 0xd4000000,             CHECK_LAST, 0xffff0000},    {"sgeui", ARITH, 0xd4000000, 0xfc000000, 0,            CHECK_LAST|IMMEDIATE_REQ, 0xffff0000},    {"sgt", ARITH, 0x0000002b, 0xfc00003f, 0x6c000000,	    CHECK_LAST|SIGN_EXTENDED, 0xffff8000},    {"sgti", ARITH, 0x6c000000, 0xfc000000, 0,	    CHECK_LAST|SIGN_EXTENDED|IMMEDIATE_REQ, 0xffff8000},    {"sgtu", ARITH, 0x00000013, 0xfc00003f, 0xcc000000,             CHECK_LAST, 0xffff0000},    {"sgtui", ARITH, 0xcc000000, 0xfc000000, 0,            CHECK_LAST|IMMEDIATE_REQ, 0xffff0000},    {"sh", STORE, 0xa4000000, 0xfc000000, 0,	    CHECK_FIRST|IMMEDIATE_REQ|SIGN_EXTENDED, 0xffff8000},    {"sle", ARITH, 0x0000002c, 0xfc00003f, 0x70000000,	    CHECK_LAST|SIGN_EXTENDED, 0xffff8000},    {"slei", ARITH, 0x70000000, 0xfc000000, 0,	    CHECK_LAST|SIGN_EXTENDED|IMMEDIATE_REQ, 0xffff8000},    {"sleu", ARITH, 0x00000014, 0xfc00003f, 0xd0000000,             CHECK_LAST, 0xffff0000},    {"sleui", ARITH, 0xd0000000, 0xfc000000, 0,            CHECK_LAST|IMMEDIATE_REQ, 0xffff0000},    {"sll", SHIFT, 0x4, 0xfc00003f, 0x0, CHECK_LAST, 0xffffffe0},    {"slli", SHIFT, 0x0, 0xfc00003f, 0, CHECK_LAST|IMMEDIATE_REQ, 0xffffffe0},    {"slt", ARITH, 0x0000002a, 0xfc00003f, 0x68000000,	    CHECK_LAST|SIGN_EXTENDED, 0xffff8000},    {"slti", ARITH, 0x68000000, 0xfc000000, 0,	    CHECK_LAST|SIGN_EXTENDED|IMMEDIATE_REQ, 0xffff8000},    {"sltu", ARITH, 0x00000012, 0xfc00003f, 0xc8000000,             CHECK_LAST, 0xffff0000},    {"sltui", ARITH, 0xc8000000, 0xfc000000, 0,            CHECK_LAST|IMMEDIATE_REQ, 0xffff0000},    {"sne", ARITH, 0x00000029, 0xfc00003f, 0x64000000,	    CHECK_LAST|SIGN_EXTENDED, 0xffff8000},    {"snei", ARITH, 0x64000000, 0xfc000000, 0,	    CHECK_LAST|SIGN_EXTENDED|IMMEDIATE_REQ, 0xffff8000},    {"sneu", ARITH, 0x00000011, 0xfc00003f, 0xc4000000,             CHECK_LAST, 0xffff0000},    {"sneui", ARITH, 0xc4000000, 0xfc000000, 0,            CHECK_LAST|IMMEDIATE_REQ, 0xffff0000},    {"sra", SHIFT, 0x7, 0xfc00003f, 0x3, CHECK_LAST, 0xffffffe0},    {"srai", SHIFT, 0x3, 0xfc00003f, 0, CHECK_LAST|IMMEDIATE_REQ, 0xffffffe0},    {"srl", SHIFT, 0x6, 0xfc00003f, 0x2, CHECK_LAST, 0xffffffe0},    {"srli", SHIFT, 0x2, 0xfc00003f, 0, CHECK_LAST|IMMEDIATE_REQ, 0xffffffe0},    {"sub", ARITH, 0x22, 0xfc00003f, 0x28000000,	    CHECK_LAST|SIGN_EXTENDED, 0xffff8000},    {"subd", FARITH, 0x04000005, 0xfc00003f, 0, FIRST_D|SECOND_D|THIRD_D, 0},    {"subf", FARITH, 0x04000001, 0xfc00003f, 0, FIRST_F|SECOND_F|THIRD_F, 0},    {"subi", ARITH, 0x28000000, 0xfc000000, 0,	    CHECK_LAST|SIGN_EXTENDED|IMMEDIATE_REQ, 0xffff8000},    {"subu", ARITH, 0x23, 0xfc00003f, 0x2c000000, CHECK_LAST, 0xffff0000},    {"subui", ARITH, 0x2c000000, 0xfc000000, 0,	    CHECK_LAST|IMMEDIATE_REQ, 0xffff0000},    {"sw", STORE, 0xac000000, 0xfc000000, 0,	    CHECK_FIRST|IMMEDIATE_REQ|SIGN_EXTENDED, 0xffff8000},    {"trap", TRAP, 0x44000000, 0xfc000000, 0,	    CHECK_FIRST|IMMEDIATE_REQ, 0xfc000000},    {"xor", ARITH, 0x26, 0xfc00003f, 0x38000000, CHECK_LAST, 0xffff0000},    {"xori", ARITH, 0x38000000, 0xfc000000, 0,	    CHECK_LAST|IMMEDIATE_REQ, 0xffff0000},    {NULL, NO_ARGS, 0, 0, 0, 0, 0}};/* * Opcode values that are used in the code of this module: */#define SUBU_OP			0x23#define ADDI_OP			0x20000000#define ADDIU_OP		0x24000000#define LUI_OP			0x3c000000#define ORI_OP			0x34000000#define BEQ_OP			0x10000000#define BNE_OP			0x14000000#define LOAD_IMM(reg, x)	(0x20000000 | ((reg) << 16) | ((x) & 0xffff))#define LOAD_IMM_UNS(reg, x)	(0x34000000 | ((reg) << 16) | ((x) & 0xffff))/* * Table mapping from register number to register name. */char *Asm_RegNames[] = {    "r0", "r1", "r2", "r3",    "r4", "r5", "r6", "r7",    "r8", "r9", "r10", "r11",    "r12", "r13", "r14", "r15",    "r16", "r17", "r18", "r19",    "r20", "r21", "r22", "r23",    "r24", "r25", "r26", "r27",    "r28", "r29", "r30", "r31",    "f0", "f1", "f2", "f3",    "f4", "f5", "f6", "f7",    "f8", "f9", "f10", "f11",    "f12", "f13", "f14", "f15",    "f16", "f17", "f18", "f19",    "f20", "f21", "f22", "f23",    "f24", "f25", "f26", "f27",    "f28", "f29", "f30", "f31",    "hi", "lo", "pc", "npc",	/* some of these will be removed later <bly> */    "status", "cause", "epc"};/* * Size of largest instruction we can assemble, in words: */#define ASM_MAX_WORDS 5		/* probably 1 <bly> *//* * Forward declarations for procedures defined in this file: */static void	AddErrMsg(Tcl_Interp *, LoadInfo *, int);static void	IndicateError(Tcl_Interp *, char *, char *, char *);static void	ReadFile(char *, DLX *, LoadInfo *);static int	StoreWords(DLX *, unsigned int, int *, int, int);/* *---------------------------------------------------------------------- * * Asm_Assemble -- * *	Given a string describing an assembler instruction, return *	the binary code corresponding to the instruction. * * Results: *	The return value is a standard Tcl result (normally TCL_OK plus *	an empty string).  If the assembly completed successfully, then *	*sizePtr gets filled in with the # of instruction words assembled *	(may be more than 1 for special pseudo-instructions), and the *	word(s) at *codePtr get filled in with the actual instruction. * * Side effects: *	None. * *---------------------------------------------------------------------- */intAsm_Assemble(machPtr, fileName, string, dot, wholeLine, sizeOnly,	sizePtr, codePtr)    DLX *machPtr;			/* Machine for which assembly is done:					 * used for symbol table and error					 * reporting. */    char *fileName;			/* File name to use for symbol					 * lookups.  See GetSym procedure in					 * sym.c for more information. */    char *string;			/* DLX assembler instruction. */    unsigned int dot;			/* Where in memory instruction(s) will					 * be placed. */    char *wholeLine;			/* Entire line containing string;  used					 * when printing error messages. */    int sizeOnly;			/* Non-zero means this is the first					 * pass, so ignore errors and just					 * compute the size of the instruction.					 */    int *sizePtr;			/* Fill in with # words assembled					 * for this instruction. */    int *codePtr;			/* Pointer to ASM_MAX_WORDS words					 * storage, which get filled in with					 * assembled code. */{    register OpcodeInfo *insPtr;	/* Info about instruction. */

⌨️ 快捷键说明

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