[Noob] Linking gcc and vasm objects

All 680x0 related coding posts in this section please.

Moderators: Zorro 2, Moderator Team

Post Reply
User avatar
Badwolf
Captain Atari
Captain Atari
Posts: 441
Joined: Thu Mar 16, 2017 12:09 pm

[Noob] Linking gcc and vasm objects

Post by Badwolf »

Hi all. I've a bit of a noobie failing here. I hope it's a simple mistake, but I'm going around in circles a bit.

I'm trying to link together a program that's mostly in assembler, but can call some C functions, making use of the C library.

I build the assembly side with vasm:-

Code: Select all

vasmm68k_mot -Faout -devpac -o demo-s.o demo.S
And the C side with gcc:-

Code: Select all

m68k-atari-mint-gcc -m68000 -c -o demo-c.o demo.c
But when it comes to link them together (with ld) I get an undefined reference to 'puts' error (I've got a printf() in the C part).

Code: Select all

m68k-atari-mint-ld -o demo.prg demo-s.o /usr/m68k-atari-mint/lib/libc.a demo-c.o
I've tried the same with vlink, but then I end up with lots of what appear to be floating point function errors too.

Reading around hasn't got me very far. I've seen reference to linking with libgcc, but that doesn't appear to have any effect. I can't see how puts is in any library other than the C standard lib, which is what I thought libc.a was.

Can anyone set me on the straight and narrow?

Thanks,

BW

PS. here's a demonstration project.
You do not have the required permissions to view the files attached to this post.
DFB1 Open source 50MHz 030 and TT-RAM accelerator for the Falcon
DSTB1 Open source 16Mhz 68k and AltRAM accelerator for the ST
Smalliermouse ST-optimised USB mouse adapter based on SmallyMouse2
FrontBench The Frontier: Elite 2 intro as a benchmark
czietz
Hardware Guru
Hardware Guru
Posts: 2822
Joined: Tue May 24, 2016 6:47 pm

Re: [Noob] Linking gcc and vasm objects

Post by czietz »

When I want to link my own startup code, I use gcc as driver with the -nostdlib argument. So something like:

m68k-atari-mint-gcc -nostdlib -o demo.prg demo-s.o demo.c [PATH-TO-C-LIBRARY] -lgcc

However, what your demo project tries to do will most likely not work: mixing your own startup code with MiNTLib's libc. MiNTLib's startup code initializes many global variables that are required for proper operation of the library functions.
ThorstenOtto
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3413
Joined: Sun Aug 03, 2014 5:54 pm

Re: [Noob] Linking gcc and vasm objects

Post by ThorstenOtto »

You have to specify the library last, otherwise the following will happen:

- the library is encountered, but it does not contain any missing references seen so far
- demo-c.o is encountered, missing a reference to puts
- the library is not scanned again

Better yet, instead of using the absolute path, use -L<directory> -lc

Apart from that, the problem @czietz mentions still applies, you should better try to avoid replacing the startup code. And if you really need to, keep in mind that text+data+bss of gcc linked program do not contain any space for your application stack.
czietz
Hardware Guru
Hardware Guru
Posts: 2822
Joined: Tue May 24, 2016 6:47 pm

Re: [Noob] Linking gcc and vasm objects

Post by czietz »

To give a glimpse regarding all the things that usually happen in MiNTLib before your code (i.e., main()) even starts:
https://github.com/freemint/mintlib/blo ... tup/crt0.S
... calls ...
https://github.com/freemint/mintlib/blo ... /crtinit.c
... calls ...
https://github.com/freemint/mintlib/blo ... lib/main.c

Among other things, this makes sure that the standard streams (stdio, stdout, stderr) are set up and that the memory layout (heap etc.) is set up.
User avatar
Badwolf
Captain Atari
Captain Atari
Posts: 441
Joined: Thu Mar 16, 2017 12:09 pm

Re: [Noob] Linking gcc and vasm objects

Post by Badwolf »

czietz wrote: Thu Feb 24, 2022 3:10 pm When I want to link my own startup code, I use gcc as driver with the -nostdlib argument. So something like:

m68k-atari-mint-gcc -nostdlib -o demo.prg demo-s.o demo.c [PATH-TO-C-LIBRARY] -lgcc

However, what your demo project tries to do will most likely not work: mixing your own startup code with MiNTLib's libc. MiNTLib's startup code initializes many global variables that are required for proper operation of the library functions.
Ah. So I could call C functions, but not really enjoy the benefits of the stdlib?

I did try libcmini too, as I know that handles startup diffrently, but I didn't get any furthe there either (I've even less clue on that front to be honest!).

Would it be fair to say it's easier/more flexible to call assembly from C than the other way around?
ThorstenOtto wrote: Thu Feb 24, 2022 4:01 pm You have to specify the library last, otherwise the following will happen:
Ah, that's actually how I started, but got many more errors. I misunderstood what I read about library order precedence so kept it reversed.
Apart from that, the problem @czietz mentions still applies, you should better try to avoid replacing the startup code. And if you really need to, keep in mind that text+data+bss of gcc linked program do not contain any space for your application stack.
Right. That all sounds a bit too advanced for me, then.

I can kind of read and modify assembly, but how it plays nicely with the OS is a bit beyond me. I only read about the 'BSS' last week!

Rats!

Thanks though, guys.

BW
DFB1 Open source 50MHz 030 and TT-RAM accelerator for the Falcon
DSTB1 Open source 16Mhz 68k and AltRAM accelerator for the ST
Smalliermouse ST-optimised USB mouse adapter based on SmallyMouse2
FrontBench The Frontier: Elite 2 intro as a benchmark
ThorstenOtto
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3413
Joined: Sun Aug 03, 2014 5:54 pm

Re: [Noob] Linking gcc and vasm objects

Post by ThorstenOtto »

Badwolf wrote: Thu Feb 24, 2022 5:06 pm Would it be fair to say it's easier/more flexible to call assembly from C than the other way around?
No, both directions work. You just have to be aware of the calling convention when you have to pass parameters, and what registers your assembly has to preserve (for gcc, that will be all except d0-d1/a0-a1).

But that's not the problem with your demo. If you just want to learn how to call C from asm and vice versa, use the normal libraries, let your main() routine start as normal, and start from there.

Apart from that, if you write everything from scratch, there is no real need to use vasm, the difference in syntax to gas is not that big.
User avatar
Badwolf
Captain Atari
Captain Atari
Posts: 441
Joined: Thu Mar 16, 2017 12:09 pm

Re: [Noob] Linking gcc and vasm objects

Post by Badwolf »

ThorstenOtto wrote: Thu Feb 24, 2022 6:15 pm But that's not the problem with your demo. If you just want to learn how to call C from asm and vice versa, use the normal libraries, let your main() routine start as normal, and start from there.
If I've understood you correctly that would be what I meant by calling assembly from C -- let C, its compiler and the libraries handle the startup and then call the assembly routines from main() [for example].
Apart from that, if you write everything from scratch, there is no real need to use vasm, the difference in syntax to gas is not that big.
I wasn't planning to start from scratch. I'd not be assembly if I were! ;)

I was hoping to be able to extend assembly programs, or disassembled source (like with Frontier for the frame counter), but using the c std lib.

I started with printf() as it's a heck of a lot simpler to output debugging information with that that from within assembly!

It sounds like I ought to rein in my hopes a bit, though. I can probably implement a printf-alike in straight C and jumping back to assembly for the OS calls if I can't link the mintlib either!

Thanks again,

BW
DFB1 Open source 50MHz 030 and TT-RAM accelerator for the Falcon
DSTB1 Open source 16Mhz 68k and AltRAM accelerator for the ST
Smalliermouse ST-optimised USB mouse adapter based on SmallyMouse2
FrontBench The Frontier: Elite 2 intro as a benchmark
User avatar
Eero Tamminen
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3997
Joined: Sun Jul 31, 2011 1:11 pm

Re: [Noob] Linking gcc and vasm objects

Post by Eero Tamminen »

The main thing seemed to be the linking order. Linker scan for symbols in the order it encounters them, so objects / libs providing the symbols need to be after things that use them.
User avatar
Badwolf
Captain Atari
Captain Atari
Posts: 441
Joined: Thu Mar 16, 2017 12:09 pm

Re: [Noob] Linking gcc and vasm objects

Post by Badwolf »

Eero Tamminen wrote: Thu Feb 24, 2022 10:21 pm The main thing seemed to be the linking order. Linker scan for symbols in the order it encounters them, so objects / libs providing the symbols need to be after things that use them.
Hi Eero,

I'm not sure that was the main thing -- in fact it appeared to have very little effect just altering the order.

Changing, for example, to:-

Code: Select all

m68k-atari-mint-ld -L/usr/m68k-atari-mint/lib -o demo.prg demo-s.o demo-c.o -lc
Produces pages of undefined references. They look mostly like floating point instructions -- so in a fit of wanton abandon I tried linking to cflib instead.

Which just brought me back to where I started with the other linking order:-

Code: Select all

demo-c.o:demo-c.o:(.text+0x14): undefined reference to `puts'

Christian's explanation makes sense to me. Both the Clib and my assembly program (which is a standalone program in its own right) are trying to perform various program startup tasks.

If I omit the C std lib and reduce my C function to something really elementary ("return 66;"), it works fine.

So thanks again, all.

BW
DFB1 Open source 50MHz 030 and TT-RAM accelerator for the Falcon
DSTB1 Open source 16Mhz 68k and AltRAM accelerator for the ST
Smalliermouse ST-optimised USB mouse adapter based on SmallyMouse2
FrontBench The Frontier: Elite 2 intro as a benchmark
czietz
Hardware Guru
Hardware Guru
Posts: 2822
Joined: Tue May 24, 2016 6:47 pm

Re: [Noob] Linking gcc and vasm objects

Post by czietz »

Badwolf wrote: Fri Feb 25, 2022 11:40 am

Code: Select all

m68k-atari-mint-ld -L/usr/m68k-atari-mint/lib -o demo.prg demo-s.o demo-c.o -lc
Produces pages of undefined references. They look mostly like floating point instructions
Actually, these are mostly integer functions. If you look closely, I had "-lgcc" in my command line - precisely because of that.

Regardless of that your demo program from the first post crashes, because it calls a library function (puts) without running the library's startup code.
Last edited by czietz on Fri Feb 25, 2022 12:03 pm, edited 1 time in total.
ThorstenOtto
Fuji Shaped Bastard
Fuji Shaped Bastard
Posts: 3413
Joined: Sun Aug 03, 2014 5:54 pm

Re: [Noob] Linking gcc and vasm objects

Post by ThorstenOtto »

Badwolf wrote: Fri Feb 25, 2022 11:40 am

Code: Select all

m68k-atari-mint-ld -L/usr/m68k-atari-mint/lib -o demo.prg demo-s.o demo-c.o -lc
Produces pages of undefined references.
If you invoke ld directly, no startup code will be linked (beside your own one), and it does not link to -lgcc. The floating point function are contained in -lgcc, not in mintlib.

If you use "m68k-atari-mint-gcc -v" instead of m68k-atari-mint-ld, you will see how the linker is actually invoked.
User avatar
Badwolf
Captain Atari
Captain Atari
Posts: 441
Joined: Thu Mar 16, 2017 12:09 pm

Re: [Noob] Linking gcc and vasm objects

Post by Badwolf »

czietz wrote: Fri Feb 25, 2022 12:00 pm Actually, these are mostly integer functions. If you look closely, I had "-lgcc" in my command line - precisely because of that.
Ah, my mistake. I did try linking the GCC lib in an earlier attempt, but missed it that time. Like you say, though, a bit pointless.

Thanks,

BW
DFB1 Open source 50MHz 030 and TT-RAM accelerator for the Falcon
DSTB1 Open source 16Mhz 68k and AltRAM accelerator for the ST
Smalliermouse ST-optimised USB mouse adapter based on SmallyMouse2
FrontBench The Frontier: Elite 2 intro as a benchmark
czietz
Hardware Guru
Hardware Guru
Posts: 2822
Joined: Tue May 24, 2016 6:47 pm

Re: [Noob] Linking gcc and vasm objects

Post by czietz »

Note that even when your C code does not use any standard library functions the compiler still might generate calls to the GCC lib and even to the standard library (depending on compiler version, optimization settings, etc.):
https://tinyurl.com/ycwwhndl

The latter can be avoided by building with "-fno-builtin":
https://tinyurl.com/y75eg7v6
User avatar
Badwolf
Captain Atari
Captain Atari
Posts: 441
Joined: Thu Mar 16, 2017 12:09 pm

Re: [Noob] Linking gcc and vasm objects

Post by Badwolf »

I've used -fno-builtin and added a couple of C functions here. One calling back to the OS via an osbind.h define.

Is the attached approach now safe?

Thanks again.

BW.
You do not have the required permissions to view the files attached to this post.
DFB1 Open source 50MHz 030 and TT-RAM accelerator for the Falcon
DSTB1 Open source 16Mhz 68k and AltRAM accelerator for the ST
Smalliermouse ST-optimised USB mouse adapter based on SmallyMouse2
FrontBench The Frontier: Elite 2 intro as a benchmark
User avatar
mfro
Atari God
Atari God
Posts: 1295
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: [Noob] Linking gcc and vasm objects

Post by mfro »

Badwolf wrote: Fri Feb 25, 2022 2:35 pm I've used -fno-builtin and added a couple of C functions here. One calling back to the OS via an osbind.h define.

Is the attached approach now safe?

Thanks again.

BW.
Yes. But it will fail once you'll start using more sophisticated C language statements, like e.g. structure assignments (needs memcpy()) or long multiplication/division (needs libgcc.a). There might be more I'm currently not thinking about.
User avatar
l12n
Atariator
Atariator
Posts: 23
Joined: Sat Dec 30, 2023 4:46 am

Re: [Noob] Linking gcc and vasm objects

Post by l12n »

I've tried to build upon demo2.zip to draw some graphics (changing the video base address to my own frame buffer, changing the line offset register) but it blows up badly when trying to do so.

Are there other things that need to be initialized in the assembly file?

Thanks in advance
mikro
Hardware Guru
Hardware Guru
Posts: 4724
Joined: Sat Sep 10, 2005 11:11 am
Location: Kosice, Slovakia
Contact:

Re: [Noob] Linking gcc and vasm objects

Post by mikro »

l12n: You will have to be more specific than this. :)

Post your code, explain what you are aiming at, what is the actual result.
User avatar
l12n
Atariator
Atariator
Posts: 23
Joined: Sat Dec 30, 2023 4:46 am

Re: [Noob] Linking gcc and vasm objects

Post by l12n »

mikro, I modified the demo.c from the demo2.zip posted above to try to read/write some of the machine's registers (I am emulating an STE). Any read/write access to said registers leads to a crash.

Code: Select all

uint8_t *line_offset = (uint8_t *)0xFF820F;
uint8_t *video_base = (uint8_t *)0xFF8205; 
uint8_t *pixel_offset = (uint8_t *)0xFF8265;

void hellotoo( unsigned char *s ) {
    char dummy[256];
    *line_offset = 160;    // Panic: Bus Error
    
    int a = Cconrs (dummy);
}
What am I trying to achieve? Set my own frame buffer, implement hardware scrolling, use the blitter.
SToS
Captain Atari
Captain Atari
Posts: 206
Joined: Sun Mar 28, 2021 12:16 pm

Re: [Noob] Linking gcc and vasm objects

Post by SToS »

l12n wrote: Fri Jan 05, 2024 2:29 pm I modified the demo.c from the demo2.zip posted above to try to read/write some of the machine's registers (I am emulating an STE). Any read/write access to said registers leads to a crash.
For starters, you need to be in supervisor mode to access the hardware registers.
I suggest you read up on that first.
https://toshyp.atari.org/en/00500e.html#Super
User avatar
l12n
Atariator
Atariator
Posts: 23
Joined: Sat Dec 30, 2023 4:46 am

Re: [Noob] Linking gcc and vasm objects

Post by l12n »

SToS wrote: Fri Jan 05, 2024 2:45 pm For starters, you need to be in supervisor mode to access the hardware registers.
Ah, that's what I was missing, thanks! I can now perform a multidirectional hardware scrolling. Next step is to time it to void the occasional blinking.
Post Reply

Return to “680x0”