[ create a new paste ] login | about

Link: http://codepad.org/eaKJDO4y    [ raw code | fork ]

Plain Text, pasted on Aug 11:
const __flash char str[] = "bla";
static void puts_m (const __flash char *str) {
    while (*str) {
        usart_putchar (*str);
        str++;
    }
}
puts_m(str);
--------------------------------------------------------
generates:
--------------------------------------------------------
 14a:   c6 e2           ldi r28, 0x26   ; 38
 14c:   d0 e0           ldi r29, 0x00   ; 0
 14e:   01 c0           rjmp    .+2         ; 0x152 <main+0x4e>

const __flash char str[] = "bla";
static void puts_m (const __flash char *str) {
    while (*str) {
        usart_putchar (*str);
 150:   84 df           rcall   .-248       ; 0x5a <usart_putchar>

 152:   fe 01           movw    r30, r28
 154:   21 96           adiw    r28, 0x01   ; 1
 156:   85 91           lpm r24, Z+
 158:   81 11           cpse    r24, r1
 15a:   fa cf           rjmp    .-12        ; 0x150 <main+0x4c>

-----------------------------------------------------------
Why is it moving the Y (r29:r28) pointer into Z (r31:r30) ptr and then
incrementing the former when the LPM instructions features
autoincrement itself? More elegant, smaller and faster code would be:
      ldi r30, 0x26
      ldi r31, 0x00   --- load immediate
      rjmp    puts
loop: rcall usart_putchar
puts: lpm r24, Z+     --- load program memory
      cpse r24, r1    --- compare, skip if equal
      rjmp loop
--------------------------------------------------------------------
The above code is compiled with 

gcc -mmcu=attiny2313 -g -ggdb -Os -Wall -Wno-main -funsigned-char
 -funsigned-bitfields -fpack-struct -fshort-enums
 -ffunction-sections -fdata-sections
 -ffreestanding -Wno-unused-function -std=gnu99 
 avr/main.c


INLINE ASM:

const __flash char str[] = "bla";
static void puts_m (const __flash char *str) {
            asm volatile ("\n\t" : : "z" (str)); // we need the location in the Z ptr
 14a:   e6 e2           ldi r30, 0x26   ; 38
 14c:   f0 e0           ldi r31, 0x00   ; 0
 14e:   01 c0           rjmp    .+2         ; 0x152 <main+0x4e>
            register u8 temp; // temp. register
            
            goto puts_f;
puts_loop:  usart_putchar(temp);
 150:   84 df           rcall   .-248       ; 0x5a <usart_putchar>
puts_f:     asm volatile ("lpm  %0, Z+  \n\t" : "=r" (temp) );
 152:   85 91           lpm r24, Z+ 
            asm volatile ("cpse %0, __zero_reg__\n\t" : : "r" (temp));
 154:   81 11           cpse    r24, r1
            asm volatile goto ("rjmp %l[puts_loop]\n\t" : : :: puts_loop);
 156:   fc cf           rjmp    .-8         ; 0x150 <main+0x4c>



Create a new paste based on this one


Comments: