009
05.03.2009, 23:15 Uhr
Hans
Library Walker (Operator)
|
Hi,
hab noch einen Nachtrag zu posting 002:
Habe mal einen Blick auf den Assemblercode geworfen, den mein Compiler produziert hat, das fand ich sehr verwunderlich... hier mal die wesentlichen Auszüge:
Code: |
; int value1; ; unsigned value2; ; ; value1 = -1; L$1: mov dword ptr [ebp-8],0ffffffffH
; printf ("\nvalue1: %0x, ", value1); mov eax,dword ptr [ebp-8] push eax mov eax,offset FLAT:L$4 push eax call near ptr FLAT:printf_ add esp,8
; value1 &= (~0)>>5; ; printf ("nach Bitop: %0x\n", value1); mov eax,dword ptr [ebp-8] ; <- eine konstante?! push eax mov eax,offset FLAT:L$5 push eax call near ptr FLAT:printf_ add esp,8
; ; value2 = ~0; mov dword ptr [ebp-4],0ffffffffH
; printf ("\nvalue2: %0x, ", value2); mov eax,dword ptr [ebp-4] push eax mov eax,offset FLAT:L$6 push eax call near ptr FLAT:printf_ add esp,8
; value2 &= (~0)>>5; ; printf ("nach Bitop: %0x\n", value2); mov eax,dword ptr [ebp-4] ; <- eine konstante?! push eax mov eax,offset FLAT:L$5 push eax call near ptr FLAT:printf_ add esp,8
|
Demnach hat der Compiler die Bitschiebeoperation schon selber ausgewertet, und daraus einen konstanten Wert gemacht. Da der Zweck des Programms aber darin bestand, herauszufinden, in welchen Befehlen die Bitschiebeoperationen münden, ist festzustellen, das es seinen Zweck nicht erfüllt hat.
Um dem Compiler das vorherige auswerten abzugewöhnen hab ich den Wert 5, um den die Bits zu verschieben sind, durch eine Variable ersetzt, die der Benutzer eingeben muss. Also so:
C++: |
int value1, s1; unsigned value2, s2;
value1 = -1; printf ("\nvalue1: %0x, ", value1); printf ("\nAnzahl verschiebungen: "); scanf ("%d", &s1); value1 &= (~0)>>s1; printf ("nach Bitop: %0x\n", value1);
value2 = ~0; printf ("\nvalue2: %0x, ", value2); printf ("\nAnzahl verschiebungen: "); scanf ("%d", &s2); value2 &= (~0)>>s2; printf ("nach Bitop: %0x\n", value2);
|
Daraus wurde dann:
Code: |
... value1 &= (~0)>>s1; 0051 8A 4D F4 mov cl,byte ptr [ebp-0xc] 0054 B8 FF FF FF FF mov eax,0xffffffff 0059 D3 F8 sar eax,cl ; Shift arithmetic right 005B 21 45 F0 and dword ptr [ebp-0x10],eax ... value2 &= (~0)>>s2; 00A9 8A 4D FC mov cl,byte ptr [ebp-0x4] 00AC B8 FF FF FF FF mov eax,0xffffffff 00B1 D3 F8 sar eax,cl ; ebenfalls Shift arithmetic right ; erwartet hab ich hier: SHR, also ; Shift right 00B3 21 45 F8 and dword ptr [ebp-0x8],eax
|
Daraus schliesse ich: Wenn es darum geht, das die oberen Bits wirklich gelöscht werden sollen, wäre eine fertige Bitmaske die bessere Lösung. Etwa so:
C++: |
unsigned int masken[] = {0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100, 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001}; ... /* obere 5 Bit löschen */ value &= ~(masken[0] | masken[1] | masken[2] | masken[3] | masken[4]);
|
Ach ja, dann noch das hier:
Zitat von 0xdeadbeef: |
in C wirste das für jeden Typen überladen ... müssen.
|
Wie stellt man das an?
Hans -- Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung. Dieser Post wurde am 05.03.2009 um 23:23 Uhr von Hans editiert. |