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.
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
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.
Ziron looks similar to Sphinx C-- (http://c--sphinx.narod.ru/indexe.htm)
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.
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
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
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 (http://www.spoilerspace.com/bcxdx/cHLasm/cHLasm.zip)
just unzip it and run jfe editor , drag and drop Exm2.cpp , press Create Console bottom.
Hi Emil,
Is there a specific reason to use inline assembly as interfers with the C\C++ compiler's optimization engine?
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.
Hi Emil,
If I remember well, Sphinx C-- can output object modules too. Does Ziron provide this feature?
No , Mr Colin the owner of Ziron was planning to allows Ziron to genrate obj file by using Ziron Plug-In extension.
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
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
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
implemented .for - .endfor for using in HighLevelAsm.
Example
======
/********************************
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
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.
/********************************
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
also implemented Uses keyword that will save some registers in front of procedure and will be restored automatically when ret from procedure
Example
======
/********************************
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
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.
if it helps, you can temporarily disable the assembler prologue and epilogue
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
thanks you.
actually , we can make a function without frame stack by many way in bcx & HighLevelAsm & VC10
Example
======
; FastProc Example
FastProc GetVal
^ Eax = 100
^ ret
End FastProc
this will translated to that
__declspec(naked) int GetVal(...)
{
__asm{
Mov Eax , 100
ret
}
}
second method is like that
!#define FastProc __declspec(naked)
!FastProc int add1(int a, int b)
!{
^ eax = a
^ eax += b
^ ret
!}
and yet another method that specific for VC10
!#pragma optimize( "y", on )
function add(a as int,b as int)
^ eax = a
^ eax += b
^ ret
end function
!#pragma optimize( "y", off )