Frank Heckenbach <f.heckenbach@xxxxxxxxxx> writes: > in gcc's inline assembler, the constraint "o" means "A memory > operand is allowed, but only if the address is offsettable. This > means that adding a small integer (actually, the width in bytes of > the operand, as determined by its machine mode) may be added to the > address and the result is also a valid memory address." > > So far, so good, but how can one actually do the offsetting? E.g., > on x86 such an operand may expand to "(%esp)" or "4(%esp)". If you > wanted to add 42 to this address, in the former case you'd need to > write "42%0" (to produce "42(%esp)"), in the latter case, you'd need > to write "42+%0" to get "42+4(%esp)". A mismatch results in > incorrect asm syntax ("42+(%esp)" or "42 4%(esp)" or even > "424%(esp)"). > > But one doesn't know in advance which form the compiler will produce > (of course, this is basically the point of those constraints, to let > the compiler choose what's best). It may depend on unrelated code > changes and even on the gcc version. (Which is actually how I found > out about the issue -- previous versions would always give me ebp > with an offset, but gcc-4.6, probably due to better optimizations, > actually gave me plain "(%esp)" in one case.) > > So is there a syntax that will work with both forms, or some trick > to make it work? (My current work-around is to modify declarations, > so it's virtually guaranteed there will be an offset and I can use > the "+" form, but I'm not too happy with it.) If you want to add an offset, then you should either do it in the value passed to the asm, or you should not use the 'o' constraint. The 'o' constraint tells gcc that it can use a small offset in the address that it passes into the asm. That is appropriate when the asm is just going to use it as a pure memory address. It is not appropriate when the asm wants to add its own offset. For that, you usually want your asm to use the address as the value and use an 'r' constraint to put the address in a register. To say this another way, you may be thinking that you are supposed to use an 'o' constraint if your asm wants to build an offset from the address. The poorly-documented truth is that 'o' is almost entirely for gcc's internal use in machine description files. The 'o' constraint is used for cases like a double-word load that is split into two single-word loads. This kind of splitting is not available for gcc's extended asm expressions. Ian