Busan IT/Assembly2015. 10. 24. 00:12

==================================Outline====================================

메모리 출력 함수 'memory_display'

프로그램 실행 함수  ‘program_execute'

----------------------------------------------------------------------------

메모리 출력 함수 'memory_display'

 

메모리를 헥사뷰로 출력하는 함수 'memory_display'를 만들어보자.

 

//'memory_modify'함수를 복사해서 필요한 부분만 수정하면 편하다.

 

사용자가 출력하고자하는 메모리의 시작 위치를 입력 받은 후 헥사뷰를 실행시켜 16씩 출력 시킨다페이지를 초과하는 경우 사용자로부터 아무키나 입력받으면 다음 페이지를 출력 시키고 q' 혹은 'Q' 입력할 시 출력을 멈춘다.

void memory_display()
{
  unsigned int uiAddr;
  unsigned int uiVal;  
  char cInput;

  
  while(1)
  {
    printf("Please input an address to display [%08X - %08X]  :  ", vpMem_start, vpMem_end);
    scanf("%x"&uiAddr);
    if('\n'==getchar());
    if(uiAddr < (unsigned int)vpMem_start || uiAddr > (unsigned int)vpMem_end)
    {
      printf("Wrong address \n");
      continue;
    }
    break;    
  }
  
  while( (uiAddr)< ( (unsigned int)vpMem_end ) )
  {
    hexaview((void *)uiAddr, 16*16);
    uiAddr = uiAddr + (16*16);
    if(uiAddr>(unsigned int)vpMem_end)
    {
      printf("Memory displayed\n");
      return;
    }
    printf("Please enter any to continue(stop for 'Q')\n");
    cInput = getch();    
    if(cInput == 'q' ||cInput == 'Q')
    {
      printf("Memory display interrupted\n");
      return;
    }    
  } 
  return; 
}

 

헥사뷰 출력 값이 ‘vpMem_end‘를 초과할 경우 해당 자리에서 헥사뷰를 멈추도록 코딩한다.

이를 위해 헥사뷰를 수정한다.

void hexaview(void * vP, unsigned int uiLen)
{
  unsigned int uiCnt;
  unsigned int uiLine;

  printf("===============================================================================\n");
  printf("  Address      Hexa           ASCII       \n"); 
  printf("-------------------------------------------------------------------------------\n");
  for (uiLine = 0; uiLine <  uiLen; uiLine += 16)
  {
    if(vP > vpMem_end)
      return;
    printf(" %08X  ", vP);
  
    for(uiCnt=0; uiCnt<16; ++uiCnt)
    {
      if(vP > vpMem_end)
      {
        while(uiCnt<16)
        {
          printf("   ");
          vP = (char *)vP + 1;
          ++uiCnt;
        }
        break;
      }
      printf("%02X ", *((unsigned char *)vP));
      vP = (char *)vP + 1;
    }
    vP = (char *)vP - 16;
    putchar(' ');

    for(uiCnt=0; uiCnt<16; ++uiCnt)
    {
      if(vP > vpMem_end)
      {
        putchar('\n');
        return;
      }
      if (32 > *((unsigned char *)vP))
      {
        putchar('.');
      }    
      else if(127 < *((unsigned char *)vP))
      {
        putchar('.');
      }
      else
      {        
        printf("%1c", *((unsigned char *)vP));
      }

      vP = (char *)vP + 1;
    }
    putchar('\n');

  }
  putchar('\n');
  return;
}


실행시킨 화면은 다음과 같다.



//코딩을 할 때 변수와 함수명의 형식에 일관성이 있어야 한다.

 

프로그램 실행 함수  ‘program_execute' 


로드함수를 사용하여 프로그램을 메모리에 적재한 후, 이것을 실행시키는 ‘program_execute'를 만들어보자사용자가 입력하는 명령어는 'GO'이다전역 변수를 만들어 주고 로드 상태에 따라 해당 변수의 값을 바꿔준다.

 

#define LOAD_ON 1

#define LOAD_OFF 0

 

unsigned int uiLoad;

 

‘program_execute'가 실행되면 로드 되어 있는 프로그램이 실행되고 난 후 다시 메뉴로 돌아가야 한다. 이를 위해 어셈블리 코드로 만든 stst‘, ’ldst‘함수를 사용한다.


레지스터 변수들을 담고 있는 ’context’를 ‘stTempState‘라는 이름으로 선언해준다이 구조체는 로드된 프로그램을 실행시키고 다시 메뉴로 돌아갈 수 있게 만들어주는 징검다리 역할을 한다.


구조체의 ‘esp’에는 ‘vpStack’, ‘eip’에는 ‘vpCode’(로드된 프로그램), ‘eax’에는 ‘stOld_state’의 주소를 담아준다.

 

세팅을 끝낸 ‘stTempState‘를 ’ldst‘의 인자로 전달한다. 'eip'가 적재된 프로그램의 코드 영역을 가리키고 있음으로 프로그램이 실행된다프로그램이 수행되고 나면 레지스터를 ’stOld_state’에 저장된 상태로 되돌려 주어야 한다‘stOldState’를 'eax'에 넣어준 것이 바로 'stOldState'가 가진 레지스터의 상태로 복구 시켜주기 위함이다.



void program_execute()
{
  context stTempState;
  if(uiLoad == LOAD_OFF)
  {
    printf("No loaded program.\nPlease load program by using 'LOAD' command.\n");
    return;
  }
  memset(&stTempState, 0sizeof(context));  
  stTempState.esp = (unsigned int)vpStack;
  stTempState.eip = (unsigned int)vpCode;    
  stTempState.eax = (unsigned int)(&stOld_state);
  
  ldst(&stTempState);
  printf("System Panic!\n");
  
  return;

} 


적재된 프로그램 실행 후 레지스터를 ‘stOldState’의 값으로 복구 시키기 위해 어셈블리로 'init'함수를 만들어준다. C에서도 호환하여 사용하기 위해 언더바(_)를 붙혀준다.


(진행중)

.386

.MODEL FLAT

.code

_start:

_INIT PROC NEAR32

  push eax  ;'&stOldState' 저장
  call _smart  
  call _t1  
  call _ldst  
  

_INIT ENDP


init.asm


smart.c



반응형

'Busan IT > Assembly' 카테고리의 다른 글

String Operation  (0) 2015.10.29
task switching  (0) 2015.10.29
LOAD함수 구현  (0) 2015.10.23
PE구조체  (0) 2015.10.22
memory_modify함수  (0) 2015.10.20
Posted by newind2000