Definition og kald af procedurer
Lær at definere Deres egne procedurer (funktioner) ved hjælp af CALL- og RET-instruktioner, og forstå opsætning af stack frames.
Definition og kald af procedurer er en gratis Assembly-sprog og x86-systemprogrammering på lavt niveau-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Assembly-sprog og x86-systemprogrammering på lavt niveau, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Assembly-sprog og x86-systemprogrammering på lavt niveau-kurset indeholder 4 lektioner i alt.
Hvad er procedurer?
I assembly er en procedure (ofte kaldet en funktion eller et underprogram) en kodeblok, der er designet til at udføre en bestemt opgave. Procedurer hjælper med at organisere programmet og undgå gentagelse af kode.
Tænk på dem som funktioner i programmeringssprog på højt niveau som C++ eller Python. De gør det muligt at opdele komplekse problemer i mindre, håndterbare dele, så koden bliver modulær og lettere at læse.
Kald af en procedure med CALL
Du udfører en procedure ved hjælp af instruktionen CALL. Når CALL udføres, sker der to vigtige ting:
- Adressen på instruktionen lige efter
CALLpushes på stakken. Den kaldes returadressen. - CPU'en springer derefter til startadressen for den angivne procedure.
Denne mekanisme sikrer, at programmet ved præcis, hvor udførelsen skal genoptages, når proceduren er færdig med sit arbejde.
Returnering fra en procedure med RET
Når en procedure er færdig med sin opgave, skal den give kontrollen tilbage til den kode, der kaldte den. Det opnås ved hjælp af instruktionen RET.
Når RET udføres:
- popper CPU'en returadressen fra toppen af stakken.
- CPU'en springer derefter til den hentede adresse, så udførelsen genoptages ved instruktionen lige efter det oprindelige
CALL.
Tilsammen udgør CALL og RET det grundlæggende par til håndtering af programflowet mellem forskellige procedurer.
Dit første procedurekald
Lad os se på et enkelt assembly-program, der demonstrerer et grundlæggende procedurekald og en returnering. Vi definerer en procedure med navnet print_hello og kalder den fra programmets startpunkt, _start.
Dette eksempel bruger Linux-systemkald til output og afslutning af programmet.
section .data
msg db "Hello from proc!", 0xA
len equ $ - msg
section .text
global _start
_start:
call print_hello
; Exit program (sys_exit)
mov eax, 1 ; System call number for sys_exit
xor ebx, ebx ; Exit code 0
int 0x80
print_hello:
; Print "Hello from proc!" (sys_write)
mov eax, 4 ; System call number for sys_write
mov ebx, 1 ; File descriptor for stdout
mov ecx, msg ; Address of string to write
mov edx, len ; Length of string
int 0x80
ret
Forstå outputtet
Når du kører den foregående kode, udskriver den "Hello from proc!" i din konsol. Her er en trinvis gennemgang af, hvad der skete:
- Rutinen
_startudførtecall print_hello. - Adressen på instruktionen
mov eax, 1(som står lige eftercall print_hello) blev pushed på stakken. - CPU'en sprang til proceduren
print_hello. print_helloudførte sine instruktioner for at udskrive meddelelsen.retpoppede den gemte returadresse fra stakken og sprang tilbage til rutinen_start._startudførte derefter systemkaldet for at afslutte programmet.
Hvad er stakrammer?
Når der kaldes på en procedure, har den ofte brug for sit eget private arbejdsområde på stakken til håndtering af sine data. Dette dedikerede område på stakken kaldes en stakramme.
En stakramme indeholder typisk flere vigtige oplysninger for en procedure:
- Returadressen (pushed af instruktionen
CALL). - Gemte registerværdier (f.eks. den kaldende funktions basispeger).
- Lokale variable, der er specifikke for proceduren.
- Argumenter, der sendes til proceduren (det gennemgår vi i næste lektion!).
Opsætning af basispegeren (EBP)
Registret basispeger (`EBP` i 32-bit, `RBP` i 64-bit) er et vigtigt værktøj til håndtering af stakrammer. Det giver et stabilt referencepunkt i den aktuelle stakramme, så det bliver nemt at få adgang til lokale variable og argumenter.
En almindelig opsætningssekvens helt i begyndelsen af en procedure er:
push ebp: Dette gemmer den kaldende funktions aktuelle `EBP`-værdi på stakken, så den kan gendannes senere.mov ebp, esp: Dette indstiller `EBP` til stakpegerens aktuelle værdi (`ESP`) og fastlægger dermed basis for den nye stakramme.
Allokering af lokale variable
Efter opsætning af `EBP` kan en procedure allokere plads til sine egne lokale variable på stakken. Det gøres typisk ved blot at dekrementere stakpegeren (`ESP`).
sub esp, NHer repræsenterer `N` det samlede antal byte, der kræves til alle lokale variable. For eksempel allokerer sub esp, 4 nok plads til ét 32-bit-heltal.
Der kan derefter opnås effektiv adgang til disse lokale variable relativt til `EBP` (f.eks. [ebp-4], [ebp-8] osv.).
Nedtagning af stakrammen
Før en procedure returnerer, skal dens stakramme nedtages korrekt, så stakken gendannes til sin oprindelige tilstand. Det indebærer at frigive lokale variable og gendanne den kaldende funktions basispeger.
Instruktionen LEAVE er en praktisk måde at udføre disse to handlinger i ét trin:
mov esp, ebp: Dette frigiver eventuelle lokale variable ved at flytte `ESP` tilbage til det sted, som `EBP` peger på (rammens basis).pop ebp: Dette gendanner den kaldende funktions `EBP`-værdi, som blev gemt i begyndelsen af proceduren.
Efter LEAVE er stakken placeret korrekt, så instruktionen RET kan poppe returadressen.
Procedure med en stakramme
Dette eksempel demonstrerer en komplet procedure, der opsætter en korrekt stakramme, allokerer plads til en hypotetisk lokal variabel og derefter nedtager rammen korrekt før returnering.
Bemærk, hvordan `push ebp`, `mov ebp, esp`, `sub esp, 4`, `leave` og `ret` arbejder sammen.
section .data
msg db "Procedure with frame!", 0xA
len equ $ - msg
section .text
global _start
_start:
call my_framed_proc
; Exit program
mov eax, 1
xor ebx, ebx
int 0x80
my_framed_proc:
push ebp ; 1. Save caller's EBP
mov ebp, esp ; 2. Set EBP for new frame
sub esp, 4 ; 3. Allocate 4 bytes for a local variable
; mov dword [ebp-4], 123 ; Example: store a local value
; Print message (for demonstration)
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, len
int 0x80
leave ; 4. Deallocate locals, restore EBP
ret ; 5. Return to caller
Kontrol af procedurekaldets flow
Se på følgende x86-assembly-kodestykke:
call my_function
mov eax, 1
my_function:
ret
Hvilken specifik adresse pushes på stakken af instruktionen call my_function?
Opsamling: Definition og kald af procedurer
Vi har gennemgået de vigtigste begreber inden for definition og kald af procedurer i x86-assembly. Her er de vigtigste pointer fra lektionen:
- Instruktionen
CALLpusher returadressen på stakken og overfører kontrollen til en procedure. - Instruktionen
RETpopper returadressen fra stakken og overfører kontrollen tilbage til den kaldende kode. - Stakrammer, som primært håndteres med registret
EBP/RBP, giver et dedikeret og organiseret arbejdsområde på stakken til en procedures lokale variable og gemte registre. - En typisk opsætning af en stakramme omfatter
push ebp,mov ebp, espog allokering af lokale variable medsub esp, N. - Stakrammen tages ned med instruktionen
LEAVE(eller manuelt medmov esp, ebpogpop ebp) førRET.
Derefter bygger vi videre på dette ved at lære, hvordan du sender argumenter til procedurer og henter returværdier.
Lær Assembly med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 12
- Lektioner
- 48
Ofte stillede spørgsmål
Er lektionen “Definition og kald af procedurer” gratis?
Ja — hele teksten til “Definition og kald af procedurer” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Assembly-sprog og x86-systemprogrammering på lavt niveau-kurset, skal du opgradere til CoddyKit PRO. Assembly-sprog og x86-systemprogrammering på lavt niveau-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Definition og kald af procedurer”?
Lær at definere Deres egne procedurer (funktioner) ved hjælp af CALL- og RET-instruktioner, og forstå opsætning af stack frames. Du øver dig i Assembly-sprog og x86-systemprogrammering på lavt niveau med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Assembly-sprog og x86-systemprogrammering på lavt niveau?
Der kræves ingen tidligere erfaring. Assembly-sprog og x86-systemprogrammering på lavt niveau på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.
Hvor lang tid tager lektionen “Definition og kald af procedurer”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Assembly-sprog og x86-systemprogrammering på lavt niveau-lektion?
Ja. Alle Assembly-sprog og x86-systemprogrammering på lavt niveau-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Grundprincipper i call stack
- Definition og kald af procedurer
- Videregivelse af argumenter og returværdier
- Stack frames og lokale variabler