inline ASM on Arduino UNO

Does inline asm work on Arduino IDE ..

I'm trying to do [Bascom varient] Rotate Bytedata,Right

I tried asm("ror Bytedata \n") and get the following:::

Arduino: 1.8.5 (Windows 10), Board: "Arduino/Genuino Uno"

C:\Users\msw10\AppData\Local\Temp\cckpaojS.s: Assembler messages:

C:\Users\msw10\AppData\Local\Temp\cckpaojS.s:992: Error: constant value required

lto-wrapper: C:\Users\msw10\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\4.9.2-atmel3.5.4-arduino2/bin/avr-gcc returned 1 exit status

c:/users/msw10/appdata/local/arduino15/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.4-arduino2/bin/../lib/gcc/avr/4.9.2/../../../../avr/bin/ld.exe: error: lto-wrapper failed

collect2.exe: error: ld returned 1 exit status

exit status 1
Error compiling for board Arduino/Genuino Uno.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Yes you can use inline assembler, although it’s a bit more involved than that. If i-asm is truly what you want, I can point you in that direction. If however, you’re just after the bit rotation function try these macros:

#define NOTT !!

#define ROR(x) ((x >> 1) | ((x & 1) << 7))
#define ROL(x) (NOTT(x & 128) | (x << 1))

I’d prefer asm … 1 instruction vs more , plus I’m courious…
I’m trying to convert BASCOM basic code for 1-wire DS2540 slave to run on Arduino UNO, I detecting the reset-presence AOK , but not receiving correct byte info, anything to speed up should help. I probably
need to speed up 1wire signal - floating-hi or set low…Using:

DDRB == DDRB | 1 << OneWirePin; //PinLow
DDRB == DDRB & ~(1 << OneWirePin); //PinRelase

Perhaps I’m PORTB pin in wrong state?

Why? The compiler is much smarter than you or me. It will take the shift operators from the C code and implement them in staggeringly-efficient machine instructions. Usually it will find a better way to do it than what you you imagined.

What is wrong with the oneWire library?

An example sketch with a ROR instruction in inline assembler:

void setup() {
  Serial.begin(250000);
  
  uint8_t value = 140;
  
  __asm__ __volatile__(
    "clc                        \n\t"//
    "ror %[value0]              \n\t"//
    "mov %[result0], %[value0] \n\t"//
    :
    // Output operands
    [result0] "=r" (value)         //
    :
    // Input operands
    [value0] "r" (value)
    : 
    // Clobbers 
  );

  Serial.println(value);

}

void loop() {
 
}

Another asm option:

volatile uint8_t value = 123;

void setup()
{
    SeriaL.begin(38400);
    .
    .
    asm
    (
        "lds %0, (value) \n"
        "ror %0 \n"
        :"=r" (value)
    );
    Serial.println(value);

In this example the variable 'value' must be global as the lds instruction only works with data stored in RAM, not the stack which would be the case if you used a local variable.

You forgot to clear the carry flag, ROR (Rotate Right through carry) shifts 8 bits plus the carry flag and LDS do not clear the carry flag.

DKWatson:
In this example the variable 'value' must be global as the lds instruction only works with data stored in RAM, not the stack which would be the case if you used a local variable.

Where is your stack located if not in RAM as my is?

Whandall:
Where is your stack located if not in RAM as my is?

It has to do with having a fixed address when compiling/assembling. There are other instructions for dealing with data available on the stack and other methods for using passed variables as with a stub function. It's just the LDS instruction that's picky, it asks for fixed memory location. You can get around this but, more code, more clks.

DKWatson:
It has to do with having a fixed address when compiling/assembling.

Why are you taking about RAM then?

Sorry, you got ahead of my edit.

For insight.

"The variable must be global in scope. This causes the compiler to locate the variable inside SRAM. If we declared the variable inside of the setup() function, it may have been stored temporarily on the stack or inside a register. If that was the case, the STS instruction would have caused an error because it only works when storing to SRAM.

LDS loads one byte from the data space (SRAM) into a register.

In both the LDS and STS instructions, the assembler inserts the SRAM memory addressing for us."

This is from the Arduino Inline Assembly Tutorial. Copy available if you wish (89 pages, 1.75MB).

uint8_t value = 140;

asm volatile(
“clc \n\t”//
“ror %[value0] \n\t”//
“mov %[result0], %[value0] \n\t”//
:
// Output operands
[result0] “=r” (value) //

Since I’m a C idiot… What does the % do and what does =r do?

asm
(
“lds %0, (value) \n”
“ror %0 \n”
:"=r" (value)

That's not C, it's assembly, what you asked for. Now you're saying you want to be taught assembly? Wrong forum.

Why the wise ass comment?

I've written a lot of assembly over the years RCA-301, Spectra 70, Unisys 90/30 and some microchips, and don't recall using anything like %0 or "=r" ....

That must be used by a particular assembler

https://www.nongnu.org/avr-libc/user-manual/inline_asm.html

What does the % do and what does =r do?

gcc has some fancy features to help you interface to inline assembler.
you had an OUT inline assembler function that output to an AVR port, you'd probably want output some C variable:

     char c = somecalc;
     asm("out PORTB, c");  // output c to PORT

With modern optimization, though, "c" probably is in some register (and you don't know which one.)
You could save it to a well-known global memory location, and then your assembler could read that location, but that sort of thing quickly defeats the purpose of using inline assembly in the first place.

But the compiler knows where things are. The "%x" and "=r" and similar are part of an interface that gcc provides to connect C and assembly. You can tell it where input variables are, have it put outputs in places that C is aware of, and notify the compiler that you've used certain registers so that it can optimize around that.

It's very powerful and pretty cool, but it's pretty much so complex that you probably need something. like this tutorial open every time you try to use it...
https://www.nongnu.org/avr-libc/user-manual/inline_asm.html

Thx