Problem with "asm volatile ()" in my Sketch

I would like to save and restore GPIO registers on the stack for certain reasons. For this I wrote a small test program, which is not compiled without errors. Where is the problem? Why are the two registers "PORTB" and "DDRB" unknown?
The error messages (Arduino IDE 2.1, Arduino UNO):
C:\Users\Rudol\AppData\Local\Temp\cccgm7Sb.ltrans0.ltrans.o: In function loop':* *D:\Arduino\Tests\AsmPushPop/AsmPushPop.ino:40: undefined reference to DDRB'
D:\Arduino\Tests\AsmPushPop/AsmPushPop.ino:40: undefined reference to PORTB'* *D:\Arduino\Tests\AsmPushPop/AsmPushPop.ino:50: undefined reference to PORTB'
D:\Arduino\Tests\AsmPushPop/AsmPushPop.ino:50: undefined reference to `DDRB'
collect2.exe: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1

... and my Sketch:

/*================================================================
	UNO/Nano (ATMEGA328P): Test push/pop with assembler instructions
	================================================================*/

//==== Arduino-Standard: setup() ==========================
void setup() {

	pinMode(13,OUTPUT);	// Signal: Prozessor is running
        digitalWrite(13,HIGH);
	delay(2000);
	Serial.begin(115200);
	while(!Serial) delay(10);
	Serial.println("Test push / pop GPIO");
}

//==== Arduino-Standard: loop() ===========================
void loop() {

  //---- Save DDRB and PORTB con Stack ----
	asm volatile 
  ( 
    "PUSH R20 \n"
    "IN R20,DDRB \n"
    "PUSH R20 \n" 
    "IN R20,PORTB \n"
    "PUSH R20 \n" 
  );
	digitalWrite(13,LOW);
	delay(250);
  //---- Restore PORTB / DDRB from stack ----
	asm volatile 
  ( 
    "POP R20 \n"
    "OUT PORTB, R20 \n"
    "POP R20 \n"
    "OUT DDRB, R20 \n"
    "POP R20 \n" 
  );
	delay(250);
}

I don't know the answer to your question, but I have successfully used DDRB and PORTB to do direct port manipulation.

For example this generates a 62.5ns pulse on pins D8-D13:

void setup() {
  DDRB = B00111111;  // Set D8-D13 as outputs
}

void loop() {
  PORTB = B00111111;  // pins D8-D13 high
  PORTB = B00000000;  // pins D8-D13 low
  delay(10);
}

This may help: Inline Assembler Cookbook

Is this in a library? Does it require arguments? Does it contain or reference the errors? It is not available in your sketch.

Sorry, I have reduced my Sketch to a minimum and forgot to change the LED.on(); It is now corrected to pinMode/digitalWrite..
To all other answers: I have often seen the port manipulation like "PORTB = ...". The problem must be in relation with PUSH and POP!

To 6v6gt: Thanks, but unfortunately that doesn't help. PUSH and POP are not handled.

PORTB and DDRB are not defined at assembly level; they are C preprocessor symbols.
To access them via "asm" C statements, you'd normally do something like:

asm("in r20, %0" : : "I" (_SFR_IO_ADDR(PORTD)) );

(Described in the cookbook 6v6gt linked.)

It has nothing to do with the use of PUSH and POP.

The internet suggests that a #define __AVR__(your processor)__ is missing or out-dated... and that will have the pre-defined DDRB, et c. that are causing the error(s).

No, that only pulls in the C preprocessor symbols, and they are no longer available when you get to the ASM phase of the build.

Thank you everyone for your contributions. But after x attempts with all possible variants I do without "asm(...) and stay with the register names that are understood in the sketch by C/C++.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.