Re: In-line Assembler Code

Alistair Gadd <[email protected]>
Newsgroups gmane.comp.hardware.avr.gcc
Message-ID <[email protected]>
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
{
     clock_div_1 = 0, clock_div_2 = 1, clock_div_4 = 2, clock_div_8 = 3, 
clock_div_16 = 4,
     clock_div_32 = 5, clock_div_64 = 6, clock_div_128 = 7, 
clock_div_256 = 8
}  clock_div_t;

static __inline__   void clock_prescale_set(clock_div_t) 
__attribute__((__always_inline__));
void clock_prescale_set(clock_div_t __x)
{
     uint8_t __tmp = _BV(CLKPCE);
     __asm__   __volatile__ (
     "in __tmp_reg__,__SREG__" "\n\t"
     "cli" "\n\t"
     "sts %1, %0" "\n\t"
     "sts %1, %2" "\n\t"
     "out __SREG__, __tmp_reg__"
     : /* no outputs */
     : "d" (__tmp),
     "M" (_SFR_MEM_ADDR(CLKPR)),
     "d" (__x)
     : "r0");
}

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,
Alistair.

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)/[email protected] -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
>

_______________________________________________
AVR-GCC-list mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.