View Full Version : [JAVA] reverse string un pò particolare
Oceans11
21-10-2008, 23:11
Volevo postare questo pezzo di codice che fa il reverse di una stringa tramite xor:
public static String reverse(String toReverse) {
char[] array = toReverse.toCharArray();
int len = str.length() - 1;
for (int i = 0; i < len; i++, len--) {
array[i] ^= array[len];
array[len] ^= array[i];
array[i] ^= array[len];
}
return new String(array);
}
Sono ben accette spiegazioni e commenti, o anche solo un'occhiata :).
Vincenzo1968
21-10-2008, 23:29
Volevo postare questo pezzo di codice che fa il reverse di una stringa tramite xor:
public static String reverse(String toReverse) {
char[] array = toReverse.toCharArray();
int len = str.length() - 1;
for (int i = 0; i < len; i++, len--) {
array[i] ^= array[len];
array[len] ^= array[i];
array[i] ^= array[len];
}
return new String(array);
}
Sono ben accette spiegazioni e commenti, o anche solo un'occhiata :).
È una tecnica utilizzata per scambiare il valore di due variabili senza far uso di una variabile temporanea d'appoggio. Per esempio(è in C ma in Java dovrebbe essere uguale):
int x = 5;
int y = 8;
x ^= y;
y ^= x;
x ^= y;
Alla fine x conterrà 8 e y 5. Dovrebbe essere anche più veloce, data l'efficienza degli operatori sui bit(ma non l'ho provato).
int x = 5;
int y = 8;
x ^= y;
y ^= x;
x ^= y;
Alla fine x conterrà 8 e y 5. Dovrebbe essere anche più veloce, data l'efficienza degli operatori sui bit(ma non l'ho provato).
No Vincenzo.
E' piu' lenta della versione classica con variabile d'appoggio.
Era utile (ogni tanto) una volta, in assembly, in carenza di registri.
Ma oggi non e' consigliabile.
Vincenzo1968
22-10-2008, 00:51
No Vincenzo.
E' piu' lenta della versione classica con variabile d'appoggio.
Era utile (ogni tanto) una volta, in assembly, in carenza di registri.
Ma oggi non e' consigliabile.
Vero. Ho fatto la prova:
http://www.guidealgoritmi.it/images/ImgForums/BitwiseSwap.jpg
#include <stdio.h>
#include <time.h>
int main()
{
clock_t c_start, c_end;
int k;
int tmp;
int x = 5;
int y = 8;
c_start = clock();
for ( k = 0; k < 100000001; k++ )
{
x ^= y;
y ^= x;
x ^= y;
}
c_end = clock();
printf("\nx -> %d\ny -> %d\n", x, y);
printf("\nTempo 1 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);
c_start = clock();
for ( k = 0; k < 100000001; k++ )
{
tmp = x;
x = y;
y = tmp;
}
c_end = clock();
printf("\nx -> %d\ny -> %d\n", x, y);
printf("\nTempo 2 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);
return 0;
}
Vero. Ho fatto la prova:
http://www.guidealgoritmi.it/images/ImgForums/BitwiseSwap.jpg
...
Se puoi stampa il codice assembly di entrambe le soluzioni, e commentiamo.
Ziosilvio
22-10-2008, 09:51
È una tecnica utilizzata per scambiare il valore di due variabili senza far uso di una variabile temporanea d'appoggio. Per esempio(è in C ma in Java dovrebbe essere uguale):
int x = 5;
int y = 8;
x ^= y;
y ^= x;
x ^= y;
Alla fine x conterrà 8 e y 5. Dovrebbe essere anche più veloce, data l'efficienza degli operatori sui bit(ma non l'ho provato).
Era:
x ^= y ^= x ^= y;
Sul mio computer è talmente veloce che la funzione clock non riesce a distinguere il tempo d'inizio dal tempo di fine :eek:
Ovviamente, funziona solo se x e y sono variabili intere: int, char, long...
incipit1970
22-10-2008, 14:13
Era:
x ^= y ^= x ^= y;
Sul mio computer è talmente veloce che la funzione clock non riesce a distinguere il tempo d'inizio dal tempo di fine :eek:
Ovviamente, funziona solo se x e y sono variabili intere: int, char, long...
Per inefficiente che sia l'assembler generato dal compilatore, un'assegnazione non può richiedere più di qualche ciclo di clock, ed in un qualsiasi processore moderno ogni ciclo di clock dura meno di un milliardesimo di secondo, quindi si parla sempre di quantità infime. Infatti, il codice di Vincenzo1968 fa 100 millioni di assegnazioni per ognuno dei codici, ed il tempo totale nel peggiore dei due casi è di appena un decimo di secondo. la differenza si apprezza solo facendo millioni di operazioni, una sola non smuove neanche il contatore. Le date di solito arrivano ad una risoluzione di un millesimo di secondo, ma è un tempo enorme per misurare una istruzione di cpu.
Se devi muovere solo qualche byte, vanno bene entrambi i modi, ma se le operazioni vanno fatte su quantità massicce di dati, allora meglio scegliere l'operazione più veloce, a parità di cose.
Vincenzo1968
22-10-2008, 14:34
Eqque qua:
http://www.guidealgoritmi.it/images/ImgForums/BitwiseSwap2.jpg
#include <stdio.h>
#include <time.h>
int main()
{
clock_t c_start, c_end;
int k;
int tmp;
int x = 5;
int y = 8;
c_start = clock();
for ( k = 0; k < 1000000001; k++ )
{
x ^= y ^= x ^= y;
}
c_end = clock();
printf("\nx -> %d\ny -> %d\n", x, y);
printf("\nTempo 0 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);
c_start = clock();
for ( k = 0; k < 1000000001; k++ )
{
x ^= y;
y ^= x;
x ^= y;
}
c_end = clock();
printf("\nx -> %d\ny -> %d\n", x, y);
printf("\nTempo 1 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);
c_start = clock();
for ( k = 0; k < 1000000001; k++ )
{
tmp = x;
x = y;
y = tmp;
}
c_end = clock();
printf("\nx -> %d\ny -> %d\n", x, y);
printf("\nTempo 2 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);
return 0;
}
e questo è l'assembly generato dal compilatore:
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.21022.08
TITLE c:\Progetti Visual Studio\Progetti visual Studio 2008\C++\MyProjects\HtmlIt\ArrayTree\ArrayTree\ArrayTree.c
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB OLDNAMES
PUBLIC ??_C@_03NHELKHFK@?$CFd?7?$AA@ ; `string'
PUBLIC ??_C@_00CNPNBAHC@?$AA@ ; `string'
PUBLIC ??_C@_0BC@BJMPBCEC@?6x?5?9?$DO?5?$CFd?6y?5?9?$DO?5?$CFd?6?$AA@ ; `string'
PUBLIC ??_C@_0BL@IABJBOLO@?6Tempo?50?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@ ; `string'
PUBLIC ??_C@_0BL@OFHOCFPI@?6Tempo?51?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@ ; `string'
PUBLIC ??_C@_0BL@EKNHGIDC@?6Tempo?52?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@ ; `string'
EXTRN @__security_check_cookie@4:PROC
EXTRN __imp__puts:PROC
EXTRN __imp__printf:PROC
EXTRN __imp__clock:PROC
; COMDAT ??_C@_0BL@EKNHGIDC@?6Tempo?52?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@
CONST SEGMENT
??_C@_0BL@EKNHGIDC@?6Tempo?52?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@ DB 0aH, 'T'
DB 'empo 2 -> %5.5f secondi', 0aH, 00H ; `string'
CONST ENDS
; COMDAT ??_C@_0BL@OFHOCFPI@?6Tempo?51?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@
CONST SEGMENT
??_C@_0BL@OFHOCFPI@?6Tempo?51?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@ DB 0aH, 'T'
DB 'empo 1 -> %5.5f secondi', 0aH, 00H ; `string'
CONST ENDS
; COMDAT ??_C@_0BL@IABJBOLO@?6Tempo?50?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@
CONST SEGMENT
??_C@_0BL@IABJBOLO@?6Tempo?50?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@ DB 0aH, 'T'
DB 'empo 0 -> %5.5f secondi', 0aH, 00H ; `string'
CONST ENDS
; COMDAT ??_C@_0BC@BJMPBCEC@?6x?5?9?$DO?5?$CFd?6y?5?9?$DO?5?$CFd?6?$AA@
CONST SEGMENT
??_C@_0BC@BJMPBCEC@?6x?5?9?$DO?5?$CFd?6y?5?9?$DO?5?$CFd?6?$AA@ DB 0aH, 'x'
DB ' -> %d', 0aH, 'y -> %d', 0aH, 00H ; `string'
CONST ENDS
; COMDAT ??_C@_00CNPNBAHC@?$AA@
CONST SEGMENT
??_C@_00CNPNBAHC@?$AA@ DB 00H ; `string'
CONST ENDS
; COMDAT ??_C@_03NHELKHFK@?$CFd?7?$AA@
CONST SEGMENT
??_C@_03NHELKHFK@?$CFd?7?$AA@ DB '%d', 09H, 00H ; `string'
CONST ENDS
PUBLIC __real@408f400000000000
PUBLIC _main
EXTRN __fltused:DWORD
; COMDAT __real@408f400000000000
; File c:\progetti visual studio\progetti visual studio 2008\c++\myprojects\htmlit\arraytree\arraytree\arraytree.c
CONST SEGMENT
__real@408f400000000000 DQ 0408f400000000000r ; 1000
; Function compile flags: /Ogtpy
CONST ENDS
; COMDAT _main
_TEXT SEGMENT
tv203 = -4 ; size = 4
tv197 = -4 ; size = 4
tv190 = -4 ; size = 4
_c_start$ = -4 ; size = 4
_main PROC ; COMDAT
; 38 : {
push ebp
mov ebp, esp
and esp, -64 ; ffffffc0H
sub esp, 48 ; 00000030H
push ebx
; 39 : clock_t c_start, c_end;
; 40 : int k;
; 41 : int tmp;
; 42 :
; 43 : int x = 5;
; 44 : int y = 8;
; 45 :
; 46 :
; 47 : c_start = clock();
mov ebx, DWORD PTR __imp__clock
push ebp
push esi
push edi
mov esi, 5
lea edi, DWORD PTR [esi+3]
call ebx
mov DWORD PTR _c_start$[esp+64], eax
mov eax, 1000000001 ; 3b9aca01H
$LL9@main:
; 48 : for ( k = 0; k < 1000000001; k++ )
; 49 : {
; 50 : x ^= y ^= x ^= y;
xor esi, edi
xor edi, esi
xor esi, edi
sub eax, 1
jne SHORT $LL9@main
; 51 : }
; 52 : c_end = clock();
call ebx
; 53 :
; 54 : printf("\nx -> %d\ny -> %d\n", x, y);
mov ebx, DWORD PTR __imp__printf
push edi
push esi
push OFFSET ??_C@_0BC@BJMPBCEC@?6x?5?9?$DO?5?$CFd?6y?5?9?$DO?5?$CFd?6?$AA@
mov ebp, eax
call ebx
; 55 :
; 56 : printf("\nTempo 0 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);
sub ebp, DWORD PTR _c_start$[esp+76]
add esp, 4
mov DWORD PTR tv203[esp+72], ebp
fild DWORD PTR tv203[esp+72]
fdiv QWORD PTR __real@408f400000000000
fstp QWORD PTR [esp]
push OFFSET ??_C@_0BL@IABJBOLO@?6Tempo?50?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@
call ebx
; 57 :
; 58 :
; 59 : c_start = clock();
mov ebp, DWORD PTR __imp__clock
add esp, 12 ; 0000000cH
call ebp
mov DWORD PTR _c_start$[esp+64], eax
mov eax, 1000000001 ; 3b9aca01H
$LL6@main:
; 60 : for ( k = 0; k < 1000000001; k++ )
; 61 : {
; 62 : x ^= y;
xor esi, edi
; 63 : y ^= x;
xor edi, esi
; 64 : x ^= y;
xor esi, edi
sub eax, 1
jne SHORT $LL6@main
; 65 : }
; 66 : c_end = clock();
call ebp
; 67 :
; 68 : printf("\nx -> %d\ny -> %d\n", x, y);
push edi
push esi
push OFFSET ??_C@_0BC@BJMPBCEC@?6x?5?9?$DO?5?$CFd?6y?5?9?$DO?5?$CFd?6?$AA@
mov ebp, eax
call ebx
; 69 :
; 70 : printf("\nTempo 1 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);
sub ebp, DWORD PTR _c_start$[esp+76]
add esp, 4
mov DWORD PTR tv197[esp+72], ebp
fild DWORD PTR tv197[esp+72]
fdiv QWORD PTR __real@408f400000000000
fstp QWORD PTR [esp]
push OFFSET ??_C@_0BL@OFHOCFPI@?6Tempo?51?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@
call ebx
add esp, 12 ; 0000000cH
; 71 :
; 72 : c_start = clock();
call DWORD PTR __imp__clock
mov DWORD PTR _c_start$[esp+64], eax
mov eax, 1000000001 ; 3b9aca01H
$LL3@main:
; 73 : for ( k = 0; k < 1000000001; k++ )
sub eax, 1
; 74 : {
; 75 : tmp = x;
mov ebp, esi
; 76 : x = y;
mov esi, edi
; 77 : y = tmp;
mov edi, ebp
jne SHORT $LL3@main
; 78 : }
; 79 : c_end = clock();
call DWORD PTR __imp__clock
; 80 :
; 81 : printf("\nx -> %d\ny -> %d\n", x, y);
push ebp
push esi
push OFFSET ??_C@_0BC@BJMPBCEC@?6x?5?9?$DO?5?$CFd?6y?5?9?$DO?5?$CFd?6?$AA@
mov edi, eax
call ebx
; 82 :
; 83 : printf("\nTempo 2 -> %5.5f secondi\n", (double)(c_end - c_start) / CLOCKS_PER_SEC);
sub edi, DWORD PTR _c_start$[esp+76]
add esp, 4
mov DWORD PTR tv190[esp+72], edi
fild DWORD PTR tv190[esp+72]
fdiv QWORD PTR __real@408f400000000000
fstp QWORD PTR [esp]
push OFFSET ??_C@_0BL@EKNHGIDC@?6Tempo?52?5?9?$DO?5?$CF5?45f?5secondi?6?$AA@
call ebx
add esp, 12 ; 0000000cH
; 84 :
; 85 : return 0;
; 86 : }
pop edi
xor eax, eax
pop esi
pop ebp
pop ebx
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
END
Ho aggiunto uno zero: 1000000001.
Domanda: un buon libro per imparare l'assembly?
P.S. Questa è la mia macchina:
AMD Athlon(tm) 64 X2
Dual Core Processor 4800+
2.50 GHz
896 MB di RAM
Microsoft Windows XP Professional (32 bit)
Service Pack 3
Volevo postare questo pezzo di codice che fa il reverse di una stringa tramite xor:
...
Sono ben accette spiegazioni e commenti, o anche solo un'occhiata :).
Non vorrei dire una caxxata, ma il tuo metodo potrebbe avere qualche problema con stringhe unicode. Non ho tempo di testarlo e verificare però.
Che ne dici di...
new StringBuilder(toReverse).reverse().toString()
??
incipit1970
22-10-2008, 15:56
Domanda: un buon libro per imparare l'assembly?
Ah, l'assembler... saranno 10-15 anni che non lo uso... un po' ostico, ma che sensazione di benessere quando assemblavi il programma e vedevi un eseguibile di 1-2Kb...
Come linguaggio è facilissimo (almeno io lo trovo facile, c'è chi direbbe il contrario), ma richiede una buona conoscenza dell'architettura che c'è dietro. Ci sono diverse intro in giro per internet, uno può essere questo (http://www.manuali.it/manuali-guide/Informatica-e-Internet/Programmazione/Assembler/Manuale-di-Assembler-8086/2387.htm), che ha il vantaggio di essere in italiano.
Ma dal mio punto di vista il punto di riferimento resta l'Intel Software Developer's Manual per le piattaforme ia32 ed ia64, non so se anche AMD abbia documentazione sul proprio set di istruzioni, ma suppongo di si. Ma non è esattamente introduttivo...
Purtroppo, di questi tempi l'assembler è quasi un hobby, difficilmente si trova spazio per utilizzarlo su progetti "reali", eccetto se ti occupi di elettronica o programmazione di basso livello.
Non vorrei dire una caxxata, ma il tuo metodo potrebbe avere qualche problema con stringhe unicode. Non ho tempo di testarlo e verificare però.
Che ne dici di...
new StringBuilder(toReverse).reverse().toString()
??
Anche cosi', sempre in C#, dovendo scrivere in output su file come richiesto
string ToPrint = "PippoPlutoPaperino";
StreamWriter output = new StreamWriter("output.txt");
output.Write(ToPrint);
output.Write(ToPrint.Reverse());
output.Close();
Vincenzo1968
22-10-2008, 16:33
Ah, l'assembler... saranno 10-15 anni che non lo uso... un po' ostico, ma che sensazione di benessere quando assemblavi il programma e vedevi un eseguibile di 1-2Kb...
Come linguaggio è facilissimo (almeno io lo trovo facile, c'è chi direbbe il contrario), ma richiede una buona conoscenza dell'architettura che c'è dietro. Ci sono diverse intro in giro per internet, uno può essere questo (http://www.manuali.it/manuali-guide/Informatica-e-Internet/Programmazione/Assembler/Manuale-di-Assembler-8086/2387.htm), che ha il vantaggio di essere in italiano.
Ma dal mio punto di vista il punto di riferimento resta l'Intel Software Developer's Manual per le piattaforme ia32 ed ia64, non so se anche AMD abbia documentazione sul proprio set di istruzioni, ma suppongo di si. Ma non è esattamente introduttivo...
Purtroppo, di questi tempi l'assembler è quasi un hobby, difficilmente si trova spazio per utilizzarlo su progetti "reali", eccetto se ti occupi di elettronica o programmazione di basso livello.
Ciao Incipit,
grazie per la risposta e per il link. Non voglio imparare l'assembly per realizzare applicazioni complesse ma vorrei, almeno, capire il codice generato dal compilatore.
:)
Vincenzo1968
22-10-2008, 17:05
Se puoi stampa il codice assembly di entrambe le soluzioni, e commentiamo.
Ohé Gugo(ma anche Incipit e chiunque se ne intenda),
a proposito di imparare l'assembly, un commento sul codice che ho postato?
Ohé Gugo(ma anche Incipit e chiunque se ne intenda),
a proposito di imparare l'assembly, un commento sul codice che ho postato?
Ciao.
Si', purtroppo e' troppo ottimizzato, nel senso che il C ha pensato bene di tenere le variabili su registri.
Normalmente quando si scambiano i valori delle due variabili si fa qualcosa, e quindi non possono essere tenute su registri, ma occorre passare in memoria.
Invece qui non si e' fatto nulla, il C l'ha capito ed ha tagliato.
L'effetto del rallentare e' solo dovuto al fatto che le XOR si accoppiano meno bene che le MOV (e comunque un po' si vede)
Se all'interno del ciclo (in entrambi i casi), provi a chiamare una funzione che usa X e Y, allora forse riusciamo a vedere meglio il problema.
non so, una funzione che sperabilmente non possa essere messa come __inline automaticamente, quindi decorosamente complessa.
Oppure puoi provare a chiedere indirettamente al C di non considerare le variabili come ottimizzabili in registri. Se non sbaglio c'e' anche in C la keyword
volatile
[code]
volatile int x=5;
volatile int y=8;
[code]
Purtroppo non ho un compilatore C sottomano per provare io direttamente.
Vincenzo1968
22-10-2008, 18:01
Ciao.
Si', purtroppo e' troppo ottimizzato, nel senso che il C ha pensato bene di tenere le variabili su registri.
Normalmente quando si scambiano i valori delle due variabili si fa qualcosa, e quindi non possono essere tenute su registri, ma occorre passare in memoria.
Invece qui non si e' fatto nulla, il C l'ha capito ed ha tagliato.
L'effetto del rallentare e' solo dovuto al fatto che le XOR si accoppiano meno bene che le MOV (e comunque un po' si vede)
Se all'interno del ciclo (in entrambi i casi), provi a chiamare una funzione che usa X e Y, allora forse riusciamo a vedere meglio il problema.
non so, una funzione che sperabilmente non possa essere messa come __inline automaticamente, quindi decorosamente complessa.
Oppure puoi provare a chiedere indirettamente al C di non considerare le variabili come ottimizzabili in registri. Se non sbaglio c'e' anche in C la keyword
volatile
[code]
volatile int x=5;
volatile int y=8;
[code]
Grazie per la risposta ma non ho capito un tubo. Vado a studiarmi un po' l'assembly. Ne riparliamo, eventualmente, tra qualche anno :D
Purtroppo non ho un compilatore C sottomano per provare io direttamente.
Domanda da Grande Inquisitore(con annessi tratti di corda :Perfido:): e la dll del contest 7 come l'hai compilata? Pensavo tu avessi il compilatore Visual C++ :Perfido:
Grazie per la risposta ma non ho capito un tubo. Vado a studiarmi un po' l'assembly. Ne riparliamo, eventualmente, tra qualche anno :D
Va bene studiare, ma qualche anno mi sembra un po' esagerato...
Comunque prova anche solo a dichiarare le due variaibli con il volatile davanti (che non e' l'uccello padulo)
Domanda da Grande Inquisitore(con annessi tratti di corda :Perfido:): e la dll del contest 7 come l'hai compilata? Pensavo tu avessi il compilatore Visual C++ :Perfido:
Certo, appunto e' un compilatore di C++ e non di C.
E comunque era a casa e non al lavoro come adesso :)
(Poi in realta' ce l'avrei anche qui, ma sai...)
Vincenzo1968
22-10-2008, 18:19
Va bene studiare, ma qualche anno mi sembra un po' esagerato...
Comunque prova anche solo a dichiarare le due variaibli con il volatile davanti (che non e' l'uccello padulo)
Certo, appunto e' un compilatore di C++ e non di C.
E comunque era a casa e non al lavoro come adesso :)
(Poi in realta' ce l'avrei anche qui, ma sai...)
Io utilizzo Visual Studio 2008 per compilare i miei programmi in C:
http://www.guidealgoritmi.it/images/ImgForums/CompileCMode.jpg
Io utilizzo Visual Studio 2008 per compilare i miei programmi in C:
Ma pensa te, non sapevo che si potesse fare la retrocompatibilita'.
Ora ci provo quindi.
int x;
int y;
int u;
int v;
int main(array<System::String ^> ^args)
{
x = 5;
y = 8;
/// XOR
x ^= y;
y ^= x;
x ^= y;
printf("%d %d",x,y);
u = 5;
v = 8;
// TMP
int tmp = u;
u = v;
v = tmp;
printf("%d %d",u,v);
return 0;
}
x = 5;
mov dword ptr ds:[0040A16Ch],5
y = 8;
mov dword ptr ds:[0040A168h],8
/// XOR
x ^= y;
mov eax,dword ptr ds:[0040A168h]
xor dword ptr ds:[0040A16Ch],eax
y ^= x;
mov eax,dword ptr ds:[0040A16Ch]
xor dword ptr ds:[0040A168h],eax
x ^= y;
mov eax,dword ptr ds:[0040A168h]
xor dword ptr ds:[0040A16Ch],eax
printf("%d %d",x,y);
push 40311Ch
push dword ptr ds:[0040A16Ch]
push dword ptr ds:[0040A168h]
push 1C6B68h
call FF9E43C8
add esp,10h
nop
nop
u = 5;
mov dword ptr ds:[0040A164h],5
v = 8;
mov dword ptr ds:[0040A160h],8
// TMP
int tmp = u;
mov eax,dword ptr ds:[0040A164h]
mov edi,eax
u = v;
mov eax,dword ptr ds:[0040A160h]
mov dword ptr ds:[0040A164h],eax
v = tmp;
mov dword ptr ds:[0040A160h],edi
printf("%d %d",u,v);
push 403124h
push dword ptr ds:[0040A164h]
push dword ptr ds:[0040A160h]
push 1C6B68h
call FF9E43C8
add esp,10h
nop
nop
Ecco, come si puo' vedere ciascuna delle istruzioni Xor e' composta da una lettura da memoria e da uno XOR in memoria.
esso equivale a:
Lettura da memoria:
- Una lettura da memoria, con salvataggio del dato dentro il registro EAX
XOR in memoria. Se avessimo voglia di andare a vedere il microcodice di quest'ultimo XOR:
- una ulteriore lettura da memoria con salvataggio su un registro interno 1
- uno XOR tra EAX (quello che avevamo letto nella prima istruzione) e il registro interno 1, con salvataggio del risultato in un altro registro interno 2
- una scrittura dal registro interno 2 alla stessa cella di memoria
Tralasciando l'operazione vera e propria, abbiamo in totale
2 letture e 1 scrittura su memoria per ciascuno dei 3 XOR del codice C
Per un totale di 6 letture e 3 scritture per gestire lo scambio di variabile
Mentre invece le operazioni con variabile d'appoggio abbiamo
un totale di 2 letture da memoria e 2 scritture su memoria.
C'e' una bella differenza.
Vincenzo1968
22-10-2008, 22:53
Ohé,
ho trovato questi:
http://xoomer.alice.it/ramsoft/asmbase/asmbase1/summary.html
http://xoomer.alice.it/ramsoft/asmavan/summary.html
http://xoomer.alice.it/ramsoft/win32asm/summary.htm
incipit1970
23-10-2008, 14:34
Ohé,
ho trovato questi:
http://xoomer.alice.it/ramsoft/asmbase/asmbase1/summary.html
http://xoomer.alice.it/ramsoft/asmavan/summary.html
http://xoomer.alice.it/ramsoft/win32asm/summary.htm
Mi sa che sono un po' attempati... TurboAssembler lo usavo insieme al TurboC della Borland, intorno al '87-'89... fa un po' tu. Comunque, la logica della programmazione in assembler è più o meno la stessa, eccetto per le descrizioni dei file .exe di DOS (chi se lo ricorda più DOS). Quello che cambia è il set di istruzioni, principalmente.
banryu79
23-10-2008, 14:36
OT
Vincenzo, forse ti può interessare anche questo IDE68K (http://home.hetnet.nl/~pj.fondse/ide68k/)
Vincenzo1968
23-10-2008, 14:41
Incipit e Banryu,
grazie mille per le dritte :)
Come libri(di carta, dico ;)) c'è niente?
P.S. per il set di istruzioni, ho scaricato i pdf dal sito della Intel.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.