https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101422
--- Comment #8 from Simon Willcocks <simon.willcocks at gmx dot de> --- (In reply to Andrew Pinski from comment #4) > (In reply to Simon Willcocks from comment #2) > > That's not an accurate description of the problem; the value of the variable > > is being passed, not its address. As a register variable, it doesn't have an > > address. > > It is the address of the array that is being passed (I was copying and > pasting from another bug). > register uint32_t *cap_and_join asm( "r5" ) = cap_and_join_style; > Is the same as: > register uint32_t *cap_and_join asm( "r5" ) = &cap_and_join_style[0]; > > Because array decays to pointers :). And, of course, I later came up against this precise problem, at least I knew what I was looking for, and thanks to you, how to fix it. The final solution is as follows. I really think that passing a pointer type into an asm should indicate that the object pointed to is used, though. void Draw_Stroke( uint32_t *path ) { // Keep this declaration before the first register variable declaration, or // -Os will cause the compiler to forget the preceding registers. // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101422 uint32_t cap_and_join_style[5] = { 0x00000001 }; // Round joints register uint32_t *draw_path asm( "r0" ) = path; register uint32_t fill_style asm( "r1" ) = 0x3f; register uint32_t *matrix asm( "r2" ) = 0; register uint32_t flatness asm( "r3" ) = 0; register uint32_t thickness asm( "r4" ) = 8; register uint32_t *cap_and_join asm( "r5" ) = cap_and_join_style; register uint32_t dashes asm( "r6" ) = 0; asm ( "swi 0x60704" : : "r" (draw_path) , "r" (fill_style) , "r" (matrix) , "r" (flatness) , "r" (thickness) , "r" (cap_and_join) , "r" (dashes) , "m" (cap_and_join_style) ); // Without this, array is not initialised } I wanted to correct the record and thank you (both). I'll shut up, now.