Go Down

Topic: Referencing a Pointer in Inline Assembly (Read 1 time) previous topic - next topic



I am trying to write part of my code in inline assembly, but I have not figured out how to get a component of the code to work. (This is for the Due if it makes a difference).

In my original C code that I am trying to convert to assembly, I had the following code:
Code: [Select]
volatile uint32_t *port = &(g_APinDescription[22].pPort -> PIO_PDSR);
uint32_t port1;

void setup(){
...not relevant to the problem...

void loop(){
port1 = *port;
... additional code follows ...

What I have written in assembly is below:
Code: [Select]
volatile uint32_t *port = &(g_APinDescription[22].pPort -> PIO_PDSR);

void setup(){
...not relevant again...

void loop() {
__asm__ volatile( "LDR R1, [%0]\n\t" ::"r"(&port));
... additional code follows ...

But this does not seem to be working.

The purpose of the line of interest within the while loop is to get the state of the port which houses pin22 from the Arduino.

Thanks in advance for your help.


Nick Gammon has a site where he discusses how to dump the assembler code that the compiler generates.


I don't understand why port is a pointer, though. You are pointing it at the address of a field. Why not just copy the value at that address?
The art of getting good answers lies in asking good questions.


I have tried doing it without the pointer as well, but that results in a similar issue and the value stored in the register is not what I want.

Also, I use the pointer because at least for the C code, it saved me 1-2 lookups per call and I need as much speed as possible for the project I'm currently working on.

Thanks for posting the link to the tutorial on getting the assembly dump. I have tried that, and the code looks to be the same, but it is not working when written inline.


This should work, except you omitted, in the clobbers list, to say that r1 is killed after the instruction.
This may lead the remaining code generated by gcc to crash. If the compiler does not know what registers an instruction kills, it won't guess.
Remember that gcc does not read at all the instruction! Hence, for it, maybe be before your instruction it does something with r1 or may after your instruction it relies on a value (propagated) stored in r1 from the calling routine... and you, you kill r1.
Your instruction should look like:

__asm__ volatile ( "ldr r1, [%0]\n\t" : :"r" (port) : "r1") ;

Using port and not *port.

-- F

Go Up