2011-03-27 2 views
7

저는 Delphi 2010을 사용하고 있습니다. 델파이에 함수의 프롤로그를 생성하지 말라고 할 수 있습니까?순수 어셈블리로 작성된 함수의 프롤로그 제거

procedure SomeAssembly; stdcall; 
begin 
    asm 
     ... 
    end; 
end; 

을 나는 C++의 __declspec(naked) 기능 등이 기능을위한 프롤로그와 에필로그를 생성하지 델파이 말하고 싶습니다 :이 같은 일부 순수 어셈블리 함수를 쓰고 있어요.

아무도 그들의 시간을 낭비하지 않습니다.이 기능을 작동 시키는데 도움이 필요하지 않습니다. 프롤로그로; 나는 이미 그렇게 할 수있다. 그것은 단지 큰 불편이며 유지 관리를 거칠게 만듭니다. 컴파일러가 생성 한 프롤로그를 수동으로 검사하여 길이를 확인해야하며, 변경하면 프로그램이 중단됩니다.

바이트 배열로 일련의 바이트로 함수를 작성할 수도 있지만, 델파이의 프롤로그 길이를 찾아야하는 것보다 훨씬 더 나 빠질 것입니다.

답변

19

델파이 인수 없는 기능 프롤로그 나 에필로그를 생성레지스터 호출 규칙으로 선언하지 않습니다. 프롤로그없이 함수를 원할 경우, 인수가없는, register-calling-convention 함수로 선언하십시오. 또한 begin - end 블록을 건너 뛰고 어셈블리로 바로 들어가십시오.

procedure SomeAssembly; // register; (implied) 
asm 
    // ... 
end; 

사실 함수의 특성에 대해 거짓말을하고 있기 때문에 까다로울 수 있습니다. 마치 매개 변수를 받고 다른 호출 규칙을 사용하는 것처럼 함수를 구현했다면 컴파일러가 호출 사이트에서이를 알고 있는지 확인해야합니다. 그렇게하려면 선언 된 형식 대신 함수의 "실제"형식을 반영하는 함수 포인터를 선언하십시오. 지금

type 
    TSomeAssemblyFunc = function (Arg1: Integer; Arg2: PAnsiChar): Boolean; stdcall; 
var 
    SomeAssemblyProc: TSomeAssemblyProc; 

을이 함수에 가리 키도록 그 변수를 할당 : 예를 들어, 함수 정말이 인수하고 stdcall 기능의 경우,이 같은 것을 선언

또한
SomeAssemblyProc := TSomeAssemblyProc(@SomeAssembly); 
if SomeAssembly(2, 'foo') then ... 

건너 뛰기로 프롤로그 및 에필로그를 작성하면 컴파일러는이 함수에 대해 (호출 규칙이 다르기 때문에) 잘못된 RET 명령어를 생성하므로 컴파일러의 기본 ret 명령어를 사용하는 대신 코드에 ret 8을 명시해야합니다.

  1. 함수의 시작 부분에 중단 점을 설정 : 당신이 작업 디버거가있는 경우 델파이의 프롤로그의 길이를 찾기


    , 간단하다.

  2. 함수를 호출하십시오.
  3. 디버거가 중단 점에서 중지되면 CPU보기로 전환하십시오.
  4. 프롤로그를 구성하는 지침을보십시오.
  5. 해당 지침 옆에 표시된 바이트 수를 셉니다.
+0

왜 모든 사람이 이렇게 대답하지 못합니까? 대단히 도움이되었습니다, 롭 감사합니다. –

+0

@K. Charles : 전문 지식의 수준이 다른가요? 그것은 야생의 추측 이었지만, 누구에게도 의도 된 위반은 아닙니다. –

+0

함수 포인터가있을 때 추가 수준의 간접 지정이 없습니까? 개인적으로 나는 tasm이 더 적합하다고 생각했을 것입니다. –

0

procedure SomeAssembly; stdcall; 
asm 
    ... 
end; 

이 트릭을하지 않는 이유는 무엇입니까?

+0

올바르게 기억하고 있다면,'stdcall'은 매개 변수가 없더라도 컴파일러가 프레임 포인터를 저장하고 복원하기 위해 프롤로그와 에필로그를 포함하게합니다. –

1

this embarcadero docwiki에 따르면 당신은 건너 뛸 수있는 beginend 주변 컴파일러가 일부 물건 건너 뜁니다. 그러나 정말로 순수한 어셈블러가 필요하다면, 함수를 별도의 어셈블러 파일에 넣고 tasm (exe는 tasm32라고 함)으로 어셈블하고 링크하십시오. 델파이 코드에서 assembler 지시어를 사용합니다.

+0

@downvoters, 설명해주세요. TASM은 Delphi의 일부이며 100 % 순수 어셈블러로 작업하는 자연스러운 방법입니다. 이 전략적 투표가 있었습니까? –

관련 문제