티스토리 툴바



일단, 기본 어셈 사용법입니다.

__asm 한줄명령어

__asm { } 의 다중 명렁어


완전 저수준의 어셈과는 다르게 레지스터 조작만이 아닌
아래처럼 코딩중에 사용하던 변수도 컨트롤 가능합니다.


int acestring(int a, int b, int *c)
{
__asm
{
mov eax, a
mov ebx, b
mov ecx, c
}
}


__stdcall 형태의 함수가 기본적으로 생성될때는 대개 이런 형태입니다. (함수에서 스택의 정리를 행함)

push ebp
mov ebp, esp
.........
.........
pop ebp
ret 혹은 retn ??h (인자크기)
※ vs에서는 __cdecl 가변인자 지원 (함수를 호출한 곳에서 스택을 정리)가 기본값입니다. 컴파일러 옵션에서 변경가능합니다.

!!! 단, vs 컴파일러의 최적화-최적화가 켜져 있는 경우(기본값 : 켜짐) 스택의 최적화도 이루어지므로

일반적으로 생각할 수 있는 인자의 크기가 (int *2) 8바이트가 되는 경우에
retn 8h 형태의 리턴 코드가 이루어지리라는 예측과 달리
최적화된 리턴 인자의 크기가 코드로 생성되므로, 함수 선언후 전체를 __asm 형태로 구성할 때에
인자를 ebp+? 형태로 접근하는 방식은 주의를 요구합니다.

해결법은 스택 초기화를 제외하여 고정된 형태의 코드를 생성하던가
첫글에 변수도 조작가능하다는 점을 이용해서 변수를 통해 인자의 접근을 하면 됩니다.
※ 자주 쓰는 함수의 경우는 아에 라이브러리 프로젝트를 통해서 최적화를 원천적으로 막는 방법도 있습니다.


!! 또한 최적화-인라인 함수 확장 이라는 설정의 기본값은 -> 변환가능한 형태는 전부 인라인으로 변경이므로
이는 함수 작동 자체를 위의 예제처럼 전부 어셈으로 할 경우 에러가 발생할 확률이 굉장히 높아지므로
이를 변경하여 명시적인 경우에만 반응하게 하던가 코드를 수정하던가 해야 합니다.

또한 레지스터의 값의 경우 mov 같은걸로 생성된 코드를 디버깅 해보면 알겠지만
컴파일러에서 어셈 소스를 보고 필요한 push , pop 레지스터복원을 시도하는 코드를 넣어주므로
인라인 어셈으로 함수를 최적화 하고 싶다면 함수는 선언만 하고 내부는 아에 어셈으로 하고 디버깅으로 최적화 하는 방법과

일단 C, C++ 코딩을 행한후 , 빌드 옵션에 어셈블러 출력을 해두고 그것을 최적화 시켜서 인라인 어셈 코드로 변경시켜도 되겠습니다.
이 방법 역시 레지스터의 복원과 관련해서 컴파일러에서 추가해줄 가능성이 있으므로 중복 복원이 안되게 고쳐야합니다.

어셈 명령어 내부에서의 레지스터 주 사용 용도

EAX : 나눗셈, 곱셈, 함수의 리턴값
EBX : EBP 레지스터처럼 주소 관련
ECX : 반복문의 카운터 예) while (0 != ECX)
EDX : 나눗셈, 곱셈
ESI : 함수의 호출 주소, 소스 파일의 주소(input)
EDI : 소스 파일의 주소(output), 함수의 호출 주소

EBP : 함수 안에서의 스택 관리 보조 (함수안에서의 스택 공간 할당을 한후 원래의 ESP로 복원 시키기 위해 사용)
예)
push ebp ; 함수 선언부
mov ebp, esp
sub esp, ??h (일정 변수 공간을 만듬)
........

mov esp, ebp (ESP 레지스터를 복원)
retn ??h

ESP : 프로그램의 스택 관리
EIP : 실행될 주소(명령어 실행중인 라인)
--------------------------------------



unsigned char* src = ?;
unsigned char* dst = ?;
int i = 50;
for(; 0 != i; --i)
*dst++ = *src++;

의 코드가 있다면

__asm {
mov esi, src
mov edi, dst
mov ecx, i
cld
rep movsb
}

이런 형태가 되겠고 만약에 이게 함수라면 자동으로 아래 레지스터 복원 코드가 들어갑니다. (컴파일러에 따라 추가되지 않을 가능성이 있지만, VC 8 이상 버전이라면 들어갑니다)

push esi
push edi
...
pop edi
pop esi

이런 추가 코드들이 있기 때문에 우선은 수동으로 입력했다가 디버깅으로 보고 중복을 삭제하는 것도 나쁘지는 않습니다.
저작자 표시 비영리 동일 조건 변경 허락
크리에이티브 커먼즈 라이선스
Creative Commons License

'勉強しよ' 카테고리의 다른 글

C, C++에서 어셈 사용하기 주의할점  (0) 2011/12/13
윈도우 프로그래밍 기본  (0) 2008/12/06
CreateFile 로 파일 컨트롤 할때  (0) 2008/12/02
VC++ 프로젝트 속성 관련  (2) 2008/11/03
어셈 명령어  (2) 2008/10/27
프로그래스바  (0) 2008/09/09
Posted by 단풍 ZeroHz

트랙백 주소 :: http://zerohz.tistory.com/trackback/105 관련글 쓰기

댓글을 달아 주세요