Oxygen Basic
Programming => Problems & Solutions => Topic started by: chrisc 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?
' 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 ?
'============================================
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
-
I added the macros and was able to compile without problems
' 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
'============================================
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
-
Hi Chris,
Almost!
Our Macros are a bit like subs:
' 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.
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
-
Thanxx Charles
You are a supreme ASM magician
-
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
$ 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"
-
This means that we need to change dword to sys when converting from pb to o2?
-
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.