This is the mail archive of the crossgcc@sources.redhat.com mailing list for the crossgcc project.

See the CrossGCC FAQ for lots more infromation.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RE: Invalid Operands with Inline assembly




Robert Floyd [mailto:robert.floyd@inet.com] wrote :
>> snip
> Why would not the following work just as well...
> 
> extern long TxStr;		  /* defined as .globl TxStr in external asm
file */
> 
> int main()
> {
>    char pHelloStr[6] = "Hello";
>    
>    while(1)
>    {
> 
>       asm( 
>           " mov  %0, r4;"          /* Move global asm label TxStr to r4 */
>           " mov  %1, r0;"          /* And string to r0 */
>           " jsr  @r4;"             /* And jump via r4 */
>           :                        /* no outputs */
>           : "r" (TxStr),           /* %0 is Input 0, a register, use TxStr
*/
>             "r" (pHelloStr)        /* %1 is Input 1, a register, use
pHelloStr */
>           : "r0", "r4"             /* and uses r0 and r4 as scratch */
>           );
>    }
>    
>    return(0);
> }
> 
> int __main() {}                     /* I was told I need this for gcc,
> don't know why */
> 

The reason I added the pointers is to make sure that the data is already in
a register because TxStr is actually a long value and pHelloStr is a pointer
to a constant string which is probably in the same segment as the code but
may not be within the range of the offset from the PC addressing mode. These
are definitely not registers. The "r" specifiers for the inputs to the asm
block specify the parameters as registers so I need to make sure that the
data is available in a register and the pointers leave it up the compiler to
get the data where it is needed.

GNU allows other (or multiple) specifiers for the asm block. The ones that I
have used are "i" for an input which specifies immediate data (for the SH2
this is limited to signed 8 bits which is sign extended) and "0" to "9"
where I use the same register for input and output. From the manual "m"
(address), "o" (offsettable address) and some other are allowed but when I
tried to use them I found that I was having trouble specifying the address
mode, it ended up easier for me to use the "r" specification and let the
compiler assign the value to a local (block scope) register variable.

BTW, __main() is called by GCC as part of the C++ initialization before
calling main(), if you don't supply one it will grab it from the library (if
it is linked) or complain.

------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sourceware.cygnus.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]