Eine Frage der Byte Order, und: Logische Verknüpfungen

11/03/2010 - 16:36 von Markus Wichmann | Report spam
Hi all,

naja, das Problem dürfte wohl klar sein: Bei Intels werden die Bytes so
oft hin und her gedreht, dass man am Ende nicht mehr weiß, wo vorne und
hinten ist. Ernsthaft!

Gerade habe ich ein Problem, dass ich folgendes nicht weiß:

Also, ich kenne eine Speicherstelle (rsp+8, um genau zu sein), wenn ich
"fld tword" auf die anwende, steht die Zahl genau richtig in der FPU
drin. Wo fàngt bei dieser Zahl der Exponent an? Bei rsp+8 oder bei
rsp+16? (Brauche ich für eine schnelle Implementierung von copysign)

Ach ja, noch was: Die double- und float-Varianten sind ja einfacher zu
lösen (mit movd/movq), also hab ich die schon fertig, aber

Ich habe jetzt in eax ein float stehen, in edx ein anderes, und möchte
von edx relativ schnell das Vorzeichen nach eax kopieren. Wie mache ich
das am schnellsten? Geht es besser als

and eax, 0x7fffffff
and edx, 0x80000000
or eax, edx

? Weil die double-Variante

and rax, 0x7fffffffffffffff
and rdx, 0x8000000000000000
or rax, rdx

so nicht möglich ist (es gibt keine Codierung für

AND reg64, imm64

Nur für

AND reg64, imm32

Wobei imm32 dann sign extended wird. Bringt mir nur gerade nix, weil
sich hier ja gerade das Sign Bit von allen anderen Bits unterscheidet).

OK, möglich wàre

xor rcx, rcx ; 3 Bytes
bts rcx, 63 ; 5 bytes
and rdx, rcx ; 3 Bytes
dec rcx ; 3 Bytes
and rax, rcx ; 3 Bytes
; -
; 17 Bytes

Und damit definitiv unter einer Kodierung für Obiges. Dennoch, gibt es
eine bessere Lösung hierfür? Müssen die zwei ANDs sein?

Was mir jetzt noch spontan einfàllt:

bt rdx, 63
jnc .l1
bts rax, 63
jmp .l2
.l1:
btr rax, 63
.l2:

Ist aber mit branching, was ich eigentlich vermeiden wollte.

Tschö,
Markus
Progress (n.): Process through which USENET evolved from smart people in
front of dumb terminals to dumb people in front of smart
terminals.

news://freenews.netfront.net/ - complaints: news@netfront.net
 

Lesen sie die antworten

#1 Jan Seiffert
11/03/2010 - 20:01 | Warnen spam
Markus Wichmann schrieb:
Hi all,

naja, das Problem dürfte wohl klar sein: Bei Intels werden die Bytes so
oft hin und her gedreht, dass man am Ende nicht mehr weiß, wo vorne und
hinten ist. Ernsthaft!




^-^
So, und jetzt bring mal SIMD mit ins Spiel, dann drehts dir irgendwann form
geistigen Auge und du ertabst dich dabei, wie du 5 Minuten mit deinen Fingern
komische Bewegungen vor deinem Gesicht machst (dreh, shuffle, dreh, unpack,
dreh, knot, 2 im sinn einer hin), als woltest du "Jack Rabbit Slim's Twist
Contest" gewinnen, John Travolta waere stolz...

Gerade habe ich ein Problem, dass ich folgendes nicht weiß:

Also, ich kenne eine Speicherstelle (rsp+8, um genau zu sein), wenn ich
"fld tword" auf die anwende, steht die Zahl genau richtig in der FPU
drin. Wo fàngt bei dieser Zahl der Exponent an? Bei rsp+8 oder bei
rsp+16? (Brauche ich für eine schnelle Implementierung von copysign)




Da sie "oben" im Register ist, sollte sie "unten" im Speicher sein, also eher
bei rsp+8. Aber war die FPU den auch little endian, hmmm, ja, ich glaube...
Ich mach so gut wie nie was mit Fliesskomma...

[snip]
Ich habe jetzt in eax ein float stehen, in edx ein anderes, und möchte
von edx relativ schnell das Vorzeichen nach eax kopieren. Wie mache ich
das am schnellsten?



Ich versuchs mal Intel-syntax-artig fuer dich zu schreiben.

Ich weiss nicht wie schnell das ist:

shl eax, 1
shl edx, 1
rcr eax, 1

Oder so rum:
shl eax, 1
shl edx, 1
sbb eax, 0
ror eax, 1

Ist die frage was den groessenen stall auf dem EFLAGS Register verursacht.

Irgendwie will mir keine bitmagie einfallen
vielleicht:
mov edi, edx
lea ecx, (edx,2)
not edi
shr ecx, 1
lea esi, (edi,2)
shr esi, 1
xor edi, esi
sub edi, 1
and edi, eax
xor edx, ecx
cmovz eax, edi
or eax, edx


oder wir packen sign quelle in eax, sign ziel nach $IRGENDWO
not eax
cdq
mov eax, edx
not edx
shr eax, 1
and eax, $IRGENDWO
shl edx, 31
cmovz $IRGENDWO, eax
or $IRGENDWO, edx

Der is mir irgendwie besser gelungen, den koennt man mit dem von da drueber
zusammen fuehren...


Und damit definitiv unter einer Kodierung für Obiges. Dennoch, gibt es
eine bessere Lösung hierfür? Müssen die zwei ANDs sein?

Was mir jetzt noch spontan einfàllt:

bt rdx, 63
jnc .l1
bts rax, 63
jmp .l2
.l1:
btr rax, 63
.l2:




Bitinstruktionen sind auf Intel Silizium langsam. Der P4 ist schnarch lahm, die
Core sind besser, aber schnell ist was anderes und der Atom hat uns die
Wiederentdeckung der Langsamkeit gebracht...

Ist aber mit branching, was ich eigentlich vermeiden wollte.




Es gibt schlimmeres.

Tschö,
Markus



"Immer ein Bit uebrig behalten"

Gruss
Jan

Assembler, verdammt nah an der CPU!


VHDL, bei uns sitzen sie in der ersten Reihe!
Was man nicht in Assembler programmieren kann, muß man löten.


Was man nicht in VHDL programmieren kann, muß in Software emuliert werden.

Ähnliche fragen