NO

Author Topic: coding in c closs to Asm  (Read 2890 times)

Emil_halim

  • Guest
coding in c closs to Asm
« on: October 27, 2018, 06:55:58 PM »
Hi ALL.

Just for fun , some c macro to simulate coding in asm.

Code: [Select]
/****************************************************************************
 *                                                                          *
 * Filename: casm.c                                                         *
 *                                                                          *
 * Purpose : Standard C sample for Pelles C for Windows.                    *
 *                                                                          *
 *           Demonstrates using the X86 inline assembler extension.         *
 *                                                                          *
 * History : Date      Reason                                               *
 *           05-03-12  Created                                              *
 *                                                                          *
 * Adapted By : Emil Halim
 *              27-10-2018
 *              coding with PellesC closs to asm
 ****************************************************************************/
#pragma comment(linker, "-subsystem:console")
#pragma comment(linker, "-entry:_mainCRTStartup")

#define $Asm  __asm {
#define $EndAsm     }
#define $DATA _asm
#define $Naked  _declspec(naked)
#define $  _asm
#define $_(x,y)  } x(y); _asm{

#define $invoke0(x)    call x
#define $invoke1(x,y)  push y ; $ call x
#define $invoke2(x,y1,y2)  push y2; $ push y1; $ call x

#define $uses( x1 , x2)  push x1; $ push x2
#define $unuses( x1 , x2)  pop x2; $ pop x1

#define $Proc(name,parm1)  $Naked int name(parm1){ $Asm
#define $EndP  } }


#pragma lib "crtdll.lib"    // found in purebasic
//#pragma lib "msvcrt.lib"
#pragma comment(linker, "kernel32.lib user32.lib gdi32.lib comdlg32.lib comctl32.lib")

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


#include <stdio.h>

static char format[] = "%s %s!\n";
static char hello[] = "Hello";
static char world[] = "world";

extern int __cdecl printf(const char* frmt,...);
extern void __stdcall ExitProcess(unsigned code);

extern char* __stdcall GetCommandLineA(void);

int __cdecl main(void);
/****************************************************************************
 *                                                                          *
 ****************************************************************************/


$Proc( prnt,const char* msg )
       
         push ebp
mov  ebp,esp
         mov  eax,[msg]
         push eax
         call printf
         add  esp,4
         mov  esp,ebp
pop  ebp
ret

$EndP

//https://forum.pellesc.de/index.php?topic=956.0
//_inline  need fix
int _DoesCPUSupportSSE( void )
{
   _asm{
    // Check feature flag 25 in EDX for SSE support
      MOV EAX, 1               
      CPUID                       
      MOV EAX, EDX           
      SHR EAX, 25             
      AND EAX, 1                   
      PUSH EAX
   }
}

$Naked int asm(void)
{
   $Asm
        // Call the C runtime function printf.
        // Same as the C code "printf(format, hello, world);"
        mov  eax,offset world
        push eax
        mov  eax,offset hello
        push eax
        mov  eax,offset format
        push eax
        call printf
        // printf is __cdecl, so we must clean the stack after the call.
        pop  ecx
        pop  ecx
        pop  ecx
    $EndAsm
$ ret
   
      $DATA val: DB 10
}

//Tiny C run-time startup module for console applications
// https://forum.pellesc.de/index.php?topic=88.15
char p__args[144];
$Naked void setargv(void)
{
    $Asm
        $uses( esi , edi)
    $invoke0( GetCommandLineA )
    mov esi,eax
    mov edx,offset p__args
    push edx
    lea edi,[edx+32]
    xor ecx,ecx
    mov ah,32
@6:
    lodsb
    test al,al
    jz @5
    cmp al,9
    jz @6
    cmp al,ah
    jz @6

    mov [edx],edi
    add edx,4
    inc ecx
    jmp @2
@1:
    lodsb
    cmp al,ah
    jz @3
    cmp al,9
    jz @3
@2:
    cmp al,34
    jnz @4
    xor ah,32
    jmp @1
@3:
    mov al,0
@4:
    stosb
    test al,al
    jnz @1
    dec esi
    jmp @6
@5:
    mov eax,ecx  // argc
    pop ecx      // argv[1]

        $unuses( esi , edi)
    ret
$EndAsm

   // $Data p__args: db 144 dup(0) // 32 for argv[x8], 128 for buffer
}

$Naked int  mainCRTStartup(void)
{
    $Asm
         push ebp
     mov ebp,esp
     $invoke0( setargv )
     $invoke2( main,eax,ecx) // argc,argv
         $invoke1( ExitProcess,eax )
    $EndAsm
}

int __cdecl main(void)
{
        asm();
prnt("welcom");
        if ( _DoesCPUSupportSSE() == 1 )
        {
             puts("SSE... OK");
            // do a sse operation...
        }
        return 0;
}
 

Have fun.
« Last Edit: October 27, 2018, 08:52:41 PM by Emil_halim »

Emil_halim

  • Guest
Re: coding in c closs to Asm
« Reply #1 on: October 27, 2018, 07:40:06 PM »

Updated $Proc macro.

Code: [Select]
#define $Proc(name,...)  $Naked int name(__VA_ARGS__){ $Asm