Извикване на функция

Обща форма

В програмата тялото на функцията се изпълнява чрез извикване на функцията и процесът е подобен на този при извиквания на подпрограма на други езици.

В езика общата форма на функцията се нарича:

Име на функция (действителен списък с параметри)

Whencallingafunctionwithoutparameters,thereisnoactualparameterlist..Theparametersintheactualparametertablecanbeconstants,variables,orotherstructureddataandexpressions.Separateeachactualparameterwithacomma.

Потребителско пространство (потребителски режим) и пространство на ядрото (режим на ядро)

Пространството на процесите на операционната система може да бъде разделено на потребителско пространство и пространство на ядрото, което изисква различни разрешения за изпълнение. Извикването на функцията изпълнява потребителско пространство.

Включително съдържание

Функционален израз

Функциите се появяват като изрази като изрази на един елемент и върнатите стойности на функциите участват в изчисляването на изразите. Този метод изисква функцията да има върната стойност. Например: z=max(x,y) е израз за присвояване, който присвоява върната променлива на zmax.

Израз на функция

Общата форма на извикване на функция плюс точка и запетая представлява израз на функция. Например: printf("%d",a);scanf("%d",&b);всички функции за извикване във формата на изрази на функция.

FunctionArguments

Thefunctionappearsastheactualparameterofanotherfunctioncall.Inthiscase,thereturnvalueofthefunctionistransmittedasanactualparameter,sothefunctionmusthaveareturnvalue.Forexample:printf("%d",max(x,y));Thatis,thereturnvalueofthemaxcallisusedastheactualparameteroftheprintffunction.Anotherissuethatshouldbepaidattentiontoinfunctioncallsistheorderofevaluation.Theso-calledevaluationorderreferstowhetherthequantitiesintheactualparametertableareusedfromlefttorightorfromrighttoleft.Inthisregard,theregulationsofeachsystemarenotnecessarilythesame.Ithasbeenmentionedintheintroductionoftheprintffunction,andIwillemphasizeitagainfromtheperspectiveoffunctioncalls.

[Пример]

главен()

{inti=8;printf("%d\n%d\n%d\n%d\n",++i,--i,i++,i--);}

Ако се оценява отдясно наляво. Резултатът от изпълнението трябва да бъде:

8

7

7

8

Например, в израза printf++i,--i,i++,i--оценка от ляво надясно, трябва да има резултат:

9

8

8

9

Itshouldbenotedthatwhetheritisevaluatedfromlefttorightorfromrighttoleft,theoutputorderisthesame,thatis,theoutputorderisalwaysTheorderoftheactualparametersisthesameasintheactualparameterlist.SinceTurboCiscurrentlyevaluatedfromrighttoleft,theresultis8,7,7,8.Ifyoustilldon’tunderstandtheabovequestions,youwillunderstandafteratryonthecomputer.

Declarationandfunctionprototypeofthecalledfunction

Beforecallingafunctioninthemaincallingfunction,thecalledfunctionshouldbeexplained(declared),whichisthesameasbeforeusingvariables.Thevariabledescriptionisthesame.Thepurposeofexplainingthecalledfunctioninthecallingfunctionistomakethecompilersystemknowthetypeofthereturnvalueofthecalledfunction,sothatthereturnvaluecanbeprocessedaccordinglyinthecallingfunctionaccordingtothistype.

Общата форма:

Определянето на типа се нарича име на функция (тип параметър, тип параметър...);

Или:

Определянето на типа се нарича име на функция (тип, тип...);

Thetypeandnameoftheformalparameteraregivenintheparentheses,oronlythetypeoftheformalparameterisgiven.Thisfacilitateserrordetectionbythecompilersystemtopreventpossibleerrors.

Например, описанието на максималната функция в основната функция е:

intmax(int​​a,intb);

Написано:

intmax(int,int);

TheClanguagealsostipulatesthatthefunctiondescriptionofthecalledfunctioninthecallingfunctioncanbeomittedinthefollowingsituations.

1)Ifthereturnvalueofthecalledfunctionisanintegerorcharactertype,youcancallthecalledfunctiondirectlywithoutexplainingit.Atthistime,thesystemwillautomaticallytreatthereturnvalueofthecalledfunctionasaninteger.ThisisthecasewhenthefunctionsisnotdescribedinthemainfunctionofExample8.2anditiscalleddirectly.

2)Whenthefunctiondefinitionofthecalledfunctionappearsbeforethecallingfunction,thecallingfunctioncanalsobecalleddirectlywithoutfurtherexplainingthecalledfunction.Forexample,inExample8.1,thedefinitionofthefunctionmaxisplacedbeforethemainfunction,sothefunctiondescriptionofthemaxfunctioncanbeomittedinthemainfunctionintmax(inta,intb).

3)Ifthetypeofeachfunctionisspecifiedoutsidethefunctionbeforethedefinitionofallthefunctions,theninthesubsequentcallingfunctions,thecalledfunctioncannolongerbedescribed.Forexample:

charstr(inta);

floatf(floatb);

главен()

{……}

charstr(inta)

{……)

floatf(floatb)

{……}

Thefirstandsecondlineshavepre-explainedthestrfunctionandtheffunction.Therefore,thestrandffunctionscanbecalleddirectlyinthefollowingfunctionswithoutfurtherexplanation.

4)Thecallofthelibraryfunctiondoesnotneedtobeexplained,buttheheaderfileofthefunctionmustbeincludedinthefrontofthesourcefilewiththeincludecommand.

Nestedcall

NestedfunctiondefinitionsarenotallowedinClanguage.Therefore,thefunctionsareparallel,andthereisnoproblemoftheupperlevelfunctionandthenextlevelfunction.ButtheClanguageallowsacalltoanotherfunctiontoappearinthedefinitionofafunction.Inthisway,nestedcallsoffunctionsappear.Thatis,otherfunctionsarecalledinthecalledfunction.Thisissimilartothenestingofsubroutinesinotherlanguages.Therelationshipcanberepresentedasshowninthefigure.

Thefigureshowsatwo-levelnestingsituation.Theexecutionprocessis:whenthestatementthatcallsfunctionainthemainfunctionisexecuted,functionaisswitchedto,whenfunctionbiscalledinfunctiona,functionbisswitchedtoexecution,andfunctionbisexecutedtoreturntothebreakpointoffunctionatocontinueExecute,theexecutionoftheafunctioniscompleteandreturntothebreakpointofthemainfunctiontocontinueexecution.

[Пример]Изчислява=2∧2!+3∧2!

Thisquestioncanwritetwofunctions,oneisthefunctionf1usedtocalculatethesquarevalue,andtheotherisThefunctionf2usedtocalculatethefactorialvalue.Themainfunctionfirstadjustsf1tocalculatethesquarevalue,andthentakesthesquarevalueinf1astheactualparameter,callsf2tocalculatethefactorialvalue,andthenreturnstof1,thenreturnstothemainfunction,andcalculatesthecumulativesumintheloopprogram.

longf1(intp)

{intk;

longr;

longf2(int);

k=p*p;

r=f2(k);

връщане;}

longf2(intq)

p>

{longc=1;

inti;

за(i=1;i<=q;i++)

c=c*i;

връщане;}

главен()

{inti;

longs=0;

p>

за(i=2;i<=3;i++)

s=s+f1(i);

printf("\ns=%ld\n",s);}

Intheprogram,thefunctionsf1andf2arebothlongintegers,whicharedefinedbeforethemainfunction,sothereisnoneedtoexplainf1andf2inthemainfunction.Inthemainprogram,theexecutionloopprogramsequentiallycallsthevalueofiastheactualparametertocallthefunctionf1toobtainthevalueofi2.Inf1,acalltofunctionf2occursagain.Atthistime,thevalueofi2isusedasanactualparametertoadjustf2,andthecalculationofi2!iscompletedinf2.Afterf2isexecuted,theCvalue(iei2!)isreturnedtof1,andthenf1returnstothemainfunctiontoachieveaccumulation.Sofar,therequirementoftheproblemisrealizedbythenestedcallofthefunction.Becausethevalueisverylarge,thetypesoffunctionsandsomevariablesaredeclaredaslongintegers,otherwiseitwillcausecalculationerrors.

Действително изпълнение

Pointerregister

EBP

EBPistheso-calledframepointer,pointingtothecurrentactivityAbovetherecord(thebottomofthepreviousactivityrecord)

ESP

ESPistheso-calledstackpointer,whichpointstothebottomofthecurrentactivityrecord(bottomAnactivityrecordtobeinsertedatthetop)

Thevalueofthesetwopointersspecifiesthepositionofthecurrentactivityrecord

Предаване на параметри

Натискане на параметрите на функцията Stack:moveax,dwordptr[n];(nisaпараметъраргумент)

бутаща ос

Операция

Извикването на функцията ще изпълни следните операции:

⒈Избутайте указателя на рамката в стека:pushebp

⒉направете точката на рамката равна на указателя на стека:movebp,esp

⒊makethestackpointerdecrement,Thememoryaddressobtainedbysubtractionshouldbeableto(enough)beusedtostorethelocalstateofthecalledfunction:subesp,0CCh

Забележка: 0CC е 0xCC, което варира в зависимост от конкретната функция.

Passinsavestate

pushebx;savethevalueofebxregister

pushesi;запазете стойността на fesiregister

pushedi;Запазете стойността на ediregister

Зареден

leaedi,[ebp-0CCh];0c еразмерът на текущия активен запис.

EDI е индексният регистър на местоназначението.

Restoretheincomingsavestate

00411417popedi

00411418попеси

popebx

stackMovethepointeruptorestorespace

addesp,0CCh

Function returnstoreleasespace

Когато функцията се върне, компилаторът и хардуерът ще изпълнят следните операции:

⒈Направете точката на стека равна на указателя на рамката:movesp,ebp

⒉Извадете стария указател на рамка от стека:popebp

⒊Връщане: ret

Пример1

;voidfunction(intn);{pushebp

movebp, особено

subesp,0CCh

pushebx

пушеси

бутане

leaedi,[ebp-0CCh]

movecx,33ч

moveax,0CCCCCCCCh

repstosdwordptres:[edi]

;chara=1;

movbyteptr[a],1

;ако(n==0)връщане;

cmpdwordptr[n],0

jnefunction+2Ah(4113CAh)

jmpfunction+77h(411417h)

;printf("%d\t(0x%08x)\n",n,&n);

movesi, особено

leaeax,[n]

бутаща ос

movecx,dwordptr[n]

pushecx

pushoffsetstring"%d\t(0x%08x)\n"(415750h)

callwordptr[__imp__printf(4182B8h)]

addesp,0Ch

cmpesi, особено

обадете се на @ILT+305(__RTC_CheckEsp)(411136h)

;функция(n-1);

moveax,dwordptr[n]

подос,1

бутаща ос

функция за извикване (411041h)

addesp,4

;printf("----%d\t(0x%08x)\n",n,&n);

movesi, особено

leaeax,[n]

бутаща ос

movecx,dwordptr[n]

pushecx

pushoffsetstring"----%d\t(0x%08x)\n"(41573Ch)

callwordptr[__imp__printf(4182B8h)]

addesp,0Ch

cmpesi, особено

обадете се на @ILT+305(__RTC_CheckEsp)(411136h);}

попеди

попеси

popebx

addesp,0CCh

cmpebp, особено

обадете се на @ILT+305(__RTC_CheckEsp)(411136h)

movesp,ebp

popebp

остан

Пример2

117:bR=t1(p);

Кодът на сглобяването е следният:

00401FB8movecx,dwordptr[ebp-8];поставете параметъра в регистъра ecx

00401FBBpushecx;параметърът в стека

00401FBCcall@ILT+10(t1)(0040100f);Functioncall,адресът на следващия ред00401FC1е избутан в стека

00401FC1addesp,4;Функцията връща, указателят на стека е увеличен с 4 и е възстановен до стойността на 00401FB8

00401FC4movdwordptr[ebp-10h],eax;Вземете върнатата от функцията стойност на езика от високо ниво от meax и поставете в променливатаbR

Функцията1 е следната:

125:BOOLt1(void*p)

126:{

00402030pushebp;ebpintothestack

00402031movebp,esp;ebppointstothetopofthestackonthtime

00402033subesp,44h;espнамалява с една стойностиосвобождаваобласт за съхранение

p>

00402036pushebx;Поставетестойностите​​на трите регистърав стека,за да можете да го използвате въвфункцията

00402037pushesi;

00402038pushedi;

00402039leaedi,[ebp-44h];

0040203Cmovecx,11h;

00402041moveax,0CCCCCCCCh;

00402046repstosdwordptr[edi];

127:int*q=(int*)p;;

00402048moveax,dwordptr[ebp+8];ebp+8pointstofunctioninputНай-ниския бит адреснапараметъра;

;ако се bp+4, сочи към най-ниския бит от адреса за връщане на функцията00401FC1, стойността е C1

0040204Bmovdwordptr[ebp-4],eax;

128:връщане0;

0040204Exoreax,eax;Върнатата стойност е поставена в регистъраeax

129:}

00402050popedi;Три регистъра излизат от стека

00402051попеси;

00402052popebx;

00402053movesp,ebp;esprestore

00402055popebp;ebppизскача от стека и стойността му е възстановена

00402056ret;Връщане към адреса на кода, съхранен в горната част на стека в този момент: 00401FC1

;soifyouareunluckyIfthereturnaddressismodified,theprogramwillbeunexpected

Горният код за сглобяване е компилиран от VC++6.0.

ThesituationofthestackaftertheEBPisputintothestack:

Нисък и висок

↓↓

Стек с адреси на паметта

┆┆

0012F600├───────┤←edi=0012F600

││

0012F604├─┄┄┄┄─┤

││

││

┆44hspace┆

┆┆

││

││

0012F640├─┄┄┄┄─┤

││

0012F644├───────┤←Ebpis е назначен да сочи към това устройство, в този моментebp=0012F644

│ACF61200│ebpis, присвоен на стойността преди

0012F648├─────────┤

│C11F4000│Обратен адрес

0012F64C├─────────┤←ebp+8

│A0F61200│Стойността на функционалния параметърp;

0012F650├──────────┤

││

├────────┤

┆┆

Note:Thememorystoragespacestackisarrangedfromhightolow,andtheaddressmarkedontheleftisthelowestaddressofthestorageunitatthebottomright.Forexample,0012F644pointstotheACbyteof0012F6AC,andACisatthetopofthestack.Thecontentinthememoryinthefigureiswrittenfromlowtohigh,"ACF61200"=0x0012F6AC

Обяснение

(1)Acprogramiscomposedofoneormoreprogrammodules,Eachprogrammoduleasasourceprogramfile.Forlargerprograms,yougenerallydon'twanttoputallthecontentinonefile,butputtheminseveralsourcefiles,andacprogramiscomposedofseveralsourceprogramfiles.Thismakesiteasytowriteandcompileseparately,andimprovedebuggingefficiency.Asourceprogramfilecanbesharedbymultiplecprograms.

(2)Asourceprogramfileiscomposedofoneormorefunctionsandotherrelatedcontent(suchasinstructions,datadeclarationsanddefinitions,etc.).Asourceprogramfileisacompilationunit,andthesubprogramiscompiledintheunitofthesourceprogramfile,notintheunitofthefunction.

(3)Theexecutionofthecprogramstartsfromthemainfunction.Ifyoucallotherfunctionsinthemainfunction,theprocessreturnstothemainfunctionafterthecall,andthewholeprogramendsinthemainfunction.

(4)Allfunctionsareparallel,thatis,whendefiningfunctions,theyareperformedseparatelyandareindependentofeachother.Afunctionisnotsubordinatetoanotherfunction,thatis,functionscannotbenesteddefinitions.Functionscancalleachother,butcannotcallthemainfunction.Themainfunctioniscalledbytheoperatingsystem.

(5) От гледна точка на потребителя има два вида функции

a:libraryfunctions,whichareprovidedbythesystem,andusersdonotneedtodefinethembythemselves,butcanusethemdirectly.Itshouldbenotedthatthenumberandfunctionsoflibraryfunctionsprovidedbydifferentclanguagecompilationsystemswillbesomewhatdifferent,ofcourse,manybasicfunctionsarecommon.

b: Дефинирана от потребителя функция. Това е функция, която отговаря на специфичните нужди на потребителите.

(6) От формата на функциите функциите са разделени на две категории.

a: Функция без параметри. Функциите без параметри не могат да връщат обратно или да не връщат функционални стойности, но обикновено има повече функционални стойности​​, които не връщат обратно.

b:Functionwithparameters.Whencallingafunction,thecallingfunctionpassesdatatothecalledfunctionthroughparameterswhencallingthecalledfunction.Undernormalcircumstances,afunctionvaluewillbeobtainedwhenthecallingfunctionisexecuted,whichcanbeusedbythecallingfunction.

Related Articles
TOP