Code Examples


This page will contain code examples and sniplets as they relate to my projects with HLA and HIDE.

To get a more general range of examples, download the hlaexamples package or visit the sample code page below.

http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/HighLevelAsm/HLAv2.14/hlaexamples.zip

http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/HighLevelAsm/hla_examples/index.html

tConfig Demo -writing configuration files

posted Jan 17, 2011, 12:19 PM by Sevag Krikorian

This is a demonstration of the tConfig class found in hidelib.lib
To use it, you'll need to include "hide/hidelib.hhf" and link with hidelib.lib

Using tConfig, creating and saving settings into configuration files becomes easy.  Various functions and methods are shown in the demo, but the library contains many more functions such as the ability to read and write entire sections, store binary files, etc.
See the hidelib manual for a full description of all the methods.

program configdemo;

    // build with
    // hla configdemo hidelib.lib
    // or use Make in HIDE

    #includeonce( "stdlib.hhf" )
    #includeonce( "hide/hidelib.hhf" )

type
    rec:record
        one    :uns32;
        two    :dword;
    endrecord;
   
static
    config    :tConfig;
    rec0    :rec := rec:[ 100, $100 ];
    config2    :tConfig;
    rec1    :rec;
   
begin configdemo;

    // create a new config, or load an existing one
    config.create( "configdemo.ini" );
   
    // write some data in sections
    // various number types
    config.writeUns( "Numbers", "Unsigned", 1 );
    config.writeInt( "Numbers", "Integer", -1 );
    config.writeHex( "Numbers", "Hex", $faa );
   
    // various data types
    config.writeString( "Data", "String", "Sample String" );
    config.writeBin( "Data", "Record", &rec0, @size(rec) );
    config.writeBool( "Data", "Boolean", true );
   
    // item types
    config.writeItem( "Items",  0, "Item 1" );
    config.writeItem( "Items", 1, "Item 2" );
   
    // also, write in a token type item.
    config.writeItem( "Items", 2, "token0, token1, token2, token3" );
   
    // save it to file
    config.writeFile();
    config.destroy();
   
    // now start a new config object and read what we wrote
    // in the file.
    config2.create( "configdemo.ini" );
   
    config2.readUns( "Numbers", "Unsigned" );
    stdout.put( (type uns32 eax ), nl );
    config2.readInt( "Numbers", "Integer" );
    stdout.put( (type int32 eax ), nl );
    config2.readHex( "Numbers", "Hex" );
    stdout.put( eax, nl );
    config2.readString( "Data", "String", hide.strbuf );
    stdout.put( hide.strbuf, nl );
    config2.readBin( "Data", "Record", &rec1, @size(rec) );
    stdout.put( ">", rec1.one, nl, ">>", rec1.two, nl );
    config2.readBool( "Data", "Boolean" );
    stdout.put( (type boolean al), nl );
    config2.readItem( "Items", 0, hide.strbuf );
    stdout.put( hide.strbuf, nl );
    config2.readItem( "Items", 1, hide.strbuf );
    stdout.put( hide.strbuf, nl );
    config2.setItemTokens( { ',' } );
    xor( ecx, ecx );
    forever
        config.readItemToken( "Items", 2, ecx, hide.strbuf );
        breakif( ! eax );
        inc( ecx );
        str.trim( hide.strbuf );
        stdout.put( (type uns32 ecx),">", hide.strbuf, nl );
    endfor;
    config2.destroy();
   
end configdemo;

Richedit - setting tabs

posted Jan 15, 2011, 6:04 PM by Sevag Krikorian

The following code sniplet will set the tab stops of a Richedit control (Windows) in average character widths of the currently selected font.

//.. set your font

// get base dialog units
w.GetDialogBaseUnits();

// dereference the low order word
movzx( ax, eax );

// multiply result with the number of tab in characters that you want.
// 6 in this case
mov( 6, ecx );
mul( ecx );

// divide the result by 2
shr( 1, eax );

// store it in a variable and set the tab stops
mov( eax, tabs );
w.SendMessage(hred, w.EM_SETTABSTOPS, 1, &tabs );

//.. redraw the window

lcm, gcd and abs functions

posted Jan 3, 2011, 6:41 PM by Sevag Krikorian   [ updated Jan 17, 2011, 2:20 PM ]

/*
    calculating
        greatest common divisor (gcd)
        least common multiple (lcm)
        and absolute value macro abs()
       
    building:
    hla gcdlcmDemo.hla
   
    or use Make->Build Active Job in HIDE

*/

program gcdlcmDemo;
#include( "stdlib.hhf" );

    /*
    ** abs-    Returns the absolute value of
    **      integer (in EAX).
    **      ** trashes EDX **
    */
    #macro abs( a );
        returns
        (
            {
                // if a is already in eax, don't bother moving it there
                #if( @isReg32( a ) )
                    #if( (@string(a) != "EAX") & (@string(a) != "eax") )
                        mov( a, eax );
                    #endif
                #else
                    mov( a, eax );
                #endif
                cdq();
                xor( edx, eax );
                sub( edx, eax );
            },
            "EAX"
        )
    #endmacro

    /*
    ** gcd-    Returns the greatest common divisor of
    **      integer values (in EAX).
    **        eax is absolute
    */
    procedure gcd( m:int32; n:int32 );
   
        /*
            gcd( m, n ) = gcd( n, m mod n ).
        */
   
    begin gcd;
   
        push( edx );
        while( n != 0 ) do
       
            mov( m, eax );
            cdq();
            imod( n, edx:eax );
            mov( n, eax );
            mov( eax, m );
            mov( edx, n );
           
        endwhile;
        abs( eax );
        pop( edx );
           
    end gcd;
   
    /*
    ** lcm-    Returns the least common multiple of
    **      integer values (in EAX).
    **        eax is absolute
    */
    procedure lcm( m:int32; n:int32 );
   
        /*
                            |m|     
            lcm( m, n ) =___________ .  |n|
                         gcd( m, n )
        */
   
    begin lcm;
       
        push( ecx );
        push( edx );
        push( ebx );
       
        mov( abs( m ), ecx );    // ecx = |m|
        mov( abs( n ), ebx );    // ebx = |n|
       
        gcd( m, n );
        cdq();
        xchg( eax, ecx );
        div( ecx );
        mul( ebx );
        abs( eax );
       
        pop( ebx );
        pop( edx );
        pop( ecx );
       
    end lcm;

begin gcdlcmDemo;
   
    gcd( 4, -14 );
    stdout.put( "gcd( 4, -14 ) = ", ( type int32 eax ), nl );
   
    lcm( 4, -14 );
    stdout.put( "lcm( 4, -14 ) = ", ( type int32 eax ), nl );
   
end gcdlcmDemo;

Heap Sort

posted Nov 23, 2010, 1:13 AM by Sevag Krikorian

program sort;
    /*
        heap sort example
        kudos to julienne walker
       
        requires hidelib 1.71.71+ for output routine
        HIDE 1.50.05+ if using HIDE to compile
       
        compile with (if using output routines)
        hla sort hidelib.lib
       
        or use make in HIDE
   
    */

    #includeonce( "stdlib.hhf" )
    #includeonce( "hide/hidelib.hhf" )
   
proc
   
    doHeap :procedure( var a:dword; i:uns32; n:uns32 );
    begin doHeap;
        push( ecx );
       
        mov( i, edx );
        mov( [esi+edx], bl ); // save bl = a[i]
        shl( 1, edx );
        inc( edx ); // edx = i * 2 + 1

        while( edx < n ) do
           
            mov( edx, ecx );
            inc( ecx );
           
            mov( [esi+edx], al );
            mov( [esi+ecx], ah );
           
            if( ecx < n && al < ah ) then
                inc( edx );
            endif;
           
            mov( [esi+edx], al );
            breakif( bl >= al );
           
            mov( i, ecx );
            mov( al, [esi+ecx] );
           
            mov( edx, i );
            shl( 1, edx );
            inc( edx );
           
        endwhile;
   
        mov( i, ecx );
        mov( bl, [esi+ecx] );
       
        pop( ecx );
    end doHeap;

   
    heapSort :procedure( var a:dword; n:uns32 );
    begin heapSort;
        mov( n, ecx );
        mov( a, esi );
        shr( 1, ecx );
        while( ecx ) do
            dec( ecx );
            doHeap( a, ecx, n );
        endwhile;
       
        mov( n, ecx );
        dec( ecx );
        while( ecx ) do
            // swap
            mov( [esi+0], al );
            mov( [esi+ecx], ah );
            mov( ah, [esi+0] );
            mov( al, [esi+ecx] );
            doHeap( a, 0, ecx );
            dec( ecx );
        endwhile;
    end heapSort;
   

static
   
    data :byte[] := [ $44, $44, $5c, $77, $32, $5b, $89, $4f, $23, $3, $8a ];
   

begin sort;
   
    stdout.put( "unsorted :" );
    hide.putMem0( &data, @elements( data ) );
    heapSort( &data, @elements( data ) );
    stdout.newln();
    stdout.put( "sorted   :" );
    hide.putMem0( &data, @elements( data ) );
   
   
end sort;

Selection Sort

posted Nov 22, 2010, 11:19 PM by Sevag Krikorian

program sort;

    /*
        selection sort example
        kudos to julienne walker
       
        requires hidelib 1.71.71+ for output routine
        HIDE 1.50.05+ if using HIDE to compile
       
        compile with (if using output routines)
        hla sort hidelib.lib
       
        or use make in HIDE
   
    */

    #includeonce( "stdlib.hhf" )
    #includeonce( "hide/hidelib.hhf" )

proc
    selectionSort :procedure( var a:dword; n:uns32 );
    begin selectionSort;
       
        mov( a, esi );
        mov( n, edi );
       
        dec( edi );
        while( edi ) do
            mov( edi, edx );    // edx = max
           
            for( mov( 0, ecx ); ecx < edi; inc( ecx ) ) do
               
                mov( [esi+edx], al );
                if( (type byte [esi+ecx]) >= al ) then
                    mov( ecx, edx );
                endif;
           
            endfor;
               
            if( edx != edi ) then
                mov( (type byte[esi+edx]), ah );
               
                for( mov( edx, ecx ); ecx < edi; inc( ecx ) ) do
                   
                    mov( (type byte[esi+ecx+1]), al );
                    mov( al, [esi+ecx] );
                   
                endfor;
               
                mov( ah, [esi+edi] );
               
            endif;
           
           
           
            dec( edi );
        endwhile;
       
    end selectionSort;

static
   
    data :byte[] := [ $44, $44, $5c, $77, $32, $5b, $89, $4f, $23, $3, $8a ];
   

begin sort;
   
    stdout.put( "unsorted :" );
    hide.putMem0( &data, @elements( data ) );
    stdout.put( nl nl );
    selectionSort( &data, @elements( data ) );
    stdout.put( "sorted   :" );
    hide.putMem0( &data, @elements( data ) );
   
end sort;

Playing with auxreg macro

posted Nov 21, 2010, 11:45 PM by Sevag Krikorian

/*
    compiled with hla 2.14
    compile using hla aux_reg
    or make menu in HIDE
   
    this is a demo using the auxreg macro in
    the HIDE macro library.
    the macro can be used with any letter from 'f' .. 'z'
    and it will generate a variable with 'register' like
    assess mode, with a little extension for the HO
   
*/

program aux_reg;
    #include("stdlib.hhf")
    #include("hide/hidelib.hhf")
   
    var
        f    :auxreg;
       
begin aux_reg;
   
    mov( $AABBCCDD, efx );
    stdout.put(    "efx                :", efx, nl,
                "High Order word    :", ef, nl,
                "Low Order word     :", fx, nl,
                "HO byte of LO word :", fh, nl
                "LO byte of LO word :", fl, nl
                "HO byte of HO word :", efh, nl
                "LO byte of HO word :", efl, nl );
   
end aux_reg;

Using tStack class from hidelib.lib

posted Nov 21, 2010, 8:04 PM by Sevag Krikorian   [ updated Nov 21, 2010, 8:18 PM ]

/*
    compiled with hla 2.14
    requires hidelib version 1.71.70+

    build with
    hla stack_class_demo hidelib.lib
    or use HIDE make menu.

    This is a demo of tStack class from hidelib.lib
*/

program stack_class_demo;

    #includeonce( "stdlib.hhf" )
    #includeonce( "hide/hidelib.hhf" )
    ?@nodisplay := true;
    ?@noalignstack := true;

type
    rec:
    record
        a    :uns32;
        b    :dword;
    endrecord;
   
   
static
    rec0    :rec := rec:[10, $0B];
    rec1    :rec;
    stk        :tStack;
   
    a    :byte := $AA;
    b    :byte := $BB;
    c    :dword:= $FFFF;
   
    d    :byte;
    e    :byte;
   
begin stack_class_demo;
   
    // create a stack class with 100 byte storage.
    // note: the stack will grow dynamically and can't
    // overflow unless you run ouf of system memory.
    // however, you can underflow in which case, zero
    // will be returned in EAX and no further action
    // will take place.
   
    stk.create( 100 );

    // push some dwords onto the stack
    stk.dpush( 1 );
    stk.dpush( 2 );
    stk.dpush( 3 );
   
    // use the macro to push several arguments
    stk.mpush( a, b, c );
   
    // pop a 32 bit object off the stack and store in EAX + stk.regVar
    stk.pop32();
    stdout.put( eax, nl );
    stdout.put( stk.regVar, nl nl );
   
    // number of dword sized objects currently on the stack
    // rounded up for uneven extra bytes
    stk.getnumobjects();
    stdout.put( (type uns32 eax ), nl nl );
   
    // use macro to pop a couple byte sized objects off the stack.
    // and store it into byte sized variables
    stk.mpop( d, e );
    stdout.put( d, nl, e, nl );
   
    // push a record/n memory on the stack
    stk.npush( &rec0, @size( rec0 ) );
   
    // pop n memory from stack
    stk.npop( &rec1, @size( rec1 ) );
    stdout.put( "rec1.a :", rec1.a, nl "rec1.b :", rec1.b, nl nl );
   
    // get the stack pointer
    mov( stk.cursor, edi );
   
    // remember, tStack class grows 'upward' and shrinks 'down'
    // print the top of stack to stdout
    stdout.put( (type dword[edi-4]), nl );
   
    /*
        there are several more methods; variations on size of the above examples.
        also, tStack is a superclass of tBuf so every method available in tBuf
        is available.  however, it's not advisable to use tBuf methods to modify
        the stack class.  one useful method from tBuf is
        writeFileName, you can use this to save the contents of a stack class to
        a file and restore it later.
       
    */
   
end stack_class_demo;

1-7 of 7