News:

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

Main Menu

masm with spinx c--

Started by Emil_halim, October 15, 2013, 11:35:23 PM

Previous topic - Next topic

Emil_halim

Hi all,

here is a ftoa procedure , from fasm forum , adapted by me.

demo
====

/*************************************
*           Sphinx C--               * 
*                                    *
*    ftoa demo From FASM forum       *
*                                    *
*         by Emil_halim              *         
*                                    *
*************************************/


#pragma option w32c       //create Windows console EXE.
#pragma option OS         //speed optimization
#jumptomain NONE          //just jump to main function

#includepath "D:\Ext_c--\winlib" 

#include <windows.h> 
#include <MSVCRT.H-->
 
#pragma option ia        //allow inserte asm instructions

#pragma option LST

^^
; #########################################################################
;
;
; #########################################################################       

.data
      itoa_digits  db "0123456789ABCDEF", 0
      ftoa_ten     dd 10
.code
 
;===============================================================================
;       integer to ASCII conversion procedure
;
;       input:
;       number - number to convert Smile
;       radix - base system like 10 for decimal, 16 for hexadecimal, etc.
;       result_buffer - pointer to memory where output will be saved
;       signed - bool value, if number is signed (-2147483646...2147483647)
;                or unsigned (0...4294967295)
;
;       output:
;       length of converted string
;
;       possible errors:
;       radix exceeds 16
;
;       coded by Reverend
;===============================================================================
itoa Proc  number:DWORD, radix:DWORD, result_buffer:DWORD, sgned:DWORD uses edi esi ebx
  local temp_buffer[33]:char

        mov     esi, radix
        lea     edi, [#temp_buffer+32]
        mov     ebx, #itoa_digits
        cmp     esi, 16
        ja      error
        std
        xor     al, al
        stosb
        mov     eax, number
        cmp     sgned, TRUE
        jnz     @F
        test    eax, 80000000h
        jz      @F
        neg     eax
    @@:
        xor     edx, edx
        idiv    esi
        xchg    eax, edx
        xlatb
        stosb
        xchg    eax, edx
        test    eax, eax
        jnz     @B
        lea     esi, [edi+1]
        mov     edi, result_buffer
        cld
        cmp     sgned, TRUE
        jnz     @F
        test    number, 80000000h
        jz      @F
        mov     al, "-"
        stosb
    @@:
        lodsb
        stosb
        test    al, al
        jnz     @B
        sub     edi, result_buffer
        lea     eax, [edi-1]
        stc
@ theend:
        cld
        ret
@ error:
        clc
        jmp     theend
itoa Endp


;===============================================================================
;       float to ASCII conversion procedure
;
;       input:
;       buffer - pointer to memory where output will be saved
;       precision - number of digits after dot
;
;       output:
;       no immediate output
;
;       notes:
;       separate integer and mantisa part with dot '.'
;       so GOOD   123.456
;          WRONG  123,456
;
;       coded by Reverend // HTB + RAG
;===============================================================================
ftoa Proc  buffer:dword, prec:dword uses eax edi ecx

  local status_original:word 
  local status_changed:word
  local integer:dword
  local mantisa:dword
  local sgned:dword

;       --------------------------------
;       set correct precision
;       --------------------------------
        mov     eax, prec
        cmp     eax, 51
        jb      @F
        mov     eax, 51
    @@:
        mov     prec, eax
;       -----------------------------------------------
;       change control wortd of fpu to prevent rounding
;       -----------------------------------------------
        fnstcw  status_original
        mov     ax, status_original
        or      ax, 0000110000000000b
        mov     status_changed, ax
        fldcw   status_changed
;       --------------------------------
;       check if sgned
;       --------------------------------
        xor     eax, eax
        fst     sgned
        test    sgned, 80000000h
        setnz   al
        mov     sgned, eax
;       ----------------------------------
;       cut integer and mantisa separately
;       ----------------------------------
        fld     st(0)
        fld     st(0)                     ; st0 = x, st1 = x
        frndint
        fist    integer                   ; st0 = x, st1 = x
        fabs
        fsubp   st(1), st(0)              ; st0 = mantisa(x)
;       --------------------------------
;       save integer part in buffer
;       --------------------------------
        mov     edi, buffer
        push    sgned
        push    edi
        push    10
        push    integer
        call    itoa
        add     edi, eax
        mov     al, "."
        stosb
;       --------------------------------
;       save mantisa part in buffer
;       --------------------------------
        mov     ecx, prec
        dec     ecx
   @ lop:
        fimul   DSDWORD[#ftoa_ten]
        fld     st(0)
        frndint
        fist    mantisa
        fsubp   st(1), st(0)
        push    0
        push    edi
        push    10
        push    mantisa
        call    itoa
        add     edi, eax
        ftst
        fnstsw  ax
        test    ax, 0100000000000000b
        jz      @F
        test    ax, 0000010100000000b
        jz      fin
    @@:
        loop    lop
        fldcw   status_original
        fimul   DSDWORD[#ftoa_ten]
        fist    mantisa
        push    0
        push    edi
        push    10
        push    mantisa
        call    itoa
      # AL = '\0';
        stosb   
;       --------------------------------
;       restore previous values
;       --------------------------------
   @ fin:
        fstp    st(0)
        stc
     
ftoa Endp



; #########################################################################
^^

void main()
{
   //buffer that holds string
   char   ss[64];
   
   // test postive value 
   ST = 55.44;
   ftoa(#ss,4);
   puts(#ss);
   
   // test nigative value 
   ST = -55.44;
   ftoa(#ss,4);
   puts(#ss);
   
   MessageBox(0,"","",0);
}   



Enjoy coding with c--,Masm,Basic.     

Emil_halim

Hi all,

I have extended the Proc keyword ,so that you can easily determine the return type of the procedure.

also i added .include keyword the allows you to include files inside masm block.

here is  example showing you the new features.

Demo
====

/*************************************
*           Sphinx C--               * 
*                                    *
*       return value demo            *
*                                    *
*         by Emil_halim              *         
*                                    *
*************************************/


#pragma option w32c       //create Windows console EXE.
#pragma option OS         //speed optimization
#jumptomain NONE          //just jump to main function

#includepath "D:\Ext_c--\winlib" 

#include <windows.h> 
#include <MSVCRT.H-->
 
#pragma option ia        //allow inserte asm instructions

#pragma option LST

^^
; #########################################################################
;  add a return type of your procedure
; #########################################################################       


FSqur Proc x:REAL8 <ST>

fld x
fmul st,st

FSqur Endp


FSqurF Proc x:REAL8 <float>

fld x
fmul st,st

FSqurF Endp

// include ftoa function
.include  ftoa.inc

; #########################################################################
^^

void main()
{
     double ds;
     float  fs;
     char   ss[64];
     
     ds = FSqur(5.0);
     printf("%f\n",ds);     
     
     fs = FSqurF(5.0);
     ftoa(#ss,fs,4);           
     puts(#ss);
                                     
     MessageBox(0,"","",0);
}


  Enjoy coding with c--,Masm,Basic.       

Emil_halim

Hi all,

this time i will show you that , how is c--Ext is so flexible and easy mixing it with masm.

iin this demo i declared a c-- global variable inside a masm block , also declared a c-- local variable
inside a masm procedure then i uesd them so easy in masm block.     

The demo
========

/*************************************
*           Sphinx C--               * 
*                                    *
*       cmm vars with Masm           *
*                                    *
*         by Emil_halim              *         
*                                    *
*************************************/


#pragma option w32c       //create Windows console EXE.
#pragma option OS         //speed optimization
#jumptomain NONE          //just jump to main function

#includepath "D:\Ext_c--\winlib" 

#include <windows.h> 
#include <MSVCRT.H-->
 
#pragma option ia        //allow inserte asm instructions

#pragma option LST

^^
; #########################################################################
;  add a return type of your procedure
; #########################################################################       
// declare a c-- global variable
# static int gVar= 10;

Fint Proc x:REAL8 <int>
   # int iData;           // declare a local variable
fld x
fistp iData
mov EAX, gVar
iMul iData // return val inside EAX register   
Fint Endp

; #########################################################################
^^

void main()
{

     printf("the int of 60.12 * 10 = %d\n",Fint(60.12));     
                                     
     MessageBox(0,"","",0);
}


NOTE WELL
the prefix # in masm block tells c--Ext to pass the line to c-- parse.

Enjoy coding with c--,Masm,Basic.

Emil_halim

Hi all,

I've implemented ".const" KeyWord ,so that you can declare a const block at any location in your source code.

you still can declare a const inside masm block without need to use .const , but what is the point here.

well , when you declare a const without using .const block you have to declare it before you can using it,
and when you declare it inside a const block you can use it before the declaration.
   
c--Ext will collects all const blocks and put them in the first in our source code.

here is a simple demo that showing you the point.

Demo
=====

/*************************************
*           Sphinx C--               * 
*                                    *
*       .const keyword test          *
*                                    *
*         by Emil_halim              *         
*                                    *
*************************************/


#pragma option w32c       //create Windows console EXE.
#pragma option OS         //speed optimization
#jumptomain NONE          //just jump to main function

#includepath "D:\Ext_c--\winlib" 

#include <windows.h> 
#include <MSVCRT.H-->

#CleanFiles of           // keep all tempo files after compiling
 
#pragma option ia        //allow inserte asm instructions

#pragma option LST

^^
; #########################################################################

;  using  masm equ directive
;
; #########################################################################


    I_am_Ten   equ  0Ah      ; declare const befor using it

Ten:
    mov eax, I_am_Ten
    ret

Zero:
    eax = I_am_Zero          ; her we use a const befor declare it
    ret
   
.const
    I_am_Zero  equ  0        ; declare a const after we used it

.code   

; #########################################################################
^^

void main()
{
     
     
  ^  invoke Ten
     printf("%d\n",EAX);   
     
     call Zero
     printf("%d\n",EAX);   
           
     MessageBox(0,"","",0);
}


also i add a new directive  #CleanFiles  to C--Ext that allow you to delete or keep tempo files after compiling.

Enjoy coding with c--,Masm,Basic.

Emil_halim

#49
Hi all

this time , I have added some Fasm syntax compatibility , for example , fasm uses st0 instead of st(0) ,also uses
dword [ ] instead of dword ptr [] ......etc.

here is a atof procedure from fasm forum , with small modification.

AtoF Proc
========

/*************************************
*           Sphinx C--               * 
*                                    *
*    ftoa demo From FASM forum       *
*                                    *
*         by Emil_halim              *         
*                                    *
*************************************/


#pragma option w32c       //create Windows console EXE.
#pragma option OS         //speed optimization
#jumptomain NONE          //just jump to main function

#CleanFiles of

#includepath "D:\Ext_c--\winlib" 

#include <windows.h> 
#include <MSVCRT.H-->
 
#pragma option ia        //allow inserte asm instructions

#pragma option LST

^^
; #########################################################################
;
;
; #########################################################################       

.data
      ftoa_ten     dd 10
.code
       
;===============================================================================
;       ASCII to float conversion procedure
;
;       input:
;       string - pointer to string
;
;       output:
;       st0 - number changed into float
;
;       coded by Reverend // HTB + RAG
;===============================================================================
align   4
Atof  Proc   string:dword uses  ecx esi
           
        fninit
        fild    [ftoa_ten]
        fldz
        fldz
        mov     esi, string
        cmp     byte  [esi], '-'
        jnz     @F
        inc     esi
    @@:
        xor     eax, eax
         
  @integer_part:
        lodsb
        cmp     al, '.'
        jz      mantisa
        test    al, al
        jz      ext
        fmul    st0, st2
        sub     al, '0'
        cmp     al, 9
        jbe     @F
        sub     al, 'A' - '9' - 1
    @@:
        push    eax
        fiadd   dword [esp]
        add     esp, 4
        jmp     integer_part
  @mantisa:
        xor     ecx, ecx
    @@:
        inc     ecx
        lodsb
        test    al, al
        jnz     @B
        cmp     ecx, 10                 ; max 10 digits in mantisa
        jbe     @F
        mov     ecx, 10
    @@:
        std
        sub     esi,2
        fxch    st1
         
  @mantisa_part:
        lodsb
        cmp     al, '.'
        jz      ext
        sub     al, '0'
        cmp     al, 9
        jbe     @F
        sub     al, 'A' - '9' - 1
    @@:
        push    eax
        fiadd   dword [esp]
        add     esp, 4
        fdiv    st0, st2
        jmp     mantisa_part
  @ext:
        cld
        faddp   st1, st0
        ffree   st1
        mov     eax, string
        cmp     byte [eax], '-'
        jnz     @F
        fchs
    @@:
        stc                             ; always returns no error 
        ret
Atof Endp


; #########################################################################
^^



void main()
{
   static char fvl = "-1.0";
         
   Atof(#fvl);
   ESP -= 8;
   fstp DSQWORD [ESP]
   printf("%f\n");
       
   MessageBox(0,"","",0);
}   

   

Enjoy coding with c--,Masm,Basic.

Emil_halim

Hi all,

I have found some bad things about c-- , it can produces COFF obj file but you can not link it with other c-- code.

c-- can only link obj file created by masm's ML.exe that uses .386 directive.

So that , i extend c--Ext to use Golink linker to solve that problem, new directive made "#Make" for creating
Win , sObj, Cns, Dll file.

c--Ext will use Golink automatically , if you do not use #Make directive then c-- will not use Golink. also if you
used #Make sObj c-- will only create obj file, if you used Win, Cns or Dll c-- will uses Golink.

I have added  another feature to include asm source code as a module , so c--Ext will compile it with ML assembler and inserted in c-- as obj file automatically.     

here is sObj demo
=============

/***************************************
*             Sphinx C--               * 
*                                      *
*     demo compile with c-- as obj     *
*       linked later with Golink       *
*           By  Emil Halim             *
*           30 / 12 / 2013             *
***************************************/

#Make sObj
#pragma option OS

#CleanFiles of

#includepath "D:\Ext_c--\winlib" 
#include <windows.h>
#include <MSVCRT.H-->


void dBox()
{
   $mov eax , 10
   $ret
}

           

here is a asm module demo
===================

; #########################################################################

      .386
      .model flat, stdcall
      option casemap :none   ; case sensitive

; #########################################################################

PUBLIC  nBox

.code

nBox proc

       mov eax , 30
       ret
       
nBox endp

end


here is a win demo
==============

/***************************************
*             Sphinx C--               * 
*                                      *
*        demo compile with c--         *
*         linked with Golink           *
*           By  Emil Halim             *
*           30 / 12 / 2013             *
***************************************/

#Make win 

#pragma option OS

#CleanFiles of

#includepath "D:\Ext_c--\winlib" 
#include <windows.h>

extern WINAPI "msvcrt.dll"
{
void cdecl wsprintf();
}


byte msg = FROM "my.txt";
$DB 0

#include "resurs.rc"   

//insert obj file made by ML
#include "m.obj"     

//insert obj file afetr compile the n.asm source file by ML
#include "n.asm"     

//link obj file that mede with c-- by Golink
#include "fnc2.sObj" 

extern dBox();

void main()
{
      int k;
      byte mm[100];
     
      k =  mBox();
      k += dBox();
      k += nBox();
      wsprintf(#mm,"sum of k = %d",k);
     
      MessageBox(0,#mm,#msg,0);
}


Enjoy coding with c--,Masm,Basic.

Emil_halim

Hi all,

c--Ext now supports including c source code as module , then it uses Pelles C to compile it to obj file that will be
linked later by GoLink.

here is example that show you how to mix c source code with c-- code, we create a round function in c code then
we include it in c-- code and declare a proto type of round function.

TstRound.c--  file
=============

/***************************************
*             Sphinx C--               * 
*                                      *
*        using c module with c--       *
*         linked with Golink           *
*           By  Emil Halim             *
*           30 / 12 / 2013             *
***************************************/

#Make cnsl 

#pragma option OS

#CleanFiles of

#includepath "D:\Ext_c--\winlib" 
#include <windows.h>

extern WINAPI "msvcrt.dll"
{
  int cdecl printf(char *,...);
}

// let c-- knows about round function
extern int cdecl round(float number);

// insert c source code as module
#include "round.c" 


void main()
{
      int   i;
     
      i = round( 1.2 );     
      printf("Round of 1.2 = %d\n",i);
     
      i = round( 1.8 );     
      printf("Round of 1.8 = %d\n",i);
     
      MessageBox(0,"","",0);
}
   

round.c  file
========

// The round function is supposed to round the float value to the nearest integer
#pragma ftol(inlined)

int round(float number)
{
    return (number >= 0) ? (int)(number + 0.5) : (int)(number - 0.5);
}


Enjoy coding with c--,Masm,Basic.

Emil_halim

Hi all,

It's time for testing.

here is a beta 3 version of C--Ext  http://bcxdx.spoilerspace.com/C--/Ext_c--.beta_3.zip

Enjoy coding with c--,Masm,Basic.

Emil_halim

Hi all,

this tutorial will show you how to create a DLL library by c--Ext.

using #Make directive will force c--Ext to use GoLink for producing a DLL file ,you can exprot any function or symbol by using #Exports directive.

also #Exports directive allows you to export functions and variables in asm & c modules.

here is simple example shows you the point.

c module "C_ToUpr.c"
================

// c module of ToUpper function
void _stdcall C_ToUpr(char* aStr)
{
   char* str = aStr;
   
   while( *str != 0)
    {
       if(*str >= 'a' && *str <= 'z')
           *str -= 0x20; 
           
       str++;
    }
}


masm module "M_ToUpr.asm"
======================

; #########################################################################

      .386
      .model flat, stdcall
      option casemap :none   ; case sensitive

; #########################################################################

PUBLIC  M_ToUpr

.code

; masm module of ToUpper function
M_ToUpr Proc aStr:Dword
         mov eax , aStr
         dec eax
      @@:
         add eax, 1
         cmp BYTE PTR [eax], 0
         je @F
         cmp BYTE PTR [eax], "a"
         jb @B
         cmp BYTE PTR [eax], "z"
         ja @B
         sub BYTE PTR [eax], 32
         jmp @B
      @@:
      ret 4   
M_ToUpr Endp

END


c-- module "cUpr.c--"
===============

/***************************************
*             Sphinx C--               * 
*                                      *
*    creating dll from c , asm & c--   *
*         linked with Golink           *
*           By  Emil Halim             *
*           13 / 01 / 2014             *
***************************************/


// force c--Ext to make a DLL output
#Make Dll
 

#pragma option OS

//#CleanFiles of

#includepath "D:\Ext_c--\winlib" 
#include <windows.h>

// just put the name of function to be exported
// and let Golink make it
#Exports Cmm_ToUpr,C_ToUpr,M_ToUpr

// inserts asm module 
#include "M_ToUpr.asm"
// inserts c module
#include "C_ToUpr.c"

// notwell , c--Ext will uses asm to compile asm module
// and pelles c to compile c module then compile c-- file
// golink will export all of then by using Exprts keyword


// c-- module of ToUpper function
void Cmm_ToUpr(char* str)
{
ESI = str;
do
{
$lodsb
if (AL >= 'a') && (AL <= 'z')
{
AL -= 0x20;
DSBYTE[ESI-1] = AL;
}

}while(AL != 0);

}

int main()

    $MOV EAX, 1
}   


and here is a test demo

Testdll.c--
=========

/***************************************
*             Sphinx C--               * 
*                                      *
*         demo testting  dll           *
*         linked with Golink           *
*           By  Emil Halim             *
*           13 / 01 / 2014             *
***************************************/


// force c--Ext to make a console output
#Make cnsl

#includepath "D:\Ext_c--\winlib" 
#include <windows.h>

// let c-- knows about our dll
extern WINAPI "cUpr.dll"
{
void C_ToUpr(char* aStr);
void M_ToUpr(dword aStr);
void Cmm_ToUpr(char* str);
}

extern WINAPI "msvcrt.dll"
{
void cdecl printf();
}

// declare some test msgs
char mes1 = "message1";
char mes2 = "message2";
char mes3 = "message3";

main()
{
   C_ToUpr(#mes1);    //call c function in module "C_ToUpr.c" compiled with Pelles c
   M_ToUpr(#mes2);    //call masm procedure in module "M_ToUpr.asm" compiled with masm
   Cmm_ToUpr(#mes3);  //call c-- function in module "cUpr.c--"
   printf("test 1 = %s\n" , #mes1);
   printf("test 1 = %s\n" , #mes2);
   printf("test 1 = %s\n" , #mes3);
   MessageBox(0,"","",0);   
}


Enjoy coding with c--,Masm,Basic.

Emil_halim

Hi all,

i have implemented masm Struct keyword , so you can declare a struct then ues it.

here is simple example.


/*************************************
*           Sphinx C--               * 
*                                    *
*       STRUCT KeyWord test          *
*                                    *
*         by Emil_halim              *         
*                                    *
*************************************/


#pragma option w32c       //create Windows console EXE.
#pragma option OS         //speed optimization
#jumptomain NONE          //just jump to main function

#CleanFiles of

#includepath "D:\Ext_c--\winlib" 

#include <windows.h> 
#include <MSVCRT.H-->
 
#pragma option ia        //allow inserte asm instructions

#pragma option LST

^^
; #########################################################################

;  using  masm struct
;
; #########################################################################

point STRUCT
       x DWORD ?
       y DWORD ?
point ENDS

rect STRUCT
      p1 point <>
      p2 point <>
rect ENDS


.data
rc rect <12, 34, 56, 78>

.code
MyTest proc pRect:DWORD
  mov eax, pRect
  # printf("right = %d\n" , EAX.rect.p2.x);
  ret
MyTest endp



; #########################################################################
^^

void main()
{
     
     
  ^  invoke MyTest, offset rc
     
           
     MessageBox(0,"","",0);
}


Enjoy coding with c--,Masm,Basic.

Emil_halim

Hi all,

Due to some linking stuff bugs that i faced when creating c-- obj file  with GoLink linker.

I have decided that , All Masm [ML]  & Pelles c [pocc] stuff must compiled to Ext.dll then c-- can link to it's functions without any error.

so i created a new directive "#Imports" that allow automatically exports the functions in Ext.dll those will be used and called from c-- code. 

here is a simple example showing you the idea

Pelles c code [test.c]
===============




__declspec(naked) unsigned long* MyTest(int idx)
{
    __asm {
        mov eax,[esp+4]        ; idx arg
        add eax,eax            ; *2
        add eax,eax            ; *4
        add eax,offset label
        ret

        align 4
        label:  dd  1,2,3,4,5,6,7,8
    }
}



c-- code
=======


/*************************************
*           Sphinx C--               * 
*                                    *
*     using asm with Pelles C        *
*                                    *
*         by Emil_halim              *         
*                                    *
*************************************/

#pragma option w32c       //create Windows console EXE.
#pragma option OS         //speed optimization
#jumptomain NONE          //just jump to main function

#CleanFiles of

#includepath "D:\Ext_c--\winlib" 

#include <windows.h> 
#include <MSVCRT.H-->


#imports "C" MyTest
#include "test.c"

 
#pragma option ia        //allow inserte asm instructions

#pragma option LST

void main()
{
   
   printf("%d \n" , MyTest(1) );
   
   MessageBox(0,"","",0);
}



Enjoy coding with c--,Masm,Basic.