Author Topic: Howto use MACRO and ASM in O2  (Read 1605 times)

0 Members and 1 Guest are viewing this topic.

chrisc

  • Guest
Howto use MACRO and ASM in O2
« on: February 25, 2018, 06:15:40 AM »

Hello all

i would like to use macro and inline asm as in PB 
how to add them into oxygen basic code ?

Can someone please give an example each of macro and an inline asm.


in PB I have the following macro which are just markers
how do I place them in O2?


Code: [Select]
' Declaration of VM_Risc markers
 MACRO VM_RISC_BEGIN  = ! DB &HEB, &H08, &H56, &H4D, &H42, &H45, &H47, &H49, &H4E, &H31
 MACRO VM_RISC_END  = ! DB &HEB, &H08, &H56, &H4D, &H45, &H4E, &H44, &H31, &H00, &H00





In powerbasic I have the following hash function in asm  how to convert to O2 ?


Code: [Select]
'============================================
FUNCTION CRepFNV32(BYVAL dwOffset AS DWORD, BYVAL dwLen AS DWORD, _
      BYVAL offset_basis AS DWORD) AS QUAD
    ' Exits function if string len = 0 otherwise can GPF   Aug 1 2017
      IF dwLen = 0 THEN
         FUNCTION = 0
         EXIT FUNCTION
      END IF

#REGISTER NONE
! mov esi, dwOffset      ;esi = ptr to buffer
! mov ecx, dwLen         ;ecx = length of buffer (counter)
! mov eax, offset_basis  ;set to 0 for FNV-0, or 2166136261 for FNV-1
! mov edi, &h01000193    ;FNV_32_PRIME = 16777619
! xor ebx, ebx           ;ebx = 0
nextbyte:
! mul edi                ;eax = eax * FNV_32_PRIME
! mov bl, [esi]          ;bl = byte from esi
! xor eax, ebx           ;al = al xor bl
! inc esi                ;esi = esi + 1 (buffer pos)
! dec ecx                ;ecx = ecx - 1 (counter)
! jnz nextbyte           ;if ecx is 0, jmp to NextByte
! mov FUNCTION, eax      ;else, function = eax
END FUNCTION







chrisc

  • Guest
Re: Howto use MACRO and ASM in O2
« Reply #1 on: February 25, 2018, 06:46:46 AM »
I added the macros and was able to compile without problems

Code: [Select]
' Declaration of VM_Risc markers
 MACRO VM_RISC_BEGIN  = ! DB &HEB, &H08, &H56, &H4D, &H42, &H45, &H47, &H49, &H4E, &H31
 MACRO VM_RISC_END  = ! DB &HEB, &H08, &H56, &H4D, &H45, &H4E, &H44, &H31, &H00, &H00





but  not the ASM function as below -- error started at line #REGISTER NONE


Code: [Select]
'============================================
FUNCTION CRepFNV32(BYVAL dwOffset AS DWORD, BYVAL dwLen AS DWORD, _
      BYVAL offset_basis AS DWORD) AS QUAD
    ' Exits function if string len = 0 otherwise can GPF   Aug 1 2017
      IF dwLen = 0 THEN
         FUNCTION = 0
         EXIT FUNCTION
      END IF

#REGISTER NONE
! mov esi, dwOffset      ;esi = ptr to buffer
! mov ecx, dwLen         ;ecx = length of buffer (counter)
! mov eax, offset_basis  ;set to 0 for FNV-0, or 2166136261 for FNV-1
! mov edi, &h01000193    ;FNV_32_PRIME = 16777619
! xor ebx, ebx           ;ebx = 0
nextbyte:
! mul edi                ;eax = eax * FNV_32_PRIME
! mov bl, [esi]          ;bl = byte from esi
! xor eax, ebx           ;al = al xor bl
! inc esi                ;esi = esi + 1 (buffer pos)
! dec ecx                ;ecx = ecx - 1 (counter)
! jnz nextbyte           ;if ecx is 0, jmp to NextByte
! mov FUNCTION, eax      ;else, function = eax
END FUNCTION


Charles Pegge

  • Guest
Re: Howto use MACRO and ASM in O2
« Reply #2 on: February 25, 2018, 09:14:08 AM »
Hi Chris,

Almost!

Our Macros are a bit like subs:

Code: [Select]
' Declaration of VM_Risc markers
 MACRO VM_RISC_BEGIN()  DB &HEB, &H08, &H56, &H4D, &H42, &H45, &H47, &H49, &H4E, &H31
 MACRO VM_RISC_END()  DB &HEB, &H08, &H56, &H4D, &H45, &H4E, &H44, &H31, &H00, &H00

The ebx register must be preserved for global use.
asm is fully integrated with o2basic, so no plings required.
this code is okay for 32bit compiling but requires 64bit variables and 64bit register usage for pointers.

Code: [Select]
FUNCTION CRepFNV32(BYVAL dwOffset AS DWORD, BYVAL dwLen AS DWORD, _
      BYVAL offset_basis AS DWORD) AS QUAD
    ' Exits function if string len = 0 otherwise can GPF   Aug 1 2017
      IF dwLen = 0 THEN
         FUNCTION = 0
         EXIT FUNCTION
      END IF

'#REGISTER NONE
sys mebx
mov mebx,ebx 'save ebx register, all globals use it, ebp is used by all locals
'
mov esi, dwOffset      ;esi = ptr to buffer
mov ecx, dwLen         ;ecx = length of buffer (counter)
mov eax, offset_basis  ;set to 0 for FNV-0, or 2166136261 for FNV-1
mov edi, &h01000193    ;FNV_32_PRIME = 16777619
xor ebx, ebx           ;ebx = 0
nextbyte:
mul edi                ;eax = eax * FNV_32_PRIME
mov bl, [esi]          ;bl = byte from esi
xor eax, ebx           ;al = al xor bl
inc esi                ;esi = esi + 1 (buffer pos)
dec ecx                ;ecx = ecx - 1 (counter)
jnz nextbyte           ;if ecx is 0, jmp to NextByte
mov FUNCTION, eax      ;else, function = eax
'
mov ebx,mebx 'retore ebx register
'
END FUNCTION



chrisc

  • Guest
Re: Howto use MACRO and ASM in O2
« Reply #3 on: February 25, 2018, 10:01:29 AM »
Thanxx Charles

You are a supreme ASM magician

Charles Pegge

  • Guest
Re: Howto use MACRO and ASM in O2
« Reply #4 on: February 25, 2018, 11:51:18 AM »
A rough and ready conversion to 64bit:

note the use of sys instead of dword, and all the register names beginning with r instead of e

Code: [Select]
$ filename "t.exe"
using rtl64

FUNCTION CRepFNV32(BYVAL dwOffset AS SYS, BYVAL dwLen AS SYS, _
      BYVAL offset_basis AS SYS) AS QUAD
    ' Exits function if string len = 0 otherwise can GPF   Aug 1 2017
      IF dwLen = 0 THEN
         FUNCTION = 0
         EXIT FUNCTION
      END IF
extern cdecl
'#REGISTER NONE
sys mrbx
mov mrbx,rbx 'save ebx register, all globals use it, ebp is used by all locals
'
mov rsi, dwOffset      ;esi = ptr to buffer
mov rcx, dwLen         ;ecx = length of buffer (counter)
mov rax, offset_basis  ;set to 0 for FNV-0, or 2166136261 for FNV-1
mov rdi, &h01000193    ;FNV_32_PRIME = 16777619
xor rbx, rbx           ;ebx = 0
nextbyte:
mul rdi                ;eax = eax * FNV_32_PRIME
mov bl, [rsi]          ;bl = byte from esi
xor rax, rbx           ;al = al xor bl
inc rsi                ;esi = esi + 1 (buffer pos)
dec rcx                ;ecx = ecx - 1 (counter)
jnz nextbyte           ;if ecx is 0, jmp to NextByte
mov FUNCTION, rax      ;else, function = eax
'
mov rbx,mrbx 'retore ebx register
'
END FUNCTION
print "ok"

chrisc

  • Guest
Re: Howto use MACRO and ASM in O2
« Reply #5 on: February 25, 2018, 01:00:54 PM »
This means that we need to change dword to sys when converting from pb to o2?

Charles Pegge

  • Guest
Re: Howto use MACRO and ASM in O2
« Reply #6 on: February 25, 2018, 04:07:16 PM »
Sys is required for handles and pointers, whose widths will extend to 64 bits in a 64bit binary. Dword usage for non-pointers remains pretty much the same.