Perché i programmi non sono scritti in Assembly più spesso? [chiuso]


216

Sembra un'opinione diffusa che la programmazione degli assiemi richieda più tempo ed è più difficile da programmare in un linguaggio di livello superiore come C. Pertanto, si consiglia o si presume che sia meglio scrivere in un linguaggio di livello superiore per questi motivi e per la migliore portabilità.

Di recente ho scritto in x86 assembly e mi sono reso conto che forse queste ragioni non sono realmente vere, tranne forse la portabilità. Forse è più una questione di familiarità e di saper scrivere bene l'assemblea. Ho anche notato che la programmazione in assembly è abbastanza diversa dalla programmazione in un HLL. Forse un programmatore di assemblaggio esperto ed esperto potrebbe scrivere programmi con la stessa facilità e rapidità di un programmatore C esperto che scrive in C.

Forse è perché la programmazione degli assembly è abbastanza diversa da quella degli HLL, e quindi richiede diversi modi di pensare, metodi e modi, il che rende molto imbarazzante programmare per i non familiari, e quindi gli dà il brutto nome per scrivere programmi.

Se la portabilità non è un problema, allora, che cosa avrebbe C su un buon assemblatore come NASM?

Modifica: solo per sottolineare. Quando si scrive in assembly, non è necessario scrivere solo nei codici di istruzione. È possibile utilizzare macro e procedure e le proprie convenzioni per rendere varie astrazioni per rendere i programmi più modulari, più gestibili e più facili da leggere. È qui che entra in gioco la conoscenza di come scrivere un buon assembly.


71
Scrivi ? Che ne dici di leggere il codice? tu (e altri) leggerete il codice molto più di quanto lo scriviate
nn

81
Perché dovrei imparare una nuova lingua solo perché il mio programma deve essere eseguito su una nuova piattaforma? Perché dovrei costruire i miei programmi per adattarli all'idea della CPU di quanti registri ci sono e cosa puoi farci? Cerco di risolvere i problemi, non di fare offerte dai computer.
Joachim Sauer,

8
Riepilogo dell'EDIT: si può usare un compilatore C.
Meinersbur,

4
@Simon Forse allora ho sbagliato i miei anni, ma sono sorpreso che stiamo discutendo ASM vs "un linguaggio di alto livello come C" nel 2010. In particolare la parte in cui C è l'esempio di un linguaggio di alto livello
matt b

11
@changelog: non è così che si scrive la programmazione.reddit.com.
BoltClock

Risposte:


331

ASM ha una scarsa leggibilità e non è realmente gestibile rispetto alle lingue di livello superiore.

Inoltre, ci sono molti meno sviluppatori ASM rispetto ad altre lingue più popolari, come C.

Inoltre, se si utilizza un linguaggio di livello superiore e diventano disponibili nuove istruzioni ASM (ad esempio SSE), è sufficiente aggiornare il compilatore e il vecchio codice può facilmente utilizzare le nuove istruzioni.

Cosa succede se la prossima CPU ha il doppio dei registri?

Il contrario di questa domanda sarebbe: quali funzionalità forniscono i compilatori?

Dubito che tu possa / desideri / debba ottimizzare il tuo ASM meglio di quanto gcc -O3possa.


10
gcc non è eccezionale nell'ottimizzazione, molto meglio dell'umano medio, ma ci sono molti posti in cui gli ottimizzatori non riescono a fare un buon lavoro. D'accordo con te, sebbene diversamente.
old_timer

4
@dwelch È in casi molto rari che gcc (o molti altri compilatori) non riescano a ottimizzare correttamente la compilazione C. In tali casi, tuttavia, è sempre possibile scrivere un numero limitato di procedure in ASM e collegare solo questi metodi durante la compilazione.
cortijon,

@Ben S: inizialmente ho modificato in "molti" anziché "molto" perché "molto" è usato solo per oggetti singolari. Poiché l'oggetto di "much" è plurale (sviluppatori), "many" è l'opzione corretta. Ma non modificherò di nuovo la tua risposta se "molto" è quello che vuoi.
Billy ONeal,

1
Ci sono molti casi in cui un compilatore non può ottimizzare bene, ma abbastanza spesso uno sviluppatore che è consapevole dei limiti dell'ottimizzatore può ottimizzare il suo codice C senza ricorrere all'assembly.
Qwertie,

1
FWIW nel mio lavoro quotidiano compilo il nostro prodotto con gcc -g -O0, perché essere in grado di collegare gdb ad esso su un sistema live e non impazzire a causa di variabili ottimizzate dall'esistenza, vale molto di più per il compagnia di quanto sarebbe lasciare inattivi altri 4 miliardi di cicli CPU ogni giorno (su un totale di 3 trilioni). Crunching interi non è molto spesso il collo di bottiglia.
Bernd Jendrissek,

1930

Hell®, sono un compilatore.

Ho appena scansionato migliaia di righe di codice mentre leggevi questa frase. Ho esplorato milioni di possibilità per ottimizzare una singola linea usando centinaia di diverse tecniche di ottimizzazione basate su una grande quantità di ricerche accademiche che impiegheresti anni a raggiungere. Non sentirò alcun imbarazzo, nemmeno un leggero dispiacere, quando converto un ciclo di tre righe in migliaia di istruzioni solo per renderlo più veloce. Non ho vergogna di fare grandi sforzi di ottimizzazione o di fare i trucchi più sporchi. E se non vuoi che lo faccia, forse per un giorno o due, mi comporterò e lo farò come preferisci. Posso trasformare i metodi che sto usando quando vuoi, senza nemmeno cambiare una singola riga del tuo codice. Posso anche mostrarti come apparirebbe il tuo codice nell'assembly, su architetture di processori diverse e sistemi operativi diversi e in convenzioni di assemblaggio diverse, se lo desideri. Sì, tutto in pochi secondi. Perché, sai, posso; e sai, non puoi.

PS Oh, a proposito non stavi usando la metà del codice che hai scritto. Ti ho fatto un favore e l'ho buttato via.


99

Ho scritto shedload di assemblatore per i chip 6502, Z80, 6809 e 8086. Ho smesso di farlo non appena i compilatori C sono diventati disponibili per le piattaforme a cui mi rivolgevo e sono diventato immediatamente almeno 10 volte più produttivi. La maggior parte dei bravi programmatori usano gli strumenti che usano per ragioni razionali.


72

Adoro programmare in linguaggio assembly, ma ci vuole più codice per fare la stessa cosa di una lingua di alto livello, e c'è una correlazione diretta tra linee di codice e bug. (Ciò è stato spiegato decenni fa in The Mythical Man-Month .)

È possibile pensare a C come ad un "assemblaggio di alto livello", ma fare qualche passo sopra e ci si trova in un mondo diverso. In C # non pensi due volte a scrivere questo:

foreach (string s in listOfStrings) { /* do stuff */ }

Si tratterebbe di dozzine, forse centinaia di righe di codice nell'assemblaggio, ogni programmatore che lo implementa avrebbe adottato un approccio diverso, e la prossima persona che sarebbe arrivata avrebbe dovuto capirlo. Quindi se credete (come molti fanno) che i programmi sono scritti principalmente per essere letti da altre persone, l'assemblaggio è meno leggibile rispetto al tipico HLL.

Modifica: ho accumulato una libreria personale di codice utilizzata per attività comuni e macro per l'implementazione di strutture di controllo simili a C. Ma ho colpito il muro negli anni '90, quando le GUI sono diventate la norma. Troppo tempo veniva speso per cose che erano di routine.

L'ultima attività che avevo in ASM era essenziale alcuni anni fa, scrivendo codice per combattere il malware. Nessuna interfaccia utente, quindi erano tutte le parti divertenti senza il gonfiamento.


Sei sicuro di questo? Mi sembra di aver letto in Code Complete che non era così ...
jcolebrand,

1
Sono sicuro che c'è un punto in cui il vantaggio di "meno linee" è battuto dallo svantaggio di "ottimizzazione prematura". Ma non vedo il codice completo da secoli ...
egrunin,

6
Un po 'ironico usare "l'ottimizzazione prematura" come argomento per l' assemblaggio ... (Probabilmente ti fraintendo però. Penso ancora che sia divertente.)
Bernd Jendrissek,

Puoi ancora chiamare la funzione nell'assemblatore, quindi dubito che un ciclo foreach porti dozzine a centinaia di linee. O cosa mi sto perdendo?
Sebastian Mach,

@phresnel: foreachfa molto più lavoro di for- crea un'istanza e usa un iteratore specifico del tipo.
egrunin,

15

Oltre alle risposte di altre persone di leggibilità, manutenibilità, codice più breve e quindi meno bug, ed essendo molto più semplice, aggiungerò un ulteriore motivo:

velocità del programma.

Sì, nell'assemblaggio è possibile ottimizzare manualmente il codice per utilizzare l'ultimo ciclo e renderlo il più veloce possibile dal punto di vista fisico. Tuttavia chi ha il tempo? Se scrivi un programma C non del tutto stupido, il compilatore farà un ottimo lavoro di ottimizzazione per te. Probabilmente fare almeno il 95% delle ottimizzazioni che faresti a mano, senza che tu debba preoccuparti di tenerne traccia. Esiste sicuramente una regola del 90/10 qui, in cui l'ultimo 5% di ottimizzazioni finirà per occupare il 95% del tuo tempo. Allora perché preoccuparsi?


4
+1. Scrivere codice assembler e scrivere codice assembler veloce sono due cose diverse. Se si utilizza un buon compilatore, si ottiene gratuitamente il codice assembler veloce.
Niki,

ottieni codice assemblatore veloce gratuitamente solo se sai come usare il compilatore, la maggior parte non usa l'ottimizzazione, la maggior parte delle persone compila con opzioni di debug e di conseguenza finisce con un assemblatore lento mal fatto. sì, oltre il 99% delle volte non dovresti toccarlo, basta toccare le manopole dei compilatori e non modificare direttamente l'output.
old_timer

se ti preoccupi delle ottimizzazioni, allora dovresti farlo dal compilatore ... SE non ti importa delle ottimizzazioni, ma stai ancora usando l'assemblaggio, allora sei solo sciocco.
Brian Postow,

@dwelch: Immagino che potrebbero esserci degli script-kiddie che non si preoccupano di scoprire come vengono utilizzati gli strumenti. Ma dubito che persone come loro sarebbero mai state in grado di scrivere codice assembler veloce.
Niki,

13

Se un programma di produzione medio prevede 100.000 righe di codice e ogni riga contiene circa 8-12 istruzioni per l'assemblatore, questo sarebbe 1 milione di istruzioni per l'assemblatore.

Anche se tu potessi scrivere tutto questo a mano a una velocità decente (ricorda, il suo codice 8 volte più che devi scrivere), cosa succede se vuoi cambiare alcune delle funzionalità? Comprendere qualcosa che hai scritto poche settimane fa tra quelle 1 milione di istruzioni è un incubo! Non ci sono moduli, classi, design orientato agli oggetti, framework, niente. E la quantità di codice simile che devi scrivere anche per le cose più semplici è al massimo scoraggiante.

Inoltre, non puoi ottimizzare il tuo codice quasi come una lingua di alto livello. Laddove C ad esempio esegue un numero folle di ottimizzazioni perché descrivi il tuo intento, non solo il tuo codice, nell'assemblatore scrivi solo il codice, l'assemblatore non può davvero eseguire ottimizzazioni degne di nota sul tuo codice. Ciò che scrivi è ciò che ottieni e, fidati di me, non puoi ottimizzare in modo affidabile 1 milione di istruzioni che correggi e correggi mentre le scrivi.


8

Beh, ho scritto un sacco di assemblee "ai vecchi tempi", e posso assicurarti che sono molto più produttivo quando scrivo programmi in un linguaggio di alto livello.


8
"L'Assemblea è latina".
Adriano Varoli Piazza

4
@Adriano: tranne che ci sono molti, molti dialetti diversi e nessuno dei due si assomiglia.
Joachim Sauer,

1
Certo, ma intendevo dire che imparare a programmare in ognuno di essi ti dà un'idea dell'architettura di una macchina che ti aiuta a livelli più alti. A meno che tu non abbia a che fare con la memoria paginata, in quel caso finirai sfregiato. Come leggere Carmen 16 di Catullo.
Adriano Varoli Piazza

5
@Adriano "L'Assemblea è latina", nessun asma è grugnito uomo delle caverne. Un grugnito per il rock 2grunt per i cervi, 3grunts per il fuoco - buono per cose semplici ma difficile da gestire un impero.
Martin Beckett,

1
@Martin: hai mai provato a fare aritmetiche complesse con numeri romani?
Adriano Varoli Piazza

6

Un livello ragionevole di competenza dell'assemblatore è un'abilità utile, specialmente se lavori a qualsiasi livello di sistema o programmazione integrata, non tanto perché devi scrivere così tanto assemblatore, ma perché a volte è importante capire cosa sta realmente facendo la scatola . Se non hai una conoscenza di basso livello dei concetti e dei problemi dell'assemblatore, questo può essere molto difficile.

Tuttavia, per quanto riguarda effettivamente scrivere molto codice nell'assemblatore, ci sono diversi motivi per cui non è stato fatto molto.

  • Semplicemente non c'è (quasi) bisogno. Tranne qualcosa come l'inizializzazione del sistema molto precoce e forse alcuni frammenti di assemblatore nascosti in funzioni C o macro, tutto il codice di livello molto basso che una volta potrebbe essere stato scritto in assemblatore può essere scritto in C o C ++ senza difficoltà.

  • Il codice nei linguaggi di livello superiore (anche C e C ++) condensa la funzionalità in molte meno righe e vi sono ricerche considerevoli che dimostrano che il numero di bug è correlato al numero di righe del codice sorgente. Vale a dire, lo stesso problema, risolto in assemblatore e C, avrà più bug nell'assemblatore semplicemente perché è più lungo. Lo stesso argomento motiva il passaggio a linguaggi di livello superiore come Perl, Python, ecc.

  • Scrivendo in assembler, devi affrontare ogni singolo aspetto del problema, dal layout di memoria dettagliato, dalla selezione delle istruzioni, dalla scelta dell'algoritmo, dalla gestione dello stack, ecc. I linguaggi di livello superiore ti tolgono tutto questo, motivo per cui sono così densi termini di LOC.

In sostanza, tutto quanto sopra è correlato al livello di astrazione disponibile nell'assemblatore rispetto a C o in qualche altra lingua. L'assemblatore ti costringe a fare tutte le tue astrazioni e a mantenerle attraverso la tua autodisciplina, in cui qualsiasi linguaggio di medio livello come C, e soprattutto le lingue di livello superiore, ti forniscono astrazioni fuori dalla scatola, così come il capacità di crearne di nuovi relativamente facilmente.


6

Come sviluppatore che trascorre la maggior parte del suo tempo nel mondo della programmazione integrata, direi che assembly è tutt'altro che un linguaggio morto / obsoleto. Esiste un certo livello di codifica simile al metallo (ad esempio, nei driver) che a volte non può essere espresso in modo accurato o efficiente in un linguaggio di livello superiore. Scriviamo quasi tutte le nostre routine di interfaccia hardware in assemblatore.

Detto questo, questo codice assembly è racchiuso in modo tale da poter essere chiamato dal codice C e viene trattato come una libreria. Non scriviamo l'intero programma in assembly per molte ragioni. Innanzitutto la portabilità; la nostra base di codice viene utilizzata su diversi prodotti che utilizzano architetture diverse e vogliamo massimizzare la quantità di codice che può essere condivisa tra di loro. Il secondo è la familiarità degli sviluppatori. In poche parole, le scuole non insegnano all'assemblaggio come una volta, ei nostri sviluppatori sono molto più produttivi in ​​C che nell'assemblaggio. Inoltre, abbiamo una vasta gamma di "extra" (cose come librerie, debugger, strumenti di analisi statica, ecc.) Disponibili per il nostro codice C che non sono disponibili per il codice del linguaggio assembly. Anche se volessimo scrivere un programma di assemblaggio puro, non saremmo in grado di farlo perché diverse librerie hardware critiche sono disponibili solo come librerie C. In un certo senso, è un problema pollo / uovo. Le persone vengono allontanate dall'assembly perché non ci sono tante librerie e strumenti di sviluppo / debug disponibili, ma le librerie / gli strumenti non esistono perché non ci sono abbastanza persone che usano assembly per giustificare lo sforzo di crearle.

Alla fine, c'è un tempo e un posto praticamente per qualsiasi lingua. Le persone usano ciò che hanno più familiarità e produttività. Probabilmente ci sarà sempre posto nel repertorio di un programmatore per l'assemblaggio, ma la maggior parte dei programmatori scoprirà di poter scrivere codice in un linguaggio di livello superiore che è quasi altrettanto efficiente in molto meno tempo.


6

Quando si scrive in assembly, non è necessario scrivere solo nei codici di istruzione. È possibile utilizzare macro e procedure e le proprie convenzioni per rendere varie astrazioni per rendere i programmi più modulari, più gestibili e più facili da leggere.

Quindi quello che stai sostanzialmente dicendo è che con un abile uso di un sofisticato assemblatore, puoi rendere il tuo codice ASM sempre più vicino a C (o comunque un altro linguaggio di basso livello della tua invenzione), fino a quando alla fine non sei solo produttivo come un programmatore C.

Questo risponde alla tua domanda? ;-)

Non lo dico pigramente: ho programmato usando esattamente un tale assemblatore e sistema. Ancora meglio, l'assemblatore potrebbe scegliere come target un processore virtuale e un traduttore separato ha compilato l'output dell'assemblatore per una piattaforma di destinazione. Come succede con l'IF di LLVM, ma nelle sue prime forme lo precede di circa 10 anni. Quindi c'era portabilità, oltre alla possibilità di scrivere routine per uno specifico assemblatore target dove richiesto per l'efficienza.

Scrivere usando quell'assemblatore era circa produttivo quanto C, e con il confronto con GCC-3 (che era in giro quando ero coinvolto) l'assemblatore / traduttore produceva un codice che era approssimativamente più veloce e di solito più piccolo. Le dimensioni erano davvero importanti e la compagnia aveva pochi programmatori ed era disposta a insegnare ai nuovi assunti una nuova lingua prima che potessero fare qualcosa di utile. E abbiamo avuto il backup che le persone che non conoscevano l'assemblatore (ad es. I clienti) potevano scrivere C e compilarlo per lo stesso processore virtuale, usando la stessa convenzione di chiamata e così via, in modo che si interfacciasse perfettamente. Quindi sembrava una vittoria marginale.

Ciò avvenne con molti anni di lavoro nella borsa che svilupparono la tecnologia degli assemblatori, le librerie e così via. Certo, gran parte del quale è andato nel renderlo portatile, se avesse mai preso di mira solo un'architettura, l'assemblatore che cantava tutto-canto sarebbe stato molto più facile.

In sintesi: potrebbe non piacerti C, ma ciò non significa che lo sforzo di usare C sia maggiore dello sforzo di trovare qualcosa di meglio.


5

L'assemblaggio non è portatile tra diversi microprocessori.


Questo non è esattamente vero con i moderni processori e programmi assembler, puoi indirizzare processori diversi proprio come puoi in C. Sicuramente non sarai in grado di usare l'intero set di istruzioni in questo caso, ma nemmeno se lo scrivi in C. La portabilità non è la preoccupazione principale.
Blindy,

6
Forse intendi architettura .
Ben S,

2
@Blindy - Puoi indirizzare diversi processori all'interno della famiglia x86 ma non vi è assolutamente alcuna comunanza nelle istruzioni di assemblaggio tra una variante x86 e un processore ARM o uno Z80 o un 8051.
Semaj

Vero, ma non è nemmeno possibile programmare uno z80 in c. Penso che stiamo tutti parlando dei normali processori x86 / x64 qui.
Blindy,

1
Tutto il mondo non è un x86. Nulla di "diversi microprocessori" suggerisce che tutti eseguano lo stesso set di istruzioni.
Bernd Jendrissek,

5

Lo stesso motivo per cui non andiamo più in bagno fuori, o perché non parliamo latino o aramaico.

La tecnologia arriva e rende le cose più facili e più accessibili.

EDIT - per smettere di offendere le persone, ho rimosso alcune parole.


4
Stai ancora offendendo Luddites con la parolaTechnology
SeanJA,

1
"Noi" non parliamo latino?
bagnato il

Né il latino né l'aramaico sono scomparsi perché sono stati sostituiti da una migliore tecnologia (ovvero una lingua più facile da imparare / imparare). In effetti, il latino è ancora con noi ovunque in Europa. Tutte le lingue romane sono basate sul latino. Il moderno (neo) aramaico è parlato oggi da quasi mezzo milione di persone. Le ragioni per cui queste lingue non sono più prevalenti sono storiche (geopolitiche, per essere più precisi), non tecnologiche. Lo stesso motivo per cui l'inglese è la lingua franca della scienza e delle classi dirigenti della nostra epoca: lo parlano le persone dell'ultimo impero, gli inglesi (e ora gli Stati Uniti).
il Ritz,

4

Perché? Semplice.

Confronta questo:

        for (var i = 1; i <= 100; i++)
        {
            if (i % 3 == 0)
                Console.Write("Fizz");
            if (i % 5 == 0)
                Console.Write("Buzz");
            if (i % 3 != 0 && i % 5 != 0)
                Console.Write(i);
            Console.WriteLine();
        }

con

.locals init (
    [0] int32 i)
L_0000: ldc.i4.1 
L_0001: stloc.0 
L_0002: br.s L_003b
L_0004: ldloc.0 
L_0005: ldc.i4.3 
L_0006: rem 
L_0007: brtrue.s L_0013
L_0009: ldstr "Fizz"
L_000e: call void [mscorlib]System.Console::Write(string)
L_0013: ldloc.0 
L_0014: ldc.i4.5 
L_0015: rem 
L_0016: brtrue.s L_0022
L_0018: ldstr "Buzz"
L_001d: call void [mscorlib]System.Console::Write(string)
L_0022: ldloc.0 
L_0023: ldc.i4.3 
L_0024: rem 
L_0025: brfalse.s L_0032
L_0027: ldloc.0 
L_0028: ldc.i4.5 
L_0029: rem 
L_002a: brfalse.s L_0032
L_002c: ldloc.0 
L_002d: call void [mscorlib]System.Console::Write(int32)
L_0032: call void [mscorlib]System.Console::WriteLine()
L_0037: ldloc.0 
L_0038: ldc.i4.1 
L_0039: add 
L_003a: stloc.0 
L_003b: ldloc.0 
L_003c: ldc.i4.s 100
L_003e: ble.s L_0004
L_0040: ret 

Sono identici per quanto riguarda le funzionalità. Il secondo non è nemmeno assemblatore ma .NET IL (Intermediary Language, simile al bytecode di Java). La seconda compilation trasforma l'IL in codice nativo (cioè quasi assemblatore), rendendolo ancora più criptico.


3

Immagino che ASM anche su x86 (_64) abbia senso nei casi in cui guadagni molto utilizzando istruzioni per le quali è difficile ottimizzare un compilatore. x264 ad esempio usa molto asm per la sua codifica e i guadagni di velocità sono enormi.


2

Sono sicuro che ci sono molte ragioni, ma due ragioni veloci che posso pensare sono

  1. Il codice assembly è sicuramente più difficile da leggere (sono sicuro che anche scrivere richiede più tempo)
  2. Quando hai un enorme team di sviluppatori che lavorano su un prodotto, è utile che il tuo codice sia diviso in blocchi logici e protetto da interfacce.

1
Si noti che è anche possibile separare l'assemblaggio in blocchi logici.
Paul Williams,

2

Una delle prime scoperte (la troverai nel Mythical Man-Month di Brooks , che proviene dall'esperienza negli anni '60) è stata che le persone erano più o meno produttive in una lingua come in un'altra, in righe di codice di debug al giorno. Questo ovviamente non è universalmente vero e può rompersi se spinto troppo lontano, ma era generalmente vero per le lingue di alto livello del tempo di Brooks.

Pertanto, il modo più rapido per ottenere la produttività sarebbe usare le lingue in cui una singola riga di codice ha fatto di più, e in effetti funziona, almeno per linguaggi di complessità come FORTRAN e COBOL, o per dare un esempio più moderno C.


2

La portabilità è sempre un problema - se non ora, almeno alla fine. L'industria della programmazione spende miliardi ogni anno per il porting di vecchi software che, all'epoca in cui era stato scritto, non avevano "ovviamente" alcun problema di portabilità.


2
"Non dovrà effettuare il porting su un'altra architettura" suona molto alle mie orecchie come "Non avrà bisogno di più di due cifre per l'anno".
David Thornley,

Oppure non possiamo usare C # perché Windows potrebbe non essere disponibile l'anno prossimo?
Martin Beckett,

Ad esempio i computer MacIntosh di Apple basati su processori Motorola MC68000 series, PowerPC (IBM et all) e ora i processori Intel x86 (IA-32 (e)). Quindi sì, la portabilità è un problema per qualsiasi sistema utilizzato abbastanza a lungo, e nessun programmatore che non è stato morso dal loro codice che dura più del previsto non è ancora sperimentato.
mctylr,

@Martin: Tra vent'anni, ci saranno molti programmi C # che le persone vogliono eseguire, e quindi ci sarà un modo per compilare ed eseguire programmi C #. Non c'è nulla di intrinsecamente risolto in C #, anche se tra vent'anni sarei sorpreso se fosse ancora così popolare come lo è ora. Tuttavia, tra vent'anni le nostre CPU saranno significativamente diverse. Un programma di assemblaggio scritto nel 1990 potrebbe benissimo funzionare al giorno d'oggi, ma sicuramente non sarà ottimale e funzionerà più lentamente di quanto compilato C.
David Thornley,

Questo è quello che intendevo dire: ho molti più problemi di porting perché un framework di alto livello è cambiato da 6 mesi fa rispetto a me perché le istruzioni in un x86 sono cambiate, soprattutto perché asm con codice manuale tende ad attenersi ai metodi più semplici.
Martin Beckett,

2

C'è stato un circolo vizioso quando l'assemblaggio è diventato meno comune: con la maturità delle lingue di livello superiore, i set di istruzioni in lingua dell'assemblaggio sono stati costruiti meno per comodità del programmatore e più per la comodità dei compilatori.

Quindi ora, realisticamente, può essere molto difficile prendere le giuste decisioni, per esempio, su quali registri dovresti usare o quali istruzioni siano leggermente più efficienti. I compilatori possono utilizzare l'euristica per capire quali compromessi avranno probabilmente il miglior profitto. Probabilmente possiamo pensare a piccoli problemi e trovare ottimizzazioni locali che potrebbero battere i nostri compilatori ora piuttosto sofisticati, ma le probabilità sono che, nel caso medio, un buon compilatore farà un lavoro migliore al primo tentativo di quanto un buon programmatore probabilmente farà. Alla fine, come John Henry, potremmo battere la macchina, ma potremmo seriamente bruciarci per arrivarci.

Anche i nostri problemi sono ora abbastanza diversi. Nel 1986 stavo cercando di capire come ottenere un po 'più di velocità dai piccoli programmi che comportavano l'inserimento di alcune centinaia di pixel sullo schermo; Volevo che l'animazione fosse meno a scatti. Un caso equo per il linguaggio assembly. Ora sto cercando di capire come rappresentare le astrazioni nella lingua del contratto e nella politica di assistenza per i mutui, e preferirei leggere qualcosa che sembra vicino alla lingua parlata dagli uomini d'affari. A differenza delle macro LISP, le macro di assembly non applicano molto in termini di regole, quindi anche se potresti essere in grado di ottenere qualcosa di ragionevolmente vicino a un DSL in un buon assemblatore, sarà incline a tutti i tipi di stranezze che hanno vinto ' non mi causano problemi se ho scritto lo stesso codice in Ruby, Boo, Lisp, C # o anche F #.

Se i tuoi problemi sono facili da esprimere in un linguaggio di assemblaggio efficiente, tuttavia, maggiore potenza per te.


2

Idem per gran parte di ciò che altri hanno detto.

Ai vecchi tempi prima che fosse inventata la C, quando le uniche lingue di alto livello erano cose come COBOL e FORTRAN, c'erano molte cose che non era possibile fare a meno di ricorrere all'assemblatore. Era l'unico modo per ottenere la massima ampiezza di flessibilità, poter accedere a tutti i dispositivi, ecc. Ma poi fu inventata la C e quasi tutto ciò che era possibile in assembly era possibile in C. Ho scritto pochissimo assembly da allora poi.

Detto questo, penso che sia un esercizio molto utile per i nuovi programmatori imparare a scrivere in assembler. Non perché lo userebbero molto, ma perché capisci cosa sta realmente accadendo all'interno del computer. Ho visto molti errori di programmazione e codice inefficiente da parte di programmatori che chiaramente non hanno idea di cosa stia realmente accadendo con bit, byte e registri.


Sì, esatto. Gli I / O su disco e nastro di Fortran su mainframe IBM anni fa erano quasi inutili, quindi abbiamo scritto le nostre routine di I / O in 370 / Assembler e le abbiamo chiamate dal codice Fortan IV. E scrivere il codice assembly mi ha fatto davvero capire l'architettura sottostante. Non scrivo nessun codice di assemblaggio da parecchi anni e tutti i giovani con cui lavoro non ne hanno mai scritto uno, ma vorrei che lo facessero, è così educativo.
Simon Knights,

2

Sto programmando in assembly da circa un mese. Scrivo spesso un pezzo di codice in C e poi lo compilo in assembly per aiutarmi. Forse non sto utilizzando tutta la potenza di ottimizzazione del compilatore C, ma sembra che la mia fonte C asm includa operazioni non necessarie. Quindi sto cominciando a vedere che il parlare di un buon compilatore C che supera un buon programmatore di assembly non è sempre vero.

Comunque, i miei programmi di assemblaggio sono così veloci. E più uso assembly, meno tempo mi serve per scrivere il mio codice perché non è poi così difficile. Anche il commento sull'assemblaggio con scarsa leggibilità non è vero. Se si etichettano correttamente i programmi e si commentano quando sono necessarie ulteriori elaborazioni, è necessario impostare tutto. In effetti, in un certo senso l'assemblaggio è più chiaro per il programmatore perché sta vedendo cosa sta succedendo a livello del processore. Non conosco altri programmatori, ma per me mi piace sapere cosa sta succedendo, piuttosto che le cose in una sorta di scatola nera.

Detto questo, il vero vantaggio dei compilatori è che un compilatore può comprendere schemi e relazioni e quindi codificarli automaticamente nelle posizioni appropriate nell'origine. Un esempio popolare sono le funzioni virtuali in C ++ che richiedono al compilatore di mappare in modo ottimale i puntatori a funzione. Tuttavia, un compilatore si limita a fare ciò che il creatore del compilatore consente al compilatore di fare. Questo porta i programmatori a volte a dover ricorrere a cose bizzarre con il loro codice, aggiungendo tempo di programmazione, quando avrebbero potuto fare banalmente con assembly.

Personalmente penso che il mercato supporti fortemente le lingue di alto livello. Se il linguaggio assembly fosse l'unica lingua esistente oggi, il loro sarebbe circa il 70% in meno di persone che programmano e chissà dove sarebbe il nostro mondo, probabilmente negli anni '90. Le lingue di livello superiore attirano un numero più ampio di persone. Ciò consente a una maggiore offerta di programmatori di costruire l'infrastruttura necessaria del nostro mondo. Le nazioni in via di sviluppo come la Cina e l'India beneficiano fortemente di lingue come Java. Questi paesi svilupperanno rapidamente la loro infrastruttura IT e le persone diventeranno più interconnesse. Quindi il mio punto è che le lingue di alto livello sono popolari non perché producono codice superiore ma perché aiutano a soddisfare la domanda sui mercati mondiali.


+1 per la scatola nera. Sì, stiamo usando scatole nere e non c'è modo di sbirciarle (troppo facile). Come funziona davvero C # foreach ? Chissà. Microsoft ha detto, è perfetto. Quindi deve essere.
Ern0

Inoltre, non dimenticare che con un "linguaggio di alto livello" arrivano molte altre cose che contano nel mondo reale. C viene fornito con le librerie standard (matematica, elaborazione di stringhe, I / O ecc.), Quindi i pesi pesanti come Java vengono forniti con un sacco di altri pacchetti e librerie per connettività, elaborazione delle immagini, elaborazione dei dati, sviluppo web ecc. È una domanda di usare il tuo tempo per concentrarti sull'ottenere 1 attività dettagliata altamente performante su una piattaforma (usando quindi assembly) invece di passare lo stesso tempo a eseguire un'attività molto più grande in esecuzione su più piattaforme con bug minimi.
jbx,

1

Sto imparando assembly in comp org in questo momento, e mentre è interessante, è anche molto inefficiente scrivere. Devi tenere molti più dettagli nella tua testa per far funzionare le cose, ed è anche più lento scrivere le stesse cose . Ad esempio, una semplice 6 righe per loop in C ++ può equivalere a 18 righe o più di assembly.

Personalmente, è molto divertente apprendere come funzionano le cose a livello hardware e mi dà maggiore apprezzamento per il funzionamento dell'elaborazione.


1

Ciò che C ha su un buon assemblatore di macro è il linguaggio C. Controllo del tipo. Costrutti Loop. Gestione automatica dello stack. Gestione (quasi) automatica delle variabili. Le tecniche di memoria dinamica nell'assemblatore sono un forte dolore al sedere. Fare una lista collegata correttamente è proprio spaventoso rispetto a C o meglio ancora elencare foo.insert (). E debug - beh, non c'è contestazione su cosa sia più facile eseguire il debug. Le HLL vincono le mani laggiù.

Ho codificato quasi metà della mia carriera in assemblatore, il che mi rende molto facile pensare in Assmebler. mi aiuta a vedere cosa sta facendo il compilatore C che mi aiuta di nuovo a scrivere codice che il compilatore C può gestire in modo efficiente. Una routine ben ponderata scritta in C può essere scritta per produrre esattamente quello che vuoi in assemblatore con un po 'di lavoro - ed è portatile! Ho già dovuto riscrivere alcune routine asm più vecchie su C per motivi multipiattaforma e non è divertente.

No, rimarrò con C e affronterò il leggero rallentamento occasionale delle prestazioni rispetto al tempo di produttività che guadagno con HLL.


1

Posso solo rispondere al motivo per cui personalmente non scrivo programmi in assembly più spesso e la ragione principale è che è più noioso da fare. Inoltre, penso che sia più facile sbagliare sottilmente senza accorgersene immediatamente. Ad esempio, potresti cambiare il modo in cui usi un registro in una routine ma dimentica di cambiarlo in un posto. Si monterà bene e potresti non accorgertene molto più tardi.

Detto questo, penso che ci siano ancora usi validi per il montaggio. Ad esempio, ho una serie di routine di assemblaggio piuttosto ottimizzate per l'elaborazione di grandi quantità di dati, usando SIMD e seguendo l'approccio paranoico "ogni bit è sacro" [quote V.Stob]. (Ma nota che le implementazioni di assembly ingenui sono spesso molto peggio di ciò che un compilatore genererebbe per te.)


1

C è un assemblatore di macro! Ed è il migliore!

Può fare quasi tutto ciò che può fare assembly, può essere portatile e nella maggior parte dei rari casi in cui non può fare qualcosa è ancora possibile utilizzare il codice assembly incorporato. Questo lascia solo una piccola parte dei programmi che è assolutamente necessario scrivere in assembly e nient'altro che assembly.

E le astrazioni di livello superiore e la portabilità rendono più utile per la maggior parte delle persone scrivere software di sistema in C. E anche se potresti non aver bisogno della portabilità ora se investi molto tempo e denaro per scrivere un programma, potresti non voler limitarti in quello che sarai in grado di usarlo per il futuro.


1

Le persone sembrano dimenticare che c'è anche l'altra direzione.

Perché stai scrivendo in Assembler in primo luogo? Perché non scrivere il programma in una lingua di livello veramente basso?

Invece di

mov eax, 0x123
add eax, 0x456
push eax
call printInt

potresti anche scrivere

B823010000
0556040000
50 
FF15.....

Questo ha tanti vantaggi, conosci la dimensione esatta del tuo programma, puoi riutilizzare il valore delle istruzioni come input per altre istruzioni e non hai nemmeno bisogno di un assemblatore per scriverlo, puoi usare qualsiasi editor di testo ...

E la ragione per cui preferisci ancora Assembler a riguardo, è la ragione per cui altre persone preferiscono C ...


0

Perché è sempre così: il tempo passa e anche le cose buone passano :(

Ma quando scrivi codice asm è totalmente diverso rispetto a quando codifichi lang di alto livello, anche se sai che è molto meno produttivo. È come se fossi un pittore: sei libero di disegnare tutto ciò che ti piace come preferisci senza alcuna limitazione (beh, solo con le funzionalità della CPU) ... Ecco perché lo adoro. È un peccato che questa lingua scompaia. Ma mentre qualcuno lo ricorda ancora e lo codifica, non morirà mai!


Vero. D'altra parte, c'è l'umiliazione che provi quando la cassiera e il supermercato si rifiutano di incassare il tuo assegno, dicendo sdegnosamente: "Oh, programmi in una lingua a LIVELLO BASSO".
Jay,

0

$$$

Una società assume uno sviluppatore per aiutare a trasformare il codice in $$$. Il più veloce che utile può essere prodotto codice , più velocemente la società può trasformare quel codice in $$$.

Le lingue di livello più elevato sono generalmente più adatte a sfornare grandi volumi di codice utile. Questo non vuol dire che l'assemblea non ha il suo posto, perché ci sono tempi e luoghi in cui nient'altro farà.


0

Il vantaggio di HLL è ancora maggiore quando si confronta assembly con un linguaggio di livello superiore rispetto a C, ad esempio Java o Python o Ruby. Ad esempio, queste lingue hanno la garbage collection: non c'è bisogno di preoccuparsi di quando liberare un pezzo di memoria e nessuna perdita di memoria o bug a causa della liberazione troppo presto.


0

Come altri hanno già detto, la ragione per cui esiste uno strumento è quanto possa funzionare in modo efficiente. Dato che gli HLL possono svolgere gli stessi lavori di molte righe di codice asm, credo sia naturale che l'assemblaggio sia sostituito da altre lingue. E per il giocherellare vicino all'hardware - c'è un assemblaggio in linea in C e altre varianti secondo la lingua. Il Dr. Paul Carter dice nel PC Assembly Language

"... una migliore comprensione di come i computer funzionano davvero a un livello inferiore rispetto ai linguaggi di programmazione come Pascal. Acquisendo una conoscenza più approfondita di come funzionano i computer, il lettore può spesso essere molto più produttivo nello sviluppo di software in linguaggi di livello superiore come C e C ++. Imparare a programmare in linguaggio assembly è un modo eccellente per raggiungere questo obiettivo. "

Abbiamo un'introduzione all'assemblea nei miei corsi universitari. Aiuterà a chiarire i concetti. Tuttavia dubito che qualcuno di noi scriverebbe il 90% del codice in assembly. Quanto è rilevante la conoscenza approfondita dell'assemblea oggi?


-2

Sfogliando queste risposte, scommetterei che 9/10 dei rispondenti non hanno mai lavorato con il montaggio.

Questa è una domanda secolare che si presenta ogni tanto e si ottengono le stesse risposte, per lo più disinformate. Se non fosse per la portabilità, farei comunque tutto da solo. Anche allora, codice in C quasi come facevo in assembly.


1
+1 che menziona persone senza alcuna esperienza di asm e un altro +1 per "codificare in C come asm". Quando scrivo app C ++ (sì, CPP, non C) per embedded, sto programmando come se fosse asm, ad esempio non usando affatto new / malloc ().
Ern0

Quindi usi molte cose come char buf [MAX_PATH] che poi cade quando qualcuno ha dati di dimensione MAX_PATH + n? ;)
paulm

1
@paulm - Intendi proprio come fa C?
Rob,

1
Spero davvero che gli autori degli assemblatori non evitino l'uso di malloc (). Sì, su embedded sei limitato dalla memoria. Ma fallo su Unix o su un altro desktop (o anche sulla maggior parte dei sistemi operativi mobili) e stai semplicemente limitando inutilmente te stesso e i tuoi utenti. Inoltre: meno LOC si scrive, minori sono le possibilità di errore, il che significa che il codice di livello superiore avrà probabilmente meno errori rispetto a quelli inferiori.
uliwitness,

1
Sembravo solo perché ero sospettoso e, sì, sono sicuro che i rossori e gli HNer siano qui.
Rob,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.