$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

Intel Assembly Language Syntax Example:

The following 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