Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
e39
PostPosted: Mar 29, 2012 - 07:01 PM
Rookie


Joined: Jan 04, 2005
Posts: 36
Location: Jura - France

Hello AVR experts,

I'm using avr-gcc-4.5.3 for compiling a ATtiny44 project made of an asm source file and a C source file.

The asm source declares a few bss data like this:
Code:
   .section .bss
   .global   swuart0_cb
swuart0_cb:   .word   0


I've discovered that there's no __do_clear_bss etc. in the machine code produced if I do not declare a bss data in the C source file:
Code:
int n ;
int main ( ) { ... }


Why?


The project is compiled this way:
Code:
avr-as -mmcu=attiny44 -I/home/indy/dev/hwa/hwa -g swuart-int0-t0a-attiny44.s -o build/swuart-int0-t0a-attiny44.attiny44.o

avr-gcc -mmcu=attiny44 -std=c99 -Wall -Wextra -fomit-frame-pointer -ffunction-sections -Os -DHWA_DEVICE=attiny44 -DFUSE_LB=0xE2 -DFUSE_HB=0xDF -DFUSE_EB=0xFE -I/home/indy/dev/hwa/hwa -c main-int0-t0a.c -o build/main-int0-t0a.attiny44.o

avr-gcc -mmcu=attiny44 -Wl,--gc-sections -o build/out.elf build/swuart-int0-t0a-attiny44.attiny44.o build/main-int0-t0a.attiny44.o

_________________
« J'ai pas Word, j'ai pas Windows, et j'ai pas la télé ! »
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
westfw
PostPosted: Mar 29, 2012 - 07:07 PM
Posting Freak


Joined: Jun 19, 2002
Posts: 1330
Location: SF Bay area

Just guessing: bss initialization is part of the C standard. So it's the C compiler that tells the linker that it needs to include bss initialization code, if needed. Otherwise, it's just an arbitrary section name, as far as the linker is concerned...
 
 View user's profile Send private message  
Reply with quote Back to top
skeeve
PostPosted: Mar 29, 2012 - 11:45 PM
Raving lunatic


Joined: Oct 29, 2006
Posts: 3043


westfw wrote:
Just guessing: bss initialization is part of the C standard. So it's the C compiler that tells the linker that it needs to include bss initialization code, if needed. Otherwise, it's just an arbitrary section name, as far as the linker is concerned...
.bss initialization is not part of any C standard.
Initialization of globals is part of the C standards.
The zeroing of the .bss section is one way some globals are initialized on some systems.
Note that on systems that actually have systems,
the zeroing of the .bss section is usually done at load time.
Among compilers that emit .bss sections, there can be differences in which globals go into the .bss sections:
Code:
int yes;
int maybe=0;
int no=666;
The smarter compilers put two of the three into the .bss section.

The issue here is how OP's code differs from that emitted by the compiler.
It might be because he specifies data instead of just leaving space.

_________________
Michael Hennebry
"Well, if anyone would know about hubris,
it would be the man who built God." -- Root
 
 View user's profile Send private message  
Reply with quote Back to top
westfw
PostPosted: Mar 30, 2012 - 08:28 AM
Posting Freak


Joined: Jun 19, 2002
Posts: 1330
Location: SF Bay area

"All uninitialized variables are initialized to zero" has apparently been true and standard since about C89.
http://www.velocityreviews.com/forums/t ... ation.html
Calling them the "bss" section is an implementation dependent detail, I suppose...
 
 View user's profile Send private message  
Reply with quote Back to top
wek
PostPosted: Mar 30, 2012 - 08:44 AM
Raving lunatic


Joined: Dec 16, 2005
Posts: 3198
Location: Bratislava, Slovakia

Please post a complete compilable example which exhibits the problem, including the commands used to compile/link.

You could also have a look at the assembler output of compilation - does it contain ".global .global __do_clear_bss"?

JW
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
SprinterSB
PostPosted: Mar 30, 2012 - 09:53 AM
Posting Freak


Joined: Dec 21, 2006
Posts: 1677
Location: Saar-Lor-Lux

You need to refer to __do_clear_bss resp. __do_copy_data.

See http://gcc.gnu.org/PR18145
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
wek
PostPosted: Mar 30, 2012 - 10:11 AM
Raving lunatic


Joined: Dec 16, 2005
Posts: 3198
Location: Bratislava, Slovakia

SprinterSB wrote:
You need to refer to __do_clear_bss resp. __do_copy_data.

See http://gcc.gnu.org/PR18145
Yes, but wouldn't the object resulting from compilation of C source refer to them?

If I understand it correctly, your modification referred to above is not pertaining to avr-gcc 4.5.3, or am I wrong?

JW
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Mar 30, 2012 - 10:13 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 69409
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Please post a complete compilable example

Code:
// test.c
#include <avr/io.h>

extern uint8_t foo(void);

int main(void) {
   DDRB = foo();
    while(1);
}
Code:
// asm.S
#include  <avr/io.h>

.global foo
foo:
   lds      r24, bar
   ret
   
   .section .bss
bar:   .word   0

Code:
E:\avr[i386_vc]>make

-------- begin --------
avr-gcc (WinAVR 20100110) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Compiling C: test.c
avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort
-enums -Wall -Wstrict-prototypes --save-temps -fverbose-asm -Wa,-adhlns=./test.lst  -std=gnu99 -MMD -MP -MF .dep/test.o.
d test.c -o test.o

Linking: test.elf
avr-gcc -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-en
ums -Wall -Wstrict-prototypes --save-temps -fverbose-asm -Wa,-adhlns=test.o  -std=gnu99 -MMD -MP -MF .dep/test.elf.d tes
t.o asm.o --output test.elf -Wl,-Map=test.map,--cref     -lm

Code:
Disassembly of section .text:

00000000 <__vectors>:
   0:   0c 94 2a 00    jmp   0x54   ; 0x54 <__ctors_end>
   4:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
   8:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
   c:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  10:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  14:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  18:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  1c:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  20:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  24:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  28:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  2c:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  30:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  34:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  38:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  3c:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  40:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  44:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  48:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  4c:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>
  50:   0c 94 34 00    jmp   0x68   ; 0x68 <__bad_interrupt>

00000054 <__ctors_end>:
  54:   11 24          eor   r1, r1
  56:   1f be          out   0x3f, r1   ; 63
  58:   cf e5          ldi   r28, 0x5F   ; 95
  5a:   d4 e0          ldi   r29, 0x04   ; 4
  5c:   de bf          out   0x3e, r29   ; 62
  5e:   cd bf          out   0x3d, r28   ; 61
  60:   0e 94 36 00    call   0x6c   ; 0x6c <main>
  64:   0c 94 3d 00    jmp   0x7a   ; 0x7a <_exit>

00000068 <__bad_interrupt>:
  68:   0c 94 00 00    jmp   0   ; 0x0 <__vectors>

0000006c <main>:
#include <avr/io.h>

extern uint8_t foo(void);

int main(void) {
   DDRB = foo();
  6c:   0e 94 3a 00    call   0x74   ; 0x74 <foo>
  70:   87 bb          out   0x17, r24   ; 23
  72:   ff cf          rjmp   .-2         ; 0x72 <main+0x6>

00000074 <foo>:
#include  <avr/io.h>

.global foo
foo:
   lds      r24, bar
  74:   80 91 60 00    lds   r24, 0x0060
   ret
  78:   08 95          ret

0000007a <_exit>:
  7a:   f8 94          cli

0000007c <__stop_program>:
  7c:   ff cf          rjmp   .-2         ; 0x7c <__stop_program>

(no call do _do_clear_bss).

Modify .c:
Code:
#include <avr/io.h>

int bar2;
extern uint8_t foo(void);

int main(void) {
   DDRB = foo();
    while(1);
}

leads to:
Code:
00000054 <__ctors_end>:
  54:   11 24          eor   r1, r1
  56:   1f be          out   0x3f, r1   ; 63
  58:   cf e5          ldi   r28, 0x5F   ; 95
  5a:   d4 e0          ldi   r29, 0x04   ; 4
  5c:   de bf          out   0x3e, r29   ; 62
  5e:   cd bf          out   0x3d, r28   ; 61

00000060 <__do_clear_bss>:
  60:   10 e0          ldi   r17, 0x00   ; 0
  62:   a0 e6          ldi   r26, 0x60   ; 96
  64:   b0 e0          ldi   r27, 0x00   ; 0
  66:   01 c0          rjmp   .+2         ; 0x6a <.do_clear_bss_start>

00000068 <.do_clear_bss_loop>:
  68:   1d 92          st   X+, r1

0000006a <.do_clear_bss_start>:
  6a:   a4 36          cpi   r26, 0x64   ; 100
  6c:   b1 07          cpc   r27, r17
  6e:   e1 f7          brne   .-8         ; 0x68 <.do_clear_bss_loop>
  70:   0e 94 3e 00    call   0x7c   ; 0x7c <main>
  74:   0c 94 45 00    jmp   0x8a   ; 0x8a <_exit>

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
wek
PostPosted: Mar 30, 2012 - 10:30 AM
Raving lunatic


Joined: Dec 16, 2005
Posts: 3198
Location: Bratislava, Slovakia

Indeed. I am confused. I was trying the same with my trusty 2007-vintage avr-gcc, and then I looked into gcc v4.6.x sources to confirm those two symbols are emitted as .global for every C source unconditionally.

So this existed as a patch by January 20100110 ([WinAVR20100110]\source\avr\gcc\4.3.3\43-gcc-4.3.3-bug-35013.patch), yet the author (EW? Probably not, there are hints that this patch's author is of German tongue) did not care to submit it into http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18145 even if the patch's name explicitly indicates it's a patch for this very issue?

Hummm.

JW
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
david.prentice
PostPosted: Mar 30, 2012 - 11:01 AM
10k+ Postman


Joined: Feb 12, 2005
Posts: 19464
Location: Wormshill, England

Jan,

There is a similar issue with SDCC and initialised data in xdata. You have to explicitly change your startup.asm.

As far as I can see, regular AVR C programs are fine. i.e. they will always clear .bss and initialise .data.
It is only if you concoct a C program with the .bss only ever used in the ASM module.

Ideally avr-gcc should fix it. As a workaround, you could force it yourself. After all, the OP went to some lengths to remove the .bss from the C files.

David.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
clawson
PostPosted: Mar 30, 2012 - 11:05 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 69409
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

. As a workaround, you could force it yourself.

The very simplest workaround is to put the BSS variables into one of the .c files in the project. In my example above:
Code:
// test.c
#include <avr/io.h>

uint16_t bar;
extern uint8_t foo(void);

int main(void) {
   DDRB = foo();
    while(1);
}
Code:
// asm.S
#include  <avr/io.h>

.global foo
foo:
   lds      r24, bar
   ret

Code:
00000054 <__ctors_end>:
  54:   11 24          eor   r1, r1
  56:   1f be          out   0x3f, r1   ; 63
  58:   cf e5          ldi   r28, 0x5F   ; 95
  5a:   d4 e0          ldi   r29, 0x04   ; 4
  5c:   de bf          out   0x3e, r29   ; 62
  5e:   cd bf          out   0x3d, r28   ; 61

00000060 <__do_clear_bss>:
  60:   10 e0          ldi   r17, 0x00   ; 0
  62:   a0 e6          ldi   r26, 0x60   ; 96
  64:   b0 e0          ldi   r27, 0x00   ; 0
  66:   01 c0          rjmp   .+2         ; 0x6a <.do_clear_bss_start>

00000068 <.do_clear_bss_loop>:
  68:   1d 92          st   X+, r1

0000006a <.do_clear_bss_start>:
  6a:   a2 36          cpi   r26, 0x62   ; 98
  6c:   b1 07          cpc   r27, r17
  6e:   e1 f7          brne   .-8         ; 0x68 <.do_clear_bss_loop>
  70:   0e 94 3e 00    call   0x7c   ; 0x7c <main>
  74:   0c 94 45 00    jmp   0x8a   ; 0x8a <_exit>

00000078 <__bad_interrupt>:
  78:   0c 94 00 00    jmp   0   ; 0x0 <__vectors>

0000007c <main>:

uint16_t bar;
extern uint8_t foo(void);

int main(void) {
   DDRB = foo();
  7c:   0e 94 42 00    call   0x84   ; 0x84 <foo>
  80:   87 bb          out   0x17, r24   ; 23
  82:   ff cf          rjmp   .-2         ; 0x82 <main+0x6>

00000084 <foo>:
#include  <avr/io.h>

.global foo
foo:
   lds      r24, bar
  84:   80 91 60 00    lds   r24, 0x0060
   ret
  88:   08 95          ret

PS just tried a .data experiment:
Code:
#include  <avr/io.h>

.global foo
foo:
   lds      r24, bar
   ret

   .data
   .type   bar, @object
   .size   bar, 3
bar:
   .string   "hi"

that suffers in the same way no _do_copy_data() generated. (it does work if the variable is in the .c of course - in fact that's how I got the Asm source to put in the .S)

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
SprinterSB
PostPosted: Mar 30, 2012 - 01:28 PM
Posting Freak


Joined: Dec 21, 2006
Posts: 1677
Location: Saar-Lor-Lux

wek wrote:
SprinterSB wrote:
You need to refer to __do_clear_bss resp. __do_copy_data.

See http://gcc.gnu.org/PR18145
Yes, but wouldn't the object resulting from compilation of C source refer to them?
That depends on the C source. If the C source has no need for .bss, no code to initialize it is dragged in. Similar for .data/.rodata.
wek wrote:
If I understand it correctly, your modification referred to above is not pertaining to avr-gcc 4.5.3, or am I wrong?
That depends on what patchset your build uses. For WinAVR-20100110 for example there is
Code:
.\source\avr\gcc\4.3.3\47-gcc-4.3.3-bug-18145-v4.patch
If a build has PR18145 not fixed, mentioned __do_ symbols are refered unconditionally at the top of the s-file produced by avr-gcc.

If it comes with PR18145 fixed, the symbols are refered to at the end of the s-file as needed. In particular: if they are not needed for the specific module, they are is no referrer.
david.prentice wrote:
Ideally avr-gcc should fix it.
The fix is PR18145: Don't drag in code that's not needed. Every module cares for it's objects and book-keeping/stock-taking because only the module knows if there is need for respective bit of startup code. See the FIXME that PR18145 removed from the sources:
Code:
 static unsigned int
@@ -4933,12 +5008,6 @@ avr_file_start (void)
   
   fputs ("__tmp_reg__ = 0\n"
          "__zero_reg__ = 1\n", asm_out_file);
-
-  /* FIXME: output these only if there is anything in the .data / .bss
-     sections - some code size could be saved by not linking in the
-     initialization code from libgcc if one or both sections are empty.  */
-  fputs ("\t.global __do_copy_data\n", asm_out_file);
-  fputs ("\t.global __do_clear_bss\n", asm_out_file);
 }
 
 /* Outputs to the stdio stream FILE some
@@ -4947,6 +5016,16 @@ avr_file_start (void)
 static void
 avr_file_end (void)
 {
+    /* Output these only if there is anything in the
+       .data* / .rodata* / .gnu.linkonce.* resp. .bss*
+       input section(s) - some code size can be saved by not
+       linking in the initialization code from libgcc if resp.
+       sections are empty. */
+    if (avr_need_copy_data_p)
+        fputs (".global __do_copy_data\n", asm_out_file);
+   
+    if (avr_need_clear_bss_p)
+        fputs (".global __do_clear_bss\n", asm_out_file);
 }

And yes, the assertion is that assembler programmers know what they are doing. Similar for C programmers that use non-standard section names or orphan sections.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
sternst
PostPosted: Mar 30, 2012 - 01:56 PM
Raving lunatic


Joined: Jul 23, 2001
Posts: 2728
Location: Osnabrueck, Germany

clawson wrote:
Quote:

. As a workaround, you could force it yourself.

The very simplest workaround is to put the BSS variables into one of the .c files in the project.
Or to put a ".global __do_clear_bss" into the asm file.

_________________
Stefan Ernst
 
 View user's profile Send private message  
Reply with quote Back to top
skeeve
PostPosted: Mar 30, 2012 - 04:25 PM
Raving lunatic


Joined: Oct 29, 2006
Posts: 3043


sternst wrote:
clawson wrote:
Quote:

. As a workaround, you could force it yourself.

The very simplest workaround is to put the BSS variables into one of the .c files in the project.
Or to put a ".global __do_clear_bss" into the asm file.
As I would expect that there is a reason the .bss
variable was not in a .c file to start with,
that is what I would do if I didn't do it very often.
Were I doing it it often, I would write a gas macro that I would use to start .bss sections.

OP's .bss variable was explicitly zero.
What if it were explicitly non-zero?
'Twould get zeroed anyway, correct?

_________________
Michael Hennebry
"Well, if anyone would know about hubris,
it would be the man who built God." -- Root
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 30, 2012 - 04:43 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 69409
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

What if it were explicitly non-zero?
'Twould get zeroed anyway, correct?

Easily tested:
Code:
#include  <avr/io.h>

.global foo
foo:
   lds      r24, bar
   ret

   .global __do_clear_bss
   .section .bss
bar:
   .word 12345

That gets wiped to 0.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
e39
PostPosted: Mar 30, 2012 - 06:00 PM
Rookie


Joined: Jan 04, 2005
Posts: 36
Location: Jura - France

Wow! Many answers that I do not understand very well but the thing is that declaring
Code:
.global __do_clear_bss
make it work.

If I would not want a data to be set to 0, I would not put it in the .bss section, so, that's ok.

Thank you.

What does "OP" mean?

_________________
« J'ai pas Word, j'ai pas Windows, et j'ai pas la télé ! »
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
wek
PostPosted: Mar 30, 2012 - 06:17 PM
Raving lunatic


Joined: Dec 16, 2005
Posts: 3198
Location: Bratislava, Slovakia

e39 wrote:
What does "OP" mean?
Original Poster (i.e. here it means you).

JW
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Mar 30, 2012 - 06:23 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 69409
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Original Poster

Or sometimes "Original Post" meaning the post that started the thread as in "he said in the OP it was a tiny44"

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
wek
PostPosted: Mar 30, 2012 - 06:54 PM
Raving lunatic


Joined: Dec 16, 2005
Posts: 3198
Location: Bratislava, Slovakia

Btw. shouldn't there be some "how to write asm using avr-gcc's suite" guide?

Snippets of wisdom of all kinds, such as what we learned here just now, could go there...

JW
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Mar 30, 2012 - 06:58 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 69409
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Snippets of wisdom of all kinds, such as what we learned here just now, could go there...

I would suggest the AVR-LibC documentation but you know where that got me last time Wink

If it was going there it could probably tag onto the bottom of this page:

http://www.nongnu.org/avr-libc/user-man ... mbler.html

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits