JIT-Assembler (x86)

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

JIT-Assembler (x86)

Postby IchMagBier » Dec 06, 2018 3:57

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: 347
Joined: Jan 05, 2014 12:33
Location: Belgium

Re: JIT-Assembler (x86)

Postby Provoni » Dec 06, 2018 10:57

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.

Return to “Projects”

Who is online

Users browsing this forum: ron77 and 9 guests