Linking ASM Object File During Compile?

New to FreeBASIC? Post your questions here.
DonW
Posts: 40
Joined: Feb 16, 2013 0:56
Location: Longview, WA

Linking ASM Object File During Compile?

Postby DonW » Mar 06, 2013 8:10

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
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Linking ASM Object File During Compile?

Postby MichaelW » Mar 06, 2013 15:05

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:

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

Test.bas:

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

And the batch file that I used to assemble, compile, and link:

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

Edit: Forgot to align the start of the second and third procedure.
Last edited by MichaelW on Mar 07, 2013 0:19, edited 1 time in total.
dkl
Site Admin
Posts: 3212
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Linking ASM Object File During Compile?

Postby dkl » Mar 06, 2013 16:54

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.
DonW
Posts: 40
Joined: Feb 16, 2013 0:56
Location: Longview, WA

Re: Linking ASM Object File During Compile?

Postby DonW » Mar 07, 2013 6:06

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.


Michael,

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
marcov
Posts: 3020
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: Linking ASM Object File During Compile?

Postby marcov » Mar 07, 2013 8:15

DonW wrote:
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?


As said before, 16-bit assembler is not compatible with 32-bits FB. Neither are 16-bit object binaries.
Theunis Jansen
Posts: 248
Joined: Jul 01, 2010 9:35

Re: Linking ASM Object File During Compile?

Postby Theunis Jansen » Mar 07, 2013 10:35

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?
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Linking ASM Object File During Compile?

Postby MichaelW » Mar 07, 2013 11:48

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.
marcov
Posts: 3020
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: Linking ASM Object File During Compile?

Postby marcov » Mar 07, 2013 15:31

Theunis 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.


Within limits, and by the uses of multiple modes, so that old binaries keep running (at least till 64-bit) IOW

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)

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 ?


The chances are near zero.

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?


Don't know. Please open a different thread for different questions.
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Linking ASM Object File During Compile?

Postby MichaelW » Mar 07, 2013 17:39

Theunis Jansen wrote:I have a question or two.
What would happen if the code is used "inline". (Some LIB's give the source)

Guessing that you mean what would happen if you used 16-bit code in inline assembly, I did a simple test using this source:

Code: Select all

static as integer i
asm
    lea ebx, [i]
    mov eax, [ebx]
    mov eax, [bx]
end asm
sleep

The defining feature of 16-bit code is the use of 16-bit addresses. The third instruction tries to load EAX from a 16-bit address, stored in the 16-bit register BX. The problem with this is that the address of the variable i, loaded into EBX by the first instruction, in my test run was 00405008h. The second instruction loads EAX from the full 32-bit address and the instruction does just what it’s supposed to do, but for the third instruction the address was truncated to 00005008h, an invalid address which triggered an access violation exception. Here are the relevant parts of the Dr. Watson State Dump:

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=????????


If I had tried to assemble this code with MASM, it would have recognized the error and reported it, but either GAS silently assembled it or FBC did not report the error.

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?

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.
dkl
Site Admin
Posts: 3212
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Linking ASM Object File During Compile?

Postby dkl » Mar 07, 2013 17:43

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).
DonW
Posts: 40
Joined: Feb 16, 2013 0:56
Location: Longview, WA

Re: Linking ASM Object File During Compile?

Postby DonW » Mar 09, 2013 1:44

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
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Linking ASM Object File During Compile?

Postby MichaelW » Mar 10, 2013 1:31

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.

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
Posts: 40
Joined: Feb 16, 2013 0:56
Location: Longview, WA

Re: Linking ASM Object File During Compile?

Postby DonW » Mar 10, 2013 6:22

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
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Linking ASM Object File During Compile?

Postby MichaelW » Mar 10, 2013 8:32

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
DonW
Posts: 40
Joined: Feb 16, 2013 0:56
Location: Longview, WA

Re: Linking ASM Object File During Compile?

Postby DonW » Mar 10, 2013 18:49

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.

Return to “Beginners”

Who is online

Users browsing this forum: No registered users and 3 guests