| Author |
Message |
|
|
Posted: Mar 29, 2012 - 07:01 PM |
|

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é ! »
|
| |
|
|
|
|
|
Posted: Mar 29, 2012 - 07:07 PM |
|

Joined: Jun 19, 2002
Posts: 950
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... |
|
|
| |
|
|
|
|
|
Posted: Mar 29, 2012 - 11:45 PM |
|

Joined: Oct 29, 2006
Posts: 2640
|
|
|
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
Iluvatar is the better part of Valar.
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 08:28 AM |
|

Joined: Jun 19, 2002
Posts: 950
Location: SF Bay area
|
|
|
|
|
|
|
Posted: Mar 30, 2012 - 08:44 AM |
|

Joined: Dec 16, 2005
Posts: 3086
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 |
|
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 09:53 AM |
|


Joined: Dec 21, 2006
Posts: 1483
Location: Saar-Lor-Lux
|
|
|
|
|
|
|
Posted: Mar 30, 2012 - 10:11 AM |
|

Joined: Dec 16, 2005
Posts: 3086
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 |
|
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 10:13 AM |
|


Joined: Jul 18, 2005
Posts: 62220
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>
|
_________________
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 10:30 AM |
|

Joined: Dec 16, 2005
Posts: 3086
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 |
|
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 11:01 AM |
|

Joined: Feb 12, 2005
Posts: 16262
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. |
|
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 11:05 AM |
|


Joined: Jul 18, 2005
Posts: 62220
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) |
_________________
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 01:28 PM |
|


Joined: Dec 21, 2006
Posts: 1483
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. |
|
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 01:56 PM |
|


Joined: Jul 23, 2001
Posts: 2437
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
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 04:25 PM |
|

Joined: Oct 29, 2006
Posts: 2640
|
|
|
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
Iluvatar is the better part of Valar.
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 04:43 PM |
|


Joined: Jul 18, 2005
Posts: 62220
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. |
_________________
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 06:00 PM |
|

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é ! »
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 06:17 PM |
|

Joined: Dec 16, 2005
Posts: 3086
Location: Bratislava, Slovakia
|
|
|
e39 wrote:
What does "OP" mean?
Original Poster (i.e. here it means you).
JW |
|
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 06:23 PM |
|


Joined: Jul 18, 2005
Posts: 62220
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" |
_________________
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 06:54 PM |
|

Joined: Dec 16, 2005
Posts: 3086
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 |
|
|
| |
|
|
|
|
|
Posted: Mar 30, 2012 - 06:58 PM |
|


Joined: Jul 18, 2005
Posts: 62220
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
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 |
_________________
|
| |
|
|
|
|
|
Posted: Apr 07, 2012 - 03:04 PM |
|

Joined: Dec 16, 2005
Posts: 3086
Location: Bratislava, Slovakia
|
|
|
|
|
|
|
Posted: Apr 07, 2012 - 03:37 PM |
|


Joined: Jul 18, 2005
Posts: 62220
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
Is this OK?
Looks good to me. |
_________________
|
| |
|
|
|
|
|
Posted: Apr 07, 2012 - 05:38 PM |
|


Joined: Dec 21, 2006
Posts: 1483
Location: Saar-Lor-Lux
|
|
|
|
|
|
|
Posted: Apr 07, 2012 - 05:51 PM |
|

Joined: Dec 16, 2005
Posts: 3086
Location: Bratislava, Slovakia
|
|
|
SprinterSB wrote:
It also applies to ctors, dtors[...]
... to be used in asm++
JW |
|
|
| |
|
|
|
|
|