views:

37

answers:

1

Code fragment from Assembly exercise (GNU Assembler, Linux 32 bit)


.data

more:
.asciz "more\n"

.text
...

movl $more, %eax        # this is compiled
cmova more, %eax        # this is compiled
cmova $more, %eax       # this is not compiled

Error: suffix or operands invalid for `cmova'

I can place string address to %eax using movl, but cmova is not compiled. I need the source operand to be $more and not more, to use it for printing. Finally, this value goes to %ecx register of Linux system call 4 (write).

+2  A: 

The assembler is correct! The CMOVcc instructions are more limited than MOV: they can only move 16/32/64-bit values from memory into a register, or from one register to another. They don't support immediate (or 8-bit register) operands.

(Reference: http://www.intel.com/Assets/PDF/manual/253666.pdf - from the set of manuals available at http://www.intel.com/products/processor/manuals/index.htm .)

Matthew Slattery
So, in this case, $more is immediate operand, because it is replaced by assembler with string address?
Alex Farber
Yes. (Well... technically, the assembler replaces it with an offset and a relocation record - because the final address isn't known until link time - and then the linker applies the relocation later. But that's just a detail; by the time the code is running, then yes, `movl $more, %eax` is a move of the address of the string - an immediate operand - to the EAX register.)If you want to use `cmova` here, you'll have to do something like `movl $more, %edx` followed by `cmova %edx, %eax`.
Matthew Slattery