|
From: | Alistair Gadd |
Subject: | Re: [avr-gcc-list] In-line Assembler Code |
Date: | Wed, 18 Mar 2015 11:24:23 +0200 |
User-agent: | Mozilla/5.0 (Windows NT 5.2; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 |
Hi Erik, I did in fact, eventually do exactly that. But I do like your tip on running xxx.S files through cpp and I'm going to use it. I just thought that because in-line assembly was being used by members of the community, it should be something I should have a handle on. I do have a better understanding of it now, but I didn't continue with it for more or less the same reasons that you don't use it. I was trying to make sense of an Atmel demo and the mistake that I was making was that I didn't see that there were actually 2 instances compiled and I was only examining the first one. The following had also been used elsewhere in the project: // Locate low level init function before RAM init (init3 section) char __low_level_init(void) __attribute__ ((section (".init3"),naked)); char __low_level_init() { clock_prescale_set(clock_div_1); return 1; } My test looked like this: #include <avr/io.h> #include <avr/power.h> int main(void) { DDRC = 0x80; PORTC |= 0x80; clock_prescale_set(clock_div_2); PORTC &= 0x7F; while(1) {}; } and an extract from "avr/power.h" (shortened for explanation here) is:
typedef enum The compilations are flawless
whether optimised or not, and needless to say, I felt a bit
stupid when I found it. Thanks to you Erik, Johann and
Jan for the help, and I apologise for any wild goose chases. Best regards, On 2015/03/18 09:07 AM, Erik
Christiansen wrote:
On 07.03.15 17:07, Alistair Gadd wrote:I'm used to using separate assembler files and I'm not a great boffin on using in-line assembly, but I really think I need to get a collar on it.Alistair, is there any reason for not using separate assembler files, as is your custom? As clock_prescale_set() is entirely assembler, it is ripe for linking in from a separate assembler source file, either put through the assembler only, or avr-gcc, as preferred. In the latest makefile I wrote for use on avr, I find I'm using: %.o: %.c $(CC) -c $(CFLAGS) -o $(OBJDIR)/$@ $< %.o: %.s $(AS) -I$(INC_DIR) $(ASFLAGS) -o $(OBJDIR)/$@ $< %.o: %.S $(CC) -c -I$(INC_DIR) -x assembler-with-cpp $(CFLAGS) -Wa,-alms=$(OBJDIR)/address@hidden -o $(OBJDIR)/$@ $< I.e. xxx.S goes through cpp, so lots of good macros are expanded. If register allocation is a doubt, the ABI is documented here: http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_reg_usage I would certainly never use in-line assembler for anything other than a desperate hack of a large C function which couldn't be fixed any other way. In-line assembler is unreadable gibberish, and not an efficient or adequately maintainable method for writing a complete function, IME. Given that linking file(s) of assembler function(s) into a C program is quite elementary, it should hardly ever be necessary to use in-line assembler. (And in a 30 year embedded systems design/programming career, I never found it useful to do so.) Erik |
[Prev in Thread] | Current Thread | [Next in Thread] |