Many thanks for your help Wouter. No, it's not a pointer to pointer, just:
<load Y-register with address> < load temp with what is addressed by Y> <store temp to my return variable> which is done here : "lds r29, ram_address + 1\n\t" // Load high byte of Y "lds r28, ram_address\n\t" // Load low byte of Y "ld __tmp_reg__, Y\n\t" // Fet value at Y into __tmp_reg__ "sts rambyte, __tmp_reg__\n\t" // Store __tmp_reg__ into named variable 'rambyte'. // It's this last line that I have not yet achieved using the 'proper' syntax. but it is wrong. I seem to have solved my immediate problem but still don't quite understand how to save __tmp_reg__ to a named variable. Just for info, the much simplified: uint8_t get_ram_byte(uint16_t ram_address) { uint8_t byte; asm ("ld %0, %a1" : "=&r" (byte) : "e" (ram_address)); return byte; } works fine (I don't really need the temp storage as %0 gets loaded from the Y-reg directly. The declaration and usage of 'byte' is completely discarded by the compiler, it just chooses R24 as %0 and uses that as its uint8_t return: 00000666 <get_ram_byte>: uint8_t get_ram_byte(uint16_t ram_address) { uint8_t byte; asm ("ld %0, %a1" : "=&r" (byte) : "e" (ram_address)); 666: fc 01 movw r30, r24 668: 80 81 ld r24, Z return byte; } 66a: 08 95 ret Anyway, many thanks for your help Wouter, I'll try to figure out storage later. Robert. Wouter van Gulik wrote: > Robert von Knobloch schreef: > >> Hi Wouter, >> >> thanks for responding. >> This is not quite what I want, but your comment about the sts is >> interesting. >> I want to achieve this: >> >> uint8_t rambyte; >> uint16_t ram_address; >> >> void get_ram_byte(void) >> { >> asm ("push R28\n\t" >> "push R29\n\t" >> >> "lds r29, ram_address + 1\n\t" >> "lds r28, ram_address\n\t" >> "ld __tmp_reg__, Y\n\t" >> "sts rambyte, __tmp_reg__\n\t" >> >> "pop R29\n\t" >> "pop R28"::); >> } >> >> Which works but completely ignores the inline-assembler stuff which >> would do automatic register saving etc. >> I want to pass a uint16_t address as the argument and get a uint8-t byte >> returned (which is the contents of the address in ram. >> > > So you want a pointer to a pointer? > So in C it would be something like this: > > get_ram_byte(char **pp) > { > char c; > char *p = *pp; > c = *p; > *p = c; > return c; > } > > >> Here is the sts that I want to achieve - namely storing the __tmp_reg__ >> contents into the variable rambyte. Of course this should become the >> return value (must I store this in a variable first or can the compiler >> know to return this in whatever the usual register is for a uint8_t () ?. >> > > You must use a C variable to return the value. Of course you could just > tell it to store it to R24 (which is the return register for an > uint8_t). But this might will lead to compile warnings and faulty code > when GCC decides to inline. > So don't use __tmp_reg__ but replace it with the construction from my > previous mail. > > >> Btw your example compiled OK but did not assemble. >> >> Robert >> >> Hi, >> >> I don't know what you intended to do but I guess this is more like it >> (read the value and write it back): >> I personally prefer the %[] construction. >> >> uint8_t get_ram_byte(uint16_t ram_address) >> { >> uint8_t byte; >> >> asm ("ld %[reg] , %[adr]" "\n\t" >> "sts %[adr] , %[reg]" "\n\t" >> : [reg] "=&r" (byte) >> : [adr] "e" (ram_address)); >> return byte; >> } >> >> You're construction of "sts %0, __tmp_reg__" is not correct. GCC is >> trying to feed sts r24 as first argument, which is invalid. >> You are feeding him the uninitialized variable 'byte'. Which is also >> allocate to R24. >> >> HTH, >> >> Wouter >> >> >> Robert von Knobloch schreef: >> >>> Hello, >>> I've been trying to decipher the intricacies of in-line assembler (using >>> the Inline Assembler Cookbook as my guide). >>> >>> I have a very simple application that I cannot seem to realise. >>> >>> I want a C function that will return the contents of the RAM address >>> that I give it as argument. >>> >>> My assembler-based function looks like this: >>> >>> file is hex.c >>> ===== >>> uint8_t get_ram_byte(uint16_t ram_address) >>> { >>> uint8_t byte; >>> >>> asm ("ld __tmp_reg__, %a1" "\n\t" >>> "sts %0, __tmp_reg__" "\n\t" >>> : "=&r" (byte) : "e" (ram_address)); >>> return byte; >>> } >>> >>> and is called from >>> >>> rambyte = get_ram_byte(i ); >>> u_hex8out(rambyte); // Print byte as 8-bit hex. >>> >>> Trying to compile this results in "~/Monitor/hex.c:5: undefined >>> reference to `r24' " >>> If I comment out the line "sts %0, __tmp_reg__" "\n\t" then it >>> compiles and I see that the parameter is passed in R24,25, copied to >>> R30,31[Z] and the value is read into R0 [__tmp_reg__]. >>> I cannot see what is wrong with the sts command or why R24 is mentioned. >>> >>> Can anybody help me ? >>> >>> Many thanks, >>> >>> Robert von Knobloch. >>> >>> >>> >>> _______________________________________________ >>> AVR-GCC-list mailing list >>> AVR-GCC-list@nongnu.org >>> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list >>> >> >> >> >> >> _______________________________________________ >> AVR-GCC-list mailing list >> AVR-GCC-list@nongnu.org >> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list >> > > > > _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list