I have a linux .so file in Ida Pro and I have the following instruction:
movss xmm0, cs:dword_5B27420
Is it possible to move a fixed value into xmm0
using the same or less number of bytes than that instruction?
The instruction bytes are:
F3 0F 10 05 C8 BB A 00
I want to do something like:
movss xmm0, 0.3
Not in fewer bytes; if you don't have room here, you'd have to jump somewhere else and then back, or just change the RIP-relative address to load a different constant from somewhere else. (e.g. from padding between two functions, or spare space in .rodata or .data if there is any.)
There is no mov-immediate to XMM registers, and mov eax, __?float32?__(0.3)
(5 bytes) / movd xmm0, eax
(4 bytes) would take more total bytes. (That's NASM syntax for the integer value that is the bit-pattern for the given FP constant. Some assemblers may allow mov eax, 0.3
, in case that's ever useful.)
Ways other than immediates to construct FP constants include pcmpeqd xmm0,xmm0
(4 bytes) and then shifting or doing other things (like pabsd
) with the all-ones bit patterns. But that's at least 2 instructions unless you want a NaN. (See Agner Fog's optimizing asm guide, and What are the best instruction sequences to generate vector constants on the fly?)
0.3f
is not a simple constant you could materialize even in 3 instructions from 0xffffffff
with left and right shifts, unlike 1.0f
for example. (But that's still three instructions, 4 and 5 bytes each to construct set1(1.0f))
cmpps
is SSE1 non-scalar so it has a smaller opcode than pcmpeqd
(no mandatory prefixes, just 0f c2
), but isn't any smaller overall because it needs an immediate for the compare predicate.