Język maszynowy, kody numeryczne dla operacji, które dany komputer może wykonać bezpośrednio. Kody są ciągami 0 i 1, czyli cyframi binarnymi („bitami”), które są często konwertowane zarówno z jak i na zapis szesnastkowy (podstawa 16) dla potrzeb przeglądania i modyfikacji przez człowieka. Instrukcje języka maszynowego zazwyczaj używają niektórych bitów do reprezentowania operacji, takich jak dodawanie, a niektórych do reprezentowania operandów, lub być może lokalizacji następnej instrukcji. Język maszynowy jest trudny do czytania i pisania, ponieważ nie przypomina konwencjonalnej notacji matematycznej ani języka ludzkiego, a jego kody różnią się w zależności od komputera.
Język asemblerowy jest jeden poziom powyżej języka maszynowego. Używa krótkich kodów mnemonicznych dla instrukcji i pozwala programiście na wprowadzenie nazw dla bloków pamięci, które przechowują dane. Można więc napisać „add pay, total” zamiast „0110101100101000” dla instrukcji, która dodaje dwie liczby.
Język asemblerowy jest zaprojektowany tak, aby można go było łatwo przetłumaczyć na język maszynowy. Chociaż do bloków danych można odwoływać się po nazwach zamiast po adresach maszynowych, język asemblacji nie zapewnia bardziej wyrafinowanych sposobów organizowania złożonych informacji. Podobnie jak język maszynowy, język asemblera wymaga szczegółowej znajomości konkretnej wewnętrznej architektury komputera. Jest przydatny, gdy takie szczegóły są ważne, jak w programowaniu komputera do interakcji z urządzeniami wejścia/wyjścia (drukarki, skanery, urządzenia pamięci masowej i tak dalej).