Assembler, eller assembler-sprog, er et lavniveau programmeringssprog, der giver en symbolsk repræsentation af en computers maskinkodeinstruktioner. I modsætning til højniveau programmeringssprog, der abstraherer hardware detaljer, giver assembler-sprog programmører mulighed for at skrive programmer, der tæt korresponderer med computerens arkitektur. Dette giver udviklere granular kontrol over hardware ressourcer, hvilket gør det essentielt for opgaver, der kræver direkte interaktion med eller manipulation af hardware, såsom operativsystemer, indlejrede systemer og ydeevne-kritiske applikationer.
Assembler-sprog opstod i de tidlige dage af computing som et middel til at forenkle programmeringsprocessen ved hjælp af binær maskinkode. Den første assembler blev skabt til den Elektroniske Numeriske Integrator og Computer (ENIAC) i 1940'erne, hvilket gjorde det muligt for programmører at skrive instruktioner i et mere menneskeligt læsbart format. Efterhånden som computerarkitekturer udviklede sig, gjorde assembler-sprog også, med forskellige assemblere, der blev udviklet for at imødekomme forskellige hardwaredesign.
Assembler er direkte inspireret af arkitekturen af den specifikke computer, den retter sig mod. Hver type processor har sit eget assembler-sprog, såsom x86 (til Intel og AMD processorer), ARM (bredt anvendt i mobile enheder) og MIPS (anvendt i indlejrede systemer). Selvom assembler-sprog deler nogle grundlæggende koncepter, afspejler de de unikke instruktionssæt og operationelle kapaciteter af deres respektive hardwareplatforme.
I dag, selvom assembler-sprog ikke er det primære sprog til applikationsudvikling, forbliver det relevant i specifikke domæner. Det bruges almindeligvis til at skrive ydeevne-kritiske sektioner af kode, enhedsdrivere og realtidsystemer. Derudover er forståelse af assembler-sprog afgørende for områder som reverse engineering, malware-analyse og system-sikkerhed.
Assembler anvender mnemonics, som er symbolske repræsentationer af maskininstruktioner. For eksempel repræsenterer MOV AX, 1
flytning af værdien 1
ind i registeret AX
.
Assembler-sprog tillader direkte manipulation af processorregistre. For eksempel tilføjer instruktionen ADD AX, BX
værdierne i registrene AX
og BX
og gemmer resultatet i AX
.
Etiketter bruges til at markere positioner i koden til spring og løkker. En etikette kunne se ud som start:
. Dette er nyttigt til at skabe løkker med instruktioner som JMP start
.
Direktiver kontrollerer assemblerens adfærd og giver metadata. For eksempel angiver direktiverne .data
og .text
sektioner for data og kode, henholdsvis.
Kommentarer kan inkluderes til dokumentationsformål ved hjælp af et semikolon. For eksempel, ; Dette er en kommentar
.
Assembler understøtter kontrolflow-instruktioner som JMP
, JE
(spring hvis lig med), og JNE
(spring hvis ikke lig med), som muliggør forgrening i kodeudførelse.
Hver assembler-instruktion består typisk af en operation (opcode) efterfulgt af operander. Operationer kan være unære, binære eller anvende mere komplekse formater afhængigt af instruktionssætsarkitekturen.
Assembler-sprog tillader brug af umiddelbare værdier direkte i instruktioner, såsom MOV AX, 5
, hvor 5
er en umiddelbar værdi tildelt registeret AX
.
Assembler understøtter procedurer og underprogramkald, som muliggør genbrug af kode. Dette kan kaldes ved hjælp af CALL
instruktionen efterfulgt af en etikette, f.eks. CALL myFunction
.
Selvom assembler ikke har højniveau datatyper, kan data styres ved hjælp af byte, ord eller dobbeltord i henhold til arkitekturen, og hukommelsesadresser kan manipuleres direkte.
En assembler konverterer assembler-sprogkode til maskinkode. Der findes forskellige assemblere, såsom NASM (Netwide Assembler), MASM (Microsoft Macro Assembler) og GAS (GNU Assembler), som hver især retter sig mod specifikke arkitekturer eller operativsystemer.
Udviklingsmiljøer for assembler-sprog er mindre almindelige end for højniveau sprog, men inkluderer specifikke IDE'er som MPLAB X IDE til PIC mikrocontrollere eller Keil til ARM-udvikling.
For at bygge et projekt i assembler-sprog skriver udviklere almindeligvis kildekoden i en teksteditor, hvorefter de kalder assembleren via kommandolinjen for at generere binære eller objektfiler. For eksempel, ved brug af NASM, kunne en typisk kommando se således ud:
nasm -f elf64 myprogram.asm -o myprogram.o
Derefter kan linking udføres ved hjælp af en linker som ld
for at oprette en eksekverbar:
ld myprogram.o -o myprogram
Assembler-sprog anvendes overvejende i områder, der kræver optimeret ydeevne og direkte hardwaremanipulation. Nøgleanvendelser inkluderer:
I modsætning til højniveau sprog som C, C++ eller Java, der tilbyder abstraktioner over hardware, giver assembler-sprog direkte kontrol over maskininstruktioner. Dette gør assembler-programmer generelt hurtigere og mindre, hvilket er kritisk i ressourcebegrænsede miljøer, men betydeligt mindre bærbare.
Selvom optimering af assembler-sprog kan give overlegen ydeevne, forenkler sprog som C og C++ udviklingsprocessen betydeligt. Højniveau sprog håndterer hukommelsesstyring, fejlkontrol og tilbyder omfattende biblioteker, hvilket gør dem egnede til de fleste applikationer.
Assembler-sprog syntaks betragtes som mere kompleks sammenlignet med sprog som Python eller JavaScript, der prioriterer læsbarhed og brugervenlighed. At lære assembler kræver en forståelse af computerarkitektur, mens højniveau sprog abstraherer disse detaljer væk.
Flere værktøjer findes til at oversætte højniveau sprog til assembler eller muliggøre, at assembler interagerer med højniveau kode. Nogle assemblere kan integrere C-kode direkte, hvilket muliggør blandede projekter. Værktøjer som LLVM kan også generere assembler fra kode skrevet i højniveau sprog.
For udviklere, der ønsker at konvertere kode fra et højniveau sprog til assembler, er det gavnligt at studere målarkitekturens instruktionssæt og anvende profileringsværktøjer til at guide optimeringsindsatsen. Det er også tilrådeligt at udnytte eksisterende compilere som GCC, der kan generere assemblerkode til analyse eller yderligere forfining.