- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The Intel documentation does not specify wether mov R8d , -1 will also zero the high dword of R8, or leave it intact.
The Microsoft Visual C++ (2010) translate the C line a = myfunc(par1, par2, 3) ; into
mov RCX, par1 ; mov RDX, par2 ; mov R8b, 3 ; call myfunc; move qword ptr , RAX
IF the behaviour is implementation-dependent, some processors may crash....
IF the high dword is set to zero when moving to the low dword, why not say it clearly?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Appendum: The function myfunc is defined as _int64 myfunc( int *par1 , int *par2 , size_t N ) ;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>>IF the behaviour is implementation-dependent, some processors may crash>>>
I suppose that software beign dependent on the register state might crash.I think that when passing an int primitive type high part of 64-bit register will be filled with zeros.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think, when used with general purpose registers, mov leaves unused parts of the registers intact. The confusion and implementation-specific behavior is present when mov is used with segment registers, which is typically done by OS.
The code you cited may well be correct if the compiler knows that R8 is 0 before the call, so it can save some code size and only load 8 bit lower part of the register.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
R8 is a scratch register. Its contents may be changed by any function call, at will. So I would consider relying on its previous state a very dongerous approach.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is R8 not supposed to be filled by cpu with zeroes when 32-bit value is beign written to it?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, Sergey.
I looked over the code: my definition was actually __int64 (double underscore).
The compiler switches are /O2 /Oi /D "_X64" /D "_MBCS" /FD /EHsc /MD /Gy /FAcs /Fa"x64\Release\\" /Fo"x64\Release\\" /Fd"x64\Release\vc90.pdb" /W3 /nologo /c /Zi /TP /errorReport:prompt
Anyway, my central point was the use of ' mov R8D, 3 ' instead of 'mov R8, 3 ' .
<<The code you cited may well be correct if the compiler knows that R8 is 0 before the call, so it can save some code size and only load 8 bit lower part of the register. >> (andysem)
To test that hipothesis, I called the function twice in succession. VeMulasm may change R8 (it is an assembler function compileded separatedly). The first call could very well changed R8, and the compiler cann't know what an external function does. The included extract shows that,the compiler assumes that mov R8D,3 is equal to mov R8,3 .
typedef double double16 ; // double on 16-bytes boundary
double VecMulasm( double16 *vec, double16 *AV, size_t Ns) ; // B= sum{vec.*AV}
VecMulasm( (double16 *)As, (double16 *)Bs, 3) ; // sum{As.*Bs}
000000013FB915FE lea rdx,[rsp+110h]
000000013FB91606 lea rcx,[rsp+40h]
000000013FB9160B mov r8d,3
000000013FB91611 call VecMulasm (13FB910A5h)
VecMulasm( (double16 *)As, (double16 *)Bs, 3) ; // B= sum{As.*Bs}
000000013FB91616 lea rdx,[rsp+110h]
000000013FB9161E lea rcx,[rsp+40h]
000000013FB91623 mov r8d,3
000000013FB91629 call VecMulasm (13FB910A5h)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
R8 is volatile register and is not preserved by compiler and any write to R8d will zero-fill upper half of this register.Interesting why compiler directly addressed lower half of R8 if immediate value Ns = 3 can be represented as 8 bit value.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry I made a mistake argument size_t Ns is 32-bit int so compiler addressed lower part of R8.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yep platform is 64-bit because of 64-bit registers beign used.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page