|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
[assembly] divisione
Cerco un piccolo chiarimento...
dando un occhio su come gcc mi traduce l'istruzione C: Codice:
area = width * height/2 Codice:
imul 0xc(%ebp),%edx
mov %edx,%eax
shr $0x1f,%eax
add %edx,%eax
sar %eax
grazie. |
|
|
|
|
|
#2 |
|
Member
Iscritto dal: Aug 2005
Messaggi: 168
|
Hai preso l'esempio sbagliato per vedere come si fa la divisione.
La divisione per due viene ottimizzata dal compilatore come uno shift a destra. Se fai una divisione per qualsiasi numero che non sia 2 vedi una divisione vera. |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
ok, so che viene fatta con uno shift, ma non ho capito in questo caso cosa viene fatto.
In particolare io vedo uno shift di EAX >> 31 poi ad EAX viene aggiunto EDX e poi sar io ero convinto avesse due operandi invece qui ne ha uno. Il mio obiettivo è capire questo esempio. |
|
|
|
|
|
#4 | ||||
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
Quote:
Risultato positivo -> EAX = risultato (nessun cambiamento) Risultato negativo -> EAX = risultato + 1. Quote:
Quote:
Per i positivi, come vedi non cambia nulla. Il problema è coi negativi. Se invece sono negativi, in particolare nel caso in oggetto bisogna controllare se per caso il risultato da dividere per 2 vale -1 oppure è < -1. Se vale -1 sappiamo che la divisione deve valere 0. Infatti in questo caso EAX = risultato + 1 = -1 + 1 = 0. E lo shift ritorna correttamente 0. Se invece è < -1, lo shift aritmetico a destra ricopierà sempre il bit del segno, per cui il risultato rimarrà sempre negativo. Esempio: -2 + 1 = -1 sar 1 = -1. -3 + 1 = -2 sar 1 = -1. -4 + 1 = -3 sar 1 = -2. E così via.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
||||
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
aa.. ora dovrei esserci, si potevo immaginare che ove c'era sar era implicito 1.
Quote:
Infatti... infatti.... se uso variabili unsigned int.... la traduzione è ben diversa. Non c'è tutto il procedimento sopra detto... Vorrei chiederti un'altra cosa... poco chiara.. La riga di codice C che ho riportato fa parte di una funzione che poi ritorna il valore area. Noto che le ultime due istruzioni prima di ret apparentemente non servono a nulla... Codice:
.... 0x0000002e <triangle+46>: imul 0xc(%ebp),%edx 0x00000032 <triangle+50>: mov %edx,%eax 0x00000034 <triangle+52>: shr $0x1f,%eax 0x00000037 <triangle+55>: add %edx,%eax 0x00000039 <triangle+57>: sar %eax 0x0000003b <triangle+59>: mov %eax,-0x4(%ebp) // << --- ?? 0x0000003e <triangle+62>: mov -0x4(%ebp),%eax // << --- ?? 0x00000041 <triangle+65>: leave 0x00000042 <triangle+66>: ret |
|
|
|
|
|
|
#6 | ||
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Quote:
Quote:
La prima sembra sia necessaria per conservare il valore in qualche variabile. Se si tratta di una variabile, allora anche questa mov è del tutto inutile, in quanto la leave provvederà a ripulire lo stack dallo spazio allocatato per le variabili locali, e a questo punto vuol dire che il risultato viene ritornato usando il registro eax.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
||
|
|
|
|
|
#7 | ||
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
Quote:
Quote:
Codice:
int triangle(int width,int height) {
int area;
area = width * height/2;
return(area);
}
|
||
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Dec 2003
Messaggi: 4907
|
E' semplice: hai compilato senza ottimizzazioni e il compilatore ha "tradotto" il codice alla lettera usando la variabile locale che non era affatto necessaria.
Codice:
mov %eax,-0x4(%ebp) mov -0x4(%ebp),%eax La seconda sposta area in eax per usarlo come valore di ritorno. Sono entrambe inutili perché il risultato in eax c'era già ed area essendo locale non servirà più, e infatti se compili con -O2 (o se scrivi la funzione senza usare variabili locali) non le mette. Ultima modifica di ||ElChE||88 : 19-04-2010 alle 14:49. |
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
Quote:
L'ottimizzazione ha ridotto molto l'assembly, pertanto per controllare la traduzione del codice direi che è sempre meglio ottimizzare. Tutto chiaro. Vi ringrazio. |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:55.




















