$ASM directive

Purpose: The $ASM directive allows inline assembly instructions to be used with BCX. An $ASM directive must be placed before and after the assembly statements.


 Syntax:

 $ASM
  /** Assembly statements go here */
 $ASM

Pelle's C Example:

The following example is a mixed code demo constructed to show the use of the $ASM directive with BCX and the Pelle's C compiler Intel syntax assembly language (opcode, destination, source).


 '********************************************************************
 ' Substr.bas written by Robert Wishlaw
 ' based on assembly code by Rainbow Sally
 ' modified by Michael Lobanovsky
 '********************************************************************
  
 DIM str1$
 DIM str2$
  
 str1$ = "123456789"
  
 str2$ = AsmLeft$(str1$, 3)
 PRINT str2$
  
 str2$ = AsmMid$(str1$, 4, 3)
 PRINT str2$
  
 str2$ = AsmMid$(str1$, 4)
 PRINT str2$
  
 str2$ = AsmRight$(str1$, 3)
 PRINT str2$
  
  
 FUNCTION SubStr%(SrcStr AS LPSTR, SrcStrLen%, StartPosn%, DestStr AS LPSTR, DestStrLen%)
 $ASM
  nop
  nop
  nop
  
  ;save used registers except for eax:edx
  push ebx
  push ecx
  push edi
  push esi
  
  ;load the 32-bit registers from the stack
  
  mov esi, dword ptr [ebp+8]  ;SrcStr
  mov edx, dword ptr [ebp+12] ;SrcLen
  mov eax, dword ptr [ebp+16] ;StartPosn
  mov edi, dword ptr [ebp+20] ;DestStr
  mov ecx, dword ptr [ebp+24] ;DestLen
  
  ;check for zero-length Destination string
  jecxz NoGood
  
  ;compensate StartPosn for 0 based count
  dec eax
  
  ;check for negative offset of StartPosn
  cmp eax, 0
  jl NoGood
  
  ;point esi to start of SrcStr
  add esi, eax
  
  ;and subtract StartPosn from SrcLen
  sub edx, eax
  
  ;check if offset is past end of SrcStr
  cmp edx, 0
  jle NoGood
  
  ;move substring of esi into edi
  rep movsb
  
  ;return this to indicate function worked
  mov eax, edi
  jmp ReturnAX
  
  NoGood:
  mov eax, -1
  
  ReturnAX:
  pop esi
  pop edi
  pop ecx
  pop ebx
  pop ebp
  ret 
 $ASM
 FUNCTION = 0
 END FUNCTION
  
 'Left$ equivalent
 FUNCTION AsmLeft$(fnstr1$, fnint1%)
 DIM RAW startp% = 1
 DIM RAW retstr$ * fnint1% + 256
 SubStr(fnstr1$, LEN(fnstr1$), startp%, retstr$, fnint1%)
 retstr[fnint1] = 0
 FUNCTION = retstr$
 END FUNCTION
  
 'MID$ equivalent
 FUNCTION AsmMid$ OPTIONAL(fnstr1$, fnint1%, fnint2%=0)
 DIM RAW startp% = fnint1%
 DIM RAW lenfnstr1% = LEN(fnstr1$)
 DIM RAW retstr$ * fnint2% + 256
 IF fnint2% = 0 THEN
   fnint2% = lenfnstr1% - startp% + 1
 END IF
 SubStr(fnstr1$, lenfnstr1%, startp%, retstr$, fnint2%)
 retstr[fnint2] = 0
 FUNCTION = retstr$
 END FUNCTION
  
 'RIGHT$ equivalent
 FUNCTION AsmRight$(fnstr1$, fnint1%)
 DIM RAW lenfnstr1% = LEN(fnstr1$)
 DIM RAW startp% = lenfnstr1% - fnint1% + 1
 DIM RAW retstr$ * fnint1% + 256
 SubStr(fnstr1$, lenfnstr1%, startp%, retstr$, fnint1%)
 retstr[fnint1] = 0
 FUNCTION = retstr$
 END FUNCTION