Inline assembler
Inline assembler
Hey all,
To improve the speed of my program, I am thinking about converting pieces of code to inline asm.
- Are there any recommend compiler options? I have previously tried to use pieces of asm code (provided by forum members) inside my program but the compiler came back with error messages related to the asm code. There seems to be some incompatibility between certain compiler options and inline asm.
- Could using inline asm code break compatibility with other computers, operating systems using the program? My program has a small user base so it should work on a variety of windows machines.
Tyvm
To improve the speed of my program, I am thinking about converting pieces of code to inline asm.
- Are there any recommend compiler options? I have previously tried to use pieces of asm code (provided by forum members) inside my program but the compiler came back with error messages related to the asm code. There seems to be some incompatibility between certain compiler options and inline asm.
- Could using inline asm code break compatibility with other computers, operating systems using the program? My program has a small user base so it should work on a variety of windows machines.
Tyvm
Re: Inline assembler
Yes, if your ASM code is not written, to be compatible with 32 as well as 64 bit OS's,Provoni wrote:- Could using inline asm code break compatibility with other computers, operating systems using the program?
(or simpler, both FBC versions 32/64), provided you're using the same OS type: e.g. Windows.
Btw. compiler options are, usually not needed ... (except maybe -asm [intel|att]).
Re: Inline assembler
An importatt thing: Don't call the BASIC variables the same as used registernames, like ah, ax etc.
Re: Inline assembler
Okay, thank you MrSwiss and Jawade.
There is a problem with the following code, it should loop 10 times (print 1) but instead loops indefinitely. Code snippet from: https://www.tutorialspoint.com/assembly ... _loops.htm
- mov is short for move? As it moves a value to a register? (ecx)
- A register (ecx) is some sort of hardware variable?
- l1: is a label?
There is a problem with the following code, it should loop 10 times (print 1) but instead loops indefinitely. Code snippet from: https://www.tutorialspoint.com/assembly ... _loops.htm
Code: Select all
dim as integer i,j,k,a,b,c
screenres 800,600,32
asm
mov ecx,10
l1:
end asm
print 1
asm
loop l1
end asm
sleep
beep
- A register (ecx) is some sort of hardware variable?
- l1: is a label?
Re: Inline assembler
Between the 2 Asm blocks, the register ecx was not saved (version for 32-bit fbc).
Code: Select all
asm
mov ecx,10
l1:
push ecx
end asm
print 1
asm
pop ecx
loop l1
end asm
sleep
Last edited by fxm on Mar 26, 2017 8:58, edited 2 times in total.
Re: Inline assembler
You cannot loop or push/pop between 2 different ASM-blocks. It are different worlds.
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Inline assembler
you are wrongJawade wrote:You cannot loop or push/pop between 2 different ASM-blocks. It are different worlds.
the problem are the call to fbPrint or any othe call to the FB runtime lib
destroys your current registers so you have push and pop it.
Joshy
Re: Inline assembler
It should be amazing if that works, it's against aal the rules from the logical coding. I will try it and will see if it 's possible. Thanks.
Re: Inline assembler
Similarly with a FB variable as memory, instead of the stack with push/pop (version for 32-bit fbc):
Code: Select all
dim as integer N
asm
mov ecx,10
l1:
mov [N],ecx
end asm
print N
asm
mov ecx,[N]
loop l1
end asm
sleep
Last edited by fxm on Mar 26, 2017 8:58, edited 2 times in total.
Re: Inline assembler
It's unbelievable but yes, it works. It is a wonder the program can find the label.
Re: Inline assembler
The push/pop version does not work with gcc 32-bit (the one other works) !
(system stack management different from gas, or bug for fbc to gcc 32-bit ?)
However, this works with gcc 32-bit:
(system stack management different from gas, or bug for fbc to gcc 32-bit ?)
However, this works with gcc 32-bit:
Code: Select all
dim as integer N
asm
mov ecx,10
l1:
push ecx
end asm
N += 1
asm
pop ecx
loop l1
end asm
print N
sleep
Last edited by fxm on Mar 26, 2017 9:10, edited 3 times in total.
-
- Posts: 4310
- Joined: Jan 02, 2017 0:34
- Location: UK
- Contact:
Re: Inline assembler
It is worth remembering that whilst the source code is Assembler, FreeBASIC, and Assembler and both the compiler and we know what 'asm/end asm' means the binary is native code from top to bottom and it has no idea what 'asm/end asm' means but it does know what a relative jump is; and that relative jump is from native code to native code.It is a wonder the program can find the label.
Edit: Had a comment here re fxm's last post but it was wrong.
Re: Inline assembler
Thanks everyone for jumping in.
However fxm's example with push/pop,
returns errors:
It says make done but no executable is generated. Using FbEdit 1.0.7.6c.
However fxm's example with push/pop,
Code: Select all
dim as integer i,j,k,a,b,c
screenres 800,600,32
asm
mov ecx,10
l1:
push ecx
end asm
print 1
asm
pop ecx
loop l1
end asm
sleep
beep
Code: Select all
C:\FreeBASIC-1.05.0-win64\fbc -t 50000 -s gui -O max "asm_test1.bas"
asm_test1.asm: Assembler messages:
asm_test1.asm:42: Error: operand type mismatch for `push'
asm_test1.asm:51: Error: operand type mismatch for `pop'
Make done
Re: Inline assembler
This kind of code (with push/pop) works for gas 32-bits only.
For 64-bit fbc (with push/pop), one can use the rcx register:
For 64-bit fbc (with not push/pop but a 32-bit FB variable as memory) one can always use the ecx register:
(obviously, this version also works for 32-bit fbc)
For 64-bit fbc (with push/pop), one can use the rcx register:
Code: Select all
dim as integer i,j,k,a,b,c
screenres 800,600,32
asm
mov rcx,10
l1:
push rcx
end asm
print 1
asm
pop rcx
loop l1
end asm
sleep
beep
Code: Select all
dim as Long N
asm
mov ecx,10
l1:
mov [N],ecx
end asm
print N
asm
mov ecx,[N]
loop l1
end asm
sleep
Re: Inline assembler
Thanks fxm,
So the 16-bit (ax,bx,cx,dx), 32-bit (eax,ebx,ecx,edx) and 64-bit registers (rax,rbx,rcx,rdx) need to be matched properly to the bits of the variable types used.
The following code is working properly. Though,
- rax has to be set to zero because there was another number in it, is that normal procedure and is "mov rax,0" the proper way to do this?
- "inc rax" is an example operation, I understand correctly that keeping stuff as much as possible in the registers is faster than using variables? For example "inc [a]" is slower.
So the 16-bit (ax,bx,cx,dx), 32-bit (eax,ebx,ecx,edx) and 64-bit registers (rax,rbx,rcx,rdx) need to be matched properly to the bits of the variable types used.
The following code is working properly. Though,
- rax has to be set to zero because there was another number in it, is that normal procedure and is "mov rax,0" the proper way to do this?
- "inc rax" is an example operation, I understand correctly that keeping stuff as much as possible in the registers is faster than using variables? For example "inc [a]" is slower.
Code: Select all
dim as integer i,j,k,a,b,c
screenres 800,600,32
i=1000000
asm
mov rax,0
mov rcx,[i]
l1:
inc rax
loop l1
mov [a],rax
end asm
print a
sleep