Author Topic: MOVSXD  (Read 14675 times)

Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
« on: June 08, 2012, 12:21:14 AM »
Code: [Select]
  SignOn  db 'A simple message', 10, 0

  mov     rsi, SignOn          ; 10 bytes of code

  mov     esi, SignOn         ;   5 btyes
  cdqe                              ;   2 bytes  (saved 3)

  movsxd  rsi, SignOn        ; or with esi and even dword SignOn

What do I need to do to make MOVSXD work.  I always get parser: instruction expected

Offline Rob Neff

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 429
  • Country: us
« Reply #1 on: June 08, 2012, 12:50:02 AM »
According to AMD documentation:

2.5.9 MOVSXD Instruction
MOVSXD is a new instruction in 64-bit mode (the legacy ARPL instruction opcode, 63h, is
reassigned as the MOVSXD opcode). It reads a fixed-size 32-bit source operand from a register or
memory and (if a REX prefix is used with the instruction) sign-extends the value to 64 bits. MOVSXD
is analogous to the MOVSX instruction, which sign-extends a byte to a word or a word to a
doubleword, depending on the effective operand size. See “General-Purpose Instruction Reference” in
Volume 3 for additional information.

Without testing myself I'm curious if you create a variable as a dword ( eg: var DD 1 ) and use that variable address if you still get the error message.  I think the key part here is "fixed-size 32-bit source".  Perhaps Nasm is simply trying to help you out, although rather cryptically, based upon the data definition?

Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
« Reply #2 on: June 08, 2012, 03:05:11 AM »
Cryptically or not, I guess it doesn't make a lot of sense to sign extend a 64 bit value into a 64 bit register.  I was a little to wrapped up in saving bytes and not thinking about the logic of what I was doing.

Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
« Reply #3 on: June 08, 2012, 04:06:28 AM »
What I've done is modified my Console routine to accept a 32 bit parameter.

Code: [Select]
push    NoArgs       ; Pointer to string to be displayed
call      Console

Then in procedure

Code: [Select]
  Console: push    rbp
                mov     rbp, rsp

                push    rdi
                push    rsi
                movsxd  rdi, [rbp + 8]
                mov     rsi, rdi
                or      rcx, -1
                mov      al, 0
                repnz   scasb
                add     rcx, 2
                neg     rcx
        ; ...... More code here

                pop     rdi
                pop     rsi
ret     4 ; Return with string size in RAX and ZR=1 if string empty.

Now I'm saving 5 bytes for every call to console and using MOVSXD as it was intended to be used.