- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[cpp]#include#include #include typedef uint32_t u32x4_t __attribute__ ((vector_size (16))); void hello_world() { printf("Hello, World!\n"); exit(0); } int main() { register void (*fn)() asm("rbx"); u32x4_t addresses={(uint32_t) hello_world, (uint32_t) hello_world, (uint32_t) hello_world, (uint32_t) hello_world}; //Put an invalid function address in the function pointer asm("movq %[from], %[to]\n" : [to] "=r" (fn) : [from] "x" (addresses)); //If MOVD zero-extends to 64-bits the function address will be valid asm("movd %[from], %%ebx\n" : : [from] "x" (addresses)); goto *fn; }[/cpp]
The above code demonstrates that Intel Core 2 zeroes out the high 32-bits in RBX when the destination is EBX and the instruction is MOVD.
Without explicit register variable contortions I can't stop GCC from zero-extending EBX to RBX (a missed optimisation) and/or avoid GAS incorrectly upgrading the movd instruction to movq (which causes invalid code generation as 64-bits are loaded into RBX instead of 32-bits into EBX with zero-extension to RBX).
[This is the small code model where functions are located in the lower 2GB of the address space]
Confirmation about the documented behaviour of MOVD is appreciated before I submit any bug reports about this issue to GCC/GAS developers.
Thanks,
Adam
Link Copied
2 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When in 64-bit mode, operand size determines the number of valid bits in the destination
general-purpose register:
64-bit operands generate a 64-bit result in the destination general-purpose
register.
32-bit operands generate a 32-bit result, zero-extended to a 64-bit result in the
destination general-purpose register.
8-bit and 16-bit operands generate an 8-bit or 16-bit result. The upper 56 bits or
48 bits (respectively) of the destination general-purpose register are not be
modified by the operation. If the result of an 8-bit or 16-bit operation is intended
for 64-bit address calculation, explicitly sign-extend the register to the full
64-bits.
Quote from Intel SDM vol1 section 3.4.1.1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Many thanks neni,
I suspect not being able to move a doubleword into a 64-bit register is a bug in GNU as (GAS) mnemonic translation. I have submitted this bug report:
http://sourceware.org/bugzilla/show_bug.cgi?id=11818
Regards,
Adam
I suspect not being able to move a doubleword into a 64-bit register is a bug in GNU as (GAS) mnemonic translation. I have submitted this bug report:
http://sourceware.org/bugzilla/show_bug.cgi?id=11818
Regards,
Adam

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page