Results 1 to 10 of 19

Thread: Converting ASM to Pascal

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1

    Converting ASM to Pascal

    Since we've got the converting C to Pas thread, I thought some of you are familiar with inline ASM. The reason is that it is obviously 32 bit Assembler. (It is originally written for Delphi but compiles with FPC, too). I want to port the program to 64 bit, so porting to Pascal would be an advantage. Speed issues are no problem. Of course it is also possible to convert the ASM part to 64 bit assembler ... Now here's the piece of code:
    Code:
    asm       push esi               // esi, edi, ebp and ebx must be kept
           push edi               // (we use only esi and edi here).
           sub esp, StkUsage      // make room on stack
           mov edi, esp           // set destination of mem copy, it is the stack
           mov esi, StkAdr        // set source of mem copy, it is Addr(ExtStk)
           mov ecx, StkUsage      // prepare ecx to copy StkUsage bytes
           shr ecx, 2             // divide by 4 to perform DWORD-copy (is faster)
    
    
           //add edi, StkUsage;
           //sub edi,4
           //add esi, StkUsage;
           //sub esi,4
           cld                    // choose copy direction
           rep movsd              // do DWORD-copy
    
    
           cmp RegCall, true
           jnz @@EXEC
           mov EAX, _EAX
           mov EDX, _EDX
           mov ECX, _ECX
    
    
           @@EXEC:
           call Adr               // execute the external function
                                  // esp is restored by the external function
                                  // (except for cdecl-convention)
           pop edi                // restore edi...
           pop esi                // ...and esi
           mov _EAX,eax
         end;                     // asm
    Best regards,
    Cybermonkey

  2. #2
    This just looks like an inefficient string copy routine, it copies string onto stack then calls some other function, i'm guessing it is stdcall, not sure what Adr is or doing in the called function. Note that is aligns memory on 4 bytes for speed copy of dword's but i don't see it writing any left over bytes. Also what is _EAX, _EDX, _ECX ? you need to post all variables used so i can convert it.

    Is RegCall a param? can you post the function declaration?

    Code:
    procedure YourProc(StkAdr: PAnsiChar; StkUsage: LongWord);
    var
    	stkDest: array of AnsiChar;
    	nLen: LongWord;
    begin
    	SetLength(stkDest, stkUsage);
    	StrLCopy(@stkDest[0], stkAdr, StkUsage);
    
    	if RegCall = True then begin
    		//_EAX, _EDX etc ???
    
    		Adr( _EAX, _EDX, _ECX);
    	end else 
    		Adr( ....    // this does not make sense what your function is doing, no params? if so this needs to be cdecl and this function needs to correct the stack.
    end;
    Also if RegCall is false, then your stack is going to become corrupt. Since stdcall requires you pass the params that it expects, you could get away with this with cdecl but not stdcall.
    Last edited by Colin; 18-03-2013 at 05:07 PM.
    Download the Ziron Assembler
    Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message.

  3. #3
    Okay, this is going to be quite long ...
    Code:
    procedure CallFunction(var n:valrec; fi:integer; needResult:boolean);    var arity:integer;
        var descriptors:string;
        var args:TArgs;
        var flag:integer;
        var needBraces:boolean;
        var i:integer;
        var missing:boolean;
    
    
        var stack:array [0..30 { TUNE: }] of integer;
        var sp:integer;
        var _eax,_edx,_ecx:integer;
        var regcount:integer;
        var ltr:boolean;
    
    
    
        var stkusage:integer;
        var stkadr:integer;
        var regcall:boolean;
        var adr:pointer;
        var resadr:pointer;
        var resvalue:integer;
        var needsExtraParam:boolean;
        var isMethod:boolean;
        var obj:TObject;
    
         asm
           push esi               // esi, edi, ebp and ebx must be kept
           push edi               // (we use only esi and edi here).
           sub esp, StkUsage      // make room on stack
           mov edi, esp           // set destination of mem copy, it is the stack
           mov esi, StkAdr        // set source of mem copy, it is Addr(ExtStk)
           mov ecx, StkUsage      // prepare ecx to copy StkUsage bytes
           shr ecx, 2             // divide by 4 to perform DWORD-copy (is faster)
    
    
           //add edi, StkUsage;
           //sub edi,4
           //add esi, StkUsage;
           //sub esi,4
           cld                    // choose copy direction
           rep movsd              // do DWORD-copy
    
    
           cmp RegCall, true
           jnz @@EXEC
           mov EAX, _EAX
           mov EDX, _EDX
           mov ECX, _ECX
    
    
           @@EXEC:
           call Adr               // execute the external function
                                  // esp is restored by the external function
                                  // (except for cdecl-convention)
           pop edi                // restore edi...
           pop esi                // ...and esi
           mov _EAX,eax
         end;                     // asm
    
    
    
    
         // TODO: convert references back
    I hope this is the correct code since there are a lot of nested procedures and functions ...
    Last edited by Cybermonkey; 18-03-2013 at 05:11 PM.
    Best regards,
    Cybermonkey

  4. #4
    OK, so from you routines i see you are needing to deal with low level access, so converting to high level pascal would not be a good idea. What you will need to do is make your integers be nativeint, ie. _EAX, _EDX etc... also change them to _RAX, _RCX etc

    replace your registers for mov to RAX, RCX etc e.g. mov rax, _RAX, the stack on 64-bit is also 16 byte aligned so you can push int64 directly on the stack for stdcall (however i don't recommend it as if the called function is not 64-bit and they do not clean the stack correctly, since they will expect stack on 4 byte alignment this could be a disaster). else you can still use the pascal functions StrLCopy etc for the memory copy to stack it will probably be more efficient.

    some other things to note, for Adr if the called function is fastcall, it will not alter esp for passed params since it does not use the stack, in this case you would need to correct the stack yourself.
    Last edited by Colin; 18-03-2013 at 05:39 PM.
    Download the Ziron Assembler
    Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message.

  5. #5
    Ok, thanks, but I have no clue what you are talking about. The complete code is not by me but by someone else, I just wanted the program to compile with 64 bit Freepascal ...
    Best regards,
    Cybermonkey

  6. #6
    if the functions that are called by "CallFunction" are 32-bit libraries functions etc, then you should not have a problem to compile this on 64-bit pascal, but if you re-compile the libs it calls into 64-bit then you will have a-lot of work ahead.

    What i would suggest is to rename this function to CallFunctionX86(... and make sure all pointers and variables used are 32-bit standard, e.g. pointer should be 32-bit pointer (i don't use freepascal dunno which you will need to use)

    then you can create a new function CallFunctionX64(

    This would be similar but using 64-bit variables and registers.
    Last edited by Colin; 18-03-2013 at 05:51 PM.
    Download the Ziron Assembler
    Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •