Originariamente inviato da VisRoboris
Per gli AMD che mi dite?
Forse processori amd e intel hanno lo stesso linguaggio macchina?
Sì, sono tutti compatibili con l'architettura IA-32 (per le versioni a 32 bit), per cui "parlano" tutti lo stesso assembly. Tuttavia in realtà la questione è più complicata.

Rispetto all'originale architettura x86 le istruzioni di base sono rimaste le stesse, anche se man mano sono state aggiunte delle estensioni, come i vari set di istruzioni aggiuntivi (MMX, i vari SSE, le istruzioni per supporto alla virtualizzazione,...) e nuove modalità di funzionamento (un processore x86 attualmente appena acceso "emula" se non erro un 8086, e passa in modalità diverse su richiesta del sistema operativo).
Un programma "per processori x86" può contare sempre sul set di istruzioni di base, e ormai si dà per assodata la presenza di diversi set di estensioni (un caso tipico è SSE2, supportato da praticamente tutti i processori recenti); eventualmente si distribuiscono degli eseguibili diversi per processori più vecchi.
Un'altra soluzione è verificare "al volo" (tipicamente con l'istruzione CPUID) se il processore supporta certe estensioni o meno, in un caso si eseguirà il codice che usa le estensioni, nell'altro quello senza (se non erro il compilatore Intel è in grado di gestire questa roba in automatico).
Questo approccio è d'obbligo se quello che si cerca di fare richiede delle estensioni diverse a seconda che ci si trovi su processori AMD e Intel; un esempio sono le estensioni per la virtualizzazione, per cui ci sono due set di istruzioni (e di approcci) differenti, per cui il software di virtualizzazione userà approcci diversi a seconda del processore.

La questione x86 a 64 bit (spesso chiamata x86_64 o x64) è a sua volta leggermente incasinata, dato che le estensioni a 64 bit all'architettura IA32 sono state inventate da AMD (per cui spesso si parla di architettura AMD64), per poi essere riproposte da Intel (chiamate con diversi nomi fino a stabilizzarsi su Intel64) in termini praticamente identici ma leggermente differenti sotto alcuni aspetti. Fortunatamente le differenze si concentrano solo in questioni che interessano solo il sistema operativo, che suppongo usi un approccio come quello indicato sopra per aggirare il problema.

Programmi pensati per architettura x86 a 32 bit girano senza problemi su x86_64 perché la CPU è in grado di "fare finta" di essere una CPU a 32 bit, per cui non è necessaria alcuna modifica (per lo stesso motivo per cui è possibile tuttora eseguire programmi x86 a 16 bit su processori a 64 bit).

La cosa paradossale è che gli attuali processori x86 non c'entrano niente con quella che era l'architettura di una volta, e l'assembly x86 è quasi esclusivamente un layer di compatibilità: ormai all'interno della CPU di fatto gira un processore RISC che elabora le micro-istruzioni corrispondenti alle macro-istruzioni (stile CISC) x86, e "dentro" sono nascosti un sacco di "trucchi" (branch predictor, instruction reordering, ...) tali per cui sembra che il processore esegua le istruzioni così come sono scritte, ma di fatto "di nascosto" riordina, esegue pezzi di codice contemporaneamente e/o speculativamente e fa ogni sorta di strane ottimizzazioni.

Ovviamente, dato che, a seconda della famiglia di processori considerata, quello che sta "sotto al cofano" cambia, l'ottimizzazione diventa una questione estremamente complicata: poche istruzioni assembly non corrispondono necessariamente a codice efficiente, e spesso soluzioni apparentemente meno efficienti risultano molto più veloci di altre più compatte.

Sì, l'architettura x86 è un gran casino.