AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Machine code functions: Bit Wizardry
Goto page Previous  1, 2, 3 ... 11, 12, 13 ... 22, 23, 24  Next
 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Lexikos



Joined: 17 Oct 2006
Posts: 7299
Location: Australia

PostPosted: Fri Mar 21, 2008 12:45 am    Post subject: Reply with quote

It is even possible to load a DLL from memory, so I wouldn't rule this out...
Quote:
Usually, branches (like goto) are self-relative, but function calls are absolute
I think this is typically only true of imported functions. I'd post an example demonstrating that basic calls are relative, but it is too boring. Smile From script2.cpp, BIF_RegisterCallback:
Code:
   // ... In essence:
   //    call xxx ; is relative
   //    call [ptr_xxx] ; is position independent
   // Typically the latter is used when calling imported functions, etc., as only the pointers (import table),
   // need to be adjusted, not the calls themselves...
Back to top
View user's profile Send private message Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Fri Mar 21, 2008 2:19 am    Post subject: Reply with quote

In my experiences with floating point functions VS’05 generated relative calls to functions for each arithmetic operation, but they were scattered around in the code. One could copy the referenced ones after the user function, but patching the addresses is tedious. Also, some of the library functions call each other, which necessitate further address patches. After a couple days of struggle I gave up, and wrote my own little library, but either way it is a lot of work. Automating it is like writing a little private linker.
Back to top
View user's profile Send private message
Azerty



Joined: 19 Dec 2006
Posts: 72
Location: France

PostPosted: Fri Mar 21, 2008 8:21 am    Post subject: Reply with quote

Lexikos wrote:
It is even possible to load a DLL from memory, so I wouldn't rule this out...


Of course, everything is possible using a computer (please note italics, take the sentence correcly, my computer doesn't wash my underwear...), but at what cost ? The URL you pointed is very interesting, but the code is still beta (v0.0.2)... and is 16 Kbytes C source... To translate it in AHK will for sure be possible, but what will the cost (in CPU cycles) be ?...
Though when I have time, I might dig it further to make an MCoded AHK lib... Wink

Laszlo wrote:
... but they were scattered around in the code ...

Might be due to optimization : I've studied the way VC works when compiling in RELEASE mode : it takes into account the CPU costs of memory accesses, so for instance, if you memset(mem,size,0) with size arg being low (20 or 30 for instance), the optimizer inlines it into several MOV which are in disorder, probably to optimize L1 cache usage. If you want code to be consistant and readable, better export DEBUG mode generated code.
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 8688

PostPosted: Fri Mar 21, 2008 9:08 pm    Post subject: Reply with quote

@Laszlo

Sir,
Can you provide me machine code for Base64 Decoder ?.
This C link looks promising : http://base64.sourceforge.net/b64.c

I tried my best with C++ : http://www.codeproject.com/KB/cpp/base64coding.aspx
It is not working though I successfully converted the function to be standalone. Sad

I do not need Encoder, though it would be handy if we have the pair together.

Rolling Eyes
Back to top
View user's profile Send private message Send e-mail
SKAN



Joined: 26 Dec 2005
Posts: 8688

PostPosted: Sat Mar 22, 2008 6:45 am    Post subject: Reply with quote

Lexikos wrote:
It is even possible to load a DLL from memory, so I wouldn't rule this out...


Azerty wrote:
To translate it in AHK will for sure be possible, but what will the cost (in CPU cycles) be ?...
Though when I have time, I might dig it further to make an MCoded AHK lib...


I compiled MemoryModule and the resultant file was 152 KB !!!
As is, it is unusable from AHK. It would be fantastic If some one can make it work, and also shrink the machine code to 50-100 K.

50K for this DLL Loader ( Loaded as a Resource )
50K for some useful external DLL ( Loaded as a Resource )
200K regular AHK Executable overhead

.. would still result in a no-dependency-whatsoever-standalone-executable under half MB.

Please share my enthusiasm. Smile
Back to top
View user's profile Send private message Send e-mail
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Sat Mar 22, 2008 8:28 pm    Post subject: base64 en/decode Reply with quote

Here are my base64 conversion routines in C, using the decoding idea of Bob Trower, http://base64.sourceforge.net/b64.c.
Code:
void encode( UChar *src, UChar *dest, UInt32 linesize, const UChar *cb ) { // base64 encode with padding, line breaks
    UChar in[3];
    UInt32 i, len, blocksout = 0;
    linesize >>= 2;

    while( *src > 0 ) {
        len = 0;
        for( i = 0; i < 3; ++i ) {
            in[i] = *src;
            if( *src > 0) { ++len; ++src; }
            else in[i] = 0;
        }
        *dest++ = cb[ in[0] >> 2 ];
        *dest++ = cb[ ((in[0]<<4) | (in[1]>>4)) & 63];
        *dest++ = len > 1 ? cb[ ((in[1]<<2) | (in[2]>>6)) & 63 ] : '=';
        *dest++ = len > 2 ? cb[ in[2] & 63 ] : '=';

        blocksout++;
        if( blocksout >= linesize ) {
            *dest++ = 10; // CR
            blocksout = 0;
        }
        *dest = 0;
    }
}

UInt32 decode( UChar *src, UChar *dest, const UChar *cd ) { // decode base64, discard padding, line breaks, noise
    int i, len; UInt32 total = 0;
    UChar in[4], v;

    while( *src > 0) {
        len = 0;
        for( i = 0; (i < 4) && (*src > 0); ++i ) {
            v = 0;
            while( (*src > 0) && (v == 0) ) {
                v = *src++;
                v = ((v < 43) || (v > 122)) ? '$' : cd[v-43];
                v = (v == '$') ? 0 : (v - 61);
            }
            if( v > 0 ) {
                ++len;
                in[i] = v - 1;
            }
            else in[i] = 0;
        }
        if( len < 2) break;
        *dest++ = in[0] << 2 | in[1] >> 4;
        if (len > 2) *dest++ = in[1] << 4 | in[2] >> 2;
        if (len > 3) *dest++ = in[2] << 6 | in[3];
        total += len-1;
    }
    return total;
}
The compiled code in AHK is:
Code:
MCode(decode64, "558bec518365fc00568b75088a1684d20f86ac000000578b7d0c5333db33c0"
. "84d2764d32c984c975318aca80e92b4680f94f770c0fb6ca8b55108a4c11d5eb02b1240fb6d1"
. "80ea3d80f9240f94c1fec923ca8a1684d277cd84c9760943fec9884c0508eb05c64405080040"
. "83f8047caf83fb027c4b8a45098a4d08c0e102c0e8040ac18a4d0a88074783fb027e108a5509"
. "8ac1c0e802c0e2040ac288074783fb037e09c0e1060a4d0b880f478b45fc8a1684d28d4418ff"
. "8945fc0f875bffffff5b5f8b45fc5ec9c3")
MCode(encode64, "558bec51518b45088365f800c16d10028038000f86ac0000008b450c53568b"
. "75145733db33ff8b4d088a1184d28d4c3dfc8811760643ff4508eb03c601004783ff0372e20f"
. "b64dfc8bd1c1ea028a143288100fb655fdc1e1048bfac1ef040bf983e73f8a0c374088088a4d"
. "fe4083fb0176140fb6f9c1e202c1ef060bfa83e73f0fb61437eb036a3d5a88104083fb027609"
. "83e13f0fb60c31eb036a3d59880840ff45f88b4df83b4d107208c6000a408365f8008b4d08c6"
. "00008039000f8760ffffff5f5e5bc9c3")
It needs two small tables coded in strings:
Code:
CB=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
CD=|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\]^_``abcdefghijklmnopq
You can test it, by attaching the following commands to the above:
Code:
MCode(ByRef code, hex) { ; allocate memory and write Machine Code there
   VarSetCapacity(code,StrLen(hex)//2)
   Loop % StrLen(hex)//2
      NumPut("0x" . SubStr(hex,2*A_Index-1,2), code, A_Index-1, "Char")
}

In =
( Join
Man is distinguished, not only by his reason, but by this singular passion from other animals,
 which is a lust of the mind, that by a perseverance of delight in the continued and
 indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.
)
Out =
(
TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0
aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1
c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0
aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdl
LCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=
)

VarSetCapacity(Out1,Ceil(StrLen(In)*(4/3+1/72)+1))
dllcall(&encode64, "UInt",&In, "str",Out1, "Uint",72, "str",CB, "CDECL")

MsgBox % (Out1==Out ? "Correct`n`n" : "Wrong`n`n") . Out1

VarSetCapacity(In1,ceil(StrLen(Out)*3/4)+1,0)
len := dllcall(&decode64, "str",Out, "UInt",&In1, "str",CD, "CDECL UINT")
VarSetCapacity(In1,-1)
MsgBox % "Length =" . len . " / ErrorLevel: " . ErrorLevel . "`n" . (In1==In ? "Correct`n`n" : "Wrong`n`n") . In1
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 8688

PostPosted: Sat Mar 22, 2008 9:14 pm    Post subject: Reply with quote

Many thanks Sir. I am grateful to you .. as always.

Very Happy Very Happy

You example works fine..

One doubt: Is magic number 72 a variable ? I usually wrap my code at 90 chars and here - I believe this number should be divisible by both 4 and 3 ...

Smile
Back to top
View user's profile Send private message Send e-mail
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Sat Mar 22, 2008 10:18 pm    Post subject: Reply with quote

This number is divided by 4 to specify the number of 4-character blocks in a line. If you set it to 0xffffffff (-1), there will be no new lines. If you set it to 90, 88 characters will appear in every line, except the last one.
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 8688

PostPosted: Sat Mar 22, 2008 10:40 pm    Post subject: Reply with quote

Thanks for the clarification, Sir. Smile
I will stress-test it and revert back by Monday.

I had been facing random problems with ASCII 85 .. like the first Char of any line in continuation section should not be ) etc..
But the real problem was intermittently created by the presence of =

I guess there should not be a problem with B64 since = will appear only on the tail of the last chunk..

Have a nice weekend. Smile
Back to top
View user's profile Send private message Send e-mail
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Sat Mar 22, 2008 10:54 pm    Post subject: Reply with quote

If you don’t want to follow the standard, you could easily modify the ascii85 algorithm: the first character used should be * (ascii 42), the last one is ~ (ascii126). This range is also 85 characters long, but avoids most of the problematic characters. The only thing you have to remember is to use literal backtick characters. For repeated 0's there are safe characters: $, !, etc.
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 8688

PostPosted: Sun Apr 06, 2008 8:15 am    Post subject: Reply with quote

@Laszlo:

Sir, it would be of immense help if we had a flip() function to deal with big-endian byte order ( motorola byte align )

I have been writing Exif Tag interpreter and exif tags can be encoded use any of the byte order. Excluding ascii data, 95% ( of the rest of data ) are ushort/ulong which I am able to deal with your BSwap16/BSwap32 mcode. But there is this "undefined" tag type on which TIFF specification does not imply any size limit. I am handling it like in the following example:

Code:
flip( Var := "Quick", 5 )
MsgBox, % Var

flip( byref var, sz ) {
  varsetcapacity( var2,sz )
  loop %sz% ; move it to var2 in reverse order
    numput( numget(var,a_index-1,"uchar"), var2, sz-a_index, "uchar" )
  loop %sz% ; copy var2 to var1
    numput( numget(var2,a_index-1,"uchar"), var, a_index-1,"uchar" )
  varsetcapacity(var2,0)
return &var   
}


Overall, I find my code is slower when dealing with Motorola byte aligned jpeg files.
If you can give me mcode for flip, it should take care of all the needs.

Please help.

Smile
Back to top
View user's profile Send private message Send e-mail
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Sun Apr 06, 2008 8:15 pm    Post subject: Reply with quote

The following C code was compiled:
Code:
rev_bytes(char* dest, char* source, int n) {
   int i = 0, j = n;
   for (;i<n;) dest[i++] = source[--j];
}
From AHK call it with
Code:
MCode(rev,"568b74241033c985f67e178b44240c03c6578b7c240c488a10881439413bce7cf15f5ec3")

MCode(ByRef code, hex) { ; allocate memory and write Machine Code there
   VarSetCapacity(code,StrLen(hex)//2)
   Loop % StrLen(hex)//2
      NumPut("0x" . SubStr(hex,2*A_Index-1,2), code, A_Index-1, "Char")
}

In = Quick
Out := In ; allocate memory with terminating NUL
dllcall(&rev,"UInt",&Out, "UInt",&In, "UInt",5, "CDECL") ; Reverse byte sequence
MsgBox % "[" Out "]"
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 8688

PostPosted: Sun Apr 06, 2008 9:40 pm    Post subject: Reply with quote

Many thanks, Sir Very Happy

I have one more request: Cannot my model Flip() be exactly reproduced ?
That is in/out should be the same variable ..
It would be very beneficial if the same variable is operated upon, as it would simplify my code much if the variable name stays the same. I cannot assign it back to the source variable as the contents would contain null.

The workaround I can think of: Use your memcpy mcode to assign the reversed contents back to the original var.. but I would be very happy if rev handles the memcpy itself.

Please help. Smile
Back to top
View user's profile Send private message Send e-mail
Laszlo



Joined: 14 Feb 2005
Posts: 4710
Location: Boulder, CO

PostPosted: Sun Apr 06, 2008 11:12 pm    Post subject: Reply with quote

The C code for in-place reversal:
Code:
rev_bytes(char* d, int n) { // Reverse byte sequence
   char t, *c = d+n;
   while (c > d) { t = *--c; *c = *d; *d++ = t; }
}
From AHK call it with:
Code:
MCode(flip,"8b4c24048b44240803c13bc17610538a19488a1088188811413bc177f25bc3")

MCode(ByRef code, hex) { ; allocate memory and write Machine Code there
   VarSetCapacity(code,StrLen(hex)//2)
   Loop % StrLen(hex)//2
      NumPut("0x" . SubStr(hex,2*A_Index-1,2), code, A_Index-1, "Char")
}

In = Quick
dllcall(&flip,"UInt",&In, "UInt",5, "CDECL") ; Reverse byte sequence
MsgBox [%In%]
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 8688

PostPosted: Mon Apr 07, 2008 12:07 am    Post subject: Reply with quote

Many thanks, Sir. Very Happy Very Happy Very Happy

I have adapted the machine code as follows:

Code:
  VarSetCapacity( flip,32,00 ), Numput( 0x04244C8B,flip,00 ), Numput( 0x0824448B,flip,04 )
  Numput( 0xC13BC103,flip,08 ), Numput( 0x8A531076,flip,12 ), Numput( 0x108A4819,flip,16 )
  Numput( 0x11881888,flip,20 ), Numput( 0x77C13B41,flip,24 ), Numput( 0x00C35BF2,flip,28 )

  In = Quick
  dllcall(&flip,"UInt",&In, "UInt",5, "CDECL") ; Reverse byte sequence
  MsgBox [%In%]


Smile

Edit: 2010-May-21

Thanks to DerRaphael for mCode UDF Benchmarking, machine code is now 'load-time optimised'
Flip() is renamed to original: rev_bytes()
Code:
 ; Machine code for Byte-stream reversal                                 -  by Laszlo Hars
 varsetcapacity(rev_bytes,32), numput( 0x00C35BF2, numput( 0x00C35BF2, numput( 0x00C35BF2
        , numput( 0x77C13B41, numput( 0x11881888, numput( 0x108A4819, numput( 0x8A531076
       , numput( 0xC13BC103, numput( 0x0824448B, numput( 0x04244C8B, rev_bytes ))))))))))
 ; C source and Hex for rev_bytes() www.autohotkey.com/forum/viewtopic.php?p=189469#189469

 ;Usage example follows:
 In = The Quick Brown Fox
 dllcall( &rev_bytes, UInt,&In, UInt,19, "cdecl" ) ; Reverse byte sequence
 MsgBox <%In%>


Last edited by SKAN on Fri May 21, 2010 9:13 am; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3 ... 11, 12, 13 ... 22, 23, 24  Next
Page 12 of 24

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group