According to the Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2 the pop fs
supports 3 variants (the same goes for pop gs
):
The AMD64 documentation op pop
doesn't describe explicitly what happens to the stack pointer. I tried to produce those and it seems gas does recognise them (I assumed they need the 66h prefix):
80490d6: 0f a1 pop fs
80490d8: 66 0f a1 popw fs
80490db: 0f a9 pop gs
80490dd: 66 0f a9 popw gs
I'm breaking my head over these. To my understanding, the FS and GS registers are 16 bits, I know they have a hidden portion, but I don't expect the pop
instruction to be able to manipulate those right? Can somebody explain what the purpose of these variant are?
In 32 bit mode, each stack slot is 32 bit. It would be rather annoying if you had to adjust the stack pointer to a multiple of 4 bytes after pushing a segment register, so the CPU provides instructions to push segment registers into 4 byte stack slots.
When a segment register is pushed with operand size 32 bit, the register contents are zero-extended to a dword. When it is popped, only the lower two byte are read into the segment register. The upper two byte are again ignored.