Charles Pegge
09-03-2008, 13:56
Well I tried to keep it simple, but this is the best I could come up with for ThinBasic so far.
The machine code string now contains methods and a jump table to access them. This works like a SELECT CASE or ON..GOTO according to the function number.
Each object contains a very small piece of code (8bytes long) to call the methods string. This allows the address of the object's elements to be recovered from the stack for use by the methods.
There are any number of variations for this technique but this one is quite simple to use in the ThinBasic environment.
' Using Machine Code with ThinBasic
'---------------------------------------------------------------------------
'---Reference:
' Intel x86 Architecture Ref Manual Vol 2
'---http://developer.intel.com/design/pentiumii/manuals/243191.htm
'---------------------------------------------------------------------------
' Syntax rules:
' #Variable patches in long address of Variable (4 bytes)
' NLn patches in long decimal value n (4 bytes)
' comments are indicated by a quote mark '
' all other words are read as hexadecimal bytes.
' An error during MC_Eval$ will produce a string containing &hc3 (ret) only.
'----------------------------------------------
' accessing functions by number
'----------------------------------------------
dim fun as long ' function number
dim sMC as string = MC_Eval$ "
5a ' pop ' obj elements pointer
42 ' inc edx ' adjust pointer to the start of data elements
8b 05 #fun ' mov eax,fun ' get function number
c1 e0 03 ' shl eax,3 ' *8 step
83 c0 05 ' add eax,5 ' add 5 to reach jump table
e8 00 00 00 00 ' call null ' where am I ? identify absolute address
59 ' pop ecx ' pop my address here intp ecx
03 c1 ' add eax,ecx ' add to jump offset to get abs address
ff e0 ' jmp eax ' indirect jump to jump table
'-------------------------------'
' long jump table ' relative jumps with stride of 8
c3 00 00 00 00 00 00 00 ' ret ' ret if fun number =0
e9 0b 00 00 00 00 00 00 ' jmp long function_1 ' fun number = 1
e9 0b 00 00 00 00 00 00 ' jmp long function_2 ' fun number = 2 '
'-------------------------------'
' function 1 '
8b 42 00 ' mov eax,[edx+12] ' load .x element
40 ' inc eax ' increment
89 42 0c ' mov [edx+16],eax ' save in .a element
c3 ' ret '
'-------------------------------'
' function 2 '
8b 42 00 ' mov eax,[edx+12] ' load .x element
48 ' dec eax ' decrement
89 42 0c ' mov [edx+16],eax ' save in .a element
c3 ' ret '
'-------------------------------'
"
' Define Object structure
'
type an_obj_type
'---------'
' linking procedure (8 bytes)
g as byte ' b8 load eax immediate
p as long ' calling adress
c as word ' ff d0 call eax
b as byte ' padding
'---------'
' data elements
x as long ' offset 0
y as long ' offset 4
z as long ' offset 8
a as long ' offset c
end type
'
' create obj
'
dim myobj as an_obj_type
dim pMyObj as long = varptr(myobj)
myobj.g=&hb8 ' b8 load eax
myobj.p=strptr(sMC) ' address for MC methods
myobj.c=&hd0ff ' ffd0 call eax
' b is left for alignment padding
'
' initial data
'
myobj.x=08
myobj.y=16
myobj.z=24
myobj.a=32
'
fun=1 : call dword pMyObj ' fun can be 0 or 1 or 2
'
msgbox 0, myobj.a
The machine code string now contains methods and a jump table to access them. This works like a SELECT CASE or ON..GOTO according to the function number.
Each object contains a very small piece of code (8bytes long) to call the methods string. This allows the address of the object's elements to be recovered from the stack for use by the methods.
There are any number of variations for this technique but this one is quite simple to use in the ThinBasic environment.
' Using Machine Code with ThinBasic
'---------------------------------------------------------------------------
'---Reference:
' Intel x86 Architecture Ref Manual Vol 2
'---http://developer.intel.com/design/pentiumii/manuals/243191.htm
'---------------------------------------------------------------------------
' Syntax rules:
' #Variable patches in long address of Variable (4 bytes)
' NLn patches in long decimal value n (4 bytes)
' comments are indicated by a quote mark '
' all other words are read as hexadecimal bytes.
' An error during MC_Eval$ will produce a string containing &hc3 (ret) only.
'----------------------------------------------
' accessing functions by number
'----------------------------------------------
dim fun as long ' function number
dim sMC as string = MC_Eval$ "
5a ' pop ' obj elements pointer
42 ' inc edx ' adjust pointer to the start of data elements
8b 05 #fun ' mov eax,fun ' get function number
c1 e0 03 ' shl eax,3 ' *8 step
83 c0 05 ' add eax,5 ' add 5 to reach jump table
e8 00 00 00 00 ' call null ' where am I ? identify absolute address
59 ' pop ecx ' pop my address here intp ecx
03 c1 ' add eax,ecx ' add to jump offset to get abs address
ff e0 ' jmp eax ' indirect jump to jump table
'-------------------------------'
' long jump table ' relative jumps with stride of 8
c3 00 00 00 00 00 00 00 ' ret ' ret if fun number =0
e9 0b 00 00 00 00 00 00 ' jmp long function_1 ' fun number = 1
e9 0b 00 00 00 00 00 00 ' jmp long function_2 ' fun number = 2 '
'-------------------------------'
' function 1 '
8b 42 00 ' mov eax,[edx+12] ' load .x element
40 ' inc eax ' increment
89 42 0c ' mov [edx+16],eax ' save in .a element
c3 ' ret '
'-------------------------------'
' function 2 '
8b 42 00 ' mov eax,[edx+12] ' load .x element
48 ' dec eax ' decrement
89 42 0c ' mov [edx+16],eax ' save in .a element
c3 ' ret '
'-------------------------------'
"
' Define Object structure
'
type an_obj_type
'---------'
' linking procedure (8 bytes)
g as byte ' b8 load eax immediate
p as long ' calling adress
c as word ' ff d0 call eax
b as byte ' padding
'---------'
' data elements
x as long ' offset 0
y as long ' offset 4
z as long ' offset 8
a as long ' offset c
end type
'
' create obj
'
dim myobj as an_obj_type
dim pMyObj as long = varptr(myobj)
myobj.g=&hb8 ' b8 load eax
myobj.p=strptr(sMC) ' address for MC methods
myobj.c=&hd0ff ' ffd0 call eax
' b is left for alignment padding
'
' initial data
'
myobj.x=08
myobj.y=16
myobj.z=24
myobj.a=32
'
fun=1 : call dword pMyObj ' fun can be 0 or 1 or 2
'
msgbox 0, myobj.a