How to relace byte of 32bit variable in inline assembly?-Collection of common programming errors
I want to replace the highest byte of 32bit value with inline assembly, following code writes buffer to FRAM memory with spi interace:
#define _load_op_code(op_code, addr)\
__asm__ __volatile__ (\
" ldi %D0, %1" "\n\t"\
: "=d" ((uint32_t)addr)\
: "M" (op_code)\
)
#define SMEM_WREN 0x06
#define SMEM_WRITE 0x02
void fram_write(uint32_t addr, uint8_t *buf, uint16_t len) {
FRAM_SELECT();
spi_send_char(SMEM_WREN);
FRAM_DESELECT();
_load_op_code(SMEM_WRITE, addr);
FRAM_SELECT();
spi_send_32b(addr);
spi_send(buf, len);
FRAM_DESELECT();
}
after _load_op_code() inline assembly addr variable gets cluttered – compiler use registers allocated for addr as temporary registers for other operations and i lose original addr value. addr is in fact 24bit variable. Any idea whats wrong with this code?
-
The original value of addr is lost because it is overwritten by the asm statement with SMEM_WRITE and 3 undefined bytes. From the GCC manual:
The ordinary output operands must be write-only; GCC assumes that the values in these operands before the instruction are dead and need not be generated. Extended asm supports input-output or read-write operands. Use the constraint character ‘+’ to indicate such an operand and list it with the output operands.
Originally posted 2013-11-09 22:42:43.