The basics are in place, and the following code runs:
NL as string
NL=chr$(10)
TestCode$=""
TestCode$=TestCode$ + "test:" + NL
TestCode$=TestCode$ + " mov eax, dword[reg0]" + NL
TestCode$=TestCode$ + " mov ebx, dword[reg1]" + NL
TestCode$=TestCode$ + " mov dword[reg0], ebx" + NL
TestCode$=TestCode$ + " mov dword[reg1], eax" + NL
TestCode$=TestCode$ + " mov eax, MyValue" + NL
TestCode$=TestCode$ + " mov dword[reg2], eax" + NL
TestCode$=TestCode$ + " ret" + NL
CallCode$=""
CallCode$=CallCode$ + "caller:" + NL
CallCode$=CallCode$ + " call test" + NL
CallCode$=CallCode$ + " ret" + NL
` Define all symbols releated to the up-and-coming assembly
SET ASSEMBLY SYMBOL "MyValue", 987654321
print "Assembling test code"
ok = CREATE ASSEMBLY CODE( "test", TestCode$ )
if ok then ok = CREATE ASSEMBLY CODE( "caller", CallCode$ )
if ok
print "No errors during compilation"
print
print "Setting the registers"
SET ASSEMBLY REGISTER 0,12345
SET ASSEMBLY REGISTER 1,54321
SET ASSEMBLY REGISTER 2,0
print
print "Before:"
print "Register 0 = "; GET ASSEMBLY REGISTER(0)
print "Register 1 = "; GET ASSEMBLY REGISTER(1)
print "Register 2 = "; GET ASSEMBLY REGISTER(2)
print
print "Executing the assembly code"
ok=EXECUTE ASSEMBLY CODE("caller")
if ok
print
print "After:"
print "Register 0 = "; GET ASSEMBLY REGISTER(0)
print "Register 1 = "; GET ASSEMBLY REGISTER(1)
print "Register 2 = "; GET ASSEMBLY REGISTER(2)
endif
endif
if ok = 0
print "Error : "; GET ASSEMBLY ERROR$(); ""
endif
WaitInput()
end
function WaitInput()
do
if mouseclick() then exitfunction
if scancode() then exitfunction
loop
endfunction
It correctly swaps the contents of reg0 and reg1, and sets the correct value into reg2.
Some things to note:
No parameter passing yet - instead I've created 1024 'registers' to allow passing of data.
Symbols must be defined before compiling - the assembler compiles immediately and cannot cope with undefined symbols.
Creating a piece of code creates a symbol that can be used in code compiled later ('test' and 'caller')
Things not shown yet:
Conditional compilation - this is already built into the library, I just haven't tried it yet.
Static data - use DB, DW and DD to define the data.
All labels in a compilation unit are local, except for the entry point.
Things still to do:
Parameter passing - probably using the c calling convention as this is least limiting.
Load assembly code directly from a file - not sure it's necessary.
Allow calling of DBPro functions - undecided on this one.
Somehow get external symbols defined - for example 'malloc'. Unless you can get the funciton address, you can't call it.