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

📄 mips-syscall.c

📁 用汇编语言编程源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
  {SYS_cacheflush, SPC_SYSCALL, NO_ARG, NO_ARG, NO_ARG, NO_ARG, NO_ARG,     "cacheflush"},  {SYS_cachectl, SPC_SYSCALL, NO_ARG, NO_ARG, NO_ARG, NO_ARG, NO_ARG,     "cachectl"},  {154, BAD_SYSCALL, NO_ARG, NO_ARG, NO_ARG, NO_ARG, NO_ARG, ""},  {SYS_atomic_op, BAD_SYSCALL, NO_ARG, NO_ARG, NO_ARG, NO_ARG, NO_ARG,     "atomic_op"},#else  {0}#endif};#define MAX_SYSCALL	(sizeof(syscall_table)/ sizeof(syscall_table[0]))static int syscall_usage[MAX_SYSCALL]; /* Track system calls */#define SYSCALL_ARG(REGOFF, ARG, REG)					\  ((syscall_table[R[REGOFF]].ARG == ADDR_ARG) ?				\     (R[REG] == 0 ? (void*)NULL : MEM_ADDRESS(R[REG])) :		\   (syscall_table[R[REGOFF]].ARG == STR_ARG) ? MEM_ADDRESS(R[REG])  :	\   (((syscall_table[R[REGOFF]].ARG == FD_ARG)				\     && (R[REG] < OPEN_MAX) && (R[REG] >= 0)))  ? (void*)prog_fds[R[REG]] : (void*)R[REG])#define SYSCALL_COUNT(SYSCALL)						\  if (SYSCALL < MAX_SYSCALL && SYSCALL >= 0) syscall_usage[SYSCALL]++;/* Decides which syscall to execute or simulate.  Returns zero upon   exit syscall and non-zero to continue execution. */#ifdef __STDC__intdo_syscall (void)#elseintdo_syscall ()#endif{  SYSCALL_COUNT(R[REG_V0]);  if (source_file)    {      /* Syscalls for the source-language version of SPIM.  These are	 easier to use than the real syscall and are portable to non-MIPS	 (non-Unix?) operating systems. */      switch (R[REG_V0])	{	case PRINT_INT_SYSCALL:	  write_output (console_out, "%d", R[REG_A0]);	  break;	case PRINT_FLOAT_SYSCALL:	  {	    float val = FPR_S (REG_FA0);	    write_output (console_out, "%.18f", val);	    break;	  }	case PRINT_DOUBLE_SYSCALL:	  write_output (console_out, "%.18g", FPR[REG_FA0/2]);	  break;	case PRINT_STRING_SYSCALL:	  write_output (console_out, "%s", MEM_ADDRESS (R[REG_A0]));	  break;	case READ_INT_SYSCALL:	  {	    static char str [256];	    read_input (str, 256);	    R[REG_RES] = atol (str);	    break;	  }	case READ_FLOAT_SYSCALL:	  {	    static char str [256];	    read_input (str, 256);	    FGR [REG_FRES] = (float) atof (str);	    break;	  }	case READ_DOUBLE_SYSCALL:	  {	    static char str [256];	    read_input (str, 256);	    FPR [REG_FRES] = atof (str);	    break;	  }	case READ_STRING_SYSCALL:	  {	    read_input ( (char *) MEM_ADDRESS (R[REG_A0]), R[REG_A1]);	    data_modified = 1;	    break;	  }	case SBRK_SYSCALL:	  {	    mem_addr x = data_top;	    expand_data (R[REG_A0]);	    R[REG_RES] = x;	    data_modified = 1;	    break;	  }	case PRINT_CHARACTER_SYSCALL:	  write_output (console_out, "%c", R[REG_A0]);	  break;	case READ_CHARACTER_SYSCALL:	  {	    static char str [2];	    read_input (str, 2);	    if (*str == '\0') *str = '\n';      /* makes xspim = spim */	    R[REG_RES] = (long) str[0];	    break;	  }	case EXIT_SYSCALL:	  return (0);	case OPEN_SYSCALL:	  {#ifdef WIN32	    R[REG_RES] = _open(MEM_ADDRESS(R[REG_A0]), R[REG_A1], R[REG_A2]);#else	    R[REG_RES] = open(MEM_ADDRESS(R[REG_A0]), R[REG_A1], R[REG_A2]);#endif	    break;	  }			case READ_SYSCALL:	  {	    /* Test if address is valid */	    MEM_ADDRESS(R[REG_A1] + R[REG_A2] - 1);#ifdef WIN32	    R[REG_RES] = _read(R[REG_A0], MEM_ADDRESS(R[REG_A1]), R[REG_A2]);#else	    R[REG_RES] = read(R[REG_A0], MEM_ADDRESS(R[REG_A1]), R[REG_A2]);#endif	    data_modified = 1;	    break;	  }	case WRITE_SYSCALL:	  {	    /* Test if address is valid */	    MEM_ADDRESS(R[REG_A1] + R[REG_A2] - 1);#ifdef WIN32	    R[REG_RES] = _write(R[REG_A0], MEM_ADDRESS(R[REG_A1]), R[REG_A2]);#else	    R[REG_RES] = write(R[REG_A0], MEM_ADDRESS(R[REG_A1]), R[REG_A2]);#endif	    break;	  }	case CLOSE_SYSCALL:	  {#ifdef WIN32	    R[REG_RES] = _close(R[REG_A0]);#else	    R[REG_RES] = close(R[REG_A0]);#endif	    break;	  }	default:	  run_error ("Unknown system call: %d\n", R[REG_V0]);	  break;	}    }  else#if (mips && dec)    {      if (!fds_initialized)	{	  initialize_prog_fds ();	  fds_initialized = 1;	}      /* Use actual MIPS system calls. First translate arguments from	 simulated memory to actual memory and correct file descriptors. */      if (R[REG_V0] < 0 || R[REG_V0] > MAX_SYSCALL)	{	  run_error ("Illegal system call: %d\n", R[REG_V0]);	}      switch (syscall_table[R[REG_V0]].syscall_type)	{	case BAD_SYSCALL:	  run_error ("Unknown system call: %d\n", R[REG_V0]);	  break;	case UNIX_SYSCALL:	  unixsyscall ();	  break;	case SPC_SYSCALL:	  /* These syscalls need to be simulated specially: */	  switch (R[REG_V0])	    {	    case SYS_syscall:	      R[REG_V0] = R[REG_A0];	      R[REG_A0] = R[REG_A1];	      R[REG_A1] = R[REG_A2];	      R[REG_A2] = R[REG_A3];	      READ_MEM_WORD (R[REG_A3], R[REG_SP] + 16);	      do_syscall ();	      break;	    case SYS_sysmips:	      {		/* The table smipst maps from the sysmips arguments to syscall		   numbers */		int callno;		static int smipst[] = {7, 7, 7, 7, 7, 7, 7, 7, 7, 7,				       7, 7, SYS_getrusage, SYS_wait3,				       SYS_cacheflush, SYS_cachectl};		callno= R[REG_A0];		callno= ( (callno >0x100) ? smipst[callno - 0x100 + 10]			  : smipst[callno]);		R[REG_V0] = callno;		R[REG_A0] = R[REG_A1];		R[REG_A1] = R[REG_A2];		R[REG_A2] = R[REG_A3];		READ_MEM_WORD (R[REG_A3], R[REG_SP] + 16);		do_syscall ();		break;	      }	    case SYS_exit:	      {		kill_prog_fds ();		return (0);	      }	    case SYS_close:	      if (unixsyscall () >= 0)		prog_fds[R[REG_A0]] = -1; /* Mark file descriptor closed */	      break;	    case SYS_open:	    case SYS_creat:	    case SYS_dup:	      {		int ret = unixsyscall ();		if (ret >= 0)		  prog_fds[ret] = ret; /* Update fd translation table */		break;	      }	    case SYS_pipe:	      {		/* This isn't too useful unless we implement fork () or other		   fd passing mechanisms */		int fd1, fd2;		if (unixsyscall () >= 0)		  {		    READ_MEM_WORD (fd1, MEM_ADDRESS (R[REG_A0]));		    READ_MEM_WORD (fd2, MEM_ADDRESS (R[REG_A0]));		    prog_fds[fd1] = fd1;		    prog_fds[fd2] = fd2;		  }		break;	      }	    case SYS_select:	      {		int fd;		/*		 * We have to use this kludge to circumvent typechecking		 * because the memory read macros take the lefthand side		 * as an argument instead of simply returnign the value		 * at the address		 */		mem_addr kludge;		fd_set a, b, c;		fd_set *readfds = &a, *writefds = &b, *exceptfds = &c;		struct timeval *timeout;		FD_ZERO (readfds);		FD_ZERO (writefds);		FD_ZERO (exceptfds);		READ_MEM_WORD (kludge, R[REG_SP] + 16);		if (kludge == NULL)		  timeout = NULL;		else		  timeout = (struct timeval *) MEM_ADDRESS (kludge);		if (R[REG_A1] == NULL)		  readfds = NULL;		else		  for (fd = 0; fd < R[REG_A0]; fd++)		    if (FD_ISSET (fd, (fd_set *) MEM_ADDRESS (R[REG_A1])))		      FD_SET (prog_fds[fd], readfds);		if (R[REG_A2] == NULL)		  writefds = NULL;		else		  for (fd = 0; fd < R[REG_A0]; fd++)		    if (FD_ISSET (fd, (fd_set *) MEM_ADDRESS (R[REG_A2])))		      FD_SET (prog_fds[fd], writefds);		if (R[REG_A3] == NULL)		  exceptfds = NULL;		else		  for (fd = 0; fd < R[REG_A0]; fd++)		    if (FD_ISSET (fd, (fd_set *) MEM_ADDRESS (R[REG_A3])))		      FD_SET (prog_fds[fd], exceptfds);		R[REG_RES] = select (R[REG_A0], readfds, writefds, exceptfds,				     timeout);		if (readfds == NULL)		  R[REG_A1] = NULL;		else		  for (fd = 0; fd < R[REG_A0]; fd++)		    if (FD_ISSET (fd, readfds))		      FD_SET (reverse_fds (fd),			      (fd_set *) MEM_ADDRESS (R[REG_A1]));		if (writefds == NULL)		  R[REG_A2] = NULL;		else		  for (fd = 0; fd < R[REG_A0]; fd++)		    if (FD_ISSET (fd, writefds))		      FD_SET (reverse_fds (fd),			      (fd_set *) MEM_ADDRESS (R[REG_A2]));		if (exceptfds == NULL)		  R[REG_A3] = NULL;		else		  for (fd = 0; fd < R[REG_A0]; fd++)		    if (FD_ISSET (fd, exceptfds))		      FD_SET (reverse_fds (fd),			      (fd_set *) MEM_ADDRESS (R[REG_A3]));		if (R[REG_RES] < 0)		  {		    R[REG_ERR] = -1;		    R[REG_RES] = errno;		    return (-1);		  }		else		  {		    R[REG_ERR] = 0;		    return (R[REG_RES]);		  }	      }	    case SYS_sbrk:

⌨️ 快捷键说明

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