gas (gnu assembler) guru question: loading an address

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I need to load a table address into the Z register.

Here's what worked in AVR Studio:

ldi ZH,high(TABL<<1)
ldi ZL,low(TABL<<1)

That doesn't work in gcc/gas. Here's the compile line in my makefile.

avr-gcc -c -mmcu=at90usb646 -I. -x assembler-with-cpp -Wa,-adhlns=$(<:.S=.lst),-gstabs

I've tried using hi8 and lo8 instead of high and low and I get the following error:
Error: invalid sections for operation on `TABL' and `L0'
I have no idea what that means.

Any help would be greatly appreciated. My project is at a halt.[/code]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

use lo8 & hi8... take the shift out. IIRC addresses in GAS are always byte oriented.

ldi ZH,hi8(TABL)
ldi ZL,lo8(TABL)

[edit] after looking at the avr-libc documentation you may need to use the pm macro here as well.

ldi ZH,hi8(pm(TABL))
ldi ZL,lo8(pm(TABL))

http://www.nongnu.org/avr-libc/u...

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

glitch wrote:
after looking at the avr-libc documentation you may need to use the pm macro here as well.

Is it a macro?

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> Is it a macro?

It's an operator, just like hi8/lo8 are.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry, my fault. shouldn't have used the term macro there. Indeed it is an operator.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

glitch, you are indeed a guru! Code now assembles.

Unfortunately, I still can't get it to link. Here's what the linker says:
avr-gcc -Map,gccTest.map -o gccTest.elf gccTest.o
c:/winavr-20070525/bin/../lib/gcc/avr/4.1.2/../../../../avr/lib/crts8515.o: In function `__vectors':
../../../../../avr-libc-1.4.6/crt1/gcrt1.S:51: undefined reference to `main'
avr-gcc.exe: unrecognized option '-Map,gccTest.map'
"make.exe": *** [gccTest.elf] Error 1

Since I have only one file (gccTest.S), and no reference to 'main', I have no idea what's wrong here.

Finally, where are these 'operations' (like hi8, etc.) documented? I search the gas documentation in vain.

Thanks!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Every program needs a place to start, and the name of that place (eg a C function) is 'main'. The gcc run-time start-up code calls (or jumps to) that function, so the name must be 'main' (unless you take on re-writing the run-time code also).

In a C project you need to supply that function. Don't know how this is supposed to be done in an asembler only project, but maybe a label 'main' will do. The gas gurus will probably pass by here ad help.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think I have solved my own problem here, although the experts may well have additional insight.

Looking in the WinAVR avr-libc manual, I found a page on avr-libc and assembler programs. Not only does this page explain how to include a 'main' label as

.global main
main:

which solved the problem, it also explained hi8, lo8 and pm - and acknowledged that these were really nowhere documented in the gas manual.

Good stuff! You can't spend too much time reading the manuals!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Finally, where are these 'operations' (like hi8, etc.) documented?
Here's one place-
your_winavr_dir\doc\binutils\as.html\AVR_002dModifiers.html

This is where 'main' is used-
http://cvs.savannah.gnu.org/view...

this file is already compiled for us into a crt*.o for each avr (and linked with our own code, unless told otherwise).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Here's one place-
your_winavr_dir\doc\binutils\as.html\AVR_002dModifiers.html

This file does not seem to be in my winavr docs. Where else might I be able to find it? (My WinAVR is 20070525.)

Quote:
this file is already compiled for us into a crt*.o for each avr (and linked with our own code, unless told otherwise).

How would I tell the linker not to link this?

Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Where else might I be able to find it? (My WinAVR is 20070525.)
I don't know, the reference I gave was from 20071221.

Quote:
How would I tell the linker not to link this
-nostartfiles linker option will eliminate the crt*.o file from being linked in. And to prevent the copy/clear startup functions from being pulled in from libgcc.a, create empty functions-
__attribute__((naked))void __do_clear_bss(){}
__attribute__((naked))void __do_copy_data(){}
//or asm empty functions

The clear bss function always comes from libgcc.a, and the copy data function can come from either the crt*.o or libgcc.a, depending on whether the avr is >64k. The above code always works (used with -nostartfiles), and eliminates the need for the -nodefaultlibs option (no use libgcc.a), which could also eliminate needed functions.

Here's code (with the -nostartfiles linker option), that will compile and result in no code produced (the best code I have ever produced)-

//test.S
//linker option -nostartfiles
.global __do_clear_bss
__do_clear_bss:
.global __do_copy_data
__do_copy_data:

You could do the same in C. Of course, you now are in control of everything- setting up vector table, determining where code starts (using sections), etc.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Regarding the main: thing:

If you write an Asm only program (only .S files) then by default the build system will still be including a reset jump, a completely populated interrupt vector table, stack setting code, the .data copying loop and the .bss wiping loop finally followed by a call to "main" which may be provided (as it usually is) by "int main(void) {...}" in C or ".gobal main; main: .." in Asm.

But you now have the C pre-amble preceding your entry to main. In one way this is good. You could add a single .c file to the project that defined both initialised and uninitialised global variables and your Asm only code code benefit from the fact that the LPM to set the .data entries and the 0-wipe to clear the .bss entries is done for you.

However you may prefer a "clean machine" in which case add "-nostartfiles" allows you to write:

#include 

	jmp		reset

reset:
	ldi		r16, 0xFF
	out		_SFR_IO_ADDR(DDRB), r16
	out		_SFR_IO_ADDR(PORTB), r16
	ldi		r17, 0xFF
loop:
	in		r16, _SFR_IO_ADDR(PORTB)
	eor		r16, r17
	out		_SFR_IO_ADDR(PORTB), r16
	rjmp	loop

and get a .lss that contains:

Disassembly of section .text:

00000000 <__ctors_end>:
   0:	0c 94 02 00 	jmp	0x4	; 0x4 

00000004 :
   4:	0f ef       	ldi	r16, 0xFF	; 255
   6:	07 bb       	out	0x17, r16	; 23
   8:	08 bb       	out	0x18, r16	; 24
   a:	1f ef       	ldi	r17, 0xFF	; 255

0000000c :
   c:	08 b3       	in	r16, 0x18	; 24
   e:	01 27       	eor	r16, r17
  10:	08 bb       	out	0x18, r16	; 24
  12:	fc cf       	rjmp	.-8      	; 0xc 

EDIT: Sorry, more caffeine needed here - I missed the fact that Curt had said almost exactly the same thing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks to all. You are indeed gurus!

My gcc/gas program is now working fine - and I understand how/why it works.

Thanks again.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks to all for being here and the help you offer. To try to capture what I learned and maybe give back a little, here's a tutorial you may find helpful.
https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=84753

Enjoy!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Very nice!

JW