ASM A cosa serve, al giorno d'oggi: l'Assembly ?

America

Utente Electrum
24 Marzo 2012
442
9
74
128
Ormai i linguaggi di programmazione si sono evoluti, e l'assembly sembra ormai inutile, quindi: secondo voi a cosa serve ? e a cosa servirà per il futuro ?
 
Ormai i linguaggi di programmazione si sono evoluti, e l'assembly sembra ormai inutile, quindi: secondo voi a cosa serve ? e a cosa servirà per il futuro ?
Non parlerei di "evoluzione". Sono solo nati linguaggi di alto livello che semplificano il lavoro, ma evoluzione mi sembra eccessivo.
L'assembly resta sempre utile in quanto è un linguaggio di basso livello. Il basso livello è utile (e a volte necessario) quando si programmano particolari software, come i driver per sistemi operativi (o sistemi operativi stessi) che spesso hanno bisogno di lavorare direttamente con l'hardware, e solo l'assembly è in grado di farlo correttamente e con precisione.
Oltre a questo l'assembly è utilizzato per reversing e tant'altro: debug di applicazioni, analisi del funzionamento di programmi (utile a chi produce antivirus ad esempio), controllo del corretto funzionamento dei software, modifica di software, studio, ecc.
Inoltre è il linguaggio che può dare le massime prestazioni.
Per il resto, solitamente, "abbassarsi" fino al C è sufficiente.
I debugger, i disassembler, i memory-scanner, ecc. "parlano" assembly. Vuoi quindi dire che anche questi tools sono inutili? :)
Attualmente con altri sto lavorando ad un progetto, di cui è meglio che non parlo in pubblico, e nell'assembly ci sto affogando :D
Resta utile, almeno finché non verrà rimpiazzato da un altro lang di basso livello (o si vedrà inutile la programmazione di basso livello), per molte cose. è giusto studiarlo (ad un programmatore praticamente serve necessariamente nella vita, per non parlare di quello che si apprende sia studiandolo sia usandolo per studiare altro software) ed utilizzarlo quando serve :)
 
Non parlerei di "evoluzione". Sono solo nati linguaggi di alto livello che semplificano il lavoro, ma evoluzione mi sembra eccessivo.
L'assembly resta sempre utile in quanto è un linguaggio di basso livello. Il basso livello è utile (e a volte necessario) quando si programmano particolari software, come i driver per sistemi operativi (o sistemi operativi stessi) che spesso hanno bisogno di lavorare direttamente con l'hardware, e solo l'assembly è in grado di farlo correttamente e con precisione.
Oltre a questo l'assembly è utilizzato per reversing e tant'altro: debug di applicazioni, analisi del funzionamento di programmi (utile a chi produce antivirus ad esempio), controllo del corretto funzionamento dei software, modifica di software, studio, ecc.
Inoltre è il linguaggio che può dare le massime prestazioni.
Per il resto, solitamente, "abbassarsi" fino al C è sufficiente.
I debugger, i disassembler, i memory-scanner, ecc. "parlano" assembly. Vuoi quindi dire che anche questi tools sono inutili? :)
Attualmente con altri sto lavorando ad un progetto, di cui è meglio che non parlo in pubblico, e nell'assembly ci sto affogando :D
Resta utile, almeno finché non verrà rimpiazzato da un altro lang di basso livello (o si vedrà inutile la programmazione di basso livello), per molte cose. è giusto studiarlo (ad un programmatore praticamente serve necessariamente nella vita, per non parlare di quello che si apprende sia studiandolo sia usandolo per studiare altro software) ed utilizzarlo quando serve :)
Speed in termini di velocità , l'assembly è molto più veloce di un linguaggio di alto livello ? Se si , la differenza di velocità tra questi linguaggi si nota molto ?
 
Speed in termini di velocità , l'assembly è molto più veloce di un linguaggio di alto livello ? Se si , la differenza di velocità tra questi linguaggi si nota molto ?
L'assembly da il massimo controllo sul programma che stai scrivendo. Sostanzialmente, con l'assembly le prestazioni sono al 100% in mano al programmatore. La velocità massima di un algoritmo (in caso che il programmatore riesca ad ottimizzare perfettamente il codice) è raggiungibile con l'assembly. L'assembly può dare le massime prestazioni, su ogni cosa (ma può anche essere, volutamente o no, rallentato dal programmatore).
 
Speed in termini di velocità , l'assembly è molto più veloce di un linguaggio di alto livello ? Se si , la differenza di velocità tra questi linguaggi si nota molto ?

so che hai chiesto a speed, ma se dovessi dire la mia direi che dipende da che linguaggio ad alto livello parliamo, il C/C++ pur essendo ad alto livello continua comunque ad essere "vicino" al basso livello quindi in termini di prestazioni rimane simile secondo me, mentre la storia cambia se andiamo su VB6 o addirittura su linguaggi con compilazione JIT come Java/ e vari basati su .NET

poi dipende molto anche da qual è la routine da confrontare, un'iterfaccia utente difficilemente ti darebbe modo di notare differenze, ma ci sono sicuramente routine, soprattutto se ripetute migliaia di volte al secondo, dove la differenza si noterebbe di sicuro
 
o addirittura su linguaggi con compilazione JIT come Java/ e vari basati su .NET
In molte situazioni, il .NET praticamente eguaglia (e in rari casi, supera) le prestazioni dei linguaggio compilati in linguaggio macchina come il C/C++. L'assembly resta comunque il linguaggio dove le prestazioni possono​ essere spinte al massimo.
 
sinceramente mi risulta che con il JIT (rispetto ai linguaggi interpretati) siano riusciti "quasi" ad eguagliare le prestazioni del compilato, ma non di superarlo, però sono curioso di sapere quali sono questi casi visto che non li ho presenti :)
 
  • Mi piace
Reazioni: Break-Line
sinceramente mi risulta che con il JIT (rispetto ai linguaggi interpretati) siano riusciti "quasi" ad eguagliare le prestazioni del compilato, ma non di superarlo, però sono curioso di sapere quali sono questi casi visto che non li ho presenti :)
Rispondo con citazioni di Predator, St3ve e Exit93 (voci non di poco conto ;)): messaggi presi da un'interessantissima discussione :) (ritaglio le parti che riguardano le prestazioni .NET e nativo, ma se vuoi puoi anche leggere la discussione per intero):
Apro una parentesi riguardo di DotNet e il codice nativo. Ho avuto con piacere modo di eseguire test di prestazione... devo dire che il net equivale il C++ come prestazioni. Anzi se gli exe in C++ non vengono compilati con l'opzione di ottimizzazione per velocità, risultano addirittura meno veloci del net. Devo dire che Microsoft con il dotnet ha fatto un lavoro meraviglioso, probabilmente il migliore in che abbiano mai fatto in casa Microsoft. Da non dimenticare che grazie a mono è diventato pure multipiattaforma. Chiusa parentesi :)
Prima di tutto, salvo espressamente detto, io non parlo mai per supposizioni ma per argomentazioni e materiale empirico :D
Il problema nasce solitamente proprio da un concetto sbagliato. La gente lo paragona ad altri framework con runtime o vm come visual basic 6 o java. Nulla di più sbagliato, il net è ben diverso.
Se non lo si sa ottimizzare e compilare bene, un eseguibile con codice c++ risulta più lento rispetto a quello codato in c#/vbnet, provare per credere.
Lo puoi verificare tu stesso utilizzando un algoritmo tipo la classica trasformata di Fourier veloce, utilizzata spesso per fare questo genere di test in quanto esegue un gran numero di operazioni ed è adatta allo scopo.
Dal risultato vedrai che se non ottimizzi la compilazione del codice c++, questo risultera' piu' lento rispetto quello net. Diversamente se ottimizzi risultano di pari velocità (anche se in alcuni casi il c# continua ad essere di qualche millisecondo più veloce su cpu recenti e di qualche millisecondo meno veloce su vecchie cpu come i P3). Tutto questo è possibile grazie anche agli hardware e dall'OS che da anni utilizzano al meglio il dll caching, memory management di managed e unmanaged code e loWrite manager migliorato
Naturalmente questi test io li ho fatti per prova personale, ma tutto è già ampiamente documentato nel web, non mi sono inventato nulla di nuovo.
Riassumento: il Net è multipiattaforma, è veloce come il c++, e lo sviluppo è più rapido.
Pero' quando parliamo di prestazioni, tu prova a scrivere codice per un'operazione importante, che ti permetta di fare un benchmark di calcolo, che equivalga in codice C++ e C#, vedrai che sorpresa. Io stesso ho dovuto rivalutare alcuni miei punti di vista. Ho proposto la trasformata di Fourier veloce, perchè è il tipo algoritmo preso dai benchmarker, ma fai pure come preferisci :)
A fronte di questo dato mi sento di affermare che se uno lavora in Windows o con mono, se deve scegliere tra C++ e C#, sicuramente lavorera' piu' velocemente in C# ottenendo prestazioni equivalenti.
Orco cane! Compilato vs. semi-compilato con prestazioni identiche :V
Ho scritto un codice per calcolare il più alto numero primo entro un certo range. Per evitare qualsivoglia cambiamento ho evitato ogni tipo di ottimizzazione e ho praticamente riscritto il programma pari pari su entrambi i linguaggi.
Per calcolare il più alto numero primo in un range da 3 (ho usato il 3 per semplificare ancor più il sorgente) a 1.000.000 (che risulta essere 999983) ci impiegano:
C++ -> 169277
C# -> 169511
Il codice in C++ è facilmente convertibile in C, quindi suppongo che anche in C i risultati siano molto molto simili; contando anche un range di tolleranza di 1 secondo, che non è poi tanto su un tempo così lungo e considerando che non ho un pc dedicato ai benchmark. Inoltre durante l'esecuzione del programma avevo altri programmi aperti... quindi 1 secondo ci sta tutto.
L'unica grossa differenza tra i due eseguibili è il consumo della ram, quello in .NET consuma quasi il triplo rispetto quello in C++, ma in velocità sono identici.
Sarebbe interessante conoscere in quali campi il C/C++ è più veloce del C#, perché suppongo che in qualche campo lo sia, altrimenti molte cose non mi tornano; se qualcuno è più informato faccia sapere!

Visto che questa cosa la ritengo interessante vi posto il sorgente e vi allego gli .exe (come potete vedere il sorgente è identico in termini di passaggi)

Sorgente C++
Codice:
#include <iostream>
#include <Windows.h>

int main()
{
    unsigned long time = 0;
    int max = 0, primo = 2;
    
    std::cout << "Range massimo di numeri primi: ";
    std::cin >> max;
    
    time = GetTickCount();
    for(int x=3; x<=max; x++)
        for(int y=2; y<x; y++)
        {
            if((x%y)==0)
                break;
            else if(y==x-1)
                primo = x;
        }
    time = GetTickCount() - time;
    
    std::cout << std::endl << "il numero primo piu' alto in un range massimo di " << max << " e' " << primo << std::endl
              << "tempo d'esecuzione: " << time << " mSec";
    
    std::cin.ignore();
    std::cin.get();
    return 0;
}

Sorgente C#
Codice:
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace benchmark_inforge_csharp
{
    class Program
    {
        static void Main(string[] args)
        {
            int time = 0;
            int max = 0, primo = 2;
            
            Console.Write("Range massimo di numeri primi: ");
            max = Convert.ToInt32(Console.ReadLine());
            
            time = Environment.TickCount;
            for(int x=3;x<=max;x++)
                for (int y = 2; y < x; y++)
                {
                    if((x%y)==0)
                        break;
                    else if(y==x-1)
                        primo = x;
                }
            time = Environment.TickCount - time;

            Console.Write("\nil numero primo piu' alto in un range massimo di " + max + " e' " + primo +
                              "\ntempo d'esecuzione: " + time + " mSec");
            Console.ReadKey();
        }
    }
}

Download
Devo dire che i benchmark fatti da St3ve mi hanno incuriosito parecchio, così ho provato a farli anche io (su Arch Linux x86_64 (64 bit)).
Per il .net ho usato mono
Per il C++ ho eseguito l'exe compilato da St3ve su Wine (un ambiente di emulazione windows ma molto veloce, per esempio alcuni giochi mi girano meglio su wine che su windows)
In più ho provato per curiosità mia a eseguire lo stesso benchmark in java.

I risultati mi hanno stupido:
C# (su mono): 155850 mSec
C++ (su wine): 154107 mSec
Sun Java 6: 170256 mSec

Come CPU ho un Intel I5 750

A parte java che mi aspettavo che sarebbe stato più lento (nonostante giri molto meglio su linux che su windows) mi ha colpito la velocità di mono non essendo un framework ufficioso.
Sarei curioso di provare come giri C++ nativamente ma conoscendolo poco non so che alternativa usare a Windows.h e a GetTickCount()

Vi lascio al sorgente java
Codice:
import java.util.Scanner;


public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        int time = 0;
        int max = 0, primo = 2;
        Scanner in = new Scanner(System.in);
        
        System.out.println("Range massimo di numeri primi: ");
        max = in.nextInt();
        
        time = (int) System.currentTimeMillis();
        for(int x=3;x<=max;x++)
            for (int y = 2; y < x; y++)
            {
                if((x%y)==0)
                    break;
                else if(y==x-1)
                    primo = x;
            }
        time = (int) System.currentTimeMillis() - time;

        System.out.println("\nil numero primo piu' alto in un range massimo di " + max + " e' " + primo +
                          "\ntempo d'esecuzione: " + time + " mSec");

    }

}
La discussione è questa: http://www.inforge.net/community/programmazione-giochi/217009-3d-engine-la-nascita.html
 
Ultima modifica:
Invece il mio è:

c# ---> 233565 mSec
c++ ---> 247792 mSec

consumo ram e cpu nella norma
cpu: Intel core2 Duo 2Ghz
Memoria ram: 3Gb

sarebbe interessante stilare una classifica con il tipo di processore ecc...

edit: piuttosto perchè a me sul mio pc risulta essere più veloce c# e non c++ come a voi???
 
  • Mi piace
Reazioni: SpeedJack
Avevo hostato su megaupload quindi dubito che tu sia riuscito a riprendere i miei files... Sei sicuro di aver buildato in release?
Probabilmente non avrai selezionato le ottimizzazioni per la release, oppure il compilatore che hai usato è meno valido di quello che ho usato io (VS10), altrimenti può essere che il test sia stato falsato da qualche altro processo: quando si fanno certi test è bene tenere tutto chiuso e non usare il pc nel frattempo.
Ti consiglio di tener aperto il task manager e controllare che sia tutto in regola, nel tuo caso: cpu (valore in basso) fissa a 50-51% e il valore cpu del processo del programma fisso a 50 (questo non dovrebbe variare praticamente mai).

Se si dovesse fare una classifica per processore non si dovrebbero trovare grosse differenze, amenoché non si cambia architettura (in particolare ho sentito che sugli ARM il C# gira notevolmente più lento della controparte C++), numero di core e casa produttrice (intel, amd, etc...) sono ininfluenti.

Comunque sia, come ho già detto, quello è il primo test che mi è passato per la mente... è molto stupido e per altro sfrutta solo la pura potenza di calcolo. Ad esempio non si vede la performance sulla gestione dinamica della memoria, dove da una parte c'è il garbage collector e dall'altra gli smart pointers (che sembrerebbero veloci quasi quanto i raw pointers).
Non vale la pena mettersi a fare troppe statistiche su sta roba... sarebbe interessante vedere qualche test fatto come si deve, ma non credo di averne le competenze (soprattutto per quanto riguarda C# e Java).
 
dipende dove vuoi arrivare... se uno si mette in testa di sviluppare un applicativo complesso in asm meglio lasciar perdere (e comunque avrebbe poco senso oggi come oggi), se come me ti metti ad imparare l'asm per quel poco che ti serve per capire qualcosa in fase di reversing oppure quando giochi con CE o MHS nel cheatare un gioco allora è fattibile e secondo me nemmeno tanto difficile. Certo se lo vuoi padroneggiare ed essere in grado di fare qualunque cosa la faccenda si complica.
 
non è proprio cosi, non siamo tutti portati per le stesse cose, può essere che la stessa cosa per uno sia facile per un altro difficile per un altro insormontabile e poi ci sta anche la motivazione, se uno è davvero motivato da il 100% delle proprie capacità (e magari del proprio tempo) se uno lo fa "tanto per fare" probabilmente si ferma subito quando capisce che richiede troppi sforzi per quella che era l'idea iniziale
 
quindi secondo voi i disassembler sono scritti in ASM? Ma per favore...
Ormai nemmeno più i PIC si programmano in ASM. L'ASM, a parte per mettere mani su cose già fatte e per imparare le architetture non serve assolutamente a niente. Soprattutto se si considera ceh il C è quasi allo stesso livello. L'epoca dell'asm è finita, persino io che sono uno convinto ed ho a ceh fare con il reverse engineering per passione, se posso utilizzao il C++.
 
quindi secondo voi i disassembler sono scritti in ASM? Ma per favore...
Chi l'ha detto? :\
L'epoca dell'asm è finita, persino io che sono uno convinto ed ho a ceh fare con il reverse engineering per passione, se posso utilizzao il C++.
Come linguaggio per la programmazione sicuramente, già da tempo. Ma per l'analisi di altri software (reversing anche) è necessario, sicuramente ancora per un po'. Già prima di tutto perché i software che cercano di fornire uno pseudo-C da un software compilato forniscono un codice complesso e spesso meno comprensibile del listato assembly. E poi perché è il linguaggio che ha le istruzioni più 'semplici' e permette quindi un'analisi più dettagliata (sopratutto durante un debug).
 
Se leggi bene vedrai che l'hanno detto.

Per il resto...qualsiasi approccio che richieda di fornire del codice da un software già compilato fa parte del reverse engineering. A parte questo non esistono altri utlizzi che richiedano l'assembly. E' tra l'altro anceh molto raro che per ragioni professionali bisogni intervenire su un codice compilato, io lavoro da 13 anni, ho lavorato nell'aeronautica, nell'embedded, nell'energia, nelle infrastrutture, ma un caso del genere non mi è mai capitato (nemmeno nell'analisi dei coredump crashes). A meno che non fosse mio esclusivo interesse capire il funzionamento di qualcosa, ma questa non è una necessità.
 
  • Mi piace
Reazioni: SpeedJack
In campo lavorativo è necessario in alcuni settori: malware analysis ad esempio (sì, reverse engineering, comunque necessario). Per chi vuole sviluppare una protezione software è utile e talvolta necessario.
Ad ogni modo che l'assembly sia utilizzato quasi solo per il reversing ok, ma il reversing è pur sempre utile in certe situazioni.
 
Personalmente mi è capitato, in passato, di utilizzare l' assembler dove altri linguaggi risultavano "lenti". E detto tra le righe non c'è paragone sia in velocità sia in "osticità".

Paragonare l' assembler con linguaggi compilati o addirittura "Interpretati" per me è fuori luogo, chi ha un minimo di conoscenza di assembler (o meglio linguaggio macchina, per essere chiari: il linguaggio della CPU) ha ben chiaro la montagna di merd... ehm mondezza e ridondanze che si porta indietro un codice generato da un compilatore (e non sto parlando di un programma "interpretato" .NET per capirci).

Programmare in .NET è più facile, semplice, veloce e ... ma non confondiamo la comodità con l' efficienza.

Un consiglio per i test utilizzate una macchina vecchia.
Personalmente su un vecchio pc Pentium in cui le applicazioni vb6 volano le .NET stentano e molte sono "Inchiodate" per usare un eufemismo. La griglia msflexgrid di .net stenta nel visualizzare (refresh) di una tabella access, mentre un controllo "griglia" scritto interamente in vb6 fischia.
 
E' vero, assolutamente. Ma oramai l'hardware problemi di questo tipo non ne ha più. E la crescente complessità degli applicativi rende anche quasi impossibile l'utilizzo dell'asm.
 
Ormai i linguaggi di programmazione si sono evoluti, e l'assembly sembra ormai inutile, quindi: secondo voi a cosa serve ? e a cosa servirà per il futuro ?

A capire come funzionano i software a basso livello, e di come questi vengano eseguiti, oltretutto l'assembly è utile.. ad esempio tutt'oggi una buona parte dei PLC sono programmabili quasi esclusivamente in ASM (da qualche anno stanno subentrando quelli che supportano il C)