In che modo l'apprendimento dell'assemblea aiuta nella programmazione? [chiuso]


132

Sto programmando in linguaggi di livello superiore (Python, C #, VBA, VB.NET) da circa 10 anni e ho una comprensione completamente zero su ciò che sta accadendo, "sotto il cofano".

Mi chiedo quali sono i vantaggi dell'apprendimento dell'assemblea e come mi aiuterà come programmatore? Potete per favore fornirmi una risorsa che mi mostrerà esattamente la connessione tra ciò che scrivo nel codice di livello superiore e ciò che accade nell'assembly?


2
Se vuoi davvero sapere cosa c'è nel tuo codice, dai un'occhiata al manuale del processore Intel (solo la parte introduttiva): download.intel.com/products/processor/manual/325462.pdf . Forse è un po 'più profondo di quello che volevi, ma lo trovo utile.
superM

4
Se vuoi sapere cosa succede sotto il cofano in modo specifico in .Net, potresti voler saperne di più su CIL. È simile all'assemblaggio in qualche modo, ma molto più alto livello. Per questo motivo, è più facile da capire rispetto all'assemblaggio reale.
svick,

6
Se impari l'assemblaggio, puoi evitare di pensare di ottimizzare un forciclo dichiarando le variabili al di fuori di esso. esempio
StriplingWarrior il

7
Dio mio. Mi hai appena ricordato della lezione di lingue dell'Assemblea che ho tenuto al college circa 1 anno fa. È incredibile vedere come le cose estremamente semplici che diamo per scontate siano tradotte in centinaia o addirittura migliaia di operazioni più piccole e di più basso livello. I computer sono macchine straordinarie.
Radu Murzea,

14
L'apprendimento dell'assemblea ti conferirà un amore profondo e costante per il concetto di linguaggio di programmazione che ti protegge da MAI dover scrivere di nuovo codice complesso in assembly.
Shadur,

Risposte:


188

Perché capirai come funziona davvero .

  • Capirai che le chiamate di funzione non sono gratuite e perché lo stack di chiamate può traboccare (ad esempio, nelle funzioni ricorsive). Capirai come vengono passati gli argomenti ai parametri delle funzioni e i modi in cui può essere eseguita (copia della memoria, puntamento alla memoria).
  • Capirai che la memoria non è gratuita e quanto sia preziosa la gestione automatica della memoria. La memoria non è qualcosa che "hai appena", in realtà deve essere gestita, curata e, soprattutto, non dimenticata (perché è necessario liberarla da soli).
  • Capirai come funziona il flusso di controllo a un livello fondamentale.
  • Apprezzerai di più i costrutti nei linguaggi di programmazione di livello superiore.

Ciò che si riduce è che tutte le cose che scriviamo in C # o Python devono essere tradotte in una sequenza di azioni di base che un computer può eseguire. È facile pensare a un computer in termini di classi, generici e comprensione delle liste, ma questi esistono solo nei nostri linguaggi di programmazione di alto livello.

Possiamo pensare a costrutti linguistici che sembrano davvero belli ma che non si traducono molto bene in un modo di fare cose di basso livello. Sapendo come funziona davvero, capirai meglio perché le cose funzionano nel modo in cui funzionano.


12
+1 per "Apprezzerai di più i costrutti nei linguaggi di programmazione di livello superiore". Bella risposta.
DevSolo,

42
Tranne che dopo alcune settimane di asm, inizierai a pensare a C come un linguaggio di programmazione di alto livello. A meno che tu non stia parlando con sviluppatori di dispositivi embedded di basso livello, dire che ad alta voce farà pensare che sei un po 'pazzo.
Dan Neely,

19
@Dan: È abbastanza divertente come questi termini cambino nel tempo. 20 anni fa, quando stavo iniziando a programmare, se avessi chiesto a qualcuno che avrebbero detto "Certo che C è un linguaggio di alto livello!" Questo dovrebbe essere ovvio; fornisce un heap standardizzato e un modello di accesso alla memoria. E questa è una seria astrazione dall'hardware; in un linguaggio di basso livello, devi tenere traccia di tutti gli indirizzi di memoria da solo, o se stai facendo qualcosa di veramente fantastico, scrivi il tuo allocatore di heap! Quindi mi chiedo, quali sono i criteri che rendono qualcosa di alto o basso livello oggi?
Mason Wheeler,

9
Il livello alto / basso non è binario. Un programmatore a tutto tondo che ha scritto sia assembly che Python nella sua carriera potrebbe considerare C o C ++ un linguaggio di medio livello.
Russell Borogove,

6
Queste sono cose importanti da capire, ma sono facilmente coperte ad un livello astratto: ad esempio, in un corso introduttivo sui computer a livello di istruzioni della macchina. Non sono un programmatore di assemblaggio ma li capisco bene, se lo dico io. In alcune risposte SO vedo la discussione di istruzioni cache e pipeline, e quelle effettivamente fanno girare la testa; ma questo livello di istruzione secondaria manca (finora) dalle risposte. Quindi, qual è il vantaggio di apprendere realmente la programmazione degli assiemi, invece di seguire un corso di base?
alexis

33

Vi fornirà una migliore comprensione di ciò che sta "accadendo sotto copertura" e di come funzionano i puntatori e il significato delle variabili e dell'architettura dei registri (allocazione e gestione della memoria, passaggio dei parametri (per valore / per riferimento), ecc.) In generale.

Per una rapida occhiata con C come va?

#include <stdio.h>

main()
{
  puts("Hello World.");
  return(0);
}

compilare gcc -S so.ce dare un'occhiata all'output dell'assembly in so.s:

 $ cat so.s

    .file   "so.c"
    .section    .rodata
.LC0:
    .string "Hello World."
    .text
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $16, %esp
    movl    $.LC0, (%esp)
    call    puts
    movl    $0, %eax
    leave
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

2
+1: buon consiglio! Puoi imparare molto osservando cosa fa il compilatore C.
Giorgio,

8
... Il SOS era intenzionale? (chiamare aiuto, ecc.)
Izkata,

1
@Izkata ah ah .. buono, non me ne sono nemmeno accorto. Ho un so.cfile standard per domande su StackOverflow (come ho fatto io so.py, so.awkecc.) Per testare rapidamente le cose. So.S .. :)
Levon,

9
Se si compila con gcc -O -c -g -Wa,-ahl=so.s so.cè possibile vedere l'output dell'assembly per ogni riga di codice C. Questo rende un po 'più facile capire cosa sta succedendo.
Mackie Messer,

1
Sì, l'output è lungo. È possibile cercare per 5:so.ctrovare il codice per la riga 5 di so.c.
Mackie Messer,

30

Penso che la risposta che cerchi sia qui: http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language

Una citazione dall'articolo:

Sebbene sia vero, probabilmente non ti ritroverai a scrivere l'app del tuo prossimo cliente nell'assemblaggio, c'è ancora molto da guadagnare dall'apprendimento dell'assemblaggio. Oggi, il linguaggio assembly viene utilizzato principalmente per la manipolazione diretta dell'hardware, l'accesso a istruzioni specializzate per i processori o per risolvere problemi di prestazioni critiche. Gli usi tipici sono driver di dispositivo, sistemi embedded di basso livello e sistemi in tempo reale.

Il fatto è che più linguaggi di alto livello diventano complessi e più ADT (tipi di dati astratti) vengono scritti, maggiore sarà il sovraccarico per supportare queste opzioni. Nelle istanze di .NET, forse MSIL gonfio. Immagina se conoscessi MSIL. Qui è dove brilla il linguaggio assembly.

Il linguaggio assembly è il più vicino possibile al processore come un programmatore, quindi un algoritmo ben progettato è ardente: l'assemblaggio è ottimo per l'ottimizzazione della velocità. Si tratta di prestazioni ed efficienza. Il linguaggio assembly consente di avere il controllo completo sulle risorse del sistema. Proprio come una catena di montaggio, si scrive codice per inserire singoli valori nei registri, gestire direttamente gli indirizzi di memoria per recuperare valori o puntatori.

Scrivere in assembly significa capire esattamente come il processore e la memoria lavorano insieme per "far accadere le cose". Attenzione, il linguaggio assembly è criptico e la dimensione del codice sorgente delle applicazioni è molto più grande di quella di un linguaggio di alto livello. Ma non commettere errori al riguardo, se sei disposto a dedicare tempo e sforzi per padroneggiare l'assemblaggio, migliorerai e diventerai uno spicco nel campo.

Inoltre, consiglierei questo libro perché ha una versione semplificata dell'architettura del computer: Introduzione ai sistemi informatici: da Bits and Gates a C and Beyond, 2 / e Yale N. Patt, Università del Texas ad Austin Sanjay J. Patel, Università dell'Illinois a Urbana / Champaign


7
Questo ha descritto a cosa serve l'ASM e menziona che gli HLL sono gonfiati, ma l'unico vantaggio specifico dato dall'apprendimento dell'ASM è scrivere codice superveloce. Sì, ma anche se impari ASM, quanto è probabile che tu lo incorpori effettivamente nelle app? Supponendo di scrivere app aziendali, non controller hardware o driver di dispositivo.

+1 @notkilroy, grazie per il link e in particolare per la raccomandazione del libro
Anthony

2
@Jon, davvero non vedo perché lo faresti se stai sviluppando un software aziendale. Una cosa è se sei un DBA, o stai scrivendo un compilatore o hai uno spazio di memoria limitato, ma non credo che molte persone lo tocchino frequentemente. L'ottimizzazione è principalmente curata dal compilatore, che è la ragione principale per scrivere in assembly. A volte aiuta a rintracciare le perdite di memoria.
Brynne,

Poiché sono specializzato nello sviluppo di applicazioni aziendali, mi affido principalmente a strumenti di sviluppo di app basati su SQL che utilizzano un 4GL. Mi permettono di prototipare rapidamente un'app e personalizzarla in un sistema di produzione. Raramente ho bisogno di scrivere un cfunc richiamabile. Il tempo di consegna e il tempo di modifica sono grandi fattori nel mio mondo!
Frank R.

2
Non sono affatto d'accordo. Un ottimizzatore automatizzato può spesso battere un programmatore umano nella creazione di un assemblaggio rapido.
DeadMG

22

Secondo la mia modesta opinione, non aiuta molto.

Conoscevo molto bene l'assemblaggio x86. Mi ha aiutato un po 'quando si è svolto il montaggio nei miei corsi, si è presentato una volta durante un'intervista e mi ha aiutato a dimostrare che un compilatore (Metrowerks) stava generando un codice errato. È affascinante il modo in cui il computer funziona davvero e mi sento intellettualmente più ricco per averlo imparato. È stato anche molto divertente con cui giocare in quel momento.

Tuttavia, i compilatori di oggi sono più bravi a generare assembly rispetto a quasi tutti su qualsiasi codice. A meno che tu non stia scrivendo un compilatore o controllando che il compilatore stia facendo la cosa giusta, probabilmente stai perdendo tempo imparandolo.

Ammetto che molte domande che i programmatori C ++ ancora fanno utilmente vengono informate conoscendo assembly. Ad esempio: dovrei usare le variabili stack o heap? dovrei passare per valore o per riferimento const? In quasi tutti i casi, tuttavia, penso che queste scelte debbano essere fatte in base alla leggibilità del codice piuttosto che al risparmio di tempo di calcolo. (Ad esempio, utilizzare le variabili dello stack ogni volta che si desidera limitare una variabile a un ambito.)

Il mio modesto suggerimento è quello di concentrarmi sulle competenze che contano davvero: progettazione del software, analisi degli algoritmi e risoluzione dei problemi. Con l'esperienza nello sviluppo di grandi progetti, la tua intuizione migliorerà, il che aumenta il tuo valore molto più che conoscere l'assemblaggio (secondo me).


2
Non sono d'accordo Se hai una conoscenza approfondita di un certo algoritmo e una buona conoscenza dell'hardware, di solito è possibile creare un codice assembly che è meglio ottimizzato di quello che il compilatore può creare dal momento che deve giocare in sicurezza. Sapere approssimativamente come il tuo codice viene tradotto in assembly aiuta anche quando si eseguono ottimizzazioni.
Leo,

L'ottimizzazione non è la ragione per impararla. Sotto questo aspetto, concordo con Neil G. Tuttavia, Neil G non ha capito il punto; Sta sottovalutando il modo in cui la sua comprensione di fondo della macchina reale informa su come usa il linguaggio di alto livello.
Warren P

Nella mia esperienza, un algoritmo viene reso veloce implementandolo, misurando le cose, trovando modi per ottimizzarlo, implementando un modo migliore, ecc. Ecc. Ecc. Il problema con assembly è che ci vogliono anni per implementarlo, quindi non lo farai avere l'opportunità di raffinatezze ripetute.
gnasher729,

Al giorno d'oggi ci sono pochissimi casi da codificare in assembly, ma sapere come funziona è semplicemente prezioso e aiuterà molto per coloro che vogliono sapere come funziona tutto. Ad esempio, trovo difficile seguire le cose quando non so perché accada.
Winger Sendon,

21

Dovresti avere familiarità con un livello "più profondo" nel sistema su cui stai lavorando. Saltare troppo in basso in una volta sola non è male, ma potrebbe non essere utile come si vorrebbe.

Un programmatore in una lingua di alto livello dovrebbe imparare una lingua di livello inferiore (C è un'opzione eccellente). Non è necessario andare fino in fondo all'assemblaggio per apprezzare ciò che accade sotto le copertine quando si dice al computer di creare un'istanza di un oggetto o creare una tabella di hash o un set, ma si dovrebbe essere in grado di codificare loro.

Per un programmatore Java, imparare un po 'di C ti aiuterebbe con la gestione della memoria, passando argomenti. Scrivere alcune delle vaste librerie Java in C sarebbe un modo per capire quando usare quale implementazione di Set (vuoi un hash? O un albero?). Trattare con char * in un ambiente thread aiuta a capire perché String è immutabile.

Passato al livello successivo ... Il programmatore AC dovrebbe avere una certa familiarità con l'assemblaggio, e i tipi di assemblaggio (spesso trovati nei negozi di sistemi embedded) probabilmente farebbero bene a comprendere le cose a livello di gate. Chi lavora con le porte dovrebbe conoscere un po 'di fisica quantistica. E quei fisici quantistici, beh, stanno ancora cercando di capire quale sarà la prossima astrazione.


1
Un livello più profondo è giusto. Tendo a cercare una coppia, ma supponendo che la conoscenza dell'assemblaggio x86 valga l'investimento rispetto allo studio MSIL per un programmatore C # chiede troppo. Come qualcuno che ha studiato assemblaggio e fisica dello stato solido in uni, non credo che conoscere la fisica del gate design mi abbia aiutato, oltre a laurearmi in elettronica.
Muhammad Alkarouri,

@MuhammadAlkarouri Stavo pensando in base alla comprensione delle perdite correnti, della durata delle corse, della resistenza e dell'impatto del calore sul sistema. La comprensione del "perché" sottostante aiuta a prendere decisioni più che regole di separazione minima delle tracce e tolleranze operative.

5

Dal momento che non hai menzionato C o C ++ nelle lingue che conosci nell'elenco. Consiglio vivamente di impararli bene prima ancora di pensare al montaggio. C o C ++ forniranno tutti i concetti di base che sono totalmente trasparenti nelle lingue gestite e capirai la maggior parte dei concetti menzionati in questa pagina con una delle lingue più importanti che potresti usare nei progetti del mondo reale. È un vero valore aggiunto per le tue capacità di programmazione. Si prega di essere consapevoli del fatto che l'assemblaggio viene utilizzato in aree molto specifiche e non è così utile come C o C ++.

Vorrei anche andare oltre per dire che non dovresti immergerti nell'assemblea prima di capire come funzionano le lingue non gestite. È quasi una lettura obbligatoria.

Dovresti imparare l'assemblea se vuoi andare ancora più in basso. Volete sapere come viene creato esattamente ogni costrutto del linguaggio. È informativo ma ha una complessità di livello molto diversa.


5

Se conosci bene una lingua, dovresti avere almeno una conoscenza di base della tecnologia a un livello di astrazione inferiore.

Perché? Quando le cose vanno male, la conoscenza della meccanica di base rende molto più semplice il debug di strani problemi e, naturalmente, la scrittura di codice più efficiente

Usando Python (/ CPython) come esempio, se inizi a ottenere strani arresti anomali o prestazioni scadenti, la conoscenza di come eseguire il debug del codice C può essere molto utile, così come la conoscenza del metodo di gestione della memoria del conteggio dei ref. Questo ti aiuterebbe anche a sapere quando / se scrivere qualcosa come un'estensione C, e così via ...

Per rispondere alla tua domanda in questo caso, la conoscenza dell'assembly non aiuterebbe davvero uno sviluppatore Python con esperienza (ci sono troppi passi in avanti nell'astrazione - qualsiasi cosa fatta in Python comporterebbe molte istruzioni per l'assemblaggio)

..ma se hai esperienza con C, sarebbe davvero utile conoscere "il livello successivo" (assembly).

Allo stesso modo, se stai usando CoffeScript, allora è (molto) utile conoscere Javascript. Se si utilizza Clojure, è utile conoscere Java / JVM.

Questa idea funziona anche al di fuori dei linguaggi di programmazione: se si utilizza Assembly, è consigliabile avere familiarità con il funzionamento dell'hardware sottostante. Se sei un web designer, è una buona idea sapere come viene implementata l'applicazione web. Se sei un meccanico di auto, è una buona idea avere qualche conoscenza di fisica


3

Scrivi un piccolo programma c e disassembla l'output. È tutto. Tuttavia, prepararsi per un livello maggiore o minore di "codice di pulizia" che viene aggiunto a vantaggio del sistema operativo.

Assembly ti aiuta a capire cosa succede sotto il cofano perché si occupa direttamente di memoria, registri del processore e simili.

Se vuoi davvero diventare bare metal senza tutta la complessità di un sistema operativo che complica le cose, prova a programmare un Arduino in linguaggio assembly.


3

Non esiste una risposta definitiva, poiché i programmatori non sono tutti di un tipo. AVETE BISOGNO di sapere cosa si nasconde sotto? Se è così, allora imparalo. vuoi semplicemente impararlo, per curiosità? Se è così, allora imparalo. Se non avrà alcun vantaggio pratico per te, allora perché preoccuparsi? È necessario il livello di conoscenza di un meccanico solo per guidare un'auto? Un meccanico ha bisogno del livello di conoscenza di un ingegnere, solo per lavorare su un'auto? Questa è una grave analogia. Un meccanico può essere un meccanico molto buono e produttivo senza immersioni per capire a fondo l'ingegnere dei veicoli che mantiene. Lo stesso vale per la musica. Vuoi davvero scandagliare le complessità della melodia, dell'armonia e del ritmo per essere un buon cantante o musicista? No. Alcuni musicisti di eccezionale talento non riescono a leggere una leccata di spartiti, per non parlare della differenza tra le modalità Dorian e Lydian. Se vuoi, bene, ma no, non è necessario. Se sei uno sviluppatore web, il montaggio non ha alcun uso pratico a cui possa pensare. Se ti trovi in ​​sistemi embedded o in qualcosa di veramente speciale, potrebbe essere necessario, ma se lo fosse, lo sapresti.

Ecco l'idea di Joel su questo valore di inclinazione di un linguaggio non di alto livello: http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html


2

In realtà, ciò che probabilmente sarebbe meglio per te sarebbe una classe che (per quanto ne so) non esiste da nessuna parte: sarebbe una classe che combina una breve panoramica del linguaggio macchina / assemblatore e dei concetti di indirizzamento dello storage con un tour attraverso la costruzione di compilatori , generazione di codice e ambienti di runtime.

Il problema è che con un linguaggio di alto livello, lontano dall'hardware come C # o Python, non apprezzi davvero il fatto che ogni mossa che fai si trasforma in centinaia se non migliaia di istruzioni della macchina, e tu non tendono a comprendere come poche righe di un linguaggio di alto livello possano far accedere e modificare grandi quantità di spazio di archiviazione. Non è tanto che devi sapere esattamente cosa sta succedendo "sotto le coperte", ma devi avere un apprezzamento per la portata di ciò che sta accadendo e una concezione generale dei tipi di cose che accadono.


1

La mia risposta a questa domanda si è evoluta relativamente di recente. Le risposte esistenti riguardano ciò che avrei detto in passato. In realtà, questo è ancora coperto dalla risposta migliore : il punto "apprezzare i costrutti nella programmazione di livello superiore", ma è un caso speciale che penso valga la pena menzionare ...

Secondo questo post sul blog di Jeff Atwood , che fa riferimento a uno studio, la comprensione del compito è una questione chiave nella comprensione della programmazione. I programmatori del discente o capiscono che la notazione rappresenta solo i passaggi che il computer segue, e le ragioni dei passaggi, oppure viene continuamente confusa da analogie fuorvianti con equazioni matematiche ecc.

Bene, se capisci quanto segue dall'assemblatore 6502 ...

LDA variable
CLC
ADC #1
STA variable

Questo è davvero solo i passaggi. Quindi quando impari a tradurlo in un'istruzione di assegnazione ...

variable = variable + 1;

Non hai bisogno di un'analogia fuorviante con un'equazione matematica - hai già un modello mentale corretto su cui mapparla.

MODIFICA - ovviamente se la spiegazione che ottieni LDA variableè fondamentalmente ACCUMULATOR = variable, che è esattamente ciò che ottieni da alcuni tutorial e riferimenti, finirai indietro da dove hai iniziato e non è affatto di aiuto.

Ho imparato 6502 assemblatore come seconda lingua, il primo era Commodore Basic, e all'epoca non avevo imparato molto di questo - in parte perché c'era così poco da imparare, ma anche perché allora l'assemblatore sembrava molto più interessante . In parte i tempi, in parte perché ero un secchione di 14 anni.

Non raccomando di fare quello che ho fatto, ma mi chiedo se studiare alcuni esempi molto semplici in un linguaggio assemblatore molto semplice possa essere un utile preliminare all'apprendimento di lingue di livello superiore.


0

A meno che tu non sia uno scrittore di compilatori o non necessiti di qualcosa di altamente ottimizzato (come l'algoritmo di elaborazione dei dati), l'apprendimento della codifica degli assembly non ti darà alcun vantaggio.

Scrivere e mantenere il codice scritto in assembly è molto difficile, quindi anche se conosci molto bene il linguaggio assembler, non dovresti usarlo, a meno che non ci siano altri modi.

L'articolo " Ottimizzazione per SSE: un caso di studio " mostra cosa è possibile fare se si va all'assemblaggio. L'autore è riuscito a ottimizzare l'algoritmo da 100 cicli / vettore a 17 cicli / vettore.


1
L'autore non ha usato alcuna istruzione vettoriale o intrinseca nella versione C ++. Non è necessario l'assemblatore per scrivere il codice SSE.
gnasher729,

@ gnasher729 Sì, non è necessario. Ma con assembly, il programma può essere eseguito molto più velocemente. Dopo tutto, un essere umano può essere più intelligente del compilatore (in rari casi).
BЈовић,

0

Scrivere in assembly non ti darebbe un magico aumento di velocità poiché a causa della quantità di dettagli (allocazione dei registri ecc.) Probabilmente scriverai l'algoritmo più banale di sempre.

Inoltre, con i moderni processori (letti dopo gli anni 70-80), l'assemblaggio dei processori non fornirà un numero sufficiente di dettagli per sapere cosa sta succedendo (vale a dire - sulla maggior parte dei processori). Le moderne PU (CPU e GPU) sono piuttosto complesse per quanto riguarda le istruzioni di pianificazione. Conoscere le basi dell'assemblaggio (o pseudoassemblaggio) consentirà di comprendere libri / corsi di architettura informatica che fornirebbero ulteriori conoscenze (cache, esecuzione fuori ordine, MMU ecc.). Di solito non è necessario conoscere ISA complessi per capirli (MIPS 5 è piuttosto popolare IIRC).

Perché capire il processore? Potrebbe darti molta più comprensione di ciò che sta succedendo. Diciamo che scrivi la moltiplicazione della matrice in modo ingenuo:

for i from 0 to N
    for j from 0 to N
        for k from 0 to N
            A[i][j] += B[i][k] + C[k][j]

Potrebbe essere 'abbastanza buono' per il tuo scopo (se è una matrice 4x4, potrebbe comunque essere compilato in istruzioni vettoriali). Tuttavia, ci sono programmi abbastanza importanti quando si compongono array di grandi dimensioni: come ottimizzarli? Se scrivi il codice nell'assemblaggio potresti avere un po 'di miglioramento (a meno che tu non faccia come la maggior parte delle persone - anche in modo ingenuo, sottoutilizzando i registri, caricando / archiviando costantemente la memoria e in effetti avendo un programma più lento rispetto al linguaggio HL) .

Tuttavia è possibile invertire le linee e ottenere magicamente prestazioni (perché? Lascio come "compiti a casa") - IIRC a seconda di vari fattori per matrici di grandi dimensioni può essere anche 10x.

for i from 0 to N
    for k from 0 to N
        for j from 0 to N
            A[i][j] += B[i][k] + C[k][j]

Detto questo, ci sono lavorando sui compilatori che sono in grado di farlo ( grafite per gcc e Polly per qualsiasi cosa usi LLVM). Sono anche in grado di trasformarlo in (scusa, sto scrivendo il blocco dalla memoria):

for i from 0 to N
    for K from 0 to N/n
        for J from 0 to N/n
            for kk from 0 to n
                for jj from 0 to n
                    k = K*n + kk
                    j = J*n + jj
                    A[i][j] += B[i][k] + C[k][j]

Riassumendo: conoscere le nozioni di base di un assieme consente di scavare in vari "dettagli" dalla progettazione del processore che consentirebbe di scrivere programmi più veloci. Potrebbe essere utile conoscere le differenze tra architetture RISC / CISC o VLIW / processore vettoriale / SIMD / .... Tuttavia non inizierei con x86 poiché tendono ad essere piuttosto complicati (forse anche ARM) - sapere cos'è un registro ecc. È IMHO sufficiente per iniziare.


Trovo interessante che tu abbia fornito diversi esempi di codice, ma nessuno di essi è in linguaggio assembly.
Robert Harvey,

-1

Normalmente è MOLTO importante per scopi di debug. Cosa fai quando il sistema si rompe nel mezzo di un'istruzione e l'errore non ha senso? È molto meno un problema con i linguaggi .NET, a patto che tu stia usando solo un codice sicuro: il sistema ti proteggerà quasi sempre da quello che succede sotto il cofano.


-2

In breve, penso che la risposta sia perché puoi fare di più se impari l'assemblaggio. L'apprendimento dell'assemblaggio consente l'accesso ai regni della programmazione di dispositivi integrati, penetrazione e elusione della sicurezza, ingegneria inversa e programmazione del sistema in cui è molto difficile lavorare se non si conosce l'assemblatore.

Per quanto riguarda l'apprendimento per migliorare le prestazioni del programma, questo è dubbio nella programmazione delle applicazioni. Il più delle volte ci sono così tante cose su cui concentrarsi prima di raggiungere questo livello di ottimizzazione come l'ottimizzazione del tuo accesso I / O sia su disco che in rete, ottimizzando il modo in cui costruisci la GUI, scegliendo gli algoritmi giusti, massimizzando tutti i tuoi core , eseguendo il miglior hardware possibile acquistare denaro e passare da linguaggi interpretati a compilati. A meno che non si stia creando software per altri utenti finali, l'hardware è economico rispetto al salario orario di un programmatore, in particolare con la disponibilità del cloud.

Inoltre, devi pesare una maggiore velocità di esecuzione del programma con la leggibilità del tuo codice dopo essere stato colpito da un bus, uscire o tornare alla base di codice per cambiarlo un anno dopo aver scritto l'ultima versione.


-3

Consiglierei gli algoritmi di apprendimento: ordinamento, elenchi collegati, alberi binari, hash, ecc.

Impara anche lisp vedi Struttura e interpretazione dei programmi per computer groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures questo corso video ti insegnerà tutto ciò che devi sapere, inclusi gli algoritmi (come fare tutto basato su alcuni comandi primitivi, un primitivo lisp e alcuni provocatori dell'assemblatore).

Infine, se devi imparare l'assemblatore, impara uno semplice come ARM (inoltre viene utilizzato in circa 4 volte più dispositivi rispetto a x86).


-8

Bene, la risposta è che semplicemente perché il linguaggio che stai usando deve essere interpretato o compilato in assembler alla fine. Non importa la lingua o la macchina.

Il design dei linguaggi deriva dal modo in cui funziona la CPU. Altro su programmi di basso livello, meno su programmi di alto livello.

Concluderò dicendo che non è solo necessario conoscere il piccolo assemblatore, ma l'architettura della CPU, che si impara apprendendo l'assemblatore.

Alcuni esempi: ci sono molti programmatori Java che non capiscono perché questo non funziona e ancor meno di sapere cosa succede quando lo si esegue.

String a = "X";
String b = "X";
if(a==b)  
    return true;

Se conoscessi un piccolo assemblatore, sapresti sempre che non è lo stesso il contenuto di una posizione di memoria rispetto al numero nella variabile puntatore che "punta" a quella posizione.

Ancora peggio, anche nei libri pubblicati leggerai qualcosa come nelle primitive JAVA che vengono passate per valore e oggetti per riferimento, il che è completamente errato. Tutti gli argomenti in Java vengono passati per valore e Java NON può passare oggetti a funzioni, solo puntatori, che vengono passati per valore.

Se ora assembli è ovvio cosa sta succedendo, in caso contrario è così complicato spiegare che la maggior parte degli autori ti dà solo una pia bugia.

Ovviamente, le conseguenze di questi sono sottili ma in seguito possono metterti nei guai. Se sai che assemblatore è un problema, in caso contrario, ti aspetta una lunga notte di debug.


5
Il tuo primo paragrafo è completamente errato: le lingue non sono compilate in ASM, sono compilate in codice macchina. Neanche gli interpreti si compilano in ASM, interpretano il codice o il codice byte e chiamano funzioni o metodi su codice macchina precompilato.

6
Anche ogni singola cosa che affermi su Java non è corretta. A partire dal String a = "X"; String b = "X"; if( a==b) return true;quale in effetti lo fa a == truecausa di qualcosa chiamato String interningdal compilatore. Anche tutte le altre dichiarazioni Java sono sbagliate. Java non ha puntatori, ha riferimenti che non sono la stessa cosa. E niente di tutto ciò ha a che fare con l'assemblatore in alcun modo. Java passa primitive per valore e riferimenti per valore. Java non ha puntatori quindi non può passarli da nulla. Ancora una volta tutto irrilevante per conoscere ASM.

Ho sempre pensato che linguaggi di livello superiore fossero compilati in oggetto (codice macchina) o pseudo-codice e non in ASM.
Frank R.

@FrankComputer corretto, ma il codice macchina bytes praticamente la mappa 1: 1 alle istruzioni di assemblaggio, quindi puoi facilmente tradurre tra un oggetto codice e ASM (decompilazione o assemblaggio)
dbr

2
@FrankComputer l'ultima volta che ho guardato gcc compilato C / C ++ / fortran / java / ada / etc nel codice byte interno e il codice byte interno nell'assemblatore. Invia quindi questo codice assembler in un assemblatore per convertirlo in codice macchina.
ctrl-alt-delor,
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.