Calling opcodes

General FreeBASIC programming questions.
Post Reply
IchMagBier
Posts: 52
Joined: Jan 13, 2018 8:47
Location: Germany
Contact:

Calling opcodes

Post by IchMagBier »

Hello
Is it somehow possible to call x86-opcodes with FreeBasic? Something like "CALL ABSOLUTE" in QBasic?
I tried the following:

Code: Select all

dim as ubyte test(0)={&hC3}
dim as ubyte ptr test_call=@test(0)
asm call [test_call]
But it is crashing with a "Segmentation fault" on my 64bit Linux.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Calling opcodes

Post by MrSwiss »

Well, calling Opcodes directly, is at best, a poor substitute for:
inline ASM (which is available in FB), therefore preferred.
IchMagBier
Posts: 52
Joined: Jan 13, 2018 8:47
Location: Germany
Contact:

Re: Calling opcodes

Post by IchMagBier »

I need to compile some stuff during runtime and can't do that with inline ASM alone.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Calling opcodes

Post by MrSwiss »

The statement by you, is by far to fuzzy to make sense, do you have a more "in depth explanation" ?
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Calling opcodes

Post by dodicat »

I don't know about Linux, but windows 64 bit fbc fails on asm call. (even to a simple label)
This crashes on 64 bit fbc win 10

Code: Select all



asm call label

asm label:
print "done"
sleep
  
IchMagBier
Posts: 52
Joined: Jan 13, 2018 8:47
Location: Germany
Contact:

Re: Calling opcodes

Post by IchMagBier »

dodicat wrote:This crashes on 64 bit fbc win 10
Works fine for me on Linux.
MrSwiss wrote:The statement by you, is by far to fuzzy to make sense, do you have a more "in depth explanation" ?
I want to write a JIT-Compiler for a script-language. The compiler generates x86-opcodes out of the script and saves them inside a byte-array. Then the program needs to execute those opcodes with an ASM "call".
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: Calling opcodes

Post by srvaldez »

you could try FASM dll http://board.flatassembler.net/topic.php?t=6239
I made a test using fb here viewtopic.php?p=178664#p178664
[edit] obviously Windows only
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Calling opcodes

Post by D.J.Peters »

@IchMagBier "prost" The right tool for you are libTCC.

I compiled a FreeBASIC version for Windows and Linux 32/64-bit.

You can compile code on the fly to memory and run the result in memory.

Of course you can use GNU inline assembly e.g. __asm__("xor %eax,%eax") also.

Remember "C code or inline assembly" are simple FreeBASIC strings so it's perfect for your needs.

Get it and be happy viewtopic.php?f=14&t=24699

Joshy
IchMagBier
Posts: 52
Joined: Jan 13, 2018 8:47
Location: Germany
Contact:

Re: Calling opcodes

Post by IchMagBier »

I found out, what the problem was. You need some memory marked as executable. On Linux, you need to use "mmap" for that. I got it working with a lot of inline-ASM:

Code: Select all

dim as ubyte ptr function_in_memory

asm 
	xor rdi, rdi		  'address = 0
	mov rsi, 4096		 'length of the array
	mov rdx, 7			 'read OR write OR exec
	mov r10, 34			'map_annonymous OR map_private
	xor r8, r8
	xor r9, r9
	mov rax, 9			 'mmap
	syscall
	mov [function_in_memory], rax
end asm

function_in_memory[0]=&hC3	'ret

asm call [function_in_memory]
@D.J.Peters
That sounds actually awesome, but I already got my compiler working and just needed a way to execute the compiled code.
Last edited by IchMagBier on May 05, 2018 4:43, edited 1 time in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Calling opcodes

Post by D.J.Peters »

32-bit:

Code: Select all

#ifndef __FB_64BIT__
dim as ubyte obcodes(...) = > { _
&H55, _           ' push ebp
&H89,&He5, _      ' mov  ebp,esp
&H8b,&H75,&H0C, _ ' mov  esi,DWORD PTR [ebp+12]
&Hdd,&H06, _      ' fld  QWORD PTR [esi]
&H8b,&H7d,&H08, _ ' mov  edi,DWORD PTR [ebp+8]
&Hd9,&H1f, _      ' fstp DWORD PTR [edi]
&H5d, _           ' pop  ebp
&Hc2,&H08,&H00}   ' ret  8
#else
#error 666: only test for x86 ! 
#endif

type DoubleToSingle_t as sub stdcall(byval pSingle as single ptr, byval pDouble as double ptr) 

dim as DoubleToSingle_t DoubleToSingle = cast(DoubleToSingle_t,@obcodes(0))

dim as single sValue
dim as double dValue = atn(1)*4
DoubletoSingle(@sValue,@dValue)
print sValue,dValue
sleep
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Calling opcodes

Post by D.J.Peters »

IchMagBier wrote:You need some memory marked as executable. On Linux, you need to use "mmap" for that.
I called code in memory without mmap.

Joshy

Code: Select all

asm 
mov rax, [pMemory]
jmp rax
end asm
Post Reply