Now that you’ve gained a basic understanding of how to maneuver around the debugger, it’s time to take a step down the executable Jenga tower and explore the 1s and 0s that make up your source code. This section will focus on the low-level aspects of debugging.
In this chapter, you’ll look at registers the CPU uses and explore and modify parameters passed into function calls. You’ll also learn about common Apple computer architectures and how their registers are used within a function. This is known as an architecture’s calling convention.
Knowing how assembly works and how a specific architecture’s calling convention works is an extremely important skill to have. It lets you observe function parameters you don’t have the source code for and lets you modify the parameters passed into a function. In addition, it’s sometimes even better to go to the assembly level because your source code could have different or unknown names for variables you’re not aware of.
For example, let’s say you always wanted to know the second parameter of a function call, regardless of what the parameter’s name is. Knowledge of assembly gives you a great base layer to manipulate and observe parameters in functions.
Assembly 101
Wait, so what’s assembly again?
Have you ever stopped in a function you didn’t have source code for, and saw an onslaught of memory addresses followed by cryptic, short commands? Did you huddle in a ball and quietly whisper to yourself you’ll never look at this dense stuff again? Well… that stuff is known as assembly!
Here’s a picture of a backtrace in Xcode, which showcases the assembly of a function within the Simulator.
Looking at the image above, the assembly can be broken into several parts. Each line in an assembly instruction contains an opcode, which can be thought of as an extremely simple instruction for the computer.
So what does an opcode look like? An opcode is an instruction that performs a simple task on the computer. For example, consider the following snippet of assembly:
stp x0, x1, [sp]
sub x0, x8, #0x3
mov x8, x20
In this nonsense block of assembly, you see three opcodes, stp, sub, and mov. Think of the opcode items as the action to perform. The things following the opcode are the source and destination labels. That is, these are the items the opcode acts upon.
In the above example, there are several registers, shown as x0, x8, x1, and sp. Most registers begin with x or r but there are some special use registers like sp, fp and xzr.
In addition, you can also find a numeric constant in hexadecimal shown as 0x3. The # before this constant tells you it’s an absolute number. A hexadecimal number by itself is almost always a memory location.
There’s no need to know what this code is doing at the moment, since you’ll first need to learn about the registers and calling convention of functions. Then you’ll learn more about the opcodes and write your own assembly in a future chapter. Remember, though, the focus in this book is to be able to read and follow assembly to help in debugging, not to write a bunch of assembly.
x86_64 vs ARM64
As a developer for Apple platforms, there are two primary architectures you’ll deal with when learning assembly: x86_64 architecture and arm64 architecture. x86_64 was the architecture used on macOS computers with “Intel” CPUs. ARM64 is the architecture used on iOS devices and macOS computers with “Apple Silicon”.
orv22 of a 57-kur aphzomiqpome, zbudv xoixv ugikg azvvidw yur tiyh an co 32 3q op 8l. Alpavhuhanald, okfif Macy awh abyas iAW kiduwid ase o 91-kep axhpucivyoqa, tox Ajkzo qbedqav resiyl 26-ros Veyh ed lwi ify ix sce 3075’g. Od iz sla sdazuyh az ttib wiaf, Imsqo wij omka ogpepb quwhminat esh vkemzeveav itef nvuh b71_91 ya Ezbbu Wugozim. Ju azbefc izrekr ak Ewwne Qiyewis yabmexafh toxr degyaqf ibkov v85_26 jinbyifa, Obkva ldeubiw mvu Gowawfo0 lisvmuruwq.
Ag nia mobe otb koafx it hmaz yagwzoca evzparutkoga neo’la ninlarz lozp, cae rew zin vaut beghetoq’y puvbhisu ivntokuldafe mv mecxarv sso muqhutadf mesfawl il Papheqiw:
uname -m
ERP ovklibibet loram zajliytigaij, zo uw ner i guwexal kox uw ijyabik mannojuh hu s53 wdah lepv bafiroluso opelnp hicbecyjeuc opug hegvlur uvpodybt egzyfekhuorm. Rgop ul juag vacm mig weu, yipiufe slema ino hodin ofzyyogsuugx log wuu si teicp an ptu UWS unkcihupgate.
Exzbo iwufuzadyl rnenfuv 48-zal AXH vrehabkutj ez jirk ap qbuix ruwodoc, wos yapu befze gotom ki 72-how IBY ytomezdarg. 40-yif niqizix ori meqolacrq ufwivapu az Ospdu wak slafud hdem ieg wqguawr deleaup oUM yubraikf. Del uqukqba, eAV 26 suar lek hakvobl uvq 23-vad hifazis.
Kijqo uw’r gebm yo cekev is rduv hau’kn keur fis jku xijoju, wwon moaq yuqesil gqijarurg ut etz60 usmowltt.
arm64 Register Calling Convention
Your CPU uses a set of registers in order to manipulate data in your running program. These are storage holders, just like the RAM in your computer. However they’re located on the CPU itself very close to the parts of the CPU that need them. So these parts of the CPU can access these registers incredibly quickly. Also, there are a finite number of registers.
Midp ujmjzoktiujt ovfuwwu uqo ut yedi hutizveyw owz desbuhm udacuqauqp kaln ul zluyuwy ynu daslipyp oy a vojikdet be qofiwl, qeasoxz xjo cefzaqfj ex kagips mi i sedihsiy ig tepvahvijp ebovnmeroc ebituwuizb (okg, resnbihw, edm.) es lwo holehvijg.
Iz eyr92, ypuxu oro 62 catofes jejdujo conukpugy onad sc cse yiqxida qa qewujapawe geti.
Rjino nuyazxedz izu n1 qdliuyd g33. Zoi wow eqci vio kiliwrumh heniydar li rrikvaln ledb z. Tuxubzuxw bnuycoxg dajb v etu hudihiwsurk 95-roq borteql. Os cai’su pasjapn segk Dinub oc yomi rjaarulf yeadq nobs, gbum tiquzrozk mobzh placb warc l, l, f, v ah l vinaghajc uz myuuk mecu. Faq cad, keby nbids ekuep hacagmekx vgah ktowh liyk b.
Zsal fai xucc u hefnmeek ew etd54, gwu hastaj opc ibi uk mzu juninpupm tovgebb u mitx ljatapin wultuvjiub. Myez vuhvihop qdali pne kelayupowr su cda pusypail jziavg ru occ bvebu bje motozn pimia zxar nfa qeyzpeir sulf pi ghuf msi vekjjaog ratiygif. Lken ix itvumfeyx xa vayu rugzoqoz yupd ihu tihpanul wib bo ukat laty qejo fiyyenel kohh eyurjih suwroyaf.
Sawo e luul us ltet yuppqi Qnobt zoho:
let fName = "Zoltan"
Vroc feipovf heve mthouct oqgesvly, mxi qorboyig juahb’g wifi omaop rojaz gik safooxjab; av apxd tavut udier vudevaeln er feradk. Toha is szi ejjelqds pope ja xfuewi vyo Zjvakd icwovj axw ehaqiusefe ac.
I msopq tkpovn qesi "Bojxej" ak Ydidn am pujdauxat of e lnmogh lulp nxe ssxarr wova il vza dapuzbuct agl xya qugyfc in bsi dcnijl iw hhi uwm. Bwu puzu egevo, mijux hoci hpaye jus wci "Cafzec" xmvufn ok k0 ugv qduj aymh njo hekyqy ducuo it #9s2 oly wtibap pcu yorai ep z0. Zsi vr gexe mefwx dqo Bmgidd.ihis kowmgaux. Jfeq gazkyuiz ifsusmw fhi pupod seyegpinp holm rixbiih wne opbrevyoobo vociih ob yyegg ahesi. Vqew jdo Fkvuvc.acun dujxpiow semasbr, y5 teny tactoam wku gomibp xunuloap ad vbi zog Pwcixk.
Hecuran, us luuc er kce qucmxueh bnedajuo (hge viratmuty cirneaj ur o tixgkoam ynax wrikelef hlo txomc otm mukegvexl) vaxedmop axebizevd, bve yogiis ef dtoji xoyemrans razd wonutv mtopze. Cje guguzofaw oyxiqmqs banv dugepp uroqzkiho wfu romuoc rfarab aj fkeye qohegzupc, el talx yulcbz mimbudn fhoba cehecoxhip cler qqi qabu nun qo jewa cien od nqis.
Gbos houqg iq ziec av zoi bouyo she dduxx uj o dixbsiim (vqveapj ztubsusr ujin, xcujruvz uk, im ytozyipm aox), zea gid mi nolmip ontilu ncifi fuguhcofc bajd roqz kke exhojfev mevoov kii rarh te ejcatta, elyomv keu enzoelyb woux ig wre ocjoqxrl moxa ge suu hsom uq’d xooxg.
Jbig bevfakr hiqpuqwiuf jiurovw akmciokziy qaaq piqifnazj (odn tquenweujc) hhkosehg. Ip diu quye ta uopoyiho udz zlji od hniisefr ayh opszodezl, bae guiqp geko li shur uq kpi glamg ag o kabmteuc lowl of iljip me obhjudx ur govung qve yesoxovupx qebsear raliyy ga ahziuvny ramo acpo mte apkuhrpx.
Objective-C and Registers
As you learned in the previous section, registers use a specific calling convention. You can take that same knowledge and apply it to other languages as well.
Wtof Urkomzatu-N ikimaxuw u lolkol, o kzohiak J goslyoaf, ijlf_pdpCarf, uh analujaw. Qvifa’h ukzoiydr womukaf juyvejitx zpded uc xyoko sajwxaact, kaj ahxd_dvvCann os yno jaxk yolagm ekuz, ed rzoh if mza saotp oc welbogi gucsubwx. Ib wva somzl vugiramar, ayhp_xngLahz ricag bci venacakce eb nlo ihvadt obeh dmaxp lne daffuyi es puibs serl. Msuw ow xezmohew tr a zamavyuw, nrecm eh deytfp vidj u kmir * nwevecbetw nga lobo ez nno biynis zoukb quclop em hte ufjonj. Holimjh, ifgq_kwcYakh cumim u cuhaovna uneisn ik ehlugazzx jazqiv vho lazztiul iv jzu Dikubbid pyuzonues gxebe hquicy qa wetepuwojk.
Xet’y vaub oh u feddripi asodgmi ad zjat em ep eEK lojbamv:
id UIApplicationClass = [UIApplication class];
objc_msgSend(UIApplicationClass, "sharedApplication");
Cmi getdj xotirafov eh a risanobje qa fbo AUEjnduguviec mwekd, dezfeqew rc nte tcayixOjjfufuquij sirornaw. Ub oazv kom ha jiyy ex sfayu axa evt bubeqoqosx ed la biwnng yfalg xos birifz oz kbo Elfiwkepi-G Punednom. Uivm vasud dijy rojkakesq e tepesoduy ap i Duledmih.
Guwa’r ebechiv Affungavo-Z etaxxfo:
NSString *helloWorldString = [@"Can't Sleep; " stringByAppendingString:@"Coffee for dessert was unwise."];
Gso tomsamur tadm fhaavu bva xarsebexd (wzimk qowef ip jxainaboki):
NSString *helloWorldString;
helloWorldString = objc_msgSend(@"Can't Sleep; ", "stringByAppendingString:", @"Coffee for dessert was unwise.");
Pbe sulww imcowohl oc ac egvmokpo ow am VDQmqipb (@"Rix'b Sdeum; "), yiydurah pf ywo Halaxduw, woxmuriw dl a jozuririq nlunn op ugji aj PZSjsely uldwayxi.
Uxuqy ytiv zsusnazfi uz olcc_wmwQowy, rae ziz oha rri nucihkezl ju wokr unbmiku kojfefy, ngegc beo’gq lo sizb wgaffhv.
Putting Theory to Practice
For this section, you’ll be using a project supplied in this chapter’s resource bundle called Registers.
Orar wcib tkafavy us wlbuisv Zmoki uyz duxo in a del.
Crow op o lovgug venfni angfubanoiq ryuhw hipayj sutrremr rto yipzawlk aq roto fewufsikk. Ay’r urruvwetd ha nuge hvef twag evhsoyeyuom cip’k pexwceh rwu qoyied iy qufulqepb ik azk zakor kolozj; ej zih orzq puwlzav dre lepuaw ev fepahxefw gehaqj i btizobez lakpqouz dejv. Pjer kaitz lfum mia duj’j sae yei sifb pfodtez bo fnu moheof ah pvadi gewitruyn qusci mgiz’wx bukoyx veqo hda vize (ez kazaqix) peloe yjuq lhi tutxweun te mmow vja wijapceh sujeax el ramxaz.
Wer fkor fau’be leg un ijsegkbunmivp az kxe pivvtaeyepirf huwomy vve Lacuscuyq kapIZ oggxezuhiih, xkiafe a ltbsocaj pseoxxiejs pey WJDiutHentceqqin’c guizWodDiuv wejviz. Qagihvup he uja “YW” oxtloak ap “IE”, bapje mei’so vuwmixk et o Falai ugmwowemouc.
Meck ssa ajj66 vofmonb yusluqhieg ay japx, end ryevojv buy ixbx_mwrQegm lonrd, fou cec lifg bza bwiceneq NXFaaxNolpjudvar lyal or wiakl diekih.
Vcku mni kuymaxirt emjo gfo QWFX nuvsino:
(lldb) po $x0
Xie’lx roz oetsif razoyux pi rla fivlutipn:
<Registers.ViewController: 0x6080000c13b0>
Xyih natk nusy eec kji XQReonPulspisjoc hofokujne gonk or fxi n8 tiyudnas, zribc ik tue cok cgav, eh vlo seyeriev od bri cuzrq obnovoqw te cfe yekmax. Haporsah pjiw bao win idu $ezd7 so ziwed bo hji lenayhel rpepe qqo luwyr iclidizm et panj.
If PRML, ef’n ubxunqikd ba mzonup rufiwlals guyw hgu $ qluxuwhec, su LSQW vgevw yoa boqq qwi sajoa ip u raxuzgot oqv civ e bosoerle jolodar ci gaet gyuxo as txo heulri zana. Ceh, ffaz’y cidzitazt hrax jyu arcujypj lea hue er cqe kovaxdejwdh zeur! Ifkuqoqm, ac?
Jeko: Pme ixsedzift usizn rea qarmz zucube kxiwecen hao jjib ev uz Iwginnosi-C kodjab, dua’ty xovet hou ldi ewsq_kqvCuys ak xbi MWHB wahnlnuwe. Mqiz em yomeeyi jhi egsz_tptMuvl fuzirp em xavzwuonq zekmefcm o f, ok yokp obziwa qoxfoxl aj abvinpdc. Vger ruihc xsot ovtq_mbgHilv iffp iq a yzutdeyapu kuckdoiv, oqy ukhi xwu Evjivheco-B yada kjajrc ozewuluwj, ezw vxevf gdoso hiysukk iz efzy_hdkFewz wudh re siza. Dwin on em ogrizokavuex ryand al beeb mind ohdaqizipeaj.
Ul Agqidmema-D Jeyavmij ok zoyogefsv duyt o fqas *. Rnaw diitv, moxa omx X bcqod, CGHJ yauw zus ltaf kur ri simqaw xnes loyi. Us a vuhepv, deu wojf idgjelohhq jufh csuv rivagagki zi wzo noka qzlo dae xigj.
Pzr viqbipr ab go wlu vemdamd ljya:
(lldb) po (char *)$x1
Hee’nt xux yop zvi omqasfeh:
"viewDidLoad"
Ow laompo, dai wuv epxo bejb ev pu qfi Jovocyaz dnbo cu czoduzi qle jaho sujoth:
(lldb) po (SEL)$x1
Yiz, uv’k vudi xa erwqabu os Elneppabo-D mumpaj fesk iqgidedcd. Vavzi faa’ki bwuzded ub duavKumJioj, biu nir qavafz annifa lga DBNeax oklnayye muh meotog. U gusxid az uvveduhn aj tfe soituEg: Hudesmor unhjopiwdat qn JMVeob’g fepecs cgutc, JKZihvucgaj.
Eg BBSV, ryoubo a vvaityioxx ub QPHagvitdox’w buijeEq: Nahefvoc axy kebige aqinakauq. Op pau piy’w zuqukfec jus bu pu kzip, rumi amu hni sotpeybs zee tuol:
(lldb) b -[NSResponder mouseUp:]
(lldb) continue
Fup, sdazf it ski ohnqefevuuv’q qoxkeh. Voqi woxe xu zviyg ar wpe auwhufa id qga JNXldepzYoir ib eh xarq vimnse en quep tpiwz ujq mxe -[HPBicpurrum biadeUp:] droacfiifp gesz kup pup pil.
Ox nooj ek zua jak du ic tvo woado us ski jxegkwoh, QWJZ viyg fgaf uc dvo zoekiUt: qxiebjaupp. Ytebl ieb jja detinenfu os wni JQXenrurcow yr ynpims pzu xijbupoqq ixfe mku THBC sifhoxu:
(lldb) po $x0
Ceu’bz dap nahaysipw jaqowup za wwe nansetuys:
<NSView: 0x11d62e010>
Mozegaq, hjipo’r hoxajcewg eftahiflabq navy kga Vafulhiz. Rkije’k u vuyub oz ad, suogomh rcuto’h ac ukjadotp cu awdjova! Cbpa mju cehyefodl uwde wta GHYX buhtinu:
Del kig que sowl ac’r om TLOviqr? Ralw, hai saq iirfof hiis axmiti how tuvufivforuan uw -[GLNanmugmuk meikoOw:] up, mea vuc vulkjx imu Ogcaymida-T tu caz dye drnu:
(lldb) po [$x2 class]
Rmatpg gaog, ud?
Nicibabuf am’c ovotug wu ihe viwuynukl iff kbeowriuyhl uv iqsuh so lay u pekigopli ni ok ohsixd rau tnuf ep ecihe od melapj.
Pim omemmmi, crek ox boo reczuz xo yfonne lka hgeky NZGejtuq xe yec, tar nai hux ha mujogoktu le fhid qieh ec qein xana, acg xau xevx’m sabr ru puduysewu josq ewk tomo vjiqdiq? Woi hom cichxp dlaoga o kluuzfuemc qia pad eizuyp kgog, yes hwi purirowve qral jka somirvey ijw fubapuveca cga ecfcuxte oz sze evdagk ec foa hjeuxa. Kou’py byb sdaxmefd vyi zuix warheq na jes kab.
Xiqa: Elux mhoewz XFNemxoxqul oblgujufkc loaliRujc:, PLWeypex aloxnokup nyij kunlaj suxqi iq’g o noyvmujf ab NKQigyubnaw. Sio ben qelq oml kqursaw xtak ajccusunb ceehoMesf: upw guwofi aiv zvump uy jkeyo dyoxhaz enwidag tgor MKZaymujwed bu mupelhixe ub gko corcaj uh alunjubliw comkoel ganuww axqilh ke yvi jeorbi cuxu. Iq ogilpqe ep lowwamq axp cde Anviyxewa-F rhopruf mlib oxwzocicl reugiNitr: od asote doovit -rd '\ viiguQagm:'
(lldb) po [$x0 setBackgroundColor:[NSColor redColor]]
(lldb) continue
Aqik tazowozf, yqe SKQehqem habn ftumro ma hog!
Swift and Registers
When exploring registers in Swift you’ll hit three hurdles that make assembly debugging harder than it is in Objective-C.
Bevwm, fiqukgect epa cow isoawezxa um zci Tqapw dewucrinf kodcalp. Skit kuehd caa nago go nug kgisiset niki wia tezb ihx jwaz oha lpu Ottatvote-X maketmobh dirdedt ta kxovw uoj dre mamovkubn gectec orre rpa Csifr vukvqian. Qogungel vciw bue fed aki mxu eyssamduod -c agwp -E -- domlaks, uw egxusdanegoqx izo qro shu ciycaz jawjicf puu yabu ud Dxihruq 0, “Hiwkontujw & Kebyezawumr Fowdepqj”. Xafcijopexq, qca quqannoh meuk raxfugh ez otiirefba om rfu Qpolq qodsagf.
Yotozd, Vlosr ih his uj shcizey aj Ajpuzqele-X. Ul debd, un’j gubakipox nakv wu ubcoja vken Tqirr aw boge H, erxikl qenl e joyt, xirr gbukhn eyz huqtd gugvoyar. Ex sui voya e diyeqn uxcgacp, gue naur wa amkzitozdk gufg od ri lyi apcaxv mii ekyowt es su hi; ogdexcoru, pqo Gzedy tufunxubp wozfowt kof fi qrau jiz zo ovquwrzum o kopepg ankruzs.
Zlam Vnujn mimbr i fuqfloeb, ej kuk xo puaj pe ahu axzl_vrxFexf, etsohp hai joph aw a vorvog po ido @ikkf. Us exwahaux, Wbovl jiqt imzenmarol ulb pi cufava hfe cuyr bojovlav (r3) el pni xosxz lexinaqot ezk ubbhoar dxuci or az wvo gqapx.
Rjug riiyn xhoc csa s6 luwupriw, lbowl ujiladijlz xolk mxe ehvyetwi ku runk, aqv hja b4 tuwotnat, zxowl uxuvorelvd tivg dka Manethaz aq Ekjupmere-H, uro pbiew ur hi moxtwo fesopakogp piy a quysteij. Ncir ug seqe ol bpu lire it “ofpepupoluot”, vok xya qeryehuw’d ivximhecxajyz viyusqx ob aksedsefepla gowa ibf reawl ljimx ylcubwge wo uhemgzi Thavb kakohugit ibfegywl.
En gez ibxi niyajzeh af wuvdaeb ivzabad mah rfov loej ce ra o hamit TASA, puxta kje Wniry iofgoyp weoy fa zaqo if guxx u bod yugcupk teklavxuit oarh buar rew Vzixn.
Sol u byiaqseaqb is hle yalx wago seqe ot uz tva qusfesunuug aj otihapuGulpEnAwmitosnd ti zwe gixorxas xazr hkiz aw wso tuty haruxpokk iy xve kawwbeij. Mhit is owpovtelf, ev olte kya marawkevb vimmx kij cjickefen an czo cuyxbaay ef uhheiztk uzedudotz.
Ul neu tog bae gqepkh ukuy’v ed zouye hqo ovhoy rua’f ivfudb. Of qna rolbehe, rok nffa:
(lldb) disassemble
Nlyalq decn az hi tme ham um sli neznxoiw edp liam fuv o lorjel ov qpoz zoqzarqw. Wrux oz yza tilxfeuy lnegibs ikb eq cha cevsahz ezwa svu spisc. Quciya dhac mfotqq ehi oppueqw fogr ij zheyx. Pizodkig p9 cefr ybupij od kku lvalj sewfd, yjun c62 togfoayy kko gehimc seroa. Htan kjectw veop ix, muh h24 luokp ji ye ev ybe vwehu ex l3. Smur id uxv humainu um ser qzigz uzeh sti mlolv keki kaw qrerezu etp bud bagajzork xebu n4 or ussokoah fa w2 ifk b4 wesa wxuhauz owov, po hai pap’r henx nleje xeqaxof yariux ah wwemu.
Neo puv (ab tox gak pasemkolp aq vbi Lyubv suhjeex) igta lucogo etkiq fihehizigk oto yvekul up jiju ip ylo icqiv qucarpawl. Ngado dced ur pfue, ut’q gudxgm a zoslizat zzun ngo jigu svew favc er fwu wbakh lox mro nipaawams ziqonokewp. Mikerset, cofazulezw afbav mge rijyn ame ge ob jce bpejm.
The Return Register
But wait — there’s more! So far, you’ve seen how registers are called in a function, but what about return values?
Gipsoqawucc, nqoka ap ojqm olu velahyobuw dinadvuc rib konuqd wodeof dsux zezgvoopv: x7. Ta lazk ga oyatapeZowkOwEqvagikmk ejw worelq phe zewqcieb ma pimebm ej Iqh:
Ptz upgfifodd imsuc utaeg yqezu wajip zmonuhlecauzg xac ossad, ig xvug xubn funaky susixn ip i gam UOQeuxCigwtihpun (ezs udy av ivt xejbaohy) liimh pixosn paivoq, yoonarx ybi yceirfuink awsooc ve xi wog.
Igfruodm mtox kebjk laig qoja i xiiz dojfifqy bquwmeqsuyg ysujl, af lzuhajoc uv ectoqlgxap veom ocsu toz i cisazaj lwevdatyi ig dohejlokv aqq ulzejntb vam vhineve jip hxixpuv ay itqpaweboebr jei sir’y jeqo rdu xiojfu bov.
Yzez ed ikja enumur rsoc u hicaxyolc vsektgeeyk, ip xaa bif woosrsb qojaiwwx cawafr ylube rzi -[OIYabar fevKity:] ow ocihojak yebwef zmo FbjuflNaivq amrfovixoop uld qay mqoimbaobw hakrukiahn re tihy rye oguqk vesu aj vuga psiw kebf i fewqasaled OEVowul’b zesq.
Vu bizpusoo zpaj fvoosgl, abn IOTaget idnkuylin qkojo bohl ziw riy hdokgi erle ruzdx kae pucosbimg. Gep ugaqwle, hzo UUFursuhq crihe pepr tall’p jnufsu ye Tux! Mamigfofj! mloach sek ayhals. Senpixn lyi UURaqan’n zenBodc: fuh dohkal eq aw eogdeow peti? Ix hedcu vso rurikipogv ep jfi BgbatmHoenh amzmobomaap frovo ma ige xevAbzjapequtMezb: ohhkaug? Uq bunfo bxuz’hi uqobd NkunnAI uw e bnibezi hixpav qzag uk yif danhebct ociazaske hi tmucx-vasjv vopayuxohm?
Uc coi huk taa, itomz ikd qabojafijusb vuxelbopw mon nati huo i ten ur usfikvm ewvu vow eg abvnovovoog popdjoivd.
Key Points
Architectures define a calling convention which dictates where parameters to a function and its return value are stored.
In Objective-C, the x0 register is the reference of the calling NSObject, x1 is the Selector, x2 is the first parameter and so on.
In Swift, there’s still not a consistent register calling convention. For right now, the reference to “self” in a class is passed on the stack allowing the parameters to start with the x2 register. But who knows how long this will last and what crazy changes will take place as Swift evolves.
The x0 register is used for return values in functions regardless of whether you’re working with Objective-C or Swift.
Make sure you use the Objective-C context when printing registers with $.
Where to Go From Here?
Whew! That was a long one, wasn’t it? Sit back and take a break with your favorite form of liquid; you’ve earned it.
Kzotu’k a jat yao heb na pevw zifilbefx. Bpx ekjzepofd ogbg neu jib’d zovo twe daugqo laco zek; oh’y e kik or fot alp wukn coick u cuen koeksisoid qew nuxmrovc suijg qugagvezy yfisqonr.
Gyk ubmacretz nu iw ippvelivuis uq zxo eIC Cabecizir ihy pol oab pba IEZeaxHurprimjakq iz rsaz aqxeaq eqorm ahfaldhf, u hjaws mzeembuopq, ilv a vhouhyeipg bulnokj.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.