flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > Shouldn't "movq r64,xmm" be legal?

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
Madis731 23 Feb 2007, 09:28
The topic today is:
use64
Code:
        movq    xmm0,rdx
        movd    xmm0,edx
;        movq    rdx,xmm0
        db      66h,48h,0Fh,7Eh,0C2h
        movd    edx,xmm0
    


FASM refuses to assemble the commented line. Why?
Lets hear some discussion before we go and bother Tomasz, shall we!

movq rdx,xmm0 - operand sizes do not match is where the problem lies
movq edx,xmm0 - invalid size of operand and is OK
movd rdx,xmm0 - invalid size of operand and is OK
movd edx,xmm0 - works and is OK

_________________
My updated idol Very Happy http://www.agner.org/optimize/
Post 23 Feb 2007, 09:28
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
Madis731 06 Aug 2008, 12:45
I'm rementioning it because it seems to have been forgotten.

Some documents say that movd r64,(x)mm is legal, but even that doesn't work and I think its okay. movq r64,(x)mm is way more logical.
Code:
use64
movd eax,mm0    ;OK!
movd eax,xmm0   ;OK!
movq rax,mm0    ;OK!
;movq rax,xmm0  ;Why? Operand sized do not match

;Not even possible with some wierd formats:
;movd rax,mm0    ;OK! Invalid size of operand
;movd rax,xmm0   ;OK! Invalid size of operand
;movq eax,mm0    ;OK! Invalid size of operand
;movq eax,xmm0   ;OK! Invalid size of operand
    


A rather simple, but ugly workaround is something like this:
Code:
db 66h
movq rax,mm0    ;OK!
    

_________________
My updated idol Very Happy http://www.agner.org/optimize/
Post 06 Aug 2008, 12:45
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8353
Location: Kraków, Poland
Tomasz Grysztar 06 Aug 2008, 12:59
OK, thanks - I have found the old thread and merged your new one into it - will look into the bug report later.
Post 06 Aug 2008, 12:59
View user's profile Send private message Visit poster's website Reply with quote
lazer1



Joined: 24 Jan 2006
Posts: 185
lazer1 14 Aug 2008, 20:44
Tomasz Grysztar wrote:
OK, thanks - I have found the old thread and merged your new one into it - will look into the bug report later.


what is the URL?

please see also my post:


http://board.flatassembler.net/topic.php?p=80780#80780

the documentation for xmm I am using is from the AMD webpage:

http://developer.amd.com/documentation/guides/Pages/default.aspx

namely:

http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/26568.pdf

volume 4, 128 bit multimedia instructions.

I need the following XMM and MMX instructions:



Quote:


use64

movd xmm0, rax ; zero extended
movlhps xmm0, xmm1 ; low 64 bits to hi 64 bits, remainder unchanged

movhlps xmm0, xmm1 ; hi 64 to lo 64, remainder unchanged
movd rax, xmm0

movsd xmm0, xmm1 ; lo64 to lo64, remainder unchanged

movd mm0, rax

movd rax, mm0



I dont know which of these are implemented as I got an error
with the first one.

for the moment I dont need any other MMX or XMM instructions,
later I probably may need a few other ones.


In order to conform with other fasm things:

for the ones which dont change the remaining bits perhaps
the way is to have eg xmm0h and xmm0l

for the hi 64 and the lo 64 bits.


eg "movsd xmm0l, xmm1l"

and

"movd rax, xmm0l"

not sure how you would deal with "movd xmm0, rax"

perhaps that should be like "movzx eax, bx"

where the 2 operands are different sizes.
Post 14 Aug 2008, 20:44
View user's profile Send private message Reply with quote
lazer1



Joined: 24 Jan 2006
Posts: 185
lazer1 14 Aug 2008, 20:52
one other thing, these xmm and mmx opcodes are IMPOSSIBLE

to remember, perhaps it is better to extend eg the definitions of mov
and movzx:

eg

Quote:


mov xmm0l, xmm1l
mov xmm0l, xmm1h
mov xmm0h, xmm1l

movzx xmm0, rax



that would be much more useful and easy to remember
Post 14 Aug 2008, 20:52
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20339
Location: In your JS exploiting you and your system
revolution 14 Aug 2008, 21:49
lazer1 wrote:
one other thing, these xmm and mmx opcodes are IMPOSSIBLE

to remember, perhaps it is better to extend eg the definitions of mov
and movzx:

eg

Quote:


mov xmm0l, xmm1l
mov xmm0l, xmm1h
mov xmm0h, xmm1l

movzx xmm0, rax



that would be much more useful and easy to remember
But fasm follows Intel syntax so even if your suggestion really is "better" (by whatever criteria you decide) it is unlikely to used because it would be incompatible with standard Intel syntax.
Post 14 Aug 2008, 21:49
View user's profile Send private message Visit poster's website Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
Madis731 15 Aug 2008, 07:34
It won't be changed! The only thing needed is this bugfix, but we won't declare another syntax here. What you can do it use macros to make your life simpler, but I can tell you this: if you've coded in SSE for a few days you have a real "epiphany" Very Happy Wow, this is so logical.

I can give you an example which is illogical:
Code:
use32
 mov ax,bx   ;okay 16-bit move
 mov eax,ebx ;okay 32-bit move
use64
 mov eax,ebx ;upper 32 bits are cleared
 mov rax,rbx ;okay 64-bit move
;Should is be more like this?
 movzx eax,ebx ;This is what it exactly means Smile
    

So SSE is pretty logical compared to this.
Post 15 Aug 2008, 07:34
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
lazer1



Joined: 24 Jan 2006
Posts: 185
lazer1 15 Aug 2008, 15:59
revolution wrote:
lazer1 wrote:
one other thing, these xmm and mmx opcodes are IMPOSSIBLE

to remember, perhaps it is better to extend eg the definitions of mov
and movzx:

eg

Quote:


mov xmm0l, xmm1l
mov xmm0l, xmm1h
mov xmm0h, xmm1l

movzx xmm0, rax



that would be much more useful and easy to remember
But fasm follows Intel syntax so even if your suggestion really is "better" (by whatever criteria you decide) it is unlikely to used because it would be incompatible with standard Intel syntax.


fasm DOESNT follow intel syntax for operands, eg it is incompatible with
most other assemblers and disassemblers.

(and is better by breaking with convention)

eg it doesnt accept the STANDARD syntax of segment:[register]

fasm uses [ segment : register ]

and later versions of fasm use different syntax from earlier ones,

for 16 bit code earlier versions allow:

jmp label

later versions require:

jmp dword label

when the code is beyond the first 64K


the above alternative I gave is a lot easier to remember as
there is nothing to remember!

merely:
mov dest, source

for a true mov (understand versus memorize)

substitute whatever dest or source you want.


and as madis points out for 64 bit

mov eax, ebx

is WRONG and should be movzx, that of course is AMD's fault.

I'll probably create my own macros for such things.

movlhps xmm0, xmm1

is an opcode syntax, but an operand syntax is logically
more efficient:

mov xmm0h, xmm1l

implicit syntaxes are ALWAYS better than explicit syntaxes
for humans: eg maths uses (sin( x ) + cos( x ))^2

instead of: square + sin x cos x

or: x sin x cos + square

the latter "stack" syntaxes are more efficient to implement
(via stacks) but more difficult
to read and less

orthogonal: more difficult to cut and paste fragments,

the implicit syntax (sin(x) + cos(x))^2 is much more difficult to implement



the advantage of an operand syntax is you need less
keywords and its more orthogonal.

you can create new instructions without any new keywords.

eg you can ask:

does "mov xmm0h, xmm1h" exist?

not sure if that does exist,

the fact that it allows me to talk about things which arent invented
yet proves its a good syntax.



anything which zero extends should be movzx,

Intel arent the mouthpiece of god! Confused

some of their ideas are good and some are rubbish Very Happy


Intel anyway globs opcodes, eg mov itself already is
many different opcodes: 88 89 8A 8B 8C 8E A0 A1 A2 A3 B0 B8 C6
C7 Laughing

can you imagine the HASSLE if those were 14 different opcodes? Mad



Intel are notorious for inefficiency, eg their crazy segment idea
and prefices. Sad

thankfully AMD's long mode supercedes as many Intel inefficiencies
as are feasible. Laughing

segments superceded by the MMU, which other CPU's have been
using for decades. Razz

AMD also have fully orthogonal multiprocessors,

Intel multiprocessors can be fake multiprocessors, 1 cpu pretending
to be 2.

speaking as someone who used Motorola 68k and MIPS RISC years before
learning x86. When you switch on a 68k or PPC or MIPS it STARTS in a state which takes a lot of work to reach with x86.

switch on a 68k and you IMMEDIATELY have flat 32 bit addressing
you arent stuck to the first 1mb

one other thing: A LOT OF ASSEMBLERS accept synonyms,

if there is only one possible interpretation of something they

tend to accept it, perhaps with a warning.

eg:

jmp label
.....

label:


can only mean one thing! and is best interpreted as a rip-relative
jmp just in case the code gets relocated.

(all my own code DOES get relocated so absolute jmps are forbidden
except via registers)

in fact its an art allowing unambigous interpretations which
are off the map



HOWEVER

label equ 12345678h

jmp label

where label isnt a code label but a const COULD be an error
for 16 bit code.
Post 15 Aug 2008, 15:59
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20339
Location: In your JS exploiting you and your system
revolution 15 Aug 2008, 17:14
Madis731 wrote:
Code:
 movzx eax,ebx ;This is what it exactly means Smile    
Perhaps you mean:
Code:
 movzx rax,ebx    
?
Post 15 Aug 2008, 17:14
View user's profile Send private message Visit poster's website Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
Madis731 15 Aug 2008, 17:57
Razz oh yeah - sorry rax was meant to be there Smile I got lost in this wierd syntax - though... isn't the very same line allowed ^o) ... hmm not exactly
Code:
use64
movzx rax,bx ;allowed
movzx rax,bl ;allowed
;movzx rax,ebx ; NOT allowed because:
mov   eax,ebx ; ...does the same thing Smile
    

erm, so I do partly agree with laser1 BUT the world is accustomed to Intel syntax and although you feel it sometimes too complicated, at the time of development they seeked for the best solution. Now that new technologies are coming and compatibility needs to remain...what's U gonna do?
Post 15 Aug 2008, 17:57
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
lazer1



Joined: 24 Jan 2006
Posts: 185
lazer1 17 Aug 2008, 19:47
Madis731 wrote:
Razz oh yeah - sorry rax was meant to be there Smile I got lost in this wierd syntax - though... isn't the very same line allowed ^o) ... hmm not exactly
Code:
use64
movzx rax,bx ;allowed
movzx rax,bl ;allowed
;movzx rax,ebx ; NOT allowed because:
mov   eax,ebx ; ...does the same thing Smile
    

erm, so I do partly agree with laser1 BUT the world is accustomed to Intel syntax and although you feel it sometimes too complicated, at the time of development they seeked for the best solution. Now that new technologies are coming and compatibility needs to remain...what's U gonna do?



you can have it multiple ways:

fasm -strict xyz.asm

fasm -alternative xyz.asm

fasm -generous xyz.asm

-strict is the current approach,

-alternative is where for use64 you disallow "mov eax,ebx" that
has to be done as "movzx rax,ebx". -alternative removes all
bug prone constructs

-generous is where things which can have only one possible
interpretation are done that way.

eg "jmp label"

has only one possible meaning. but:

xyz equ 123456h

jmp xyz

could be an error for 16 bit. fasm needs to keep track of which definitions
are labels and which are other.

there are only a few things which are affected. most things are fine
as they are.

BTW is there any trick way for me to do "movd xmm1, rax" with
fasm curently?

can I do it with a define byte followed by some instruction which
it currently accepts?
Post 17 Aug 2008, 19:47
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 17 Aug 2008, 20:08
Quote:

fasm needs to keep track of which definitions are labels and which are other.

I think you are right about this. For example, look this funny example
Code:
use64
virtual at $FFFFFFFFFFFFFF00
  someLabel:
end virtual
someValue = $FFFFFFFFFFFFDEAD

mov ebx, someLabel
mov eax, someValue    


I think that fasm should either consider numbers negative ONLY when minus is found or consider labels as an special type of value (unsigned).
Post 17 Aug 2008, 20:08
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 17 Aug 2008, 21:10
same old "no-sign-bit" bug, in my opinion
Post 17 Aug 2008, 21:10
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20339
Location: In your JS exploiting you and your system
revolution 18 Aug 2008, 02:08
lazer1 wrote:
fasm needs to keep track of which definitions are labels and which are other.
I think that is the wrong approach. If you need to make a distinction between code labels and data values then use a naming scheme that makes it clear. Don't expect the assembler to hold your hand.
Post 18 Aug 2008, 02:08
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 18 Aug 2008, 02:57
Quote:

Don't expect the assembler to hold your hand.

But it already does it a little however, for example you are not allowed to XOR a label against a constant on a PE with fixups. I do understand that the XOR example is a sightly different category because the executable would randomly crash instead of having constant behavior (the crash depends on whether the expected virtual address space was satisfied or not), but since fasm already knows (internally) what is a label and what is not, why don't go a step further and add some extra checks and additionally give the programmer the opportunity to check if a symbol is a label or a value? Of course backward compatibility would be broken, but that happened before anyway and was for good.
Post 18 Aug 2008, 02:57
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20339
Location: In your JS exploiting you and your system
revolution 18 Aug 2008, 03:00
Yes, it will do a little bit of hand holding but I meant not the expect it to always do it. One should try to write code/labels etc. in such a way that hand holding won't be needed.
Post 18 Aug 2008, 03:00
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8353
Location: Kraków, Poland
Tomasz Grysztar 18 Aug 2008, 06:49
LocoDelAssembly wrote:
Quote:

Don't expect the assembler to hold your hand.

But it already does it a little however, for example you are not allowed to XOR a label against a constant on a PE with fixups. I do understand that the XOR example is a sightly different category because the executable would randomly crash instead of having constant behavior (the crash depends on whether the expected virtual address space was satisfied or not), but since fasm already knows (internally) what is a label and what is not, (...)

This isn't knowing what is a label and what not. It is knowing which symbol is an absolute value, and which is not. Try:
Code:
symbol = $    

for example.
All numerical symbols in fasm have the same properties (not counting the ability to redefine the "=" ones), that's one of the principles.
Post 18 Aug 2008, 06:49
View user's profile Send private message Visit poster's website Reply with quote
lazer1



Joined: 24 Jan 2006
Posts: 185
lazer1 18 Aug 2008, 17:32
revolution wrote:
Yes, it will do a little bit of hand holding but I meant not the expect it to always do it. One should try to write code/labels etc. in such a way that hand holding won't be needed.


if it CAN hold your hand it SHOULD

safe programming occurs at different levels:

1. safe language, well designed languages PREVENT you doing unsafe things,
eg Modula 3 is very safe,

2. safe compilation, compiler actively warns on potential unsafe constructs
eg "gcc -Wall"

3. programmer level safety: using naming conventions.

the problem with long mode "mov eax,ebx" is that it is unsafe
at the language level. Most people reading that will assume
it just moves ebx to eax.

with languages and compilation, THE MORE SAFETY THE BETTER.
Post 18 Aug 2008, 17:32
View user's profile Send private message Reply with quote
lazer1



Joined: 24 Jan 2006
Posts: 185
lazer1 18 Aug 2008, 17:38
I have created my own fasm macro for "movd xmm,reg64"

if you want to do "movd xmm,mem64" you need to do it indirectly
via a reg64,

the macro leaves unchanged any movd which isnt of the above form.

here is the macro:

Quote:

;==== "movd xmm,reg64" via fasm macros: =================


registers64old equ rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi
registers64new equ r8, r9, r10, r11, r12, r13, r14, r15
registers64xmmlo equ xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
registers64xmmhi equ xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15


macro mod_rm mod_*, reg*
{
if reg in <al,ax,eax,rax,mm0,xmm0,r8,xmm8>

db (mod_ shl 3) or 0

else if reg in <cl,cx,ecx,rcx,mm1,xmm1,r9,xmm9>

db (mod_ shl 3) or 1

else if reg in <dl,dx,edx,rdx,mm2,xmm2,r10,xmm10>

db (mod_ shl 3) or 2

else if reg in <bl,bx,ebx,rbx,mm3,xmm3,r11,xmm11>

db (mod_ shl 3) or 3

else if reg in <ah,spl,sp,esp,rbx,mm4,xmm4,r12,xmm12>

db (mod_ shl 3) or 4

else if reg in <ch,bpl,bp,ebp,rbp,mm5,xmm5,r13,xmm13>

db (mod_ shl 3) or 5

else if reg in <dh,si,sil,esi,rsi,mm6,xmm6,r14,xmm14>

db (mod_ shl 3) or 6

else if reg in <bh,di,dil,edi,rdi,mm7,xmm7,r15,xmm15>

db (mod_ shl 3) or 7

else
display 'BUG: unrecognised register'
end if
}

macro mod_reg_rm mod_*, reg*, rm*
{
if reg in <al,ax,eax,rax,mm0,xmm0,r8,xmm8>

mod_rm (mod_ shl 3) or 0, rm

else if reg in <cl,cx,ecx,rcx,mm1,xmm1,r9,xmm9>

mod_rm (mod_ shl 3) or 1, rm

else if reg in <dl,dx,edx,rdx,mm2,xmm2,r10,xmm10>

mod_rm (mod_ shl 3) or 2, rm

else if reg in <bl,bx,ebx,rbx,mm3,xmm3,r11,xmm11>

mod_rm (mod_ shl 3) or 3, rm

else if reg in <ah,spl,sp,esp,rbx,mm4,xmm4,r12,xmm12>

mod_rm (mod_ shl 3) or 4, rm

else if reg in <ch,bpl,bp,ebp,rbp,mm5,xmm5,r13,xmm13>

mod_rm (mod_ shl 3) or 5, rm

else if reg in <dh,si,sil,esi,rsi,mm6,xmm6,r14,xmm14>

mod_rm (mod_ shl 3) or 6, rm

else if reg in <bh,di,dil,edi,rdi,mm7,xmm7,r15,xmm15>

mod_rm (mod_ shl 3) or 7, rm

else
display 'BUG: unrecognised register'
end if
}

macro movd_br rexr*, rexb*, xmm*, reg*
{
db 66h, 40h or 8h or (rexr shl 2) or rexb, 0fh, 6eh

mod_reg_rm 11b, xmm, reg
}

macro movd_b rexb*, xmm*, reg*
{
if xmm in <registers64xmmlo> ; rex.r==0
movd_br 0, rexb, xmm, reg
else if xmm in <registers64xmmhi> ; rex.r==1
movd_br 1, rexb, xmm, reg
else
movd xmm, reg
end if
}

macro movd xmm*, reg*
{
if reg in <registers64old> ; rex.b==0
movd_b 0, xmm, reg
else if reg in <registers64new> ; rex.b==1
movd_b 1, xmm, reg
else
movd xmm, reg
end if
}


;==============================================


I havent tried testing the code, but fasm accepts the macro.

the bug at the top of the thread also can probably be done this way,
as long as all operands are registers. for mem64 args I dont know
if those are feasible via macros.
Post 18 Aug 2008, 17:38
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20339
Location: In your JS exploiting you and your system
revolution 18 Aug 2008, 17:47
lazer1 wrote:
if it CAN hold your hand it SHOULD
I don't agree, if we go down that path then we end up with something with so many restrictions that we will end up fighting the assembler just to get simple tasks done.

Think of some of the seriously terrible HLL's that are hyper-restrictive about what you can and cannot do, they can become a real PItB to use for some tasks.
Post 18 Aug 2008, 17:47
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.