Arduino programming in assembly?

I realize I can program the Arduino in C, but with my current project (tiny Arduino core) I would prefer to use Assembly for some sections to learn the assembly and possibly improve the efficiency of the SLIGHTEST bit.

Is there something I can use like __ASM __ ()? I was actually able to find people on the internet trying to convince people who asked similar questions to learn C rather than actually answering the question.

Thank!

+3


source to share


1 answer


one that I wrote and published many years ago.

.device ATmega168
.equ  DDRB       = 0x04
.equ  PORTB      = 0x05

.org 0x0000
    rjmp RESET

RESET:
    ldi R16,0x20
    out DDRB,R16

    ldi R18,0x00
    ldi R17,0x00
    ldi R20,0x20
Loop:

    ldi R19,0xE8
aloop:
    inc R17
    cpi R17,0x00
    brne aloop

    inc R18
    cpi R18,0x00
    brne aloop

    inc R19
    cpi R19,0x00
    brne aloop

    eor R16,R20
    out PORTB, R16
    rjmp Loop

      

I used avra and probably wrote my own arduino bootloader

blinker01.s.hex : blinker01.s
    avra -fI blinker01.s

clean :
    rm -f blinker01.s.*

      

you could use avr_dude of course.

With gnu, something slightly different:

.globl _start
_start:
    rjmp RESET

RESET:
    ldi R18,0x00
    ldi R17,0x00
    ldi R20,0x20
Loop:

    ldi R19,0xE8
aloop:
    inc R17
    cpi R17,0x00
    brne aloop

    inc R18
    cpi R18,0x00
    brne aloop

    inc R19
    cpi R19,0x00
    brne aloop

    rjmp Loop

      

you do not need header files to define ports, you can declare them yourself.

MEMORY
{
    rom : ORIGIN = 0x00000000, LENGTH = 0x1000
}

SECTIONS
{
    .text : { *(.text*) } > rom
}

avr-as so.s -o so.o
avr-ld -T so.ld so.o -o so.elf
avr-objdump -D so.elf > so.list
avr-objcopy so.elf -O ihex so.hex

      

Using apt-got avr-gcc (and binutils), maybe the same tools used with arduino sandbox and should be accessed directly, but I'm not using sandbox so I don't know.



EDIT

the other approach is limited but more likely to succeed with the toolchain since you start with a working C application and environment, then add an object, also help with the basics of building, see what the compiler does, then read on it:

unsigned short fun ( unsigned short x, unsigned short y )
{
    return(x+y+5);
}

avr-gcc -c -O2 so.c -o so.o
avr-objdump -D so.o

00000000 <fun>:
   0:   6b 5f           subi    r22, 0xFB   ; 251
   2:   7f 4f           sbci    r23, 0xFF   ; 255
   4:   86 0f           add r24, r22
   6:   97 1f           adc r25, r23
   8:   08 95           ret

      

So

create so.s

.globl fun
fun:
    subi r22, 0xFB  ; 251
    sbci r23, 0xFF  ; 255
    add  r24, r22
    adc  r25, r23
    ret



avr-as so.s -o so.o
avr-objdump -D so.o

00000000 <fun>:
   0:   6b 5f           subi    r22, 0xFB   ; 251
   2:   7f 4f           sbci    r23, 0xFF   ; 255
   4:   86 0f           add r24, r22
   6:   97 1f           adc r25, r23
   8:   08 95           ret

      

and then instead of linking in the generated object C a reference to the object created by the assembly, you should learn the calling convention, which you can experiment with.

unsigned char fun ( unsigned char x, unsigned char y )
{
    return(x+(y<<1));
}
00000000 <fun>:
   0:   66 0f           add r22, r22
   2:   86 0f           add r24, r22
   4:   08 95           ret

      

in this case the second parameter in r22 is first in r24, the return value in r24. so 22/23 is probably for the first parameter for large items like the short one, and 24/25 for the second. it will be documented somewhere as well, the compiler matches it, there will be exceptions, so create a correct example to see what the compiler does and not just assume that everything from one example is critical, even if you read the docs, this is probably vaguely, or uses terminology that may not make sense until you experiment.

+4


source







All Articles