basicprogramming.org


Welcome, Guest. Please login or register.
Did you miss your activation email?
Forum time; Jul 31. 2010, 04:31
Home Help Search Calendar Login Register
News: Have you got suggestions for BasicProgramming.org? Let's hear them!
Interested in creating your own programming language? Check out the QDepartment group!

+  BASIC programming forum
|-+  Basic Coding
| |-+  Basic Interpreters.
| | |-+  How to make bind
0 Members and 1 Guest are viewing this topic. « previous next »
Pages: 1 [2] Go Down Reply Print
Author Topic: How to make bind  (Read 592 times)
rdc
Sr. Member
****
Offline Offline

Posts: 289


Clark Productions


WWW
« Reply #15 on: Dec 07. 2009, 17:15 » Reply with quote

I wrote a binder for my AtomVM. Here is the binder code in Delphi:

Code:
program bindercl;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  fvm, fsource, fexe: string;
  fname, fpath: string;

procedure bind;
var
   fin, fout: file of Byte;
   bread: Byte;
   vmsize, size: Longint;
   i: integer;
   faname, fsname, foutname: string;
   tag: string;
begin
   //get the atomvm path
   faname := fvm;
   //get the source path
   fsname := fsource;
   //get the output file name
   foutname := fexe;
   //copy over the runtime
   if (Length(faname) > 0) and (Length(foutname) > 0 ) and (Length(fsname) > 0 ) then begin
      try
        //open the vm
        AssignFile(fin, faname);
        Reset(fin);
        //get the file size
        size := FileSize(fin);
        vmsize := size;
        //create the out file.
        AssignFile(fout, foutname);
        Rewrite(fout);
        writeln('Writing VM...');
        while not eof(fin) do begin
          Read(fin, bread);
          Write(fout, bread);
        end;
        CloseFile(fin);
        //open the source
        AssignFile(fin, fsname);
        Reset(fin);
        //get the file size
        size := FileSize(fin);
        //write out the source
        writeln('Writing Source...');
        while not eof(fin) do begin
          Read(fin, bread);
          Write(fout, bread);
        end;
        //Set the tag
        writeln('Writing Tag...');
        tag := 'atabind' + IntToStr(vmsize);
        //pad the tag to 20 spaces
        tag := tag + StringOfChar(' ', 20 - Length(tag));
        //write out the tag
        for i := 1 to 20 do begin
          bread := Byte(tag[i]);
          Write(fout, bread);
        end;
        Beep;
        writeln('Done!');
      finally
        CloseFile(fin);
        CloseFile(fout);
      end;
   end;
end;

begin
    //get the command line parameters
    if ParamCount < 3 then begin
        Beep;
        writeln('ERROR: Not enough paramaters.');
        writeln('Useage: bindercl [path]/atomvm.exe [path]/source.ata [path]/outfile.exe');
    end
    else begin
        //get the comamnd line
        fvm := ParamStr(1);
        fsource := ParamStr(2);
        fexe := ParamStr(3);
        //validate the path and file names.
        if not FileExists(fvm) then begin
            Beep;
            writeln('Cannot find file ',fvm);
        end
        else begin
            if not FileExists(fsource) then begin
                Beep;
                writeln('Cannot find file ',fvm);
            end
            else begin
                bind;
            end;
        end;
    end;


end.

What I do here is copy over the VM exe from a stub file (an exe that is marked as a dat file). I then append the source file to the end of the exe file. I then write a 20 byte tag that starts with "atabind" the magic word, and the size of the VM file. You need to size of the VM file when reading the source file.

Here is where I read in the source from the bind.

Code:
         //Get the exe name.
          exename := ParamStr(0);
         //Check for bind tag at end of file. Should be 'atabind' + vm filesize + padding (20 chars total).
         try
           AssignFile(fin, exename);
           FileMode := fmOpenRead;
           Reset(fin);
           size := FileSize(fin);
           //calc the tag start position
           offset := size - 20;
           Seek(fin, offset);
           //get the tag info
           while not eof(fin) do begin
             Read(fin, bread);
             tag := tag + Char(bread);
           end;
           //Do we have a tag?
           if Pos('atabind', tag) > 0 then begin
             //get the offset of the source code
             tmp := RightStr(tag, 13);
             tmp := Trim(tmp);
             offset := StrToInt(tmp);
             //Make sure we have a valid offset
             if offset > 0 then begin
               Reset(fin);
               //Seek to source code position
               Seek(fin, offset);
               //load source code. Lines delimited by linefeed (10)
               for i := offset to size - 20 do begin
                 Read(fin, bread);
                 lin := lin + Char(bread);
                 //look for line delimiter
                 if bread = 10 then begin
                   //trim any spaces
                   wlin := Trim(lin);
                   //parse the current line of source
                   ok := LoadLine(wlin);
                   if ok = false then begin
                     break;
                   end;
                   //clear input line
                   lin := '';
                 end;
               end;
             end;
           end

Here I first look at the last 20 bytes of the file. If it has the magic word, atabind then I load the offset of the source file in the exe which is the size of the VM I stored earlier. I then seek to that position in the exe file, and start reading in the source lines until I reach the last 20 bytes of the file. Each line is delimited by chr(10) so I know I have a full line when I read a chr(10). I store each line in a array and then process the source file the same as if it was loaded via the command line.


« Last Edit: Dec 07. 2009, 17:17 by rdc » Report to moderator   Logged

aurelB
Hero Member
*****
Offline Offline

Posts: 663



WWW
« Reply #16 on: Dec 08. 2009, 07:09 » Reply with quote

Thanks RDC Wink
Report to moderator   Logged

aurelB
Hero Member
*****
Offline Offline

Posts: 663



WWW
« Reply #17 on: Feb 11. 2010, 14:10 » Reply with quote

Hi alll...
I finaly make binded exe in 3 step.
1. Load runtime exe to memory-
2 .Load source code to memory
3.Open new file as binary and
write membuffer(exe)
write membuffer(src)
This is little bit written as pseudocode.

So i now have problem how to find name of new exe?

In RDC example he use
Code:
//Get the exe name.
          exename := ParamStr(0);

What is the ParamStr Huh?
Is this some kind of WinApi or something else.
Any help...
Report to moderator   Logged

Derek
Administrator
Hero Member
*****
Offline Offline

Posts: 1001



WWW
« Reply #18 on: Feb 11. 2010, 15:06 » Reply with quote

Hi,
Code:
if ParamCount < 3 then begin
        Beep;
        writeln('ERROR: Not enough paramaters.');
        writeln('Useage: bindercl [path]/atomvm.exe [path]/source.ata [path]/outfile.exe');
    end
I assume to run that program you would need to run it from the command line with something like:
Code:
bindercl c:\path\to\atomvm.exe c:\path\to\source.ata c:\path\to\outfile.exe
I doubt it's any kind of WINApi but the Delphi method of retrieving paramters passed to the program on the command line (note the name of program bindercl which I assume means binder command line).

Derek.
« Last Edit: Feb 11. 2010, 15:06 by Derek » Report to moderator   Logged

wget http://*
rdc
Sr. Member
****
Offline Offline

Posts: 289


Clark Productions


WWW
« Reply #19 on: Feb 11. 2010, 19:01 » Reply with quote

Derek is correct. ParamStr is just the command line handler for Delphi. In FreeBasic it would be Command. From the wiki:

Code:
''
'' command-line arguments example
''

     Print "exe name= "; Command( 0 )

     Dim argc As Integer, argv As String

     argc = 1
     Do
         argv = Command( argc )

         If( Len( argv ) = 0 ) Then
             Exit Do
         End If

         Print "arg"; argc; " = """; argv; """"

         argc += 1
     Loop

     If( argc = 1 ) Then
         Print "(no arguments)"
     End If
     Print "The complete list: ";Command


If you are not using the command line you would need to query the user for the exe name to use.

Report to moderator   Logged

aurelB
Hero Member
*****
Offline Offline

Posts: 663



WWW
« Reply #20 on: Feb 12. 2010, 03:10 » Reply with quote

Thank you guys but there is API which can retrive exe name .
Sapero help me again.
I guess that might work but i dont know right api shape.
So this is right way:
Code:
declare "kernel32", GetModuleFileNameA(module:int, path:string, stringsize:int)
def path:istring[260]
GetModuleFileNameA(0, path, 260)
In string path is full qualified path (name of exe).
So whaen i run program this api tell me which exe is open then i open
this exe in binary and only i need starting position of source code on the end
of exe.
Report to moderator   Logged

Derek
Administrator
Hero Member
*****
Offline Offline

Posts: 1001



WWW
« Reply #21 on: Feb 15. 2010, 10:46 » Reply with quote

Hi,

I've just tried running this program with AurelBASIC on Linux using the Windows emulator "wine". Sadly I get an error "Window not created" which is probably due to the fact that I'm not running it on a Windows PC. So I'm afraid I can't test it for you Sad

Derek.
Report to moderator   Logged

wget http://*
Pages: 1 [2] Go Up Reply Print 
« previous next »
Jump to:  
Atom RDF RSS 0.91 RSS 2.0


Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2008, Simple Machines LLC Valid XHTML 1.0! Valid CSS!