News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

BCX+MSVC10+High level asm

Started by Emil_halim, July 20, 2012, 05:52:29 PM

Previous topic - Next topic

Emil_halim

Hi Everyone.

I was using Ziron assembler , it is a high level asm. then i tried to implement some features of it with MSVC10 inline assembly.

also i was thinking to mix that with basic language. so i do it with BCX , Basic To C translator.

here are some examples showing you the idea.

Exm1
====

/********************************
  High level asm Example No 1
        By Emil Halim
          9-7-2012
*********************************/
$CPP
$NOMAIN
$NOWIN
#include "Windows.h"

FUNCTION main()
   !DWORD b;            /* allocate a local variable in inline-C  */
   ^ eax = 200         ' this is inline asm code inserted in BCX code
   ^ b = eax           ' this two lines put 200 into b variable
     PRINT  b          ' print the result to make sure the b equal 200
     Pause
END FUNCTION
   

this example declare a variable "b" by using inline-c then puts 200 in eax register in high level asm so you code do it with that

   ^ mov eax,200
   
so this is the idea of using high level asm.

Exm2
====

/********************************
  High level asm Example No 2
        By Emil Halim
          9-7-2012
*********************************/
$CPP
$NOMAIN
$NOWIN
#include "Windows.h"

function add(a as int,b as int)
   ^ eax  = a    ' we can use parametrs directly
   ^ eax += b    ' see the power of MSVC10
end function

FUNCTION main()
     PRINT  add(10,5)              ' print the result to make sure the add equal 15
     Pause
END FUNCTION


this example show you how to use parameters and also any variables name directly with asm , thanks to MSVC10.

Exm3
====

/********************************
  High level asm Example No 3
        By Emil Halim
          9-7-2012
*********************************/
$CPP
$NOMAIN
$NOWIN

#include "Windows.h"

// declare global variable
!int  k = 10;

function add(a as int,b as int)
  $asmx
     eax  = a
     eax += b
     eax += k
  $asmx
end function

// declare global array 
!int a[] = { 0x1234, 0x4567 };

FUNCTION main()
         
     PRINT  add(10,5)     ' print the result to make sure the add equal 25
     
     raw cc%
     ^ eax = a            ' interpreted as eax <- a[0]
     ^ eax = &a           ' interpreted as eax <- &a[0]
     ^ ebx = [eax]
     ^ ecx = [eax+4]
     ^ cc = ecx
     PRINT hex$(cc)       ' print 4567
     
     Pause
END FUNCTION
   

I think now you got the idea of my project , if you see it is useful  then let me know.

thanks. 

qWord

Did I understand you right: you are creating an assembler named Ziron that should support shown syntax?

EDIT: I misunderstand it: for those who are not familiar with Ziron: http://www.movsd.com/board/index.php?topic=17429.msg146202#msg146202
MREAL macros - when you need floating point arithmetic while assembling!

Emil_halim


I was just a user for Ziron. 

the idea here is to simplify the inline asm with MSVC10 so you can use those syntex with high level asm

  [ebp-16] = 256                       --------should be------->>       mov  dowrd ptr[ebp-16] , 256   
  dwrod [ebp-16] = 256
  dword ptr [ebp-16] = 256   
  long [ebp-16] = 256
  char [ebp-16] = 256              --------should be------->>        mov byte ptr [ebp-16] , 256 
  short [ebp-16] = 256     
  eax = [edx]             
  eax = [edx+ecx]         
  eax = [edx+ecx*4]       
  eax = [edx+ecx*4-16]   
  Eax += Edx                            --------should be------->>       add  eax,edx           
  Eax -=  Esi
  eax = & b                              --------should be------->>        lea eax,b
  eax = & [ebx+ecx]                --------should be------->>        lea eax , [ebx+ecx] 
  eax = & b 
  eax = [edx+ecx*4-16] 
  [ebp-16] = 256
  eax += edx
  eax += [edx+ecx*4]
  eax -= [edx+ecx*4]
  ax *=  bx                    ' by defaulte unsigned multiply
  ax *= (int) bx               ' signed multiply   
  al  *=  [edx]
  ah  *=  [edx]
  ax  *=  [edx]
  Eax  *=  [edx]
  DX.AX *=   [ecx]
  EDX.EAX *=  [ebx]
  EDX.EAX *=  byte [ebx]
  -Eax
  - [ebx+4]
  ~Eax
  ~ [ebx+4]
  Eax  >>  4                  ' shr
  [Eax+8]  << 3            ' shl
  Eax  >>  cl                 ' shr
  [Eax+8]  << cl

  st = float[eax]                   --------should be------->>  fld dword ptr [eax]
  st = qword ptr[eax]           --------should be------->>  fld qword ptr [eax]
  st = tbyte ptr[eax+10]      --------should be------->>  fld tbyte  ptr [eax]
  st = st(2)             
  float[eax] = st                   --------should be------->>  fstp dword ptr [eax]
  al = CARRY                         --------should be------->>  setc al
  [edx] =  Carry 
   al = Zero
   al = Sign
   al = Ovrflw
   al = Parity
   invoke test4,10,20,30
   esp += 3*4
   eax = 130
   ebx = 140
   invoke test4,10, eax ,ebx
   esp += 3*4
   eax = 1200
   cinvoke printf ,&frm,eax
   [ebx] = tst5(eax,40,30)    ; call tst5 function the move eax to [edx] 


hope the idea is now more clear and simple.

Vortex


Emil_halim


yes , i was asking Mr Colin several times to add some feature of Sphinx C-- .

i liked it very much but it is buggy and old. 

Emil_halim

Hi ,

all of us know that inline asm in MSVC10 does not allow using DB ,DW,DD,DQ.  but allows us to use _emit directive to emit only one byte.

i have successfully allow that but inside a function , MSVC10 does not allow _emit outside a function.

here is an example
=============


$CPP
$NOMAIN
$NOWIN

#include "Windows.h"

FUNCTION main()
    print asmtest()
   Pause
END FUNCTION

function asmtest()
    $asmx
     goto fin
   bytes:               
     DB 32,40,50,"emil",10,0
     DW 0xFFAA,0xccbb,100
    MyData:
     DD 0xffaaccbb
     DQ 0xffaaccbb11223344
    frm:
     DB  "%d",10,0 
    nge:
     -EAX
     return   
    fin:
     eax = 1200
     eax++
     cinvoke printf ,&frm,eax
     eax = &bytes
     al = char[eax]
     eax &= 0xFF
     gosub nge
    $asmx
end function

   

Emil_halim


Hi ,

I have  implemented  .if-.endif statement , hope to make the inline asm with MSVC10 as comparable as masm syntax.

here is an example

$CPP
$NOMAIN
$NOWIN

#include "Windows.h"

FUNCTION main()

   ! char frm[] = "%d\n";
    $asmx
      eax = 5
     .if eax == 5     
         cinvoke printf ,&frm,eax
     .endif
    $asmx

Pause
END FUNCTION
   

Emil_halim


hi ,

I have made a tool that will process the inline-c high level asm with MSVC10 , consider the following Example



/********************************

     High level asm && VC10
         Example No 2
 
        By Emil Halim
 
          26-7-2012

*********************************/


#include "Windows.h"
#include <conio.h>
#include <stdio.h>

void __declspec(naked) main()
{
    int i;
    static char frm[] =  "welcome  i=%d\n";
    // Naked functions must provide their own prolog...
    __asm {
        push ebp
        ebp = esp
        esp -= __LOCAL_SIZE
       
        i = 10
        cinvoke printf,&frm,i
       
        .if i > 15
            eax = i
        .else
            eax = 0   
        .endif
       
        eax = getch()   
   
        esp = ebp
        pop ebp
        ret
    }
   
}


here is a beta version of cHLasm  www.spoilerspace.com/bcxdx/cHLasm/cHLasm.zip
just unzip it and run jfe editor , drag and drop Exm2.cpp , press  Create Console bottom.


Vortex

Hi Emil,

Is there a specific reason to use inline assembly as interfers with the C\C++ compiler's optimization engine?

Emil_halim

Hi  Vortex,

the point here is to make something similar to sphinx C-- and ziron , with a power and optimized compiler.

so when you like coding with asm and have the power of c/c++ , by mixing them i think you can get a good
resulte that saticfied your disirde.

also using high level asm will simplify programing in asm level.

Vortex

Hi Emil,

If I remember well, Sphinx C-- can output object modules too. Does Ziron provide this feature?

Emil_halim


No , Mr Colin the owner of Ziron was planning to allows Ziron to genrate obj file by using Ziron Plug-In extension.

Emil_halim


Hi ,

i have added a .while-.endw loop and .repeat-.until loop.

also push will accept mor than one parametr.

Example
======

$CPP
$NOMAIN
$NOWIN

#include "Windows.h"

FUNCTION main()

   ! char frm[] = "%d\n";
    $asmx
      eax = 5
     .while eax > 0     
         push eax
         cinvoke printf ,&frm,eax
         pop eax
         eax--
     .endw

     push eax ebx ecx
     pop   ecx ebx eax
    $asmx

Pause
END FUNCTION

Emil_halim

Hi all

I have implement FastProc - EndFastProc with BCX just like PowerBasic
keyword.

FastProc will produce a function without stack frame.

Example
=======


/********************************

  High level asm Example No 14
 
        By Emil Halim
 
          3-3-2013

*********************************/

$CPP
$NOMAIN
$NOWIN

#include "Windows.h"

'====================================
'  in Fast Procedure you have
'  no stack frame in the beginning
'  of the function
'====================================     
FASTPROC GetEAX()
     print "Example of Function without frame stack"
     ^ EAX = 100
     ^ ret        ' you have to wirte it by your self
End FASTPROC   

FUNCTION main()
   !DWORD b;            /* allocate a local variable in inline-C  */
   b = GetEAX()
   PRINT  b          ' print the result to make sure the b equal 100
   Pause
END FUNCTION


Emil_halim

FastProc Example Ported From PowerBasic


/********************************

  High level asm Example No 16
 
        By Emil Halim
 
          3-3-2013

*********************************/

$CPP
$NOMAIN
$NOWIN

#include "Windows.h"

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

FASTPROC ASM_len

    $AsmX

          eax = [esp+4]          ; load the string address
          eax--                        ; set up the address for loop entry
      lbl0:
          eax++                      ; increment up to the next character
          .if [eax] != 0             ; test if  character is terminator
               jne lbl0                ; loop back if not
          .endif
          eax -= [esp+4]         ; sub the start address from EAX
          ret 4                         ; return while balancing the stack

    $AsmX

END FASTPROC

' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

FUNCTION main()
    LOCAL rval AS DWORD
    LOCAL szStr AS STRING * 64

    szStr = "1234567890"
    ^ invoke  ASM_len , &szStr     
    ^ rval =  eax             
     
     PRINT  rval         
     
     Pause
END FUNCTION