On 03/10/2011 11:01 PM, bearophile wrote:
While creating the rotation code I have found two things I don't understand.
Maybe some of you is able to help me understand.
This version of the code:
union Four {
uint u;
ubyte[4] a;
}
void main() {
Four f;
asm {
rol f.u, 8;
}
}
DMD 2.052 gives this error, do you know why?
test.d(8): bad type/size of operands 'f.u'
----------------------------------
So to avoid wasting load asm instructions I have tried to write it like this:
union Four {
ubyte[4] arr;
uint ui;
}
void main() {
Four fo;
fo.arr[0] = 1;
fo.arr[1] = 2;
fo.arr[2] = 3;
fo.arr[3] = 4;
uint* uptr =&(fo.ui);
asm {
rol [uptr], 8;
}
asm {
rol uptr, 8;
}
}
but looking at the asm it produces, do you know why the rol with [uptr] and
uptr are translated to the same instruction (so it rotates the pointer instead
of the pointed uint)?
__Dmain comdat
push EBP
mov EBP,ESP
sub ESP,8
mov dword ptr -8[EBP],0
lea EAX,-8[EBP]
mov byte ptr -8[EBP],1
mov byte ptr -7[EBP],2
mov byte ptr -6[EBP],3
mov byte ptr -5[EBP],4
mov -4[EBP],EAX
rol -4[EBP],8 ;<======
rol -4[EBP],8 ;<======
mov ESP,EBP
pop EBP
ret
Bye and thank you,
bearophile
About first point: looks like a bug at the interface between union and asm. I
could rol either a pointer or an uint, but none of them member of a union.
Dunno why. Indeed, using '<<' works as expected.
But I could have this work (which rather confirms the above interpretation):
union Four {
uint u;
ubyte[4] a;
}
void main() {
Four f;
f.u = 0x_01_02_03_04u;
writefln ("'0x%08X'" , f.u);
// deceiving D:
auto p = &(f.u);
auto u = *p;
asm {
rol u, 8;
}
writefln ("'0x%08X'" , u);
/* output:
'0x01020304'
'0x02030401'
*/
}
I have no idea about the second point.
Denis
--
_________________
vita es estrany
spir.wikidot.com