NASM - The Netwide Assembler

NASM Forum => Programming with NASM => Topic started by: Olsonist on March 10, 2015, 08:30:07 PM

Title: push and movzx
Post by: Olsonist on March 10, 2015, 08:30:07 PM
I'm having trouble assembling two instructions: push [rsp] and movzx r12,ebx.
This is 64 bit on OSX with homebrew installed "NASM version 2.11.06 compiled on Nov  4 2014".
The assembler command line is:

  nasm -f macho64 tst.asm -o tst.o

The errors are:

  tst.asm:5: error: operation size not specified
  tst.asm:6: error: invalid combination of opcode and operands

and the (minimal) source is:

  %use      smartalign
  ALIGNMODE   generic,32
  BITS         64
  section .text
   push      [RSP]
   movzx   R12,EBX

I really don't understand why the PUSH is not assembling. The MOVZX is a zero extend from 32b to 64b and the September 2014 Intel architecture manual, Vol. 1 5-29, says:

  5.19 64-BIT MODE INSTRUCTIONS

  MOVZX (64-bits)  Move doubleword to quadword, zero-extension


FWIW, I can inline these instructions with Clang:

   asm volatile("push      [RSP]");
   asm volatile("movzx      R12,EBX");

begets:

   ## InlineAsm Start
   push      [RSP]
   ## InlineAsm End
   ## InlineAsm Start
   movzx      R12,EBX
   ## InlineAsm End
Title: Re: push and movzx
Post by: shaynox on March 10, 2015, 09:40:06 PM
Hello,

For (push      [RSP]), you need to specify what kind of data's size to push, so it begin (push  word/dword/qword [rsp]).

For (movzx   R12,EBX), I read this one intel doc software:
Title: Re: push and movzx
Post by: Olsonist on March 10, 2015, 10:30:41 PM
Thanks, the push qword [rsp] works. I hadn't used qword with asm().
I'm still working through the other. Since movzx R12,BX worked
then I thought the 32b case would work as well.
I suppose the fix may be to switch registers.

(I'm already getting tired of sorting cats.)
Title: Re: push and movzx
Post by: shaynox on March 10, 2015, 10:33:20 PM
No problem
Title: Re: push and movzx
Post by: Olsonist on March 10, 2015, 11:03:13 PM
The encoding restriction is on BX, not EBX. Documentation bug?
Title: Re: push and movzx
Post by: Olsonist on March 10, 2015, 11:10:10 PM
movzx R12,R11D

still gets:

error: invalid combination of opcode and operands
Title: Re: push and movzx
Post by: shaynox on March 10, 2015, 11:15:17 PM
d in r11d mean dword (32 bit), try movzx   r12, r12w and it will work.
As documentation say, the source can only be 8/16 bit wide.

And no ^^ official documentation not bug.
Title: Re: push and movzx
Post by: Olsonist on March 10, 2015, 11:20:34 PM
So when the documentation says r/m8 and r/m16 that's restricting it to 8b and 16b?
That does seem to be what's happening. But isn't this a docubug?

5.19 64-BIT MODE INSTRUCTIONS

  MOVZX (64-bits)  Move doubleword to quadword, zero-extension
Title: Re: push and movzx
Post by: shaynox on March 10, 2015, 11:26:07 PM
Where you get that ?

I take documentations here: https://www-ssl.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html

And that: https://www-ssl.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-2a-manual.pdf
for see movzx instruction.

PS: what kind of CPU have you got ? Intel or Amd
Title: Re: push and movzx
Post by: Olsonist on March 10, 2015, 11:40:16 PM
That was page  Vol. 1 5-29 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual,
September 2014, latest and greatest.

Penyrn MacBook Pro.
Title: Re: push and movzx
Post by: shaynox on March 10, 2015, 11:47:11 PM
https://www-ssl.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-1-manual.pdf That ?

Code: [Select]
MOVZX (64-bits) Move doubleword to quadword, zero-extension

Code: [Select]
Move with sign or zero extension — The MOVSX (move with sign extension) and MOVZX (move with zero
extension) instructions move the source operand into a register then perform the sign extension.
The MOVSX instruction extends an 8-bit value to a 16-bit value or an 8-bit or 16-bit value to a 32-bit value by sign
extending the source operand, as shown in Figure 7-5. The MOVZX instruction extends an 8-bit value to a 16-bit
value or an 8-bit or 16-bit value to a 32-bit value by zero extending the source operand.

Yes you right, lol, anyway it's better to search in Volume 2A/2B apparently.
Title: Re: push and movzx
Post by: Olsonist on March 11, 2015, 12:02:27 AM
There's a January 2015 edition but it's there as well.
I'll figure out how to file a bug with them.
And thanks for your help.
Title: Re: push and movzx
Post by: shaynox on March 11, 2015, 12:04:15 AM
No problem, i will try to find who say right ^^

Try this pseudo code:


Code: [Select]
or        rax, 0xFFFF_FFFF_FFFF_FFFF
mov       rbx, 0xFFFF_FFFF
movzx     rax, ebx

printf("rax = %llX", rax);

I don't have clang.
If rax is 0xFFFF_FFFF, so movzx can move 32-bit data into 64-bit register, else it's wrong.
Title: Re: push and movzx
Post by: Olsonist on March 11, 2015, 12:30:44 AM
Heck, for the 'workaround' use the XOR idiom.

xor R12,R12
mov R12D,EBX

I've posted a bug in the Intel Developer's Forum.
Title: Re: push and movzx
Post by: shaynox on March 11, 2015, 12:36:44 AM
#can delete
Title: Re: push and movzx
Post by: Olsonist on March 11, 2015, 04:44:16 AM
I submitted the docubug at IDF and Intel fessed up immediately.
That's what I like about Intel. They're fast about that.
Title: Re: push and movzx
Post by: shaynox on March 11, 2015, 07:45:36 AM
that's cool  8)