Linking ASM Object File During Compile?
Linking ASM Object File During Compile?
Is there a way with FB to link an Assembler object file (filename.obj) when compiling a .BAS file that needs to use a subroutine that's in the Assembler object file? In other words, is there a convention similar to using LINK.EXE in the old QB days?
Don
Don
Re: Linking ASM Object File During Compile?
This is quick and dirty, without much in the way of comments, and it includes some stuff that you didn’t ask about. I assumed that you intend to use the GNU assembler.
Testproc.asm:
Test.bas:
And the batch file that I used to assemble, compile, and link:
Edit: Forgot to align the start of the second and third procedure.
Testproc.asm:
Code: Select all
.intel_syntax noprefix
.arch pentium
.altmacro
.data
.bss
.text
// Make the procedures visible to the linker.
.globl _Add1, _Add2, _Add3
// No stack frame on this one, equivalent to a FreeBASIC naked procedure.
.align 16
_Add1:
mov eax, [esp+4]
add eax, [esp+8]
ret 8
// Stack frame without locals.
.align 16
_Add2:
push ebp
mov ebp, esp
mov eax, [ebp+8]
add eax, [ebp+12]
mov esp, ebp
pop ebp
ret 8
// Stack frame with local var, here used to store return value.
.align 16
_Add3:
push ebp
mov ebp, esp
sub esp, 4
mov dword ptr [ebp-4], 0
mov eax, [ebp+8]
add eax, [ebp+12]
mov [ebp-4], eax
mov eax, [ebp-4]
mov esp, ebp
pop ebp
ret 8
Code: Select all
extern "windows-MS"
declare function Add1 alias "Add1"( byval arg1 as integer, _
byval arg2 as integer ) as integer
declare function Add2 alias "Add2"( byval arg1 as integer, _
byval arg2 as integer ) as integer
declare function Add3 alias "Add3"( byval arg1 as integer, _
byval arg2 as integer ) as integer
end extern
print Add1(1,2)
print Add2(2,4)
print Add3(4,8)
sleep
Code: Select all
set path=c:\program files\freebasic;c:\program files\freebasic\bin\win32;%PATH%
as -v -alsm=testproc.lst -o testproc.o testproc.asm
pause
fbc -w pendantic -v -C -R -s console test.bas testproc.o
pause
Last edited by MichaelW on Mar 07, 2013 0:19, edited 1 time in total.
Re: Linking ASM Object File During Compile?
Yea, it should be enough to pass the .o file on the fbc command line, or if it uses another extension such as .obj or something else, by using the "fbc -a foo.obj" option.
Also, by using the -v option you can see the assembling/linking commands that fbc uses behind the scenes.
Also, by using the -v option you can see the assembling/linking commands that fbc uses behind the scenes.
Re: Linking ASM Object File During Compile?
Michael,This is quick and dirty, without much in the way of comments, and it includes some stuff that you didn’t ask about. I assumed that you intend to use the GNU assembler.
Actually I don't intend to write and compile assembler code. I have some existing ASM subroutines in object files that I call from my QB code, and when I move my QB code to FB, I'd like to link the ASM subroutines. Since I want to stay as QB compatible as possible, can I use either the "qb" flag or "fblite" flag when invoking fbc from the command line to compile and link .bas and .obj files? What would be the proper syntax for doing so?
Thanks
Re: Linking ASM Object File During Compile?
As said before, 16-bit assembler is not compatible with 32-bits FB. Neither are 16-bit object binaries.DonW wrote:Actually I don't intend to write and compile assembler code. I have some existing ASM subroutines in object files that I call from my QB code, and when I move my QB code to FB, I'd like to link the ASM subroutines. Since I want to stay as QB compatible as possible, can I use either the "qb" flag or "fblite" flag when invoking fbc from the command line to compile and link .bas and .obj files? What would be the proper syntax for doing so?This is quick and dirty, without much in the way of comments, and it includes some stuff that you didn’t ask about. I assumed that you intend to use the GNU assembler.
-
- Posts: 248
- Joined: Jul 01, 2010 9:35
Re: Linking ASM Object File During Compile?
I have a question or two.
What would happen if the code is used "inline". (Some LIB's give the source)
I checked ASM in the FBIDE Help file and it gives a FUNCTION example. It also mentions 386 cpu's.
I always understood that Intel CPU's are backward compatible.
If the code does not include any of the "words" as per the help file that may not be used, Will it compile and run ?
What must be added to the FreeBASIC setup in FBide 0.4.6 iro compiler and/or run to indicate which CPU to use i.e 386, 586, 686 or is there no such instruction?
What would happen if the code is used "inline". (Some LIB's give the source)
I checked ASM in the FBIDE Help file and it gives a FUNCTION example. It also mentions 386 cpu's.
I always understood that Intel CPU's are backward compatible.
If the code does not include any of the "words" as per the help file that may not be used, Will it compile and run ?
What must be added to the FreeBASIC setup in FBide 0.4.6 iro compiler and/or run to indicate which CPU to use i.e 386, 586, 686 or is there no such instruction?
Re: Linking ASM Object File During Compile?
Don,
If the object modules work with QuickBASIC then they must be 16-bit real mode binaries. For an object module to work with FreeBASIC it must be a 32-bit protected mode binary. Simply put, the 16/32 and real/protected refer to the size of the addresses used and how memory “segments” are managed, and the differences between the two are more or less extreme.
If you have the source code for the object modules and the necessary tools then you can, with some effort, convert the code and assemble 32-bit protected mode binaries. If you don’t have the source code then you basically have two possible routes, disassemble each object module and use the disassembly as the starting point for the code conversion, or start with a description of what the routines in the object modules do and roll your own source code.
If I were doing this I probably would just take the easiest route posssible and replace the assembly subroutines with straightforward FreeBASIC code.
If the object modules work with QuickBASIC then they must be 16-bit real mode binaries. For an object module to work with FreeBASIC it must be a 32-bit protected mode binary. Simply put, the 16/32 and real/protected refer to the size of the addresses used and how memory “segments” are managed, and the differences between the two are more or less extreme.
If you have the source code for the object modules and the necessary tools then you can, with some effort, convert the code and assemble 32-bit protected mode binaries. If you don’t have the source code then you basically have two possible routes, disassemble each object module and use the disassembly as the starting point for the code conversion, or start with a description of what the routines in the object modules do and roll your own source code.
If I were doing this I probably would just take the easiest route posssible and replace the assembly subroutines with straightforward FreeBASIC code.
Re: Linking ASM Object File During Compile?
Within limits, and by the uses of multiple modes, so that old binaries keep running (at least till 64-bit) IOWTheunis Jansen wrote:I have a question or two.
What would happen if the code is used "inline". (Some LIB's give the source)
I checked ASM in the FBIDE Help file and it gives a FUNCTION example. It also mentions 386 cpu's.
I always understood that Intel CPU's are backward compatible.
The backwards compatibility requirement means that on a 32-bit system one can run 16-bit and 32-bit exes. But that is in separate processes, not in the same one.
So no. (iow, what MichaelW says)
The chances are near zero.If the code does not include any of the "words" as per the help file that may not be used, Will it compile and run ?
Don't know. Please open a different thread for different questions.What must be added to the FreeBASIC setup in FBide 0.4.6 iro compiler and/or run to indicate which CPU to use i.e 386, 586, 686 or is there no such instruction?
Re: Linking ASM Object File During Compile?
Guessing that you mean what would happen if you used 16-bit code in inline assembly, I did a simple test using this source:Theunis Jansen wrote:I have a question or two.
What would happen if the code is used "inline". (Some LIB's give the source)
Code: Select all
static as integer i
asm
lea ebx, [i]
mov eax, [ebx]
mov eax, [bx]
end asm
sleep
Code: Select all
Exception number: c0000005 (access violation)
eax=00000000 ebx=00405008 ecx=00000001 edx=77c61ae8 esi=00340036 edi=00320035
eip=0040134d esp=0012ff40 ebp=0012ff58 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
function: test
00401330 0000 add [eax],al
00401332 00e8 add al,ch
00401334 e409 in al,09
00401336 0000 add [eax],al
00401338 6a00 push 0x0
0040133a ff750c push dword ptr [ebp+0xc]
0040133d ff7508 push dword ptr [ebp+0x8]
00401340 e8a3000000 call test+0x13e8 (004013e8)
00401345 8d1d08504000 lea ebx,[test+0x5008 (00405008)]
0040134b 8b03 mov eax,[ebx]
FAULT ->0040134d 678b07 mov eax,[bx] ds:0023:00005008=????????
You can specify the target CPU architecture (instruction set) with the –arch command line option. The default value is 486, which will restrict the compiler to the 486 instruction set. The possible values include native, which I just noticed for the first time. Testing it on a Pentium 3 (686) system I cannot see any difference in the as command line.What must be added to the FreeBASIC setup in FBide 0.4.6 iro compiler and/or run to indicate which CPU to use i.e 386, 586, 686 or is there no such instruction?
Re: Linking ASM Object File During Compile?
Note that the -arch option only affects the code generated by fbc, not pre-compiled libraries such as libfb.a or others (so -arch 386 alone doesn't guarantee a pure i386 binary -- only a full cross-compiler with the proper libraries would guarantee that).
Re: Linking ASM Object File During Compile?
OK...I'm going to show my ignorance regarding ASM code. Recently I read a dissertation on Assembler by Ethan Winer (one of the all time guru's for QB), and I came away with the impression that ASM code communicated directly with registers on a CPU and stored results in a stack that was in a memory area of the CPU. If that is the case, and if Intel/AMD CPU's are considered backwards compatible (at least to the 80386 level), then that gave me the impression that ASM code was neither 16bit, 32bit or 64bit....other than whether it was written to take advantage of ASM features provided by 32bit or 64bit CPU's.
I can understand that ASM written for 80386 CPU's (and its offspring) would not execute properly with a CPU of a different architecture, But what I am hearing from some of the posts is that ASM code is dependent upon the architecture of the operating system, and not that of the CPU.
Don
I can understand that ASM written for 80386 CPU's (and its offspring) would not execute properly with a CPU of a different architecture, But what I am hearing from some of the posts is that ASM code is dependent upon the architecture of the operating system, and not that of the CPU.
Don
Re: Linking ASM Object File During Compile?
Ignoring the complicating details, recent x86 processors have 3 operating modes: 16-bit real mode, 32-bit protected mode, and 64-bit protected mode. The processor starts in 16-bit real mode, and from that point the operating mode is typically controlled by the operating system (Windows, Linux, etc) or by a DOS Extender (DOS). Over time the x86 processor instruction set has been expanded, adding individual instructions and/or entire instruction set extensions. The assembly code must be compatible with the processor operating mode and instruction set.DonW wrote:But what I am hearing from some of the posts is that ASM code is dependent upon the architecture of the operating system, and not that of the CPU.
Re: Linking ASM Object File During Compile?
Michael,
Thanks for the insight that you provided. So if I understand correctly, the 32bit versions of Win7 and Win8 evidently allow 16bit calls to the CPU, whereas, for reasons that escape me, Microsoft decided not to allow that functionality in their 64bit versions. Ironically, most of the consumer oriented PC's/laptops are loaded with 64bit Windows and everyday users then are flummoxed to find out that a lot of their older software will no longer run.
Don
Thanks for the insight that you provided. So if I understand correctly, the 32bit versions of Win7 and Win8 evidently allow 16bit calls to the CPU, whereas, for reasons that escape me, Microsoft decided not to allow that functionality in their 64bit versions. Ironically, most of the consumer oriented PC's/laptops are loaded with 64bit Windows and everyday users then are flummoxed to find out that a lot of their older software will no longer run.
Don
Re: Linking ASM Object File During Compile?
The 32-bit versions of Windows support 16-bit DOS or 16-bit Windows programs. AFAIK there are multiple workarounds, including at least one from Microsoft, for running 16-bit programs with the 64-bit versions of Windows.
http://en.wikipedia.org/wiki/NTVDM#NTVDM
http://en.wikipedia.org/wiki/NTVDM#NTVDM
Re: Linking ASM Object File During Compile?
That link leads to an interesting article on the implementation of 8086 emulation in various generations of Windows...culminating in the NTVDM subsystem. However, toward the end of the article is the statement "64-bit versions of Windows...do not include the NTVDM subsystem". That leads me to believe there is no fix from Microsoft to implement it.