asm movq question

New to FreeBASIC? Post your questions here.
Post Reply
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

asm movq question

Post by srvaldez »

why does the first snippet work but not the second?

Code: Select all

Dim As Ulongint k, v(0)
Dim As Ulongint Ptr z=@v(0)
k=2
v(0)=123456789
Print "before"
Print "v(0) = ";v(0)
Print "z = ";z
Asm
	movd	mm6, k   ' mm6 is k
	mov		rax, z
	movq	[rax],	mm6
	emms
End Asm
Print "after"
Print "z = ";z
Print "v(0) = ";v(0)
Sleep
output
before
v(0) = 123456789
z = 8519120
after
z = 8519120
v(0) = 2

Code: Select all

Dim As Ulongint k, v(0)
Dim As Ulongint Ptr z=@v(0)
k=2
v(0)=123456789
Print "before"
Print "v(0) = ";v(0)
Print "z = ";z
Asm
	movd	mm6, k   ' mm6 is k
	movq	[z],	mm6
	emms
End Asm
Print "after"
Print "z = ";z
Print "v(0) = ";v(0)
Sleep
output
before
v(0) = 123456789
z = 8519120
after
z = 2
v(0) = 123456789
SARG
Posts: 1764
Joined: May 27, 2005 7:15
Location: FRANCE

Re: asm movq question

Post by SARG »

Obvious :-)

movq [z], mm6 just means that the value in mm6 is moved to the address of z not to the address pointed by z.

That's the usual syntax. Look at the doc : [<variable name>] is replaced by its address.

edit Not so obvious.
Compiled with gas or gas64

Code: Select all

 mov      rax, z 
throws an error unlike with gcc. [ ] are missing in the asm code....

But with gcc

Code: Select all

 movq   [z],   mm6 
translated in

Code: Select all

 [movq   [QWORD PTR -232[rbp]],   mm6 

is equivalent to

Code: Select all

 movq   QWORD PTR -232[rbp],   mm6
: move mm6 value to z.

So compilation of asm blocks is different between gasXX and gcc.
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: asm movq question

Post by srvaldez »

thank you SARG :-)
I also noticed the difference between gas and gcc, kind of disappointing that you can't do *z = value without first moving z into a register
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: asm movq question

Post by Munair »

srvaldez wrote:thank you SARG :-)
I also noticed the difference between gas and gcc, kind of disappointing that you can't do *z = value without first moving z into a register
That's how assemblers work. In order to reference or dereference requires an extra register to obtain the value or address. In NASM it's no different.
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: asm movq question

Post by deltarho[1859] »

SARG wrote:movq [z], mm6 just means that the value in mm6 is moved to the address of z not to the address pointed by z.
I don't write much asm - I find fbc + gcc optimized fast enough for my needs.

The following may be worth thinking about for those that do write a lot of asm.

Code: Select all

#define ValueOf(x)  Dword Ptr [x]
Dim as ULong TestVar

TestVar = 47
Asm
  mov Dword Ptr [TestVar], 123
End Asm
Print TestVar ' gives 123

TestVar = 47
Asm
  mov ValueOf(TestVar), 123
End Asm
Print TestVar ' gives 123

Sleep
The above works with gas and gcc , 32-bit and 64-bit.

I should imagine that a seasoned asm writer could devise quite a few definitions that would make their code easily readable in six months time, and make their code easily readable for others today.

However, as I wrote — "I don't write much asm" — so the above idea may not be that useful.
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: asm movq question

Post by deltarho[1859] »

SSE has no rotate instructions.

The following will rotate 32 bits. x is to be rotated, y is free to use and k is the rotation.

The 'qword Ptr [n]' statements are used to simply populate x for illustration purposes.

I am off topic but shows where macros can make our asm a litle more readable; and writable.

I cannot imagine what macros seasoned asm coders can knock out.

Code: Select all

#macro rotl(x, y, k)
  movdqa y, x
  pslld x, k
  psrld y, (32-k)
  por x, y
#endmacro
 
#macro rotr(x, y, k)
  movdqa y, x
  psrld x, k
  pslld y, (32-k)
  por x, y
#endmacro
 
Dim As Ulong n = &b10011010110000110101001110111001
 
Asm
movq xmm2, qword ptr [n]
  rotl(xmm2, xmm6, 7)
movq qword ptr [n], xmm2
End Asm
' => &b01100001101010011101110011001101
Print Bin(n,32)
 
n = &b10011010110000110101001110111001
Asm
movq xmm3, qword ptr [n]
  rotr(xmm3, xmm5, 3)
movq qword ptr [n], xmm3
End Asm
' => &b00110011010110000110101001110111
Print Bin(n,32)
 
Sleep
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: asm movq question

Post by srvaldez »

Hi deltarho[1859]
thank you for the interesting contributions, I plan on trying them out in a day or two, here in the USA it's thanksgiving day so I don't have time at the moment.
I am especially intrigued by your rotate macros, will give them a trough workout :-)
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: asm movq question

Post by deltarho[1859] »

@srvaldez

Happy thanksgiving day. Image

If I wrote more asm I would not spend as much time as I do trying to fathom out what the compiler is complaining about and then taking longer to come up with the correct way of doing something to avoid the complaints. Image

The rotl macro is not my idea. I saw an example and thought “I'll never remember that” and will have to keep referring to notes in future. However, rotl(x, y, k) is easy to remember, and I can forget how the macro worked. We use a lot of #define in BASIC so why not asm as well. A lot of SSE2 opcodes are gobbledygook to me. A simple plain English #define can help. Yes, they will be longer. Some Windows APIs have extraordinarily long names.

Now someone like yourself, jj2007 and a few others could write some macros which would make writing asm a lot easier for someone like me. Some members may even give asm a try after being turned off by 'raw' code.
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: asm movq question

Post by deltarho[1859] »

Just for the record, here are 64-bit rotates.

Code: Select all

#macro rotl64(x, y, k)
  movdqa y, x
  psllq x, k
  psrlq y, (64-k)
  por x, y
#endmacro
 
#macro rotr64(x, y, k)
  movdqa y, x
  psrlq x, k
  psllq y, (64-k)
  por x, y
#endmacro

They work with gas, gas64, gcc 32-bit, and gcc 64-bit.

The two earlier macros can be renamed rotl32 and rotr32.

Sebastiano Vigna uses rotl, the rotl64 variant, in several of his PRNGs and in one uses rotl three times. You may expect the code blocks to be slow. They are, in fact, blindingly fast. I wrote two of his PRNGs using SSE some years ago and the code would have been much more readable had I used rotl64 then.
Post Reply