$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

Example:

The following Intel Assembly Language Syntax example is a mixed code demo constructed to show the use of the $ASM directive with BCX using Intel assembly language syntax, that is, opcode, destination, source.

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$
 
PAUSE

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
  leave
  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