20131014

2013. 10. 14. 20:43

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

20131014

2013. 10. 11. 09:02

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

20131002

___________RFID_______________________________________________________________________

 

[0xB0] Host commands for ISO15693 Mandatory and Optional Commands

>> [0x23] Read Multiple Blocks <<

 ※ 트랜스폰더 내에 메모리 값을 블록단위로 가져옴

 

 

 

 

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/signal.h>


#define SPEED  B38400
#define SPORT  "/dev/ttyS1"  //Serial Port2

unsigned short CRC16(unsigned char *, unsigned int);
void Handle_Serial_Sig(int);

volatile int iBreak = 0;

int main()
{
  char cBuff[255]; //수신용 버퍼 
  int iDev = 0;    //장치 데스크립션 
  int iRet = 0;    //반환값 
  int iCnt;
  unsigned char ucTemp;
  
  struct termios stOldState;         // 기존 Serial Port 상태 정보 
  struct termios stNewState;           // 새로운 Serial Port 상태 정보 
  struct sigaction stSigAct;    // 시그널 액션 설정

  //unsigned char ucRecvBuff[255];
  
  unsigned char Buff[255= {
                  
                      
/*  [0xB0] Host commands for ISO15693 Mandatory
                            and Optional Commands*/
//--------------
   
                  0x11,  //[0x23] Read Multiple Blocks
                  0x00,
                  0xB0,
                  0x23,
                  0x01 //<- Address Mode
                            
                  0xE0,  //<- UID
                  0x04,
                  0x01,
                  0x00,
                  0x03,
                  0x0F,
                  0x3B,
                  0x70,

                  0x00,  // DB-ADR

                  0x02,  // DB-N (BLOCK 수)
                  // 원하는 블록 주소(위치,DB-ADR)에서 DB-N (BLOCK 수) 만큼 DB리턴을 받겠다는 REQUEST
              
/*
                  0x07,  //[0x01] Inventory
                  0x00,
                  0xB0,
                  0x01,
                  0x00,
              */

                  //-----------------------------------------------------
    
              
/*
                  0x05, // Get Software Version
                  0x00,
                  0x65,
              */

                  
              
/*  
                  0x06, // Baud Rate Detection
                  0x00,
                  0x52,
                  0x00,
              */


                  
              
/*    0x0D, // Set Output
                  0x00,
                  0x71,
                  0x00,
                  0x30,
                  0x00,
                  0x00,
                  0x00,
                  0x0A,
                  0x00,
                  0x00,
              */

             

 /*
                  0x0D, // Set Output2
                  0x00,
                  0x71,
                  0x00,
                  0x3F,
                  0x00,
                  0x07,
                  0x00,
                  0x0A,
                  0x00,
                  0x00,
              */


                  0xFF,
                  0xFF
                 };
  
  iDev = open(SPORT, O_RDWR | O_NOCTTY | O_NONBLOCK);// Serial Port Open

  if0 > iDev)                       //시리얼 포트 Open Error
  {
    perror(SPORT);
    exit(-100);
  
  }
  
  //시리얼 포트 설정 전에 시그널 핸들러 등록
  
  bzero(&stSigAct, sizeof(stSigAct));
  stSigAct.sa_handler = Handle_Serial_Sig;
  sigaction(SIGIO, &stSigAct, NULL);

  //SIGIO signal 을 수신하도록 설정
  fcntl(iDev, F_SETOWN, getpid());//iDev(시리얼 포트) 소유자를 현재 프로세스로 바꿈
  // SIGIO 발생은 소유자에게 알려지기 때문에... 

  // file descriptor를 비동기로 설정
  fcntl(iDev, F_SETFL, FASYNC);

  
  tcgetattr(iDev, &stOldState);  // 현재 Serial Port 상태 저장 (백업해둠)  
  
  bzero(&stNewState, sizeof(stNewState)); // 구조체 초기화
   

  stNewState.c_cflag = SPEED | CRTSCTS | CS8 | CLOCAL | CREAD | PARENB;
  

  stNewState.c_iflag = IGNPAR | ICRNL ;
  stNewState.c_oflag = 0;  // 수신된 데이터를 그대로 출력 

  //stNewState.c_lflag = ICANON; //Canonical 통신 기법 사용 
  stNewState.c_lflag = 0//Non-Canonical 통신 기법 사용 
  stNewState.c_cc[VMIN] = 1//read시 리턴되기 위한 최소 문자 개수 지정
  stNewState.c_cc[VTIME] = 0

  tcflush (iDev, TCIFLUSH); // 시리얼 포트수신 큐 초기화 
  tcsetattr(iDev, TCSANOW, &stNewState); //시리얼 포트에 새 속성 적용

 

  *((unsigned short *)(&Buff[Buff[0]-2])) = CRC16(Buff, Buff[0]-2);

  
/*
  printf("%02X\n", Buff[0] );
  printf("%02X\n", Buff[1] );
  printf("%02X\n", Buff[2] );
  printf("%02X\n", Buff[3] );
  printf("%02X\n", Buff[4] );
  printf("%02X\n", Buff[5] );
  printf("%02X\n", Buff[6] );
  printf("%02X\n", Buff[7] );
  printf("%02X\n", Buff[8] );
  printf("%02X\n", Buff[9] );
  printf("%02X\n", Buff[10] );
  printf("%02X\n", Buff[11] );
  printf("%02X\n", Buff[12] );
  */


  write(iDev, Buff, Buff[0]);               //송신 
  
  read(iDev, Buff, sizeof(Buff)); //수신 

  //Buff[0] = 13;
    
  for(iCnt = 0; iCnt < Buff[0]; ++iCnt)
  {
    printf("%02X ", Buff[iCnt]);  
  }
  putchar('\n');



  
/*
  //[0x01] Inventory------------------------
  
  printf("__TR-TYPE__\n");
  printf("RF_TEC : ");
  
  if(0 != (Buff[5] & 0x80) )
  {
    printf("[UHF Transponder]\n");
  }
  else
  {
    printf("[13,56 MHz Transponder]\n");    
  }
  printf("TYPE_NO : ");  
  if(0x00 == (Buff[5] & 0x0F) )
  {
    printf("[Philips I-Code 1]\n");
  }
  else if(0x01 == (Buff[5] & 0x0F) )
  {
    printf("[Texas Instruments Tag-it HF]\n");    
  }
  else if(0x03 == (Buff[5] & 0x0F) )
  {
    printf("[ISO15693 Tags]\n");    
  }
  else if(0x06 == (Buff[5] & 0x0F) )
  {
    printf("[Philips I-Code EPC]\n");    
  }
  else if(0x07 == (Buff[5] & 0x0F) )
  {
    printf("[Philips I-Code UID]\n");    
  }
  else
  {
    printf("Unknown\n");
  }  
     
  printf("UID : ");
  for(iCnt = 7; iCnt < 15; ++iCnt)
  {
    printf("%02X ", Buff[iCnt]);
  }
  putchar('\n');

  */

  //------------------------------------------
  //printf("%04X\n", CRC16(Buff, Buff[0]-5) );
  //printf("%04X\n", CRC16(Buff, Buff[0]-2) );
 
  
/*// Get Software Version
  ucTemp = Buff[4];
  Buff[4] = Buff[5];
  Buff[5] = ucTemp; // Big endian이라서 스왑해줌 
  
  printf("SW-REV   : %d\n", *((unsigned short *)(&Buff[4])) );
  printf("D-REV   : %d\n", Buff[6] );
  printf("HW-TYPE  : %d\n", Buff[7] );
  printf("SW-TYPE  : ");
  
  
  switch( *((unsigned short *)(&Buff[8])) )
  {
  
    case 30: 
      printf("ID ISC.M01\n");
      break;

    case 31: 
      printf("ID ISC.M02\n");
      break;

    case 71: 
      printf("ID ISC.PRH100.U (USB-Version)\n");
      break;

    case 72: 
      printf("ID ISC.PRH100\n");
      break;

    case 73: 
      printf("ID ISC.MR100.U (USB-Version)\n");
      break;

    case 74: 
      printf("ID ISC.MR100 / .PR100\n");
      break;

    case 75: 
      printf("ID ISC.MR200-A / -E\n");
      break;

    case 40: 
      printf("ID ISC.LR100\n");
      break;

    case 41: 
      printf("ID ISC.LR200\n");
      break;

    case 91: 
      printf("ID ISC.LRU1000\n");
      break;

    case 80: 
      printf("ID CPR.M0\n");
      break;

    case 81:   
      printf("ID CPR.02\n");
      break;

    case 84: 
      printf("ID CPR.M03 (586/#)\n");
      break;

    default: 
      printf("unknown\n");
        
  }
  
  ucTemp = Buff[9];
  Buff[9] = Buff[10];
  Buff[10] = ucTemp; // Big endian이라서 스왑해줌 
  
  printf("TR-TYPE : ");

  if( 0 != ((*((unsigned short *)(&Buff[9]))) & 0x0001) ) 
  {
    printf("[I-Code 1] ");
  }
  if( 0 != ((*((unsigned short *)(&Buff[9]))) & 0x0002) ) 
  {
    printf("[Tag-it HF] ");
  }
  if( 0 != ((*((unsigned short *)(&Buff[9]))) & 0x0008) ) 
  {
    printf("[ISO 15693] ");
  }
  if( 0 != ((*((unsigned short *)(&Buff[9]))) & 0x0040) ) 
  {
    printf("[I-Code EPC] ");
  }
  if( 0 != ((*((unsigned short *)(&Buff[9]))) & 0x0080) ) 
  {
    printf("[I-Code UID] ");
  }
   putchar('\n');
*/

  tcsetattr(iDev, TCSANOW, &stOldState); // 시리얼 포트의 원래 속성 복귀
  close(iDev); // 시리얼 포트 닫음

  
  return 0;
}

void Handle_Serial_Sig(int Arg)
{
  printf("Receive SIGIO Signal\n");
  iBreak = 1;
}

#define   CRC_POLYNOM      0x8408
#define   CRC_PRESET      0xFFFF
unsigned short CRC16(unsigned char *DATA, unsigned int cnt)
{
  unsigned short crc = CRC_PRESET;
  unsigned int i;
  unsigned int j;
  
  /* cnt = number of protocol bytes without CRC */
  for (i = 0; i < cnt; i++)         
  {
    crc ^= DATA[i];
    for (j = 0; j < 8; j++)
    {
      if (crc & 0x0001)        
      crc = (crc >> 1) ^ CRC_POLYNOM;
      else
      crc = (crc >> 1);
    }
  }
  return crc;
}

____________________________________________________________________________________________

 

 

 

 

 

 

 

 

___________ASM________________________________________________________________________

 

MASM 프로시저를 이용한 context switching 프로그램 만들기

 

 monitor.c

 #include <stdio.h>
#include <fcntl.h>
#include <windows.h>

#define  MAX_PROGRAM_SIZE   0x10000 // 64k
#define  SECTION_SIZE      512


typedef struct _context
{
  int  efl;
  int  eip;
  int  edi;
  int  esi;
  int  ebp;
  int  esp;  
  int  ebx;
  int  edx;
  int  ecx;
  int  eax;
  
}context;


typedef struct _cmdmap
{
  void *vpCmd;
  void (*fP)(void);
  
}cmdmap;


void       hexaview        (unsigned char *, unsigned int);
void       Printf_REG        (void);
void      STST          (context *);
void      LDST          (context *);
int       ASKY          (void);
unsigned char   MD            (void *);      // Memory Display Function By Assembly
void       MM            (void *, char);    // Memory Modify Function By Assembly
void       Printf_NOW_REG    (void);
void       Code_View        (void);
void       Data_View        (void);
void       Stack_View        (void);
void       Load          (void);
void       Clear_mem        (void);
void       go            (void);
void       Help_List        (void);
void       Mem_Address      (void);
void       Memory_Modify    (void);
void       Memory_Display    (void);


static unsigned char   ucMem[MAX_PROGRAM_SIZE*2];
static unsigned char *  ucpMem_end;
static unsigned char *  ucpCode;
static unsigned char *  ucpData;
static unsigned char *  ucpStack;
static unsigned char    ucLoad_Flag;
static unsigned char    ucDisplay_Flag;
static int         iFd;



cmdmap stCmd_List[] = {
            { "CODE"    ,   Code_View     },
            { "DATA"    ,   Data_View       },
            { "STACK"  ,   Stack_View     },
            { "LOAD"    ,  Load               },
            { "MC"    ,  Clear_mem    },
            { "GO"    ,  go                        },
            { "R"    ,  Printf_NOW_REG  },
            { "P"    ,  Mem_Address    },
            { "MM"    ,  Memory_Modify  },
            { "MD"    ,  Memory_Display  },
            { "HELP"    ,  Help_List      },
            { 0      ,        0              }
          };

context stOldReg;  // 레지스터 정보를 담을수 있는 구조체 변수
context stNowReg;
context *stpReg;  // 레지스터 정보를 출력하기 위해 해당 구조체변수를 가리키는 포인터변수

int main()
{
  unsigned char     ucCmd[31];
  unsigned int     uiCnt;
  cmdmap *    stpCmd;
  int         iRet;

  ucpMem_end = ucMem+(MAX_PROGRAM_SIZE*2);
  (unsigned int)ucpCode = ((unsigned int)(ucMem+MAX_PROGRAM_SIZE)& 0xFFFF0000);
  ucpData = ucpCode + 0x2000;
  ucpStack = ucpCode + MAX_PROGRAM_SIZE;



    
  STST(&stOldReg);
  stpReg = &stOldReg;
  if(0 == ucLoad_Flag)
  {
    printf("\n    < 프로그램 실행 초기의 레지스터 상태 >\n");
    Printf_REG();
  }
  else
  {
    printf("\n    < 프로그램 실행 초기의 레지스터 상태 >\n");
    Printf_REG();
    Printf_NOW_REG();
  }
  
  while(1)
  {  
    
    fflush(stdin);
    putchar('>');
    putchar(' ');
    
    iRet = read(0, ucCmd, 30);  //명령어 입력받음
    ucCmd[iRet-1= 0;



    for(uiCnt = 00 != ucCmd[uiCnt]; ++uiCnt)
    {
      ucCmd[uiCnt] = toupper(ucCmd[uiCnt]);// 입력받은 명령어를 모두 대문자로 바꿈 
     }


    if(0 == strcmp(ucCmd, "Q" ) ) //입력받은 문자가 Q라면 종료
    {
      break;
    }

    stpCmd = stCmd_List;
    while(1)
    {
      if0 == stpCmd->fP)
      {
        printf("메모리 디버거 명령어\n");
        Help_List();
        break;
      }
      
      if(0 == strcmp(stpCmd->vpCmd, ucCmd ) )
      {
        (stpCmd->fP)(); 
        break;
      }
      
      ++stpCmd;
    }
    

  }  
  

  //printf("EAX Return : %d\n", ASKY());
  //printf("MD : 0x%X\n", MD(&A));
  //MM( &A, 0xFF);
  //printf("MM : 0x%X\n", A);
  //hexaview((unsigned char *)&A, 160);
  //Printf_REG(&stOldReg);
  //STST(&stOldReg);
  //Printf_REG(&stOldReg);

    
  return 0;
}


void Printf_NOW_REG(void) // 명령어로 R을 치면 현재 레지스터 정보를 출력해줌
{
  printf("         < 현재 레지스터 상태 >\n");
  STST(&stNowReg);
  stpReg = &stNowReg;
  Printf_REG();  
}


void Printf_REG(void)
{
    
  printf("___________________________________________________\n\n");
  printf(" EAX : 0x%08X    ECX : 0x%08X \n", stpReg->eax, stpReg->ecx);
  printf(" EDX : 0x%08X    EBX : 0x%08X \n", stpReg->edx, stpReg->ebx);
  printf(" ESP : 0x%08X    EBP : 0x%08X \n", stpReg->esp, stpReg->ebp);
  printf(" ESI : 0x%08X    EDI : 0x%08X \n", stpReg->esi, stpReg->edi);
  printf(" EIP : 0x%08X    EFL : 0x%08X \n", stpReg->eip, stpReg->efl);
  printf("___________________________________________________\n\n");
}


void hexaview(unsigned char *ucP, unsigned int iSize)
{
  
  int iCnt;
  int iLoop;
  int iRemainder;
  
  
  printf("------------------------------------"
      "-------------------------------------\n");
  printf("Address                       Hexa"
      "                            ASCII \n");
  printf("         ");

  for(iCnt = 0; iCnt < 16; ++iCnt )
  {
    printf("%02X ", iCnt);
  }
  putchar('\n');
  
  printf("------------------------------------"
      "-------------------------------------\n");
    
  
/*
  if( 0 == iSize%16 )
  {
    iSize = iSize/16;
  }
  else
  {
    iSize = (iSize/16)+1;
  }
  */

  if(0 == iSize)
  {
    return;
  }
  else
  {
    iRemainder = iSize%16;
    iSize = iSize/16;
  }
  
  
  for( iLoop = 0 ;iLoop < iSize; ++iLoop)
  {
    printf("%08X ", ucP);          //주소 출력
        
    for(iCnt = 0; iCnt < 16; ++iCnt )
    {
      printf("%02X ", MD(ucP+iCnt));   //hexa값 출력
    }

    for(iCnt = 0; iCnt < 16; ++iCnt )     //아스키코드 값 출력
    {
      if(0 == MD(ucP+iCnt))
      {
        printf(".");
      }
      else if(32 > MD(ucP+iCnt))
      {
        printf(".");
      }
      else if(127 < MD(ucP+iCnt))
      {
        printf(".");
      }
      else
      {  
        printf("%c", MD(ucP+iCnt));
      }
    }

    putchar('\n');
    ucP = (ucP + 16);

  }

  if(0 == iRemainder)
  {
    printf("------------------------------------"
      "-------------------------------------\n");
    return;
  }
  printf("%08X ", ucP);          //주소 출력
      
  for(iCnt = 0; iCnt < iRemainder; ++iCnt )
  {
    printf("%02X ", MD(ucP+iCnt));   //hexa값 출력
  }

  for(iCnt = 0; iCnt < (16-iRemainder); ++iCnt ) //빈자리 공백으로 ...
  {
    printf("   ");   
  }
  

  for(iCnt = 0; iCnt < iRemainder; ++iCnt )     //아스키코드 값 출력
  {
    if(0 == MD(ucP+iCnt))
    {
      printf(".");
    }
    else if(32 > MD(ucP+iCnt))
    {
      printf(".");
    }
    else if(127 < MD(ucP+iCnt))
    {
      printf(".");
    }
    else
    {  
      printf("%c", MD(ucP+iCnt));
    }
  }
  putchar('\n');
  printf("------------------------------------"
      "-------------------------------------\n");
  
  
}




void Code_View(void) //지정해 놓은 code 영역 메모리를 헥사뷰로 보여줌
{
  hexaview(ucpCode, 160);
}

void Data_View(void) //지정해 놓은 data 영역 메모리를 헥사뷰로 보여줌
{
  hexaview(ucpData, 160);
}

void Stack_View(void) //지정해 놓은 stack 영역 메모리를 헥사뷰로 보여줌
{
  hexaview(ucpStack-159160);
  //hexaview(ucpStack-160, 160);
}

 

 


// load 명령을 치면 실행파일의 code섹션과 data섹션을 할당해 놓은 각 영역별 메모리에 적재해줌
void Load(void)
{
  IMAGE_DOS_HEADER     *stpDos;
  IMAGE_NT_HEADERS     *stpNT;
  IMAGE_SECTION_HEADER  *stpSection;

  int   Total_Read = 0;
  int   Read_Num = 0;
  int  Header_Size;
  
  
  int   iRet;
  int   iCode_Offset;
  int   iData_Offset;
  int   iSection_Size;
  
  unsigned char ucFile_Name[255];


  printf("파일이름을 입력하시오 :  ");
  fflush(stdin);
  
  iRet = read(0, ucFile_Name, 32);             //파일 이름 입력받음
  ucFile_Name[iRet-1= 0;
  
  iFd = open(ucFile_Name, O_RDONLY |O_BINARY);     //파일 오픈
  //iFd = open("A.exe", O_RDONLY |O_BINARY);

  if(0 > iFd)
  {
    printf("open error\n");
    return;    
  }
  else
  {
    Clear_mem();
  }
    
  
  iRet = read(iFd, ucpCode, MAX_PROGRAM_SIZE); // 파일로부터 64kb 읽어들임

  if(0 > iRet)
  {
    printf("파일이 존재하지만 읽을수 없습니다.\n");

    close(iFd);
    return;    
  }
  else
  {
    stpDos  =   (IMAGE_DOS_HEADER *)ucpCode;
    //파일을 메모리에 읽어들인 첫지점이 DOS Header 시작지점임

   
    stpNT  =    (IMAGE_NT_HEADERS *)(ucpCode + (stpDos->e_lfanew));
    
/* DOS Header 구조체 멤버중 e_lfanew에 시작점으로부터 얼마나 떨어진곳에
         NT header가 있는지 오프셋값이 있음 */



    (unsigned char *)stpSection  = (unsigned char *)stpNT + sizeof(IMAGE_NT_HEADERS);   
    
/* stpNT(NT header 시작주소)에서 NT header 크기( sizeof(IMAGE_NT_HEADERS) )만큼
        떨어진 곳에 Section Header(text) 가 있음 */

    
    Header_Size = stpNT->OptionalHeader.SizeOfHeaders; //PE header 의 전체 크기
    
    //lseek(iFd, stpNT->OptionalHeader.SizeOfHeaders, SEEK_SET);
    //PE header 의 헤더 전체 크기
    //파일 시작에서 SizeOfHeader 옵셋만큼 떨어진 위치에 첫번째 섹션이 위치
  
  }
  


  iSection_Size   =   stpNT->OptionalHeader.FileAlignment;   //섹션크기
  iCode_Offset     =   stpSection->PointerToRawData;     //code 섹션 오프셋값 iCode_Offset에 임시저장


  (unsigned char *)stpSection   =   (unsigned char *)stpSection + sizeof(IMAGE_SECTION_HEADER);
  
/* stpSection( Section Header(text) )에서 Section Header 크기( sizeof(IMAGE_SECTION_HEADER) )만큼
      떨어진 곳에 Section Header(data) 가 있음 */



  iData_Offset  =   stpSection->PointerToRawData;
  //code 섹션 오프셋값에서 섹션크기 만큼 주소를 증가시키면 data섹션 오프셋값이 있음 
  //data 섹션 오프셋값을 iData_Offset에 넣음  




  //파일 오프셋이 파일의 처음부분을 가리키도록하고 거기서 부터
  //PointerToRawData(파일에서 섹션의 시작 위치 오프셋값) 값을 읽어들여서
  // 파일 오프셋을 이동시킴 (code 섹션)
  if(0 > lseek(iFd, iCode_Offset, SEEK_SET) )
  {
    printf("파일의 헤더정보 Skip 실패!!\n");
    printf("파일을 적재할수 없습니다.\n");
    close(iFd);
    return;
  }
  else
  {
    Read_Num =  read(iFd, ucpCode, iSection_Size); 
    //code 섹션에서 값을 읽어들여 ucpCode가 가리키는 메모리에 저장

    Total_Read = Total_Read +  Read_Num; 
  }
  
 
  if(0 > Read_Num)
  {
    printf("파일이 존재하지만 읽을수 없습니다.\n");
    close(iFd);
    return;    
  }




  //파일 오프셋이 파일의 처음부분을 가리키도록하고 거기서 부터
  //data섹션 오프셋값 (code 섹션 오프셋값 + 섹션크기) 만큼 파일 오프셋 이동시킴
  if(0 > lseek(iFd, iData_Offset, SEEK_SET) )
  {
    printf("파일의 헤더정보 Skip 실패!!\n");
    printf("파일을 적재할수 없습니다.\n");
    close(iFd);
    return;
  }
  else
  {
    Read_Num =  read(iFd, ucpData, iSection_Size); 
    //data 섹션에서 값을 읽어들여 ucpData가 가리키는 메모리에 저장
    
    Total_Read = Total_Read +  Read_Num; 
  }  
  
  
  
  if(0 > Read_Num)
  {
    printf("파일이 존재하지만 읽을수 없습니다.\n");

    close(iFd);
    return;    
  }
  else
  {
    //iFd = 0;
    ucDisplay_Flag = 0;
    ucLoad_Flag = 1;
    printf("파일을 성공적으로 메모리에 적재하였습니다.\n");
    printf("읽어들인 파일의 크기는 : [%d]Bytes\n\n", Total_Read);
  }  

  close(iFd);
  return;
}



 

 


void Clear_mem(void) // 할당해 놓은 메모리 전체를 0으로 초기화
{
  unsigned int     uiCnt;
  unsigned char *  ucpTemp = ucpCode;

  for(uiCnt = 0; ucpTemp <= ucpMem_end; ++uiCnt)
  {
    *ucpTemp = 0;
    ++ucpTemp; 
  }
  //printf("Memory Clear !\n");
  ucLoad_Flag = 0;
  
  return;
}

 

 

 

 

 

 

// load 명령어로 실행 파일의 code섹션과 data섹션을 메모리에 적재한후 go명령을 치면 적재된 code가 수행됨

// 수행후 data영역과stack영역을 보면 code(실행파일)을 수행한 흔적을 확인할수 있음
void go(void)
{
  context stNewReg = {0,};

  stNewReg.eax   =   (int&stOldReg;
  stNewReg.eip   =   (int) ucpCode; 
  //stNewReg.esp   =   (int) (ucpMem_end)+4;
  stNewReg.esp   =   (int) (ucpStack);

  if(1 == ucLoad_Flag)
  {
    LDST(&stNewReg);
    printf("Kernel panic\n");
  }
  else
  {
    printf("외부 프로그램이 적재되어 있지 않습니다.\n");
    printf("load 명령을 사용하여 프로그램을 적재하시길 바랍니다.\n");
  }
   
  return;
}

 

 

 

 



void Help_List(void) //명령어 리스트를 보여줌
{
  printf("R\t: Register Value Display\n");
  printf("P\t: Memory Status Display\n");
  printf("MC\t: Memory Clear\n");
  printf("MM\t: Memory Modify\n");
  printf("MD\t: Memory Display\n");
  printf("LOAD\t: Program Load\n");
  printf("GO\t: Loaded Program Execute\n");
  printf("CODE\t: Code Area Display\n");
  printf("DATA\t: Data Area Display\n");
  printf("STACK\t: Stack Area Display\n");
  printf("HELP\t: Help Message Display\n");
  printf("Q\t: Exit Program\n");

  return;
}

 



void Mem_Address(void) //명령어로 p(P)눌렀을때 출력됨
{
  printf("CODE Start Address\t:\t %08X\n", ucpCode);
  printf("DATA Start Address\t:\t %08X\n", ucpData);
  printf("STACK Start Address\t:\t %08X\n", ucpStack);
  printf("Memory area\t\t:\t %08X to %08X (128KBytes)\n", ucMem, ucpMem_end);


  return;
}


void Memory_Display (void) //명령어로 md(MD)눌렀을때 원하는 메모리 주소의 값들을 헥사뷰로 출력
{
  unsigned char *ucpAdd;
    
  printf("\n메모리 주소를 입력하세요(%08X ~ %08X) : ", ucMem, ucpMem_end);
  fflush(stdin);

  scanf("%x"&ucpAdd); // 주소값 입력

  if( (ucpAdd < ucMem) || (ucpAdd > ucpMem_end) )
  {
    printf("출력할수 없는 주소 공간입니다.\n");
  }
  else
  {
    if160 > ((int)ucpMem_end - (int)ucpAdd) )
    {
      
      hexaview(ucpAdd, 1+((int)ucpMem_end - (int)ucpAdd)); 
      
    }
    else
    {
      hexaview(ucpAdd, 160); // 해당 주소값 헥사뷰 출력  
    }    
  }
  
  return;

}

 

 

 

 



//명령어로 mm(MM)눌렀을때 원하는 메모리 주소에 1 바이트를 원하는 값으로 수정함

void Memory_Modify(void)

{

  unsigned char *ucpAdd;
  int      iVal = 0;  
    
  printf("\n메모리 주소를 입력하세요(%08X ~ %08X) : ", ucMem, ucpMem_end);
  fflush(stdin);

  scanf("%x"&ucpAdd); // 주소값 입력

  if( (ucpAdd < ucMem) || (ucpAdd > ucpMem_end) )
  {
    printf("출력할수 없는 주소 공간입니다.\n");
  }
  else
  {
    hexaview(ucpAdd, 1); 
  }

  printf("변경하고 싶은 값(16진수)을 입력하세요 : ");
  fflush(stdin);
  
  scanf("%x"&iVal); // 변경하고 싶은 값 입력
  if( (0 > iVal) || (0xFF < iVal))
  {
    printf("잘못된 값입니다.\n");  
  }
  else
  {
    MM(ucpAdd, iVal); //원하는 주소에 원하는 값으로 수정
    hexaview(ucpAdd, 1);
  }

   
  return;  
}

 


 

 

 

 

 monitor.asm

 .386
.MODEL FLAT

PUBLIC _STST  ;store status
PUBLIC _LDST  ;load status
PUBLIC _ASKY  
PUBLIC _MD  ; Memory   Display Function By Assembly
PUBLIC _MM  ; Memory   Modify Function By Assembly


.CODE
_STST  PROC   NEAR32

    PUSH  EBP
    MOV  EBP, ESP

    PUSHFD        ; EFL 임시저장    
    
    MOV  EAX, [EBP-4]    ;EFL이 변형되기 때문에  
    AND  EAX, 0FFFFFEFFH    ;TF(Trap Flag) 제거
    MOV  [EBP-4], EAX 
    

    MOV  ESP, [EBP+8]    ; ESP를 _EAX 위치로 이동
    ADD  ESP, 40


    PUSHAD                                        ;레지스터 값 push
      PUSH       [EBP+4]                      ;EIP(return address)
      PUSH       [EBP-4]                         ;push EFL

   
      ADD         ESP,  24                         ; _ESP  위치로 가서

      MOV         EAX, EBP
      ADD         EAX, 8                             ; EBP로 부터 ESP를 찾아서  
      PUSH   EAX                               ; old ESP-4 push

    

      PUSH  [EBP]                            ; old EBP push



      ;MOV         ESP, EBP
      ;SUB   ESP, 4                             ; ESP 원래 위치로
        ;POPFD                                          ; EFL 복원        


      MOV  ESP, EBP                       ; Exit code
      POP  EBP
      RET
_STST     ENDP



; mem - > cpu
_LDST  PROC  NEAR32

    MOV  ESP, [ESP+4]  ;ESP=&context    ( ESP를 context 위치로)

    POPFD      ;EFL = context.EFL    

    POP  EAX    ;EAX= OLD EIP    ( old EIP를 EAX에 임시저장)

    MOV  EBX, ESP  ;EBX= current ESP  ( 현재 스택포인터를 EBX에 임시저장)
        
    MOV  ESP, [ESP+12]  ;ESP = OLD ESP    ( ESP를 OLD ESP-4위치로 이동)
                                                        
    PUSH  EAX    ;Save OLD EIP    ( 백업해둔 EIP를 OLD ESP-8 위치(return address)에 넣음)

    MOV  ESP, EBX  ;ESP = current ESP  ( ESP를 메모리 위치로 이동)          

    POPAD

    MOV  ESP, [ESP-20]  ;ESP
      
    SUB  ESP, 4    

      RET
_LDST    ENDP



_ASKY  PROC  NEAR32
    PUSH  EBP
    MOV  EBP, ESP    


    MOV  EAX, 100    ; 리턴값은 EAX에 있다.  

    MOV  ESP, EBP                       ; Exit code
      POP  EBP
    RET    
_ASKY    ENDP




_MD    PROC  NEAR32
    PUSH  EBP
    MOV  EBP, ESP

    
    MOV  EAX, [EBP+8]  ;&A를 EAX에 넣음     
    MOV  EAX, [EAX]  ; A가 가리키는 곳의 값을 EAX에 넣음

    MOV  ESP, EBP
    POP  EBP
    RET
_MD    ENDP  




_MM    PROC  NEAR32
    PUSH  EBP
    MOV  EBP, ESP

    PUSH  EBX


    MOV  EAX, [EBP+8]    ; &A를 EAX에 넣음     
    MOV  EBX, [EBP+12]    ; 0xFF(첫번째 인자)를 EBX에 넣음     

    MOV  BYTE PTR [EAX], BL  ; A가 가리키는 곳에 0xFF(인자값)을 넣음
            ; AL위치의 1바이트만 덮어써짐
            

    POP  EBX

    MOV  ESP, EBP
    POP  EBP
    RET
_MM    ENDP  



END

 

 

 

 

 

 init.asm

 .386
.MODEL   FLAT


PUBLIC  _INIT
EXTRN  _test:NEAR32
EXTRN  _LDST:NEAR32


.CODE
_INIT:

  PUSH  EAX  ;EAX 백업 , LDST의 인자값이 됨

  CALL  _test
  CALL  _LDST

END

 

 

 

 

 

 

 

 t1.c

char flstz[] = "1111222233334444";
int sum=0x78563412;

test ()
{
  int i = 0x12345678;
  int j = 0x78563412;
  int k = 0x77777777;
  
  sum = 0x12345678;
  for (i = 0; i < sizeof(flstz)-1; i++)
  {
    flstz[i] = 'a';
  }
}

 

 

 

 

______________________________________________________________________________________________

 

 

 

 

 

______실습파일 & 수업자료_______

 

asynchronous_serial.c<= RFID

 

 

 

 

init.asm

 

monitor2.asm

 

monitor_c.c

 

t1.c

 

 

monitor_c.exe

 

t1.exe

 

 

________________________________

'스마트 컨트롤러 게시물' 카테고리의 다른 글

20131014  (0) 2013.10.11
20131001  (0) 2013.10.01
20130930  (0) 2013.09.30
20130927  (0) 2013.09.27
20130926  (0) 2013.09.26