C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
분야별 포럼
C++빌더
델파이
파이어몽키
C/C++
프리파스칼
파이어버드
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

자유게시판
세상 살아가는 이야기들을 나누는 사랑방입니다.
[14981] EIP 레지스터 읽기... 덴장할...
김상구.패패루 [peperu] 4808 읽음    2008-08-27 18:03
최근 중학교때 한 번 된통 당한 이후로 절대로 하지 않겠다고 결심했던 어셈블러를 다시 꺼내게 됐습니다.
뭐, 이유야 어케 됐건... 간단할 것 같았던 상대주소로 jmp하는 코드 하나가 정말 더럽게 해결이 안되네요.

하고 싶은건 컨셉 코드로 말하자면 뭐, 이런겁니다.

asm {
....
jmp [ebx+eip] // 빌더나 VC++에서는 컴파일 안됩니다. eip는 직접 읽기가 안되는군요.
...
}


즉... 현재 위치에서 ebx레지스터에 든 내용만큼 점프하기. 상대주소로 점프하는거죠.
인라인 어셈블러 문법도 잘 모르는 상태에서 다른건 어케 다 만들었는데 저 부분이 해결이 안됩니다.
다른 인라인 어셈블러 문법에서는 $ 부호로 eip를 읽을 수 있는 것도 있더군요.

jmp ebx + $
이런 식으로요.

jmp ebx
물론 이런건 잘 됩니다. 절대주소로 이동하는게 문제지...

만약 eip를 읽어낼 수만 있다면
mov ebx,eip
add ebx, 상대주소
jmp ebx
이런 식으로도 분기할 수 있겠다 싶어서 여기저기 찾아보니 VC에서 eip를 읽어내는 코드가 몇가지 있긴 한데, 방법이 진짜 안습입니다. 함수를 call해서 call 한 위치를 추적해서 얻어낸다든지... 함수 콜 할때 드는 비용이나 그냥 다중 조건분기 쓰는 비용이나 비슷비슷하네요.

암튼.. 지금까지의 결론:
그냥 조건분기 중첩해서 쓰자...

흠냘... 오늘 하루 다 갔네요. 즐프...
이정구 [appleii]   2008-08-27 20:28 X
eip 를 직접 접근할 수 있는 방법은 없죠. jmp ebs + $ 를 디스어셈블 하면 어떻게 될까요?
김상구.패패루 [peperu]   2008-08-27 21:29 X
저도 궁금해요. linux쪽에서 쓰는 문법인지... 어느 컴파일러에서 쓰는 문법인지는 잘 모르겠지만...
김도완 [purplecofe2]   2008-08-28 10:11 X
jmp ebx + $는 아마도

short jump로 아마 -128 ~ 127 주소를 지정할 수 있을 것 같습니다.

EIP를 기반으로 하는 분기 명령이 있는게 아니고 단지 상대 분기일 뿐일겁니다.
김상구.패패루 [peperu]   2008-08-28 10:24 X
조금전에 MSDN에서 VC++2008 문서들을 읽다보니
jne $+5
이런식으로 사용하는게 가능한 것 같군요. $가 현재 위치 (current location counter)를 제공한답니다. (http://msdn.microsoft.com/en-us/library/78cxesy1.aspx)
빌더(2006)에서 같은 코드를 넣어봤더니 역시나 컴파일 에러가 나네요. 흠냘...
short jump는 분명 상대주소로 점프지만... 그건 컴파일러가 알아서 번역하는거 아닌가요?

jmp lbl_mylabel

이렇게 구현해도 lbl_mylabel이 근거리에 있는 경우 실제 OPCODE는 short jump로 번역되는것 같았습니다. 그렇다면 저렇게 $를 지원할 이유가 없어보이는데요...
일단 C++ Builder 2009에서 $를 지원하는지 테스트 해 봐야 겠습니다.

김상구.패패루 [peperu]   2008-08-28 11:02 X
이런걸 하고싶은건데...

void __fastcall VectorArithmetic(float *arr1, float *arr2, int n, int op)
{
    asm {
        dec    ecx   // fastcall 이므로 eax=arr1, edx=arr2, ecx=n 이 들어가 있습니다.
        mov    ebx,op // op는 + = 0. - = 5, * = 10, / = 15
        add    ebx,0x0040312E    // lbl_add:의 주소... 가변적임. 이걸 해결하고잡다...
        jmp    lbl_loopfirstonly
    lbl_loop_begin:
        fstp    dword ptr [eax+ecx*4]
        dec    ecx
        cmp    ecx,0
        jl    lbl_exit
    lbl_loopfirstonly:
        fld    dword ptr [eax+ecx*4]

        jmp    ebx    // op만큼 상대주소 점프
    lbl_add:
        fadd    dword ptr [edx+ecx*4]
        jmp    lbl_loop_begin
    lbl_sub:
        fsubr    dword ptr [edx+ecx*4]
        jmp    lbl_loop_begin
    lbl_mul:
        fmul    dword ptr [edx+ecx*4]
        jmp    lbl_loop_begin
    lbl_div:
        fdivr    dword ptr [edx+ecx*4]
        jmp    lbl_loop_begin
    lbl_exit:
    }
}

김상구.패패루 [peperu]   2008-08-28 11:19 X
꽁수버전... ㅎㅎ
되긴 됩니다.

void __fastcall VectorArithmetic(float *arr1, float *arr2, int n, int op)
{
    static const BYTE* AddrOfVectorArithmetic = (BYTE*)&VectorArithmetic+0x2A;
    __asm {
        dec    ecx
        mov    ebx,AddrOfVectorArithmetic
        add    ebx,op
        jmp    lbl_loopfirstonly
    lbl_loop_begin:
        fstp    dword ptr [eax+ecx*4]
        dec    ecx
        cmp    ecx,0
        jl    lbl_exit
    lbl_loopfirstonly:
        fld    dword ptr [eax+ecx*4]

        jmp    ebx
    lbl_add:
        fadd    dword ptr [edx+ecx*4]
        jmp    lbl_loop_begin
    lbl_sub:
        fsubr    dword ptr [edx+ecx*4]
        jmp    lbl_loop_begin
    lbl_mul:
        fmul    dword ptr [edx+ecx*4]
        jmp    lbl_loop_begin
    lbl_div:
        fdivr    dword ptr [edx+ecx*4]
        jmp    lbl_loop_begin
    lbl_exit:
    }
}

+ -

관련 글 리스트
14981 EIP 레지스터 읽기... 덴장할... 김상구.패패루 4808 2008/08/27
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.