x64기반 어셈블리 프로그래밍에 대해서 소개와 함께 간단히 다루는 문서입니다.
x64 어셈블리 프로그래밍 입문자를 대상으로 하는 문서입니다.


출처 : 인텔
저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
by Sone 2010.09.24 09:49

그냥 어셈블리 언어 책을 보다가...잠시 딴짓좀 할겸 N사의 모 게임 프로그램 바이너리를 열어서 사용된 API를  봤는데
timeGetTime  API가 보여서  ,  갑자기 삘 받아서 카운터를 만들어볼까~?  하는 생각이 들었다.

(원래 시계 만드려고 했는데 ,  하다보니 이상하게 카운터로 변질된...)

MASM으로 해도 되지만 , 
VC컴파일러에서 __asm 디렉티브를 이용한 인라인 어셈블리로 구현해도 별 지장 없기에..
(오히려 더 편한듯)



일단 아래 코드는  서브루프가 계속되는 구조로 이루어져 있기때문에  , CPU사용율이 높아진다는 점 주의하자.
(CPU 사용율을 낮출수는 없을까?  
무슨 카운터 하나 구현하는데 CPU사용율이 50% ㅡㅡ;;; 
루프를 돌리지않으면 될텐데..그럼 어떠한 방법이 있을까? 
Sleep 함수 이런거 쓰면 좀 유치할것 같은데.. )


원래 변수 안쓰고 레지스터만을 이용해서 구현해보려고 했는데...
함수마다 리턴되는 위치와 값이 제각각 다르고 , 자꾸 삑사리 나서 , 결국 변수 3개 간단히 선언해서 구현을 해보았다..


** 주의 ** 
필자는 실력이 미흡하므로  주의 요망...언제 어디서 에러가 발생할지 모름.
(사실 시 단위는 테스트 안해봄 -_-;;  시 단위까지 기다리기 귀찮고 ,  물론 디버거로 일부러 분에다가 60 잡아넣어서 해볼수도 있지만
귀차니즘때문에 패스.)



아 ,  또 다른 주의할점은 , timeGetTime API를 이용하려면 ,  MMSystem.h 헤더파일을 Include 해주어야하고,
프로젝트  링커 명령줄에다가  Winmm.lib  정적 라이브러리 파일을  명령줄에다가 추가시켜주어야 한다.


//---------------------------inline_assembly.cpp------------------------//
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <MMSystem.h>  //timeGetTime API 이용

int main(void)
{
 DWORD Hour=0,Min=0,Sec=0;

 __asm{
   XOR EDI,EDI //카운트 0으로 초기화 (EDI 레지스터는 카운터 목적으로 이용)
 }

EntireLoop:
 timeGetTime();

 __asm{
   MOV ESI,EAX //1차 시간이 EAX에 반환되고, 그것을 ESI에 집어넣음
 }
SubLoop: timeGetTime(); //2차 시간이 EAX에 반환됨
 __asm{
   SUB EAX,ESI  //2차시간 - 1차시간
   MOV EBX,0x3E8 //10진수 1000을 EBX에 넣는다.
   DIV EBX  //EAX에 들어있는 값과 EBX에 있는 10진수 1000으로 나눈다.
   CMP EAX,0x01 //EAX와 1초를 비교한다.
   JB SubLoop  //1초보다 작다면 SubLoop를 계속 돌면서 연산 수행(CPU 사용율 높아지는 주범)
   ADD EAX,EDI  //EAX에는 1이 있는 상태
   INC EDI   //카운트 증가

   MOV DWORD PTR DS:[Sec],EAX //초 단위 시간을 Sec 변수에 넣음
   CMP EAX,060d //60초 비교
   JNE ShowTime
   INC DWORD PTR DS:[Min] //분 단위 1 증가
   MOV DWORD PTR DS:[Sec],0 //초 단위 0으로 초기화
   XOR EDI,EDI //카운트 초기화

   MOV EDX,DWORD PTR DS:[Min]
   CMP EDX,060d //60분 비교
   JNE ShowTime
   INC DWORD PTR DS:[Hour]  //시 단위 1 증가
   MOV DWORD PTR DS:[Min],0 //분 단위 0으로 초기화

   MOV ECX,DWORD PTR DS:[Hour]
   CMP ECX,024d //24시간 비교
   JNE ShowTime
   MOV DWORD PTR DS:[Hour],0 //0 시로 초기화
   MOV DWORD PTR DS:[Min],0 //0 분으로 초기화
   MOV DWORD PTR DS:[Sec],0 //0 초로 초기화
 }
ShowTime:
   system("cls");
   printf("%02d : %02d : %02d\n",Hour,Min,Sec);
   goto EntireLoop; //무한 루프
}

저작자 표시 비영리 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
by Sone 2009.07.31 18:49
| 1 |

티스토리 툴바