JIT-Assembler (x86)

User projects written in or related to FreeBASIC.
Post Reply
IchMagBier
Posts: 52
Joined: Jan 13, 2018 8:47
Location: Germany
Contact:

JIT-Assembler (x86)

Post by IchMagBier »

Hello

I was in need of creating executable code during runtime, so I have created this little JIT-Assembler. It allows you to dynamically compile Assembler-code during runtime. This can be used to speed up a scripting language or an emulator. At the moment it only works with 8bit operations, I might add 32 or 64bit ops in the future. The syntax is similar to AT&T rather than Intel:

Code: Select all

movb(123,al)		'al = 123
Usage
Just write your code like you would in ASM. When you are finished you call "asm_execute()" to execute the generated code:

Code: Select all

dim shared as ubyte tests = 1
 addb(41,@tests)	'tests += 41
 ret()				 'end
asm_execute()
print tests		 '42
It is important to add a "ret" at the end of your code.
Labels and JMPs:

Code: Select all

jmp("testlabel")
movb(al,bl)	'This code won't be executed
jmp_label("testlabel")
ret()
When you are finished executing the code, call the sub "asm_reset()", when you want to create more code:

Code: Select all

' // First code:
 shlb(al)
 ret()
asm_execute()
' // Second code:
asm_reset()
 andb(&h10,bh)
 ret()
asm_execute()
Features
The following operations are possible ...
  • Integer -> Register
    movb(123,al) 'al = 123
  • Register -> Register
    movb(bl,al) 'al = bl
  • Variable -> Register
    movb(@var,al) 'al = var
  • Register -> Variable
    movb(al,@var) 'var = al
  • Integer -> Variable
    movb(123,@var) 'var = 123
... with the following commands ...
  • mov
  • add, sub
  • and, or, xor, not
  • cmp
  • jmp, je, jne, ja, jb
  • sete, setne, seta, setb
  • shl, shr (only shift by one bit!)
  • ret
... in the following registers:
  • al , ah
  • bl , bh
  • cl , ch
  • dl , dh
It *should* work on Linux, Windows and DOS, both 32- and 64bit. I only tested it on Linux and Windows 10 64bit though.
Code

Code: Select all

#define __code_groesse 64000

dim shared as ulong __code_position, __code_position2
dim shared as long __jmp_position
dim shared as ubyte ptr __code
dim shared as string __code_string

#ifdef __FB_64BIT__
	#ifdef __FB_LINUX__
		asm 
			xor rdi, rdi			'Adresse = 0
			mov rsi, __code_groesse	'Größe = 64kB
			mov rdx, 7				'Lesen ODER Schreiben ODER Ausführen
			mov r10, 34				'map_annonymous ODER map_private
			xor r8, r8
			xor r9, r9
			mov rax, 9				'mmap
			syscall
			mov [__code], rax
		end asm
	#else 	'WINDOWS
		#include once "windows.bi"
		#include once "win/winbase.bi"
		__code = VirtualAlloc(0,__code_groesse,MEM_COMMIT,PAGE_EXECUTE_READWRITE)
	#endif
#else 	'32bit Win/Linux/DOS
	__code = allocate(__code_groesse)
#endif

#define asm_size() __code_position
#define asm_execute() asm call __code

sub asm_reset()
	__code_position = 0 : __jmp_position = 0 : __code_position2 = 0
	__code_string = ""
end sub

sub asm_clear()
	asm_reset()
	#ifdef __FB_64BIT__

	#else
		deallocate(__code)
	#endif
end sub

const al = "al"
const bl = "bl"
const cl = "cl"
const dl = "dl"
const ah = "ah"
const bh = "bh"
const ch = "ch"
const dh = "dh"

enum REG
	C_AL,C_CL,C_DL,C_BL,C_AH,C_CH,C_DH,C_BH
end enum

function __register(reg as ubyte)as string
	select case as const reg
		case C_AL : return "al"
		case C_CL : return "cl"
		case C_DL : return "dl"
		case C_BL : return "bl"
		case C_AH : return "ah"
		case C_CH : return "ch"
		case C_DH : return "dh"
		case C_BH : return "bh"
	end select
end function

function __register_string(reg as string)as ubyte
	select case reg
		case "al" : return C_AL
		case "cl" : return C_CL
		case "dl" : return C_DL
		case "bl" : return C_BL
		case "ah" : return C_AH
		case "ch" : return C_CH
		case "dh" : return C_DH
		case "bh" : return C_BH
	end select
end function

#macro c_i32(i32)
	__code[__code_position]=lobyte(i32)
	__code[__code_position+1]=hibyte(i32)
	__code[__code_position+2]=lobyte(hiword(i32))
	__code[__code_position+3]=hibyte(hiword(i32))
	__code_position+=4
#endmacro

#macro movb(par1,par2):
	#if typeof(par2) = "ZSTRING * 3"
		#if typeof(par1) = INTEGER
			mov_i8_r8(par1,__register_string(par2))
		#elseif typeof(par1) = "ZSTRING * 3"
			mov_r8_r8(__register_string(par1),__register_string(par2))
		#else
			mov_m8_r8(par1,__register_string(par2))
		#endif
	#else
		#if typeof(par1) = INTEGER
			mov_i8_m8(par1,par2)
		#elseif typeof(par1) = "ZSTRING * 3"
			mov_r8_m8(__register_string(par1),par2)
		#else
			#error "(ASM) 'mov' memory to memory operations not allowed"
		#endif
	#endif
#endmacro

#macro andb(par1,par2):
	#if typeof(par2) = "ZSTRING * 3"
		#if typeof(par1) = INTEGER
			and_i8_r8(par1,__register_string(par2))
		#elseif typeof(par1) = "ZSTRING * 3"
			and_r8_r8(__register_string(par1),__register_string(par2))
		#else
			and_m8_r8(par1,__register_string(par2))
		#endif
	#else
		#if typeof(par1) = INTEGER
			and_i8_m8(par1,par2)
		#elseif typeof(par1) = "ZSTRING * 3"
			and_r8_m8(__register_string(par1),par2)
		#else
			#error "(ASM) 'and' memory to memory operations not allowed"
		#endif
	#endif
#endmacro

#macro orb(par1,par2):
	#if typeof(par2) = "ZSTRING * 3"
		#if typeof(par1) = INTEGER
			or_i8_r8(par1,__register_string(par2))
		#elseif typeof(par1) = "ZSTRING * 3"
			or_r8_r8(__register_string(par1),__register_string(par2))
		#else
			or_m8_r8(par1,__register_string(par2))
		#endif
	#else
		#if typeof(par1) = INTEGER
			or_i8_m8(par1,par2)
		#elseif typeof(par1) = "ZSTRING * 3"
			or_r8_m8(__register_string(par1),par2)
		#else
			#error "(ASM) 'or' memory to memory operations not allowed"
		#endif
	#endif
#endmacro

#macro xorb(par1,par2):
	#if typeof(par2) = "ZSTRING * 3"
		#if typeof(par1) = INTEGER
			xor_i8_r8(par1,__register_string(par2))
		#elseif typeof(par1) = "ZSTRING * 3"
			xor_r8_r8(__register_string(par1),__register_string(par2))
		#else
			xor_m8_r8(par1,__register_string(par2))
		#endif
	#else
		#if typeof(par1) = INTEGER
			xor_i8_m8(par1,par2)
		#elseif typeof(par1) = "ZSTRING * 3"
			xor_r8_m8(__register_string(par1),par2)
		#else
			#error "(ASM) 'xor' memory to memory operations not allowed"
		#endif
	#endif
#endmacro

#macro addb(par1,par2):
	#if typeof(par2) = "ZSTRING * 3"
		#if typeof(par1) = INTEGER
			add_i8_r8(par1,__register_string(par2))
		#elseif typeof(par1) = "ZSTRING * 3"
			add_r8_r8(__register_string(par1),__register_string(par2))
		#else
			add_m8_r8(par1,__register_string(par2))
		#endif
	#else
		#if typeof(par1) = INTEGER
			add_i8_m8(par1,par2)
		#elseif typeof(par1) = "ZSTRING * 3"
			add_r8_m8(__register_string(par1),par2)
		#else
			#error "(ASM) 'add' memory to memory operations not allowed"
		#endif
	#endif
#endmacro

#macro subb(par1,par2):
	#if typeof(par2) = "ZSTRING * 3"
		#if typeof(par1) = INTEGER
			sub_i8_r8(par1,__register_string(par2))
		#elseif typeof(par1) = "ZSTRING * 3"
			sub_r8_r8(__register_string(par1),__register_string(par2))
		#else
			sub_m8_r8(par1,__register_string(par2))
		#endif
	#else
		#if typeof(par1) = INTEGER
			sub_i8_m8(par1,par2)
		#elseif typeof(par1) = "ZSTRING * 3"
			sub_r8_m8(__register_string(par1),par2)
		#else
			#error "(ASM) 'sub' memory to memory operations not allowed"
		#endif
	#endif
#endmacro

#macro cmpb(par1,par2):
	#if typeof(par2) = "ZSTRING * 3"
		#if typeof(par1) = INTEGER
			cmp_i8_r8(par1,__register_string(par2))
		#elseif typeof(par1) = "ZSTRING * 3"
			cmp_r8_r8(__register_string(par1),__register_string(par2))
		#else
			cmp_m8_r8(par1,__register_string(par2))
		#endif
	#else
		#if typeof(par1) = INTEGER
			cmp_i8_m8(par1,par2)
		#elseif typeof(par1) = "ZSTRING * 3"
			cmp_r8_m8(__register_string(par1),par2)
		#else
			#error "(ASM) 'cmp' memory to memory operations not allowed"
		#endif
	#endif
#endmacro

#macro notb(par):
	#if typeof(par) = "ZSTRING * 3"
		not_r8(__register_string(par))
	#else
		#error "(ASM) 'not' operation is only allowed with __registers"
	#endif
#endmacro

#macro seteb(par):
	#if typeof(par) = "ZSTRING * 3"
		sete_r8(__register_string(par))
	#else
		sete_m8(par)
	#endif
#endmacro

#macro setneb(par):
	#if typeof(par) = "ZSTRING * 3"
		setne_r8(__register_string(par))
	#else
		setne_m8(par)
	#endif
#endmacro

#macro shlb(par):
	#if typeof(par) = "ZSTRING * 3"
		shl_r8(__register_string(par))
	#else
		shl_m8(par)
	#endif
#endmacro

#macro shrb(par):
	#if typeof(par) = "ZSTRING * 3"
		shr_r8(__register_string(par))
	#else
		shr_m8(par)
	#endif
#endmacro

#macro mov_i8_r8(wert,reg):
	__code_string+="movb $"+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&hB0+reg : __code_position += 1
	__code[__code_position]=wert : __code_position += 1
#endmacro

#macro mov_r8_r8(reg1,reg2):
	__code_string+="movb %"+__register(reg1)+", %"+__register(reg2)+!"\n"
	__code[__code_position]=&h88
	__code[__code_position+1]=(reg1*8)+reg2+&hC0
	__code_position += 2
#endmacro

#macro mov_m8_r8(wert,reg):
	__code_string+="movb "+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&h8A
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro mov_r8_m8(reg,wert):
	__code_string+="movb %"+__register(reg)+", "+str(wert)+!"\n"
	__code[__code_position]=&h88
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro mov_i8_m8(wert2,wert):
	__code_string+="movb $"+str(wert2)+", "+str(wert)+!"\n"
	__code[__code_position]=&hC6
	__code[__code_position+1]=&h04
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
	__code[__code_position]=wert2 : __code_position += 1
#endmacro

#macro not_r8(reg):
	__code_string+="notb %"+__register(reg)+!"\n"
	__code[__code_position]=&hF6 : __code_position += 1
	__code[__code_position]=&hD0+reg : __code_position += 1
#endmacro

#macro and_i8_r8(wert,reg):
	__code_string+="andb $"+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&h80 : __code_position += 1
	__code[__code_position]=&hE0+reg : __code_position += 1
	__code[__code_position]=wert : __code_position += 1
#endmacro

#macro and_r8_r8(reg1,reg2):
	__code_string+="andb %"+__register(reg1)+", %"+__register(reg2)+!"\n"
	__code[__code_position]=&h20
	__code[__code_position+1]=(reg1*8)+reg2+&hC0
	__code_position += 2
#endmacro

#macro and_m8_r8(wert,reg):
	__code_string+="andb "+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&h22
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro and_r8_m8(reg,wert):
	__code_string+="andb %"+__register(reg)+", "+str(wert)+!"\n"
	__code[__code_position]=&h20
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro and_i8_m8(wert2,wert):
	__code_string+="andb $"+str(wert2)+", "+str(wert)+!"\n"
	__code[__code_position]=&h80
	__code[__code_position+1]=&h24
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
	__code[__code_position]=wert2 : __code_position += 1
#endmacro

#macro or_i8_r8(wert,reg):
	__code_string+="orb $"+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&h80 : __code_position += 1
	__code[__code_position]=&hC8+reg : __code_position += 1
	__code[__code_position]=wert : __code_position += 1
#endmacro

#macro or_r8_r8(reg1,reg2):
	__code_string+="orb %"+__register(reg1)+", %"+__register(reg2)+!"\n"
	__code[__code_position]=&h08
	__code[__code_position+1]=(reg1*8)+reg2+&hC0
	__code_position += 2
#endmacro

#macro or_m8_r8(wert,reg):
	__code_string+="orb "+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&h0A
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro or_r8_m8(reg,wert):
	__code_string+="orb %"+__register(reg)+", "+str(wert)+!"\n"
	__code[__code_position]=&h08
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro or_i8_m8(wert2,wert):
	__code_string+="orb $"+str(wert2)+", "+str(wert)+!"\n"
	__code[__code_position]=&h80
	__code[__code_position+1]=&h0C
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
	__code[__code_position]=wert2 : __code_position += 1
#endmacro

#macro xor_i8_r8(wert,reg):
	__code_string+="xorb $"+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&h80 : __code_position += 1
	__code[__code_position]=&hF0+reg : __code_position += 1
	__code[__code_position]=wert : __code_position += 1
#endmacro

#macro xor_r8_r8(reg1,reg2):
	__code_string+="xorb %"+__register(reg1)+", %"+__register(reg2)+!"\n"
	__code[__code_position]=&h30
	__code[__code_position+1]=(reg1*8)+reg2+&hC0
	__code_position += 2
#endmacro

#macro xor_m8_r8(wert,reg):
	__code_string+="xorb "+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&h32
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro xor_r8_m8(reg,wert):
	__code_string+="xorb %"+__register(reg)+", "+str(wert)+!"\n"
	__code[__code_position]=&h30
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro xor_i8_m8(wert2,wert):
	__code_string+="xorb $"+str(wert2)+", "+str(wert)+!"\n"
	__code[__code_position]=&h80
	__code[__code_position+1]=&h34
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
	__code[__code_position]=wert2 : __code_position += 1
#endmacro

#macro add_i8_r8(wert,reg):
	__code_string+="addb $"+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&h80 : __code_position += 1
	__code[__code_position]=&hC0+reg : __code_position += 1
	__code[__code_position]=wert : __code_position += 1
#endmacro

#macro add_r8_r8(reg1,reg2):
	__code_string+="addb %"+__register(reg1)+", %"+__register(reg2)+!"\n"
	__code[__code_position]=&h00
	__code[__code_position+1]=(reg1*8)+reg2+&hC0
	__code_position += 2
#endmacro

#macro add_m8_r8(wert,reg):
	__code_string+="addb "+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&h02
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro add_r8_m8(reg,wert):
	__code_string+="addb %"+__register(reg)+", "+str(wert)+!"\n"
	__code[__code_position]=&h00
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro add_i8_m8(wert2,wert):
	__code_string+="addb $"+str(wert2)+", "+str(wert)+!"\n"
	__code[__code_position]=&h80
	__code[__code_position+1]=&h04
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
	__code[__code_position]=wert2 : __code_position += 1
#endmacro

#macro sub_i8_r8(wert,reg):
	__code_string+="subb $"+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&h80 : __code_position += 1
	__code[__code_position]=&hE8+reg : __code_position += 1
	__code[__code_position]=wert : __code_position += 1
#endmacro

#macro sub_r8_r8(reg1,reg2):
	__code_string+="subb %"+__register(reg1)+", %"+__register(reg2)+!"\n"
	__code[__code_position]=&h28
	__code[__code_position+1]=(reg1*8)+reg2+&hC0
	__code_position += 2
#endmacro

#macro sub_m8_r8(wert,reg):
	__code_string+="subb "+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&h2A
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro sub_r8_m8(reg,wert):
	__code_string+="subb %"+__register(reg)+", "+str(wert)+!"\n"
	__code[__code_position]=&h28
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro sub_i8_m8(wert2,wert):
	__code_string+="subb $"+str(wert2)+", "+str(wert)+!"\n"
	__code[__code_position]=&h80
	__code[__code_position+1]=&h2C
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
	__code[__code_position]=wert2 : __code_position += 1
#endmacro

#macro cmp_i8_r8(wert,reg):
	__code_string+="cmpb $"+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&h80 : __code_position += 1
	__code[__code_position]=&hF8+reg : __code_position += 1
	__code[__code_position]=wert : __code_position += 1
#endmacro

#macro cmp_r8_r8(reg1,reg2):
	__code_string+="cmpb %"+__register(reg1)+", %"+__register(reg2)+!"\n"
	__code[__code_position]=&h38
	__code[__code_position+1]=(reg1*8)+reg2+&hC0
	__code_position += 2
#endmacro

#macro cmp_m8_r8(wert,reg):
	__code_string+="cmpb "+str(wert)+", %"+__register(reg)+!"\n"
	__code[__code_position]=&h3A
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro cmp_r8_m8(reg,wert):
	__code_string+="cmpb %"+__register(reg)+", "+str(wert)+!"\n"
	__code[__code_position]=&h38
	__code[__code_position+1]=&h04+reg*8
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro cmp_i8_m8(wert,mem):
	__code_string+="cmpb $"+str(wert)+", "+str(mem)+!"\n"
	__code[__code_position]=&h80
	__code[__code_position+1]=&h3C
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(mem)
	__code[__code_position]=wert
	__code_position += 1
#endmacro

#macro shl_r8(reg):
	__code_string+="shlb $1, "+__register(reg)+!"\n"
	__code[__code_position]=&hD0
	__code[__code_position+1]=&hE0+reg
	__code_position += 2
#endmacro

#macro shl_m8(wert):
	__code_string+="shlb $1, "+str(wert)+!"\n"
	__code[__code_position]=&hD0
	__code[__code_position+1]=&h24
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro shr_r8(reg):
	__code_string+="shrb $1, "+__register(reg)+!"\n"
	__code[__code_position]=&hD0
	__code[__code_position+1]=&hE8+reg
	__code_position += 2
#endmacro

#macro shr_m8(wert):
	__code_string+="shrb $1, "+str(wert)+!"\n"
	__code[__code_position]=&hD0
	__code[__code_position+1]=&h2C
	__code[__code_position+2]=&h25
	__code_position += 3
	c_i32(wert)
#endmacro

#macro sete_r8(reg):
	__code_string+="sete %"+__register(reg)+!"\n"
	__code[__code_position]=&h0F
	__code[__code_position+1]=&h94
	__code[__code_position+2]=&hC0+reg
	__code_position += 3
#endmacro

#macro sete_m8(wert):
	__code_string+="sete "+str(wert)+!"\n"
	__code[__code_position]=&h0F
	__code[__code_position+1]=&h94
	__code[__code_position+2]=&h04
	__code[__code_position+3]=&h25
	__code_position += 4
	c_i32(wert)
#endmacro

#macro setne_r8(reg):
	__code_string+="setne %"+__register(reg)+!"\n"
	__code[__code_position]=&h0F
	__code[__code_position+1]=&h95
	__code[__code_position+2]=&hC0+reg
	__code_position += 3
#endmacro

#macro setne_m8(wert):
	__code_string+="setne "+str(wert)+!"\n"
	__code[__code_position]=&h0F
	__code[__code_position+1]=&h95
	__code[__code_position+2]=&h04
	__code[__code_position+3]=&h25
	__code_position += 4
	c_i32(wert)
#endmacro

#macro seta_r8(reg):
	__code_string+="seta %"+__register(reg)+!"\n"
	__code[__code_position]=&h0F
	__code[__code_position+1]=&h97
	__code[__code_position+2]=&hC0+reg
	__code_position += 3
#endmacro

#macro seta_m8(wert):
	__code_string+="seta "+str(wert)+!"\n"
	__code[__code_position]=&h0F
	__code[__code_position+1]=&h97
	__code[__code_position+2]=&h04
	__code[__code_position+3]=&h25
	__code_position += 4
	c_i32(wert)
#endmacro

#macro setb_r8(reg):
	__code_string+="setb %"+__register(reg)+!"\n"
	__code[__code_position]=&h0F
	__code[__code_position+1]=&h92
	__code[__code_position+2]=&hC0+reg
	__code_position += 3
#endmacro

#macro setb_m8(wert):
	__code_string+="setb "+str(wert)+!"\n"
	__code[__code_position]=&h0F
	__code[__code_position+1]=&h92
	__code[__code_position+2]=&h04
	__code[__code_position+3]=&h25
	__code_position += 4
	c_i32(wert)
#endmacro

type t_Label
	as string nam
	as long position 'Position in __code[]
	as long suche(7) 'Suchpositionen, was muss ersetzt werden

	as t_Label ptr naechstes
end type

dim shared as t_Label ptr __Labels

function __such_label(nam as string)as long
	dim as t_Label ptr label = __Labels
	if label = 0 then return -1
	do
		if label->nam = nam then return label->position
		label = label->naechstes
	loop until label = 0
	return -1
end function

sub __neues_label(nam as string, position as long = 0)
	dim as t_Label ptr label = new t_Label
	label->position = position
	label->nam = nam
	label->suche(0) = __code_position
	label->naechstes = __Labels
	__Labels = label
end sub

#macro jmp(nam)
	__code_string+="jmp "+nam+!"\n"
	__jmp_position = __such_label(nam)
	if __jmp_position = -1 then
		__code[__code_position]=&hE9
		__code_position += 1
		__neues_label(nam)
		c_i32(0)
	else
		__code[__code_position]=&hEB
		__code[__code_position+1]=(__jmp_position-__code_position-2)
		__code_position += 2
	end if
#endmacro

#macro je(nam)
	__code_string+="je "+nam+!"\n"
	__jmp_position = __such_label(nam)
	if __jmp_position = -1 then
		__code[__code_position]=&h0F
		__code[__code_position+1]=&h84
		__code_position += 2
		__neues_label(nam)
		c_i32(0)
	else
		__code[__code_position]=&h74
		__code[__code_position+1]=(__jmp_position-__code_position-2)
		__code_position += 2
	end if
#endmacro

#macro jne(nam)
	__code_string+="jne "+nam+!"\n"
	__jmp_position = __such_label(nam)
	if __jmp_position = -1 then
		__code[__code_position]=&h0F
		__code[__code_position+1]=&h85
		__code_position += 2
		__neues_label(nam)
		c_i32(0)
	else
		__code[__code_position]=&h75
		__code[__code_position+1]=(__jmp_position-__code_position-2)
		__code_position += 2
	end if
#endmacro

#macro ja(nam)
	__code_string+="ja "+nam+!"\n"
	__jmp_position = __such_label(nam)
	if __jmp_position = -1 then
		__code[__code_position]=&h0F
		__code[__code_position+1]=&h87
		__code_position += 2
		__neues_label(nam)
		c_i32(0)
	else
		__code[__code_position]=&h77
		__code[__code_position+1]=(__jmp_position-__code_position-2)
		__code_position += 2
	end if
#endmacro

#macro jb(nam)
	__code_string+="jb "+nam+!"\n"
	__jmp_position = __such_label(nam)
	if __jmp_position = -1 then
		__code[__code_position]=&h0F
		__code[__code_position+1]=&h82
		__code_position += 2
		__neues_label(nam)
		c_i32(0)
	else
		__code[__code_position]=&h72
		__code[__code_position+1]=(__jmp_position-__code_position-2)
		__code_position += 2
	end if
#endmacro

#macro jmp_label(nams)
	__code_string+=nams+!":\n"
	__neues_label(nams,__code_position)
	dim as t_Label ptr label = __Labels
	while label <> 0
		if label->nam = nams then 
			label->position = __code_position
			__code_position2 = __code_position
			for i as integer = 0 to 7
				if label->suche(i) = 0 then exit for
				__code_position = label->suche(i)
				c_i32(__code_position2-label->suche(i)-4)
			next
			__code_position = __code_position2
		end if
		label = label->naechstes
	wend
#endmacro

' #macro jmp_label()
' 	__code_position2 = __code_position
' 	__code_position = __jmp_position
' 	c_i32(__code_position2-__jmp_position-4)
' 	__code_position = __code_position2
' #endmacro

#macro ret():
	__code_string+=!"ret\n"
	__code[__code_position]=&hC3 : __code_position += 1
#endmacro
Save this file as "assembler.bi" and include it. I know the code isn't very elegant, but it works fine.
Example

Code: Select all

#include "assembler.bi"
dim shared as ubyte tests = 21
 shlb(@tests)
 ret()
asm_execute()
print tests
(When do you say "Assembler" and when "Assembly"?)
Provoni
Posts: 513
Joined: Jan 05, 2014 12:33
Location: Belgium

Re: JIT-Assembler (x86)

Post by Provoni »

Thanks for sharing IchMagBier.
Wikipedia wrote: In computer science an assembler is a program that turns assembly language into machine code. An assembler is a program that takes basic computer instructions and converts them into a pattern of bits that the computer's processor can use to perform its basic operations. Some people call these instructions assembler language and others use the term assembly language.
Post Reply