IDE Supports Assembly?

I don't want to hijack the thread, but I'm interested to know if that assembler code is supported directly by the Arduino IDE, or do you need any third party software to support writing in assembler.

BTW. Sorry for the noob question, but I was led to believe that the only way you could access assembler (with just the standard IDE) was to use the inline "asm" statement.

stuart0:
I don't want to hijack the thread...

Uh huh. Little voice inside your head made you do it?

...but I'm interested to know if that assembler code is supported directly by the Arduino IDE...

Yes. Ctrl+Shift+N to create a new tab. Give the file a dot-S (case is important; e.g. "whatever.S") extension.

[quote author=Coding Badly link=msg=2989161 date=1478411505]
Uh huh. Little voice inside your head made you do it?[/quote]
Yup. I’ve been reading a few threads here and that thread was the only one where I’d seen non inline assembler being used. So it seemed like a good place to ask. :slight_smile:

Yes. Ctrl+Shift+N to create a new tab. Give the file a dot-S (case is important; e.g. “whatever.S”) extension.

Thanks. I’ll give that a try.

Probably, the Arduino IDE is still good enough not as the complaining I have heard about it.

It's nice. However, anyone can tell me the reasons why we need to programming by assembler code. I know that assembler is faster and less coding size. But do we really need assembler? Have any app that must use assembler instead of C?

jts33:
It's nice. However, anyone can tell me the reasons why we need to programming by assembler code.

For most programs we don't need it.

It is however useful if you need very precise timing, as you can tell exactly how many cycles a given section of code will take. Sometimes a section of code, particularly interrupt routines, need to have fairly tight timing, and assembler can be a good option in those cases.

If you're not familiar with assembler then it might seem a bit daunting. However, once you're familiar with it then stuff like port and I/O manipulation is about as easy as any other method.

Finally, some people need it for educational purposes as they are learning assembly language.

It's nice. However, anyone can tell me the reasons why we need to programming by assembler code. I know that assembler is faster and less coding size. But do we really need assembler? Have any app that must use assembler instead of C?

There are no good reasons for using ASM. And is does not produce shorter or faster code!

All the registers that you can access are memory mapped and can be accessed using simple C.

Mark

particularly interrupt routines, need to have fairly tight timing,

Keep ISR’s short that way there are never any “timing” issues.

Mark

holmes4:
There are no good reasons for using ASM. And is does not produce shorter or faster code!

Keep ISR's short that way there are never any "timing" issues.

Mark

I just did some interrupt testing. Timer output connected to external interrupt 0 to trigger interrupt repetitively. Timer configured to clear on compare. Int0 configured for (low) level sensitive.

Test1. Basic response time.

Interrupt merely force compares the Timer to set the timer output and remove the interrupt source. Timer output (low going pulse) measured on scope to observe interrupt response time.

Results.

Assembler interrupt routine: 815 ns (nanoseconds)
Best I could manage in C : 1430 ns

Test2. Double interrupt.

The previous test measured the time to respond and clear the event, but not the entire interrupt routine including the return. This test used the level sensitive interrupt to get a double entry. First interrupt entry just sets a flag to show it has occurred and then returns. Second entry clears the flag and services the Timer to remove the source of the interrupt.

Results.

Assembler interrupt routine: 2.0 to 2.1 us (microseconds)
Best I could manage in C: 4.0 to 4.1 us.

Conclusion. I can write faster interrupt routines in assembler.

There are certainly times when a bit of ASM can be a lot faster.

For example:
I did a project where I needed to update 45 shift registers at a 20 KH rate - a new set of data every 50uS.
Using some ASM and direct port manipulation and turnoff interrupts, I was able to send out a byte every 17 clocks with SPI clock at 8 MHz, leaving just enough to point to the next array address for the next set of data:

// turn off interrupts and do the datablast from a while, using an if for counting was taking too long, as was going thru the loop() code. Turning off interrupts kept the millis()/micros() interrupt from adding irregular delays also - had to stay synced with an external 20 KHz clock:
if (clockEdge occurred){ // have to look to see how I caught that - maybe an interrupt after which interrupts were disabled until done
while (rowCount < 325){
PORTB = PORTB & 0b11111011; // D10 low
spdr = array[x + 0]; nop; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; //wait for transfer completion
spdr = array[x + 1]; nop; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; //wait for transfer completion
spdr = array[x + 2]; nop; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; //wait for transfer completion
:
:
spdr = array[x + 42]; nop; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; //wait for transfer completion
spdr = array[x + 43]; nop; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; //wait for transfer completion
spdr = array[x + 44]; nop; nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; //wait for transfer completion
PORTB = PORTB | 0b00000100; // D10 high, update the output register

x = x+45; // point to block in the array
rowCount = rowCount +1;
}
}

Nick Gammon helped me with the ASM and the fast SPI transfers, I worked out the other parts and confirmed timing was being met (& disturbed) with a Saleae logic analyser and digital oscilliscope.

The rest of the time, I find direct port manipulation for toggling Slave Select, SPI clock divisor at 2, and writing to the PINx registers to toggle an output to be the closest I come to getting away from C++ and regular IDE commands.

CrossRoads:
There are certainly times when a bit of ASM can be a lot faster.

Yes I agree. C is good enough 99.9% of the time, but it's an overreaching statement to say that asm is never faster.

The rest of the time, I find direct port manipulation for toggling Slave Select, SPI clock divisor at 2, and writing to the PINx registers to toggle an output to be the closest I come to getting away from C++ and regular IDE commands.

That's one of the good things about C. You can use more abstract and higher level constructs if you want to, but you can also get right down to near assembler level with things like direct port manipulation when it suits you. C lets you get up pretty close and personal with the hardware if you want to.

A bit like the choice between using "digitalWrite(13,HIGH)" or "PORTB |= 0x20" for example.

Fond good old days :frowning:

#define SETd13      PORTB |= B00100000  // D13 HIGH
#define RESETd13    PORTB &= B11011111  // D13 LOW
#define TOGGLEd13    PINB  = B00100000  // D13 Toggle
#define TESTd13     (PINB  & B00100000) // D13 is tested

But this isn't assembler is it?

.

#define SETd13      PORTB |= B00100000  // D13 HIGH

But this isn't assembler is it?

Nope. It's a good example of something that people EXPECT to be faster in assembler, that actually isn't.
(The C compiler is able to optimize such a statement into the same single instruction that an assembly language programmer would use.)

westfw:
(The C compiler is able to optimize such a statement into the same single instruction that an assembly language programmer would use.)

And is smart enough to know when the single instruction won't work.