[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference 7.286::atarist

Title:Atari ST, TT, & Falcon
Notice:Please read note 1.0 and its replies before posting!
Moderator:FUNYET::ANDERSON
Created:Mon Apr 04 1988
Last Modified:Tue May 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:1433
Total number of notes:10312

820.0. "MWC - linktime relocation error, HELP!" by MRSVAX::MISKINIS () Wed Apr 04 1990 14:40

    Hello,
    
    	Has anyone out there had experience with linking large modules
    in C and assembler?  I have 3 "C" programs, and 1 assembler program.
    I'm trying to establish a "large" buffer for data that will be coming
    in *real* fast. 
    
    	If I reduce the size of the 3 main arrays, everything links/runs
    OK.  BUT, If I extend the size of the arrays to where I want them,
    it causes my assembly module to return an error during the linking
    process.
    
    	The error is "word relocation doesn't reach SHRI:xxxx"  (some
    number)....
    
    	The MWC manual doesn't really go into detail on program sections,
    and I've tried putting my assembly routines at PRVI, PRVD, SHRI
    with no luck.
    
    
T.RTitleUserPersonal
Name
DateLines
820.1I may be able to helpPRNSYS::LOMICKAJJeffrey A. LomickaWed Apr 04 1990 16:344
What version of MWC are you using?

Are you sure your assembly routine is using long address arithmetic to
address the large buffer?
820.2more info on my linking problem...MRSVAX::MISKINISWed Apr 04 1990 17:4821
    Hi Jeff!
    
    	I belive it's version 3 (MWC)...  As far as the addressing,
    hmmm...
    
    	In a C module, I have: 
    
    		unsigned char midi_buf[10000];
    
    	In the assembler module I have: (the byte is in d0)
    
    		lea	midi_buf_(pc),a0	/ get addr of buffer
    		move	byte_count_(pc),d1	/ get current offset
    		move.b	d0,(a0,d1)		/ place byte in buffer
    		
	Everything works fine (including my MIDI thru code!), until
    I change the array size of 3 arrays (1 byte array, 2 word arrays)
    from 10,000 to 20,000...
    
    _John_
    
820.3How about dynamic allocation?SMURF::COUTUHe who will not risk, cannot win.Wed Apr 04 1990 18:2611
    Rather than use statically defined arrays why not use dynamically
    allocated arrays instead? It sounds like you're using the large buffers
    for storage of data which arrives at run time rather than for compile
    time data. This would end up taking a lot less time to compile too.
    
    I'd suggest judicious use of malloc() to grab the memory space
    necessary to store your large arrays. I also believe that this will
    insure that the arrays are located in data space rather than code
    space.
    
    Dan
820.4I guess the time has come to use malloc!MRSVAX::MISKINISWed Apr 04 1990 19:0912
    Hello,
    
    	Thanks for your input!  In the long run, I will be using dynamic
    allocation, but I figured (for now) I'd just pre-allocate it...
    I'm still in the "internals learning mode", and I figured now would
    be a good time to undersand the correct use of program sections,
    and the side effects...
    
    	I guess it's time to "get dynamic", and check out the malloc
    bug notes!
    
    _John_
820.516-bit limitPRNSYS::LOMICKAJJeffrey A. LomickaWed Apr 04 1990 19:4417
>    		lea	midi_buf_(pc),a0	/ get addr of buffer

PC-relative addressing on the 68000 is limited to word-sized offsets.

Unless you have some reason why you need this to be PIC code, I'd just
code this as a

		lea	midi_buf_, a0

and take the one word code size hit.

By being sure to put the code in the right psect (.shri or .prvi), you
could probabally arrange for the code to be close enough to the buffer
that you could stay with PC-relative addressing, but it doesn't seem
worth it.

820.6<more>MRSVAX::MISKINISWed Apr 04 1990 19:5313
   	What's PIC code?
    
    	I've been using PC-relative addressing, because I thought I
    had to.  (I saw it in some other code) If I can avoid it I will...  
    
    	So, a

        	  lea	midi_buf_,a0
    
    	will load the address of the buffer also?  If so, than I can
    use a buffer size of up to 65536? (maximun offset using 16 bits)
    
    _John_ 
820.7Why malloc?PRNSYS::LOMICKAJJeffrey A. LomickaWed Apr 04 1990 20:4024
I see no reason to go to using malloc(), unless the size of this buffer
varies with the input data, and you would therefore be able to offer
greater utility to owners of computers with more available memory.

If you don't initialize the buffer at compile time, MWC will put the
large array in the .bss section, which is allocated by the operating
system at run time.  It won't take up any extra space in your program
image or .o files.

Regarding Malloc() bugs, I've found that on a 4MB system, the MWC
malloc() routine will trigger the GEMDOS Malloc() bug if you allocate
enough memory in small pieces.  In programs that do not use Pexec(),
this problem is easily circumvented by giving MWC's malloc engine a
large pile of memory:

	char *glop;

	glop = lmalloc( Malloc( -1L) - 8*1024L);
	if( glop != NULL) free( glop);

This will turn over all but 8k of the memory over to the Mark Williams
library routines, which will then be able to give you that memory in
small chunks with no problems.

820.8PIC codePRNSYS::LOMICKAJJeffrey A. LomickaWed Apr 04 1990 20:5824
PIC stands for "position independent code", which is code that will
still work even if you move it somewhere else.  PIC code doesn't need
"address fixups" at execution time.  You become PIC by making all your
data references relative to the PC, so that as you load the code into
different places in memory, the data still has the same relative
displacement to the PC.

The Atari linker writes images with "fixup" information, so that every
place where you do a non-PIC reference will be adjusted to the correct
value for wherever your program is loaded into memory.

You can make you buffer up to 4 gigabytes long by using the following:

	lea	midi_buf_, a0	/	Loader will fix-up the absolute
				/	reference to midi_buf
	move.l	byte_count_, d1	/	Get 32-bit byte count
	move.b	d0, (a0,d1.l)/		(I never understood this
					addressing mode)

The ".l" on d1 will tell the machine to use "indexed register indirect
with offset" mode, with a long value.  The manual page for "as" seems to
say that there is a 16-bit offset available here, but I can't find it in
the Signetics 68000 manual.  I'll have to go home to check the (much
better) Motorola manual.