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

📄 picasm.c

📁 MicroChip的12BIt和14Bit的PIC系列单片机的汇编器
💻 C
📖 第 1 页 / 共 3 页
字号:
static inthandle_opt(void){  if(token_type != TOK_IDENTIFIER) {    error(1, "OPT syntax error");    return FAIL;  }  /*   * Note: when listing is turned off, 'listing_on' is set to -1   * here and the listing routine sets it to zero after listing   * the line containing the 'opt nol'.   */  if(strcasecmp(token_string, "nol") == 0     || strcasecmp(token_string, "nolist") == 0) {    listing_on = -1;  } else if(strcasecmp(token_string, "l") == 0	  || strcasecmp(token_string, "list") == 0) {    listing_on = 1;  } else {    error(1, "OPT syntax error");    return FAIL;  }  get_token();  return OK;}/* * Define a macro */static voiddefine_macro(char *name){  struct symbol *sym;  struct macro_line *ml;  int t;  if(token_type != TOK_NEWLINE && token_type != TOK_EOF)    error(0, "Extraneous characters after a valid source line");  skip_eol();  write_listing_line(0);  sym = add_symbol(name, SYMTAB_GLOBAL);  sym->type = SYM_MACRO;  sym->v.text = NULL;  ml = NULL;  for(;;) {    get_token(); /* read first token on next line */    t = 0;    if(token_type == TOK_IDENTIFIER) {      t = 1;      get_token();      if(token_type == TOK_COLON)	get_token();    }    if(token_type == TOK_EOF || token_type == KW_END)      fatal_error("Macro definition not terminated");    if(token_type == KW_MACRO)      fatal_error("Nested macro definitions not allowed");    if(token_type == KW_ENDM) /* end macro definition */      break;/* OPT must be handled inside macros at definition time */    if(token_type == KW_OPT) {      get_token();      handle_opt();    } else {      if(ml == NULL) {	ml = mem_alloc(sizeof(struct macro_line)		       +strlen(line_buffer));	sym->v.text = ml;      } else {	ml->next = mem_alloc(sizeof(struct macro_line)			     +strlen(line_buffer));	ml = ml->next;      }      strcpy(ml->text, line_buffer);      ml->next = NULL;    }    write_listing_line(0);    line_buf_ptr = NULL;    tok_char = ' ';  }  if(t)    error(0, "Label not allowed with ENDM");  get_token();}/* * Skip subroutine used by the conditional assembly directives * return: -1=premature EOF, 0=ok, 1=label (not allowed) */static intif_else_skip(void){  int t, ccount;  ccount = 0;  ifskip_mode++;  do {    skip_eol();    get_token();    write_listing_line(1);    t = 0;    if(token_type == TOK_IDENTIFIER) {      t = 1;      get_token();      if(token_type == TOK_COLON)	get_token();    }    if(token_type == KW_IF) {      ccount++;    } else if(token_type == KW_ENDIF) {      if(ccount <= 0)	break;      ccount--;    } else if(token_type == KW_ELSE && ccount <= 0) {      break;    }  } while(token_type != TOK_EOF && token_type != KW_END);  ifskip_mode--;  return (token_type == TOK_EOF || token_type == KW_END) ? -1 : t;}/* * Add a patch pointing to the current location */voidadd_patch(int tab, struct symbol *sym, patchtype_t type){  struct patch **patch_list_ptr, *ptch;  patch_list_ptr =    (tab == SYMTAB_GLOBAL ? &global_patch_list : local_patch_list_ptr);  if(O_Mode == O_NONE) {    O_Mode = O_PROGRAM;    if(org_val < 0) {      error(0, "ORG value not set");      prog_location = 0;      return;    }    prog_location = org_val;  }  ptch = mem_alloc(sizeof(struct patch));  ptch->label = sym;  ptch->type = type;  ptch->location = prog_location;  /* add a new patch to patch_list */  ptch->next = *patch_list_ptr;  *patch_list_ptr = ptch;}  /* * Apply the store patches and also free the patch list */static voidapply_patches(struct patch *patch_list){  struct patch *ptch, *p2;  /*   * fix forward jumps/calls   */  for(ptch = patch_list; ptch != NULL; ptch = p2) {    p2 = ptch->next;    if(ptch->label->type == SYM_FORWARD)      error(0, "Undefined label '%s%s'",	    (patch_list == global_patch_list ? "" : "="),	    ptch->label->name);    else      switch(ptch->type) {        case PATCH8:	  if(pic_type->instr_set == PIC12BIT && (ptch->label->v.value & 0x100) != 0	     && (prog_mem[ptch->location] & 0xff00) == 0x900)	    error(0, "CALL address in upper half of a page (label '%s%s')",		  (patch_list == global_patch_list ? "" : "="),		  ptch->label->name);	  prog_mem[ptch->location] =	    (prog_mem[ptch->location] & 0xff00)	      | (ptch->label->v.value & 0xff);	  break;	case PATCH9:	  prog_mem[ptch->location] =	    (prog_mem[ptch->location] & 0xfe00)	      | (ptch->label->v.value & 0x1ff);	  break;	case PATCH11:	  prog_mem[ptch->location] =	    (prog_mem[ptch->location] & 0xf800)	      | (ptch->label->v.value & 0x7ff);	  break;      }    mem_free(ptch);  }}/* * Generate code for an instruction with 8-bit literal data * allows forward references */intgen_byte_c(int instr_code){  int t, symtype;  long val;  struct symbol *sym;  t = 0;  if(token_type == TOK_IDENTIFIER || token_type == TOK_LOCAL_ID) {    symtype =      (token_type == TOK_IDENTIFIER ? SYMTAB_GLOBAL : SYMTAB_LOCAL);    if(symtype == SYMTAB_LOCAL && local_level == 0) {      error(1, "Local symbol outside a LOCAL block");      return FAIL;    }    sym = lookup_symbol(token_string, symtype);    if(sym == NULL || sym->type == SYM_FORWARD)	{      if(sym == NULL) {	sym = add_symbol(token_string, symtype);	sym->type = SYM_FORWARD;      }      add_patch(symtype, sym, PATCH8);      get_token();      gen_code(instr_code);      list_flags |= LIST_FORWARD;      return OK;    }  }  val = get_expression();  if(expr_error)    return FAIL;  if(val < -0x80 || val > 0xff) {    error(0, "8-bit literal out of range");    return FAIL;  }  gen_code(instr_code | (val & 0xff));  return OK;}/* * check if the current token is a valid ORG mode specifier * and return the mode (or O_NONE if not valid mode specifier) */static intorg_mode(void){  if(token_type == KW_EDATA)    return O_EDATA;  if(token_type == TOK_IDENTIFIER) {    if(strcasecmp(token_string, "code") == 0)      return O_PROGRAM;    if(strcasecmp(token_string, "reg") == 0)      return O_REGFILE;  }  return O_NONE;}/* * The assembler itself */static voidassembler(char *fname){  static char symname[256];  struct symbol *sym;  int op, t, symtype;  long val;  char *cp;  struct pic_type *pic;  if(pic_type != NULL) {    sprintf(symname, "__%s", pic_type->name);    sym = add_symbol(symname, SYMTAB_GLOBAL);    sym->type = SYM_DEFINED;    sym->v.value = 1;  }  begin_include(fname);  get_token();  while(token_type != TOK_EOF) {    sym = NULL;    if(token_type == TOK_IDENTIFIER || token_type == TOK_LOCAL_ID) {      symtype =	(token_type == TOK_IDENTIFIER ? SYMTAB_GLOBAL : SYMTAB_LOCAL);      if(symtype == SYMTAB_LOCAL && local_level == 0) {	error(1, "Local symbol outside a LOCAL block");	continue;      }      t = (line_buf_off == 0);      strcpy(symname, token_string);      sym = lookup_symbol(symname, symtype);      if(sym != NULL && sym->type == SYM_MACRO) {	/* skip whitespace */	while(tok_char != '\n' && isspace(tok_char))	  read_src_char();	if(line_buf_ptr != NULL &&	   strncasecmp(line_buf_ptr-1, "macro", 5) == 0 &&	   line_buf_ptr[4] != '.' && line_buf_ptr[4] != '_' &&	   !isalnum((unsigned char)line_buf_ptr[4])) {	  error(1, "Multiple definition of macro '%s'", symname);	  continue;	}	expand_macro(sym);	continue;      }      get_token();      switch(token_type) {        case KW_MACRO:	  get_token();	  if(sym != NULL) {	    error(1, "Multiply defined symbol '%s%s'",		  (symtype == SYMTAB_LOCAL ? "=" : ""),		  sym->name);	    continue;	  }	  define_macro(symname);	  goto line_end;	case KW_EQU:	  if(sym != NULL) {	    if(sym->type != SYM_FORWARD)	      error(0, "Multiply defined symbol '%s%s'",		    (symtype == SYMTAB_LOCAL ? "=" : ""),		    sym->name);	  } else	    sym = add_symbol(symname, symtype);	  get_token();	  sym->type = SYM_DEFINED;	  sym->v.value = get_expression();	  if(expr_error)	    continue; /* error_lineskip() done in expr.c */	  list_val = sym->v.value;	  list_flags = LIST_VAL;	  goto line_end;	case KW_SET:	  if(sym != NULL && sym->type != SYM_SET)	    error(0, "Multiply defined symbol '%s%s'",		  (symtype == SYMTAB_LOCAL ? "=" : ""),		  sym->name);	  else if(sym == NULL)	    sym = add_symbol(symname, symtype);	  get_token();	  sym->type = SYM_SET;	  sym->v.value = get_expression();	  if(expr_error)	    continue;	  list_val = sym->v.value;	  list_flags = LIST_VAL;	  goto line_end;	case TOK_COLON:	  get_token();	  goto do_label;	default:	  if(t == 0)	    warning("Label not in the beginning of a line");do_label:	  switch(O_Mode) {	    case O_PROGRAM:	      t = prog_location;	      break;	    case O_REGFILE:	      t = reg_location;	      break;	    case O_EDATA:	      t = edata_location;	      break;	    case O_NONE:	      t = org_val;	      break;	  }	  if(t < 0) {	    error(0, "ORG value not set");	  } else {	    if(sym != NULL && sym->type != SYM_FORWARD)	      error(0, "Multiply defined symbol '%s%s'",		    (symtype == SYMTAB_LOCAL ? "=" : ""),		    sym->name);	    if(sym == NULL)	      sym = add_symbol(symname, symtype);	    sym->type = SYM_DEFINED;	    sym->v.value = t;	    list_loc = t;	    list_flags = LIST_LOC;	  }	  break;      }    }    /* if this line has a label, 'sym' points to it */    if(token_type == TOK_NEWLINE) {      write_listing_line(0);      get_token();      continue;    }    if(token_type == TOK_IDENTIFIER &&       (sym = lookup_symbol(token_string, SYMTAB_GLOBAL))       != NULL && sym->type == SYM_MACRO) {      expand_macro(sym);      continue;    }    if(token_type == KW_END)      break;    if(token_type == KW_ERROR) {      while(isspace((unsigned char)(*line_buf_ptr)))	 line_buf_ptr++;      error(1, "%s", line_buf_ptr);      continue;    }	      op = token_type;    get_token();    switch(op) {      case KW_INCLUDE:      if(token_type != TOK_STRCONST) {	error(1, "Missing file name after INCLUDE");	continue;      }      strcpy(symname, token_string);      get_token();      if(token_type != TOK_NEWLINE && token_type != TOK_EOF)	error(0, "Extraneous characters after a valid source line");      begin_include(symname);      write_listing_line(0);      get_token();      continue;    case KW_SET:    case KW_EQU:      if(sym == NULL)	error(1, "SET/EQU without a label");      else	error(1, "SET/EQU syntax error");      continue;    case KW_MACRO:      error(1, "MACRO without a macro name");      continue;    case KW_ENDM:      error(1, "ENDM not allowed outside a macro");      continue;    case KW_EXITM:      /*       * EXITM works now (version 0.97). Strange that       * nobody noticed that it wasn't implemented       * at all in previous versions.       */      if(current_file == NULL || current_file->type != INC_MACRO) {	error(1, "EXITM not allowed outside a macro");	continue;      }      cond_nest_count = current_file->cond_nest_count;      end_include();      break;    case KW_OPT:      if(handle_opt() != OK) {	error_lineskip();	continue;      }      break;    case KW_LOCAL:

⌨️ 快捷键说明

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