title: Call Object Method using ASM -- Part 2
body: <p>This question is based on a <a href="https://stackoverflow.com/questions/9453238/call-object-method-using-asm">previous</a>, but that's just FYI.</p>
  
  <p>I've managed to get it working, however, I've found something that's not clear to me, so if anyone can explain the following behaviour, it would be awesome.</p>
  
  <p>I have the following class:</p>
  
  <pre><code>type
    TMyObj = class
    published
      procedure testex(const s: string; const i: integer);
    end;
  
  procedure TMyObj.testex(const s: string; const i: integer);
  begin
    ShowMessage(s + IntToStr(i));
  end;
  </code></pre>
  
  <p>and the following two procedures:</p>
  
  <pre><code>procedure CallObjMethWorking(AMethod: TMethod; const AStrValue: string; const AIntValue: Integer);
  begin
    asm
      PUSH DWORD PTR AIntValue;
      PUSH DWORD PTR AStrValue;
      CALL AMethod.Code;
    end;
  end;
  
  procedure CallObjMethNOTWorking(AInstance, ACode: Pointer; const AStrValue: string; const AIntValue: Integer);
  begin
    asm
      MOV EAX, AInstance;
      PUSH DWORD PTR AIntValue;
      PUSH DWORD PTR AStrValue;
      CALL ACode;
    end;
  end;
  </code></pre>
  
  <p>In order to test the working version, one needs to call the following:</p>
  
  <pre><code>procedure ...;
  var
    LObj: TMyObj;
    LMethod: TMethod;
    LStrVal: string;
    LIntVal: Integer;
  begin
    LObj := TMyObj.Create;
    try
      LMethod.Data := Pointer( LObj );
      LMethod.Code := LObj.MethodAddress('testex');
  
      LStrVal := 'The year is:' + sLineBreak;
      LIntVal := 2012;
  
      CallObjMethWorking(LMethod, LStrVal, LIntVal);
    finally
      LObj.Free;
    end; // tryf
  end;
  </code></pre>
  
  <p>and in order to test the <strong>NOT</strong> working version:</p>
  
  <pre><code>procedure ...;
  var
    LObj: TMyObj;
    LCode: Pointer;
    LData: Pointer;
    LStrVal: string;
    LIntVal: Integer;
  begin
    LObj := TMyObj.Create;
    try
      LData := Pointer( LObj );
      LCode := LObj.MethodAddress('testex');
  
      LStrVal := 'The year is:' + sLineBreak;
      LIntVal := 2012;
  
      CallObjMethNOTWorking(LData, LCode, LStrVal, LIntVal);
    finally
      LObj.Free;
    end; // tryf
  end;
  </code></pre>
  
  <p>And finally the question: why isn't <strong>CallObjMethNOTWorking</strong> working, while <strong>CallObjMethWorking</strong> is? I'm guessing that there's something special in how the compiler treats TMethod... but since my assembly knowledge is limited, I can't understand it.</p>
  
  <p>I would highly appreciate if someone could explain this to me, thank you!</p>