4

I need GCC to produce a consistent set of instructions for inline asm, but one of the instructions I'm using is sometimes compiled two different ways:

__asm__ ("mov %1,%%rax;" \ : \ : "m"(ref) \ : "%rax"); 

Compile #1:

mov 0x200894(%rip),%rax 

Compile #2:

mov 0x200894(%rip),%rdx mov (%rdx),%rax 

I'm not sure what the reason is for the second version, but I don't want it. Is there a constraint to specify that a memory reference should only be direct, i.e., not via register?


Update:

This variation always produces the exact same instruction:

 __asm__ ("mov ref@GOTPCREL(%rip),%rax"); 

Compiles to:

mov 0x200910(%rip),%rax 
5
  • 2
    The two sequences of instructions are not equivalent. In the first 0x200894(%rip) contains the result directly, in the second 0x200894(%rip) contains a pointer to the result. What is ref? Does it have the same type in both instances? Is it pointer to a function or object that's exported from a DLL (which sometimes might have to be an indirect reference through a 'GOT')? Commented Jun 12, 2014 at 18:19
  • It's extern const char *ref, and the second version does only occur in a shared library--so it must have a GOT reference even though the variable is defined inside the library. Can I avoid that somehow? Commented Jun 12, 2014 at 18:27
  • 1
    I'm not sure. There's a good description of the GOT mechanism here: eli.thegreenplace.net/2011/11/03/… If there is a way to do what you want, that article might give you a clue (or a starting point) for how. Commented Jun 12, 2014 at 19:10
  • @MichaelBurr: thanks, I found a way (see update). Commented Jun 12, 2014 at 22:16
  • Byron, you should post your solution as an answer to your own question. That was an interesting one. Commented Jun 12, 2014 at 22:17

1 Answer 1

3

Answering my own question:

This variation always produces the exact same instruction:

__asm__ ("mov ref@GOTPCREL(%rip),%rax"); 

Compiles to:

mov 0x200910(%rip),%rax 

For x86 where RIP-relative is not available, it takes two instructions:

__asm__ ("mov $_GLOBAL_OFFSET_TABLE_,%%eax; \ add ref@GOT,%%eax;"); 

Compiles to:

mov $0x2ff7,%eax add 0xfffffff0,%eax 

Two more instructions are required to make %eax RIP-relative, but I'm working in a binary translator where that's easier to do internally.

Sign up to request clarification or add additional context in comments.

1 Comment

Just for the record, these "Basic Asm" statements with no constraints aren't safe to use inside functions. You need asm("..." ::: "eax"). gcc.gnu.org/wiki/ConvertBasicAsmToExtended

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.