The MASM Forum

Specialised Projects => Compiler Based Assembler => Assembler With Microsoft Visual C => Topic started by: Emil_halim on July 20, 2012, 05:52:29 PM

Title: BCX+MSVC10+High level asm
Post by: Emil_halim on July 20, 2012, 05:52:29 PM
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
====
Code: [Select]
/********************************
  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
Code: [Select]
   ^ mov eax,200
   
so this is the idea of using high level asm.

Exm2
====
Code: [Select]
/********************************
  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
====
Code: [Select]
/********************************
  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. 
Title: Re: BCX+MSVC10+High level asm
Post by: qWord on July 20, 2012, 10:10:59 PM
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
Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on July 21, 2012, 03:09:38 AM

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
Code: [Select]
  [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.
Title: Re: BCX+MSVC10+High level asm
Post by: Vortex on July 21, 2012, 03:15:37 AM
Ziron looks similar to Sphinx C-- (http://c--sphinx.narod.ru/indexe.htm)
Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on July 21, 2012, 03:23:27 AM

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. 
Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on July 21, 2012, 03:37:27 AM
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
=============
Code: [Select]

$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

   
Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on July 23, 2012, 02:56:21 AM

Hi ,

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

here is an example
Code: [Select]
$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
   
Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on July 27, 2012, 04:39:17 AM

hi ,

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

Code: [Select]

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

     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 (http://www.spoilerspace.com/bcxdx/cHLasm/cHLasm.zip)
just unzip it and run jfe editor , drag and drop Exm2.cpp , press  Create Console bottom.

Title: Re: BCX+MSVC10+High level asm
Post by: Vortex on July 27, 2012, 05:05:09 AM
Hi Emil,

Is there a specific reason to use inline assembly as interfers with the C\C++ compiler's optimization engine?
Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on July 27, 2012, 05:45:32 AM
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.
Title: Re: BCX+MSVC10+High level asm
Post by: Vortex on July 27, 2012, 05:48:29 AM
Hi Emil,

If I remember well, Sphinx C-- can output object modules too. Does Ziron provide this feature?
Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on July 27, 2012, 05:59:16 AM

No , Mr Colin the owner of Ziron was planning to allows Ziron to genrate obj file by using Ziron Plug-In extension.
Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on July 31, 2012, 05:23:29 AM

Hi ,

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

also push will accept mor than one parametr.

Example
======
Code: [Select]
$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
Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on March 09, 2013, 12:26:57 AM
Hi all

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

FastProc will produce a function without stack frame.

Example
=======

Code: [Select]
/********************************

  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

Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on March 09, 2013, 12:31:25 AM
FastProc Example Ported From PowerBasic

Code: [Select]
/********************************

  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
Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on March 09, 2013, 12:33:25 AM
 implemented .for - .endfor for using in HighLevelAsm.

Example
======

Code: [Select]
/********************************

  High level asm Example No 17
 
        By Emil Halim
 
          5-3-2013
*********************************/


$CPP
$NOMAIN
$NOWIN
 
#include "Windows.h"
 

FUNCTION main()

     !char* MyStr = "welcome....\n";
     raw ndx
     $AsmX
          ' using variable as a loop counter                   
          .for ndx = 5 to 10 
             cinvoke printf,MyStr
          .endfor
           
          ' using ecx rigester as a loop counter
          ' note well Printf will change ecx , so save it   
          .for ecx = 4 to 10 step 2
             push ecx                   
             cinvoke printf,MyStr     
             pop  ecx                 
          .endfor   
         
          ' using space memory in the stack as a loop counter
          ' do nt forget to blanced the stack when loop finished
          esp -= 4                 // allocate local variable
          .for [esp] = 5 to 10     // loop fro 5 to 10
             cinvoke printf,MyStr 
          .endfor                  //end the loop here
          esp += 4                 // de aloacate the local variable 
     $AsmX   
   
     Pause
END FUNCTION

Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on March 09, 2013, 12:35:37 AM
implemented masm label "@@:" with High Level Asm

here is example that has 2 procedures , both of them will convert string to value.

in the first one Ebx must hold string address , Ecx must hold end address of string

in the second one you call it by normal way.

the 2 procedures i got them from MASM forum and modified it.

Code: [Select]
/********************************

  High level asm Example No 18
 
        By Emil Halim
 
          6-3-2013
*********************************/


$CPP
$NOMAIN
$NOWIN
 
#include "Windows.h"
 
FastProc atod_proc
 $AsmX
     xor edx, edx           
   @@:
     movzx eax, byte ptr [ebx]   
     lea edx, [edx+4*edx]       
     lea edx, [2*edx+eax-48]     
     inc ebx
     cmp ecx, ebx       
     jne @B
     xchg eax, edx
     ret
 $AsmX   
End FastProc

FastProc atod_proc_2
  $AsmX
         edx = [esp+4]              ; get first para in edx
         xor eax, eax               ; clear eax

   @@:   movzx ecx, byte ptr [edx]  ; move 1 byte into ecx
         lea eax, [eax+4*eax]       ; eax -> 5 * eax
         lea eax, [2*eax+ecx-30h]   ; eax -> 2 * eax + (ecx-30h)
         edx++                      ; inc edx
         cmp byte ptr [edx], 0      ; if end of string then return
         jne @b
         ret
  $AsmX   
End FastProc

FUNCTION main()
   
     !const char MyStr[] = "2000";
     raw ln ,value
     !ln = strlen( MyStr );
     
     ^ ebx = &MyStr        ; get str address into ebx         
     ^ ecx = ebx           ; copy ebx to ecx
     ^ ecx += ln           ; get length of str into ecx
     ^ call atod_proc      ; call the function
     ^ value =  eax        ; store result in value variable
     print  value     
     
     print  atod_proc_2(MyStr$)   
     Pause
END FUNCTION     
Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on March 09, 2013, 12:37:03 AM
also implemented Uses keyword that will save some registers in front of procedure and will be restored automatically when ret from procedure

Example
======

Code: [Select]
/********************************

  High level asm Example No 19
 
        By Emil Halim
 
          7-3-2013
*********************************/


$CPP
$NOMAIN
$NOWIN
 
#include "Windows.h"
 
FastProc Test
 $AsmX
     'we want to save 2 registers esi and edi
     uses esi edi
     esi = [esp+4+8]  ;get first arg into esi
     edi = [esp+8+8]  ;get second arg into edi
     eax = esi        ; copy esi to eax
     eax += edi       ; add eax and edi
     ' here HiegLivelAsm will restore the saved registers 
     ret
 $AsmX   
End FastProc

FUNCTION main()
       
     print  Test(10,20)   
     Pause
END FUNCTION

Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on March 09, 2013, 12:41:51 AM

if someone interesting,

here is the source code of bcx 6.9.9.1 & HighLevelAsm source code.

www.spoilerspace.com/bcxdx/cHLasm/BCX6_9_9_1&HighLevelAsm_1.zip (http://www.spoilerspace.com/bcxdx/cHLasm/BCX6_9_9_1&HighLevelAsm_1.zip)

you must have MSVC10 to create BC translator with HighLevelAsm.

Feel free to improve and enhanced it.

thanks.
Title: Re: BCX+MSVC10+High level asm
Post by: dedndave on March 09, 2013, 01:49:05 AM
if it helps, you can temporarily disable the assembler prologue and epilogue
Code: [Select]
        OPTION  PROLOGUE:None
        OPTION  EPILOGUE:None

OpnFile PROC    lpFileName:LPSTR,dwOpenFlags:DWORD

;code
        ret     8   ;you must pop the parameters off the stack

OpnFile ENDP

        OPTION  PROLOGUE:PrologueDef
        OPTION  EPILOGUE:EpilogueDef
Title: Re: BCX+MSVC10+High level asm
Post by: Emil_halim on March 09, 2013, 02:18:01 AM
thanks you.

actually  , we can make a function without frame stack by many way in bcx & HighLevelAsm & VC10

Example
======
Code: [Select]
; FastProc Example
FastProc  GetVal
      ^ Eax = 100
      ^ ret
End FastProc

this will translated to that
Code: [Select]
__declspec(naked) int GetVal(...)
{
  __asm{ 
           Mov Eax , 100
           ret
   }
}

second method is like that
Code: [Select]
!#define FastProc __declspec(naked)
!FastProc int add1(int a, int b)
!{
     ^ eax  = a
     ^ eax += b
     ^ ret
!}

and yet another method that specific for VC10
Code: [Select]
!#pragma optimize( "y", on )
function add(a as int,b as int)
   ^ eax  = a
   ^ eax += b
   ^ ret
end function
!#pragma optimize( "y", off )