From 689d3105836a10dcbec20534b4dbd326da1903f0 Mon Sep 17 00:00:00 2001 From: gy <1092923610@qq.com> Date: Mon, 28 Oct 2024 09:04:32 +0800 Subject: [PATCH] lab2 --- labcodes/lab2/bin/bootblock | Bin 0 -> 512 bytes labcodes/lab2/bin/kernel | Bin 0 -> 131208 bytes labcodes/lab2/bin/kernel_nopage | Bin 0 -> 131208 bytes labcodes/lab2/bin/sign | Bin 0 -> 23304 bytes labcodes/lab2/bin/ucore.img | Bin 0 -> 5120000 bytes labcodes/lab2/boot/bootasm.S | 32 +- labcodes/lab2/kern/init/init.c | 15 +- labcodes/lab2/kern/mm/default_pmm.c | 250 +- labcodes/lab2/kern/mm/pmm.c | 432 +- labcodes/lab2/kern/trap/trap.c | 54 +- labcodes/lab2/obj/boot/bootasm.d | 1 + labcodes/lab2/obj/boot/bootasm.o | Bin 0 -> 2268 bytes labcodes/lab2/obj/boot/bootmain.d | 2 + labcodes/lab2/obj/boot/bootmain.o | Bin 0 -> 3984 bytes labcodes/lab2/obj/bootblock.asm | 354 + labcodes/lab2/obj/bootblock.o | Bin 0 -> 4408 bytes labcodes/lab2/obj/bootblock.out | Bin 0 -> 446 bytes labcodes/lab2/obj/kern/debug/kdebug.d | 5 + labcodes/lab2/obj/kern/debug/kdebug.o | Bin 0 -> 7700 bytes labcodes/lab2/obj/kern/debug/kmonitor.d | 4 + labcodes/lab2/obj/kern/debug/kmonitor.o | Bin 0 -> 5856 bytes labcodes/lab2/obj/kern/debug/panic.d | 3 + labcodes/lab2/obj/kern/debug/panic.o | Bin 0 -> 2704 bytes labcodes/lab2/obj/kern/driver/clock.d | 3 + labcodes/lab2/obj/kern/driver/clock.o | Bin 0 -> 1824 bytes labcodes/lab2/obj/kern/driver/console.d | 5 + labcodes/lab2/obj/kern/driver/console.o | Bin 0 -> 14804 bytes labcodes/lab2/obj/kern/driver/intr.d | 2 + labcodes/lab2/obj/kern/driver/intr.o | Bin 0 -> 1448 bytes labcodes/lab2/obj/kern/driver/picirq.d | 2 + labcodes/lab2/obj/kern/driver/picirq.o | Bin 0 -> 3140 bytes labcodes/lab2/obj/kern/init/entry.d | 2 + labcodes/lab2/obj/kern/init/entry.o | Bin 0 -> 25640 bytes labcodes/lab2/obj/kern/init/init.d | 6 + labcodes/lab2/obj/kern/init/init.o | Bin 0 -> 4788 bytes labcodes/lab2/obj/kern/libs/readline.d | 2 + labcodes/lab2/obj/kern/libs/readline.o | Bin 0 -> 2136 bytes labcodes/lab2/obj/kern/libs/stdio.d | 2 + labcodes/lab2/obj/kern/libs/stdio.o | Bin 0 -> 2932 bytes labcodes/lab2/obj/kern/mm/default_pmm.d | 4 + labcodes/lab2/obj/kern/mm/default_pmm.o | Bin 0 -> 18564 bytes labcodes/lab2/obj/kern/mm/pmm.d | 5 + labcodes/lab2/obj/kern/mm/pmm.o | Bin 0 -> 29356 bytes labcodes/lab2/obj/kern/trap/trap.d | 5 + labcodes/lab2/obj/kern/trap/trap.o | Bin 0 -> 10056 bytes labcodes/lab2/obj/kern/trap/trapentry.d | 2 + labcodes/lab2/obj/kern/trap/trapentry.o | Bin 0 -> 1180 bytes labcodes/lab2/obj/kern/trap/vectors.d | 1 + labcodes/lab2/obj/kern/trap/vectors.o | Bin 0 -> 30360 bytes labcodes/lab2/obj/kernel.asm | 12382 ++++++++++++++++++++++ labcodes/lab2/obj/kernel.sym | 461 + labcodes/lab2/obj/kernel_nopage.asm | 12382 ++++++++++++++++++++++ labcodes/lab2/obj/kernel_nopage.sym | 461 + labcodes/lab2/obj/libs/printfmt.d | 2 + labcodes/lab2/obj/libs/printfmt.o | Bin 0 -> 9372 bytes labcodes/lab2/obj/libs/string.d | 2 + labcodes/lab2/obj/libs/string.o | Bin 0 -> 7536 bytes labcodes/lab2/obj/sign/tools/sign.d | 1 + labcodes/lab2/obj/sign/tools/sign.o | Bin 0 -> 17456 bytes labcodes/lab2/tools/gdbinit | 3 +- 60 files changed, 26644 insertions(+), 243 deletions(-) create mode 100644 labcodes/lab2/bin/bootblock create mode 100755 labcodes/lab2/bin/kernel create mode 100755 labcodes/lab2/bin/kernel_nopage create mode 100755 labcodes/lab2/bin/sign create mode 100644 labcodes/lab2/bin/ucore.img create mode 100644 labcodes/lab2/obj/boot/bootasm.d create mode 100644 labcodes/lab2/obj/boot/bootasm.o create mode 100644 labcodes/lab2/obj/boot/bootmain.d create mode 100644 labcodes/lab2/obj/boot/bootmain.o create mode 100644 labcodes/lab2/obj/bootblock.asm create mode 100755 labcodes/lab2/obj/bootblock.o create mode 100755 labcodes/lab2/obj/bootblock.out create mode 100644 labcodes/lab2/obj/kern/debug/kdebug.d create mode 100644 labcodes/lab2/obj/kern/debug/kdebug.o create mode 100644 labcodes/lab2/obj/kern/debug/kmonitor.d create mode 100644 labcodes/lab2/obj/kern/debug/kmonitor.o create mode 100644 labcodes/lab2/obj/kern/debug/panic.d create mode 100644 labcodes/lab2/obj/kern/debug/panic.o create mode 100644 labcodes/lab2/obj/kern/driver/clock.d create mode 100644 labcodes/lab2/obj/kern/driver/clock.o create mode 100644 labcodes/lab2/obj/kern/driver/console.d create mode 100644 labcodes/lab2/obj/kern/driver/console.o create mode 100644 labcodes/lab2/obj/kern/driver/intr.d create mode 100644 labcodes/lab2/obj/kern/driver/intr.o create mode 100644 labcodes/lab2/obj/kern/driver/picirq.d create mode 100644 labcodes/lab2/obj/kern/driver/picirq.o create mode 100644 labcodes/lab2/obj/kern/init/entry.d create mode 100644 labcodes/lab2/obj/kern/init/entry.o create mode 100644 labcodes/lab2/obj/kern/init/init.d create mode 100644 labcodes/lab2/obj/kern/init/init.o create mode 100644 labcodes/lab2/obj/kern/libs/readline.d create mode 100644 labcodes/lab2/obj/kern/libs/readline.o create mode 100644 labcodes/lab2/obj/kern/libs/stdio.d create mode 100644 labcodes/lab2/obj/kern/libs/stdio.o create mode 100644 labcodes/lab2/obj/kern/mm/default_pmm.d create mode 100644 labcodes/lab2/obj/kern/mm/default_pmm.o create mode 100644 labcodes/lab2/obj/kern/mm/pmm.d create mode 100644 labcodes/lab2/obj/kern/mm/pmm.o create mode 100644 labcodes/lab2/obj/kern/trap/trap.d create mode 100644 labcodes/lab2/obj/kern/trap/trap.o create mode 100644 labcodes/lab2/obj/kern/trap/trapentry.d create mode 100644 labcodes/lab2/obj/kern/trap/trapentry.o create mode 100644 labcodes/lab2/obj/kern/trap/vectors.d create mode 100644 labcodes/lab2/obj/kern/trap/vectors.o create mode 100644 labcodes/lab2/obj/kernel.asm create mode 100644 labcodes/lab2/obj/kernel.sym create mode 100644 labcodes/lab2/obj/kernel_nopage.asm create mode 100644 labcodes/lab2/obj/kernel_nopage.sym create mode 100644 labcodes/lab2/obj/libs/printfmt.d create mode 100644 labcodes/lab2/obj/libs/printfmt.o create mode 100644 labcodes/lab2/obj/libs/string.d create mode 100644 labcodes/lab2/obj/libs/string.o create mode 100644 labcodes/lab2/obj/sign/tools/sign.d create mode 100644 labcodes/lab2/obj/sign/tools/sign.o diff --git a/labcodes/lab2/bin/bootblock b/labcodes/lab2/bin/bootblock new file mode 100644 index 0000000000000000000000000000000000000000..b04b04f58b3af9b64903fdd9b677a794735388c2 GIT binary patch literal 512 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µ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 literal 0 HcmV?d00001 diff --git a/labcodes/lab2/bin/sign b/labcodes/lab2/bin/sign new file mode 100755 index 0000000000000000000000000000000000000000..4c69da8f26a9573c07a1d247b6b26a80f5319392 GIT binary patch literal 23304 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 literal 0 HcmV?d00001 diff --git a/labcodes/lab2/bin/ucore.img b/labcodes/lab2/bin/ucore.img new file mode 100644 index 0000000000000000000000000000000000000000..57ec409fac360aeb16cfd7aadddf05b7157a3630 GIT binary patch literal 5120000 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

iWb2}iZ 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%0Dons`TxTdu{u zj%8jETUq86@tLNlkY&>3GdQa3>EahnPch53xKl5cP(ZeN!S??}h06%S{G7VKTE{Z$wf<_o)=t-JdmS6)y57*_{=G4n>mU&CAp&Xl>sxP8@SetE|{D8P8+T>kIMjl>_z>S$VX?@XFtuNZ5 z^+oS%ebEP68Mn&5=yRk?^TP=kyN6+_N@I7YGcXSamx1H(q2urNw_TYZw0ZRp+PwM) zt&iHHH0E?bPEEmZ`?mQtF_6br16|(q4{ltYY~AT3H6lvN$?lVVQ$k|6GIFuA~1~ zZQgrW+y7Mi>Q32DIDb+}B+VJzWqp75mTI z9KNq*_TRQwe%kU*&@~bM&&m{B$Ze1MV@P>6k&zU%O zi%oLsajN02VW%1$ND&U~aT%TP?bO9NEI$A%b#+kv(hA1W*_~x(7^y6iYqC=72%}rK^g&(4ha}%3=4u_9DX_m+vvIVwro4Yc!_+y+_5p$GDz3 zWMqLI-8JP#dI!*zE(KHqKGO2!Gb-27cU5YbVk=ar}Bg zOZP=B-Ion)Ey=?x)@kkf6@zR@`9^6<8nhj)zTc4V)3Pb=>ht-R%0KT~dWX8Ceib~^Q97S)Txw;KI4rap%bl5zW% z54FDKL&Keue`I7TamasSxbyQJhP&@tVa$Y#?uU*|=$;5g57Qs}sKocJ_(c0>Ho_Ld zK09D5+Lt5N_vQB3Hl%R2hA`#I0tTHgf-VpIt_JrlQ6! zEh^W!;1Ya02R%>j9Q6FK+mE%=ewWcs+XHMbf2DCD^pFj^v~k+0$58_x>nQa&c1UHJ zG)|4?-kt0iv_Igs!F25&Wtz5MovzKV(zJVX>DpR2O}odDE($gM?pinCr$LMQCZ)p(@FSzz+Rd)W?jrVhH-}n(i5gX_ECv%`X64NvC9&B7JkR5$$tYb zgN)lRU5+z#cyVVsMq{_UH)?ByaoQSloVFi$v(^SDXluGGxd*r(=~5k~;(Z^Kg#1H* zqY|IK_$0Jd_P+pm?g=hI7#$ab%kWKk9;<~nL3dMvFz4{{uhGc1leMx;mcI!iIj@)^ z*Q6gJF6E~LK64P94898KHpb5$%D}FDoEbdDy;bvp0&RU=DB~j)?rR~4X(w@hj&E=%~;CE3%IK0^XT%!;?S9>1yHnEe#Z_}QazTI8{Q`~vN zVBec3;xtZRp0Dkp%@^(-+I->8?dJ=RCf|*@M7VSNc_NL&=gH@sRsQG6->xYRh%qb^ z5I1Q&o_P^gU8-R8oNzJoU07{6;dg7#n%*s*;P9Z_H*1OdErBS_8_%-&RP!ZzHnkIE z$T$9Mhxgl@;2ZirZK>uPOSN(QUTq&>nYPz`pZ09b{o45QFA-ElK^-j@PclCspD(%! zdGOd_H))(}=W~7gllkx?b_}Zb$F=?B$F=qT)7mqK&uDwU&tS(_9bS0b6U@(R&-Sm? z{BW)O9Vdx-LF-ulCGGyyI&DvQoz_pjqU{O)Tl~gxUl+$TcK!AZZH!wldT?F8DK601 zect{}9<#i-iWWUSd_o#=_+$Vjzddi9yWGL@IN< zxSYAU@G>Wgbmo@gYUa~L26HQMEpuxznz@Y_!+e&wk-421$J}0wXYL@fnLT1Mb4M|i zIa$nP?kw_{yNFwvyNX%N-NYQ`?&3D)USd9TZ?S;+d~p|ZKe3p(zqp6_B5^PC0C6Al zAn_pcV6lSvQt>!*s(6z53bC3QcfFXe6fZERi5Ho#7XM}*CSGIC5N|M#6mKzKBmTpD zt$3F?Q*2=#BR*ihL43?SR%~a!QS4y8S?pvUFTP-&Aa*fN65ldsi|?6p#1G6<#ZS!B zM1=Vkv7dRSILMqUer3)RhnWjR9dn^L#_SiznP&^bhWRehp80NZ4)bE+Va9(a!@NYC$6PA9GA|RonC}yPnC}{#2}D{!Bd0{9o}b^A}<* z^Oxc!=3QbP^Ecvk=G|gF^S9zn=1TDn^A94-yhm(i-Y3eLe-a-u|13Uc-Y+VctHfu_ z)nX^}LGcxHjrfN7SMe=#t=Pl-o7l_zyZDLusHkE-CVpZ5LmXuOOVl#gi{F`rQO6u( z{K*_^)H63SjE+t}5N9-IKFx?@ZfZ1TZf+znw=h~VCm3fipKi2eKEpVRImu|x+{Wn0 z+}7yCe5TQvxxLYi`D~*H^EpN@=8i@`=5vh;m^&F4F?TTrGoNQ%!kl8HGIuw8%sq@N znR^=P%zcdE%zcfK%;y`|GGAa^$9$o21M@}3jm#Gt6PO1X6PX7a+02(3)0k6@>CBfI zGnu_c0khBWGY>UpF{c~1GhbyCGhc1YXC7`WWFBGM#XQnj%sk2{WgczZ%baQ4$9%o< zAoC5z3g)rKBh2HBCz)?HRx*z_RxwXB)-X>po@dTB)-q2qUSXbUyvjVyc%6BMv5|SE z@iud=@ecE?#(T^K#{0~LMmh5=V;l2q;}hmNMg{Zj#^=m;7+*3M8(%S(7~e53Fe;hv zH1;qrGJa;h%dnX5HmaEKF>07Y#v$eF#vjc08GkY_H_UULw*P<;%lx3x znE7F&8S^7XbLK~l1m-7{@BQ2-eyc;-fm1|t}t?$KQ;21KQjuLKR0GGe__mJ z{?fRe`D>$u`5WU-=H13Z=I@OlbEOet{=q0^-fP^?yw6z9{FCt@vt>NWyx(}7xypEw z`GB#S`JnL(bB(cv`LOXKbFJ|*^KZs0%yq^a%twt4%*Tw4%zqm1GXG_4Vy-vdV>ZpL z%rWLi%(3P+<|gK+%yH&_nNKr6XO1_&W^QioW^Q4A$K2BVk@<9UAM+XJ&&;jOYUVcP z0p_-54Rbs5H|F-{5$3baqs$)jFXoP>=;XBhb4`=Ev)P2Xi+LLJd1f=_Ze}8Lck^`S z9%d4AZ}Uv%K4v@SzUJA?{mpZkFEEptFEqO_4>Y?oUu^bd9%S}rzQpX$e5rXMbE-Lj z`3iFgv)8zx29$}7RzSg{+d6YSpd9-;G^L1tx z^Y!K=<{Qi$=9|o0n8%qjm~S?7nX}A7=80wz^CWXN^JMc5<|*bp=BZ{0^K^3&^9=KD z=9y-YIp18$e5<*Pxxl=ixyXEod6xMw^KA1`=G)9N=G)DunC~!GGtW1lV=ggYU|wLZ zV_s;!&b-K6&wQ8pHgnM2#C(tW9&^at%DmLv&U~-AgL#>`llfofSIo=JZz}J(<^=y_q+d{h8k~2Qt5H4r2a~naUhCeaxH8 zE15T&!eT^=3?gW%u?p>&3lfblBs@Rw5K|oe1lx<)bs;ZainE`2_*|%l~0jqnuYkHdLrKsv220H z6cEvNLFA7}qkz_kGp5s~*jkr5|jdS=jf@B6=Z@B3uV{JMT8 z;zVS`$=EX^Q~A;9uP8qz{dMKXr*BezLi%RqC#Jun{N(f<%1=q(sr=M*U3qu+*`|4@ErI^4;X{|}|p%Fjx#tNbJBjg+60o~68&-cNT{OR<|%72r7Rrznze^dUu^jpfGO~0-D_vy^et}gs3y`J*t z(i0OlnHNCs?*VB6_|6966`J3ql z%KwpGr2MUPhw>n^zw$71pz>7aFy(7yj#9pM<{0JcWKLARe&$r=8)S;gH_Y@YpOqO< z-jrFUe0HX+eACRB^35`5DBnDDw(>1A=PKVSbDr|8GZ!jE<@;uyRlZ;5IpqgrUQ&Kw=FiFx%KSz7 zp_w<7AC`Gj`Qe#h7gy%HGHWS6DzlFAqca;SKQ1#{`SF=|DL)~zh4K$%wpD&|W;^Al zWOh(q%*;{Vo!L!!PbR0lFVm{Ll$o!5NoG&w1DSo4pO)EA`LfJG%7-(DD<8=msl1#y zR(UmZlJe2a$;!tv-O5*FO3Kg7^eg{RW>EQuGp8&6NT#a%oXiU4AI*GN`FWXhl%JnD zU-`!~7b(9m^GW3wWyY0%D)SlT7iX?i{^`u;m0z0qlJd(kUr~N}=IhEoo4HB(m6@BB zUzPce@@q18DF1xsPUY8T>dGfF_bUHV=6>a0&OD_2y3C`>zn1yA^6N8CDF2Vl)5>qm z{8srlGQU@TbLM&FlbIKk-;$YD{+-Ng%5TlQuKc#lKa}5*3Fo--|Gi9F`JI_{mH#la zk@6p9W+|^{HdTIiW=rMwWVTj*Zzik!fy|D|AI$8m{68~ul|P)xEB|SxS@|QGcI7|I z?4|tYnZ1=img!Xf%gn*bpU51l{K-t0@~1M#DStY1g7V*FPEr0$rbqejGQG;5%`8>^ z$IOuOKV?RgKbIL*{zB$Vtxd4?wy+yM8VyIyab=-EYaKLB2nhk7`U@pzBND<1#Y=CS@q zai1WZJQI7Zr{lkOZr--Bei<&$P04xr;khZdvqkuk-gCKK=2_y8puYopccFhVd;%Un ze|rp4bae6tkoY;SW4*ob$C>>FSKD}gwc2>jaM6$kp5M?o&ot+{!G`@kVef_4tiPY0 zpV_oUJ5(euXM1se*o*Tc=6UI-(a&0q9oQ^Yv%DQH`IT>}$+bJ*a`EmAJ}E!J;pm9_ z+vtca@7Rg=jO-e4dCVd1ToTK73$};3I5*`xZQ{|%TT9+6grk!;ug&H6B%22LmfIM7 z0ynYwxt7Oyyd2l)kmpfj`(NShJN}G*ZA0FR+ot+gnSCgquz6Xg>1kmXf{U{?I3DWK ze4grD6?Ci4RpyyI5j%Oaz=i65wYTTuYVTbfpYxtmz0!MM-<9SW+9;kYy?3WvyV84l ze~p4m^TvGVF4Eu3dv3P2toQnQcT#FiMU(>$1#pq0+Bjr=R z@pq@yN7S+r*Ujt1*&On|g}7|+9tL&ieG49MRsMDFoq_+sb&ZZr-jZ{u@|(QpU_{Vx9`%^sd3&G{77|fGw=TqQQn6T?+^N} zzHzoQ;62Hzf4f&!Zx5!`{f^+TaF_lo^;|~+*-g)eG70CUPAdD}ueX*Bl%9|JGZfS5h6O+f9gG-f4BF1{yp9v_WRhy?)2|B@1}5eJCbvW zk9@bn^}6y6qf>BmcI#K2`@Q$6-f#B1xp>Y}ofdt|yTl`HuZ!n$)w$nmhwl$QD+%C` z=h(j&QTT(wJ<9L%_O;#T?N7PSeA6ik`;hnE{)f$86_>V6=D9p>=Iu|}JlG1GyR!X0 z)j2D8FYYeQbJYD2Z;#uQ_a5~}&HG_oJRPckRbZr03c$xKMSn=Kbm}Uze-SFN4d_aq0iOy3eNJfZHt3ZC}(vmSq5`LE4>1ef2` z9`5>X=j}V->+(GF@6xcL>O2+1dk~%uW~1ZszP0L{>g`83HOQh9+4=LqZpyC> z!tOnnhF9%KS=yOb&G=P(IvIh*?aXW5o}<^iJ#nvj?@xQ(`xe9NLA>|vb#I^S>%s0? zR^JHXcTK$E?ce-+aIxzA-Fsito56$X{$}uu^0$Juu(K;Cjl8q-uEDmrM|s&b*vaE_ zmG2hhl~=qyH5Idu#+88$3NFsK1KBSV#rbw{nDQ_zD^GuLRq`oqe8DolU|WRcDiMj`GbzRuiq=HV^xhzdO9p<5wx)GW@>B?^V8a z_`LFM!oMqjPncTE#lKy+neuG7i}LNmMetK?ot5#)60iP_ST6N?h2>N5Pg^cy6<7D= zI|y>NdUQ(jx53{I;{P)GJHX{z-uzIHcCsZ^_|D;a;>aPqDWdRQ%sWOR_g%gBf$SD$ zRcCHE2kzSTJvIIoZw%9F_C>nua;)mi4Uh8TIZpZR;h7$Hv+z!8=|^#QW#Dp+=PdI* z7Z?B4>b`6ES&e7c@M`6`@M|9bmhwXQ3*{}L%oF8cTonFSL=BI}+il^dSkdKu=Qd~C zmLPr~PHRv=$E9s=)oBa&)V886>`>kw%J{+M@f_9P)r>i#^z0g3p!&Oddkl9A#?`$N zxVOmgE+ex~)}`S;G|q+L^{T%xbZ>C!3>JltsQaSux61bl(^}u(AIAN1N4S}~?-Ry- z?mponb>BBE!kw+g=Et_Gs7`B8gS&KItUCLKpHQ8B!%uts^UC)N>mHB4b|2w+AhlYQIyZGPGur20&;gL>jkfEJ%@y}l1(r{?Fv9>>lhMRbNTjhs``*{3h z}#<3IEGZ9w7md%_JpKFi~qczg@EtB<=Za&|r|*b#SU z|9R^E!EiSX`@wLY^4@U1$M;g+7xs9(UwJ9~B>Z;U&P)4$kL5D1b7MT|FI?XteSzyc zgh^&K<&3)hc4hK^XM4zfUw1{eoUN4}?nXmp&-8^~f4IT~ObK1G_d za5>(z>5rsnAMWMY?QhxWy&}R_x4tdz|6ilCp2ht(4UfzS`+xU7#Zxw(r)R_y zrTJVh{U7z_eeriOI=NG^8Cugep1-U%o{xL+T1Jw|36#Z*ZltfEmh}#{r&&D*>uh)&VAt%q$#eCn@AGP@vq+beBmf)w$!HQJkI+eFFjHGmzwiL{4%dhUT*H+eawcv zRMUKwr+UjSHI}J3+RhM-Nw|(8(tnz{^j6dxO-1j`TfpTm-02a z=;&mn^^Z_z&lRfkHCAP4mu#9ptnN43kYdl9yfokJ+4g47wzqg~@-5!`+rMSrV>4;v z|2FZz^P2YU-g)ov&U=T~AAQffKk6PE=i|ib?mx!$=to{W{(Fz__STW^^WKGipZ89x z2fcUA{ik;=eq!!X`u7NaNg8UL$?sp>i5rlG;5nPlS$qGhyg%xKV)Mtmy#Lb6`!BtF zxKDaz_*dqBnM;rKeG*w+V~oa5av$wYo1RY6Bi@}sLw?L5-xFM0`5(OV{=qx%pS<@J zJr~t;!pQqlh&pKErJgl@#U}qMJ-ef~75Y;5PbWQdZCJ$MXpcYTaq*My61t<4J5_Q2 z`?6Q3UN!f%BmLLB@6^1;U5@DJ_)Lgs^GeB5YN@Ww^-W@mzkZaH+a)?ak%44$t@8WnM1_-`fh~HOY;` z>pk~xD9?ts!r!!IUgk}+cZ=(k`)-=d(cWX-@0n5G=UVqk+!t8>bx+5Y`37l{GTCW$ zraT=fS4UX)hdlRB*=sFfU3qi-M63URr|-&!=tvoGX_L96OPfFMlQQ7aQ}^PL>*CV$ zeb0SUYd48M=W)4qPXBgK-(5%1ch^z4yDq|I&14CAk#?zhzoz;*@Cmr|FBe-bZO)aJ z%Xq`htu}>!#k%v_L34EKokA%CyN7WbySw+^;5|ZjT{^jgzEs2J!(orR5fJZ|49`*b z=I~2R(j?$K42*?*xTk_S~;iepYzB@(aSplz-AIdl!elQTI#2XW_0r z@$Iv=)oJi6`EojbxpHY19ZB1Z)`tE2uemP&1Dy$U>W|~v)=pO{}>*v?tcnpjOyAhzg}1s({4!lKh);yt#`;*?<)Cv$;;O|DOcAzgLP6H zXd2c@ZLECVlv}ar-IZ^Uip%*%sZMp@ICZ%4rc@E`%88#Z7k>kP(J9+} z^&Gh7>xCLNba#)0zuU{pmZ`WtZk3WbiyWQ7HYsUO{*`T|{XE~M;p;Qg;63Z>#tBkp z+;~9726Au@G!-%7yLxGx>!odXFKxM0vkkzvL{sng_*M_P*`=*PICoy*cY-UeZF>*; zSJyY1QMh%F0rUxuJ?{$Qa(lO#8~!aDts_-b=fKn~QRe6j4ovZQpE-o@liPY6_cOO&gpu3MLV+_}J`E8Ws+>I+_tm4KM z{=CDL!v?ypyb1pT=lZp+gXbRU+NH1B(j#U5dan*%pW28pa&!hac=hpyR6JI^A$3Hg zVst*F{KnK5JbsJv>r?R<@A}kJ>i*5tiym*%y7SFcv&ZF`RXO;!PAYz9^<-*T-M^iZ z=S3r(TT^k}yfqa+w{}~~jV3yS+fr|-{_QE=ie$syo;q0h9bO&0BlTf*zcckE<=;=m z&ourpb*H-jF!gig_0;PgPift$r`A#amP8y(YBZ(@Kpf&02Z4(1xxYQm?S*$iJVQZYO(t5d1jo_jnG z`dKPo_joL|o$5T6+R@|jxa%=*toT@J57qfaDqg4kWonVSKauKyZ$tWb;rBxBfAJHT zKSDSfU|+B&Iy>-tB>6qg%Wse68{#)?x%8oDSuW$Wamyty|6#fGt#a@zt7og{yt@3n z*Dt^5+2MuM)=^NxzTl1VUhwkxLMmP#_#a+=|D4)S!%nB-G07{bqtyKsZ;ba!YN@)v znsRF+oxxvHWzW6p@v}VsDUV<3@hg=7H6?RuIXZ*az4qsg)Yl?s+}}*ysQe$PN%#-3 zVU6E^P`1UZ4qUz(aM6Dd9l2iVV_lo6x7Ua>OvmLgo!$&RIXZ*2((!d!C%t{-jQhH2 zin}?Ozog@`w0`<@bzeVyhVl*5al5*4`fPQdmHxQ$jnkJX-!T1<$7PL3j?Q4i^m@wI zO25nFZpBE_9DmzlleAmW;ht~$gXlkPZ6)>kIm=DEVYxqslykmq-K9NQXI^Ayf9|}! zC~-7^OONn=&NT~tzaI7Be%f(O^{sK2@A3#2+wBSD*bVoc_{~Sx(=iTlUla_vO_ zOAKsl;>d9=?i2hvf*xvIhQX%ctNHwl04-uCnfO-G5-Yxc|~}=_7t`xs;h# zESEm$ZOi@g;O09G;&AyDo}xT#l#8z8;PFlMZQv8Q%eC9fa=CVg!fX7xqf@OZHrz`q zZ6~{o;yT;m-DBOy`|gi?T{AjZM>Wp~oov%^Cu#V+cdl>QG|Wtognp;zsp2#o?WN%u zFAc}DOUb3-MDtD6AJ{acPH3t>?49>lmWv&pv%E>e_E;wA>GS5HCGQ?(zj@x^Rl?TL zo>`YAf(FQgx6s*v-)7RVF%C7j9L*j-#^e7^I{VO{AP(u{yF;F@5ZlTj&sVG; zQFzU(M`wHYRnPXm*>tvdkM(SC|K|CgZ7=Yy^#wtP#{V&{d~|g3rJ}=?U*yfNFEabl z#H*99-4s2Y#mX<{OGnWmdzRyV?J{!X+%Na)@|D4P>V8!aucKb&?MJ)H+ar9nw@3Ku z;Hw(;bHVi<|AumZAMsVechvn$!EMUF?Cm|dF1SzKzvk^jx!(Im*nb31sLqYvGag?s z-wPA3&fuHgzRsJy{c$&YdyOZ9e`q}4@xJSHYmlKGkVC$A6Zd7`3*M*hKlJv&{fIkJ zPQUJb8~rZt+vsDWrbmLW zsQV+q4a%p?x6Y&Zr-HiY{($mFga1@M`|j-5)pKF^}SZJa|>z ze-Zpm`IEs$cH}6}cx>bG?L5AN$9MMlt{$J~@puo~Q)b^;l!m9h@8dib9Ig6K1#UH{ zlhPym&LaJ1S;dKYeEjK6z1ID47T&Qd`nP{PD+1^ z^0xwaUzl-bxR<)8!sC=@yl42=3NKUl^};KZuOEIz`Nm9yEEkpYJnqIAGETSz_Zt2(w!Fr28Iye7 zav3w+VY!Sk?z7y#w?gpXaqIqTbVRNL*N-&dlIGRvxb%yTq+gB(coN}bA^9O>`q-80=WWcl74vX5zdkMHDh zhN|X}eN4@;e$pW6+?RB&fKR|Bo#$IVbDVJ1DrwH!)d+c?)WmS{u&Tj)qSSIkJ~J-AQcJ~N%GjuQ^{(s_uN&O^L(9^%>aP|t>k zhC6c(IXchUbJkYke!#4_j2-LolE=q9zAc4fg7~EjEP~hgbq8}p zN6Gs}-uQ51r09_EnG&5jcwWdGcWvxFcek-OmznLor)3lKOyGg`y#8Fepfl+5p0Vum($nSbYwj}NbdJ(|lxM?ZJR2Tkp1q88 zjx_U&h#wb_C3AH0#vGaBe3QJ?_+3-kkh$1xHoueP*MDErv(~m!wqLS5E++iAFCh>K-#Kt1&9QVrJrCxq7_40d} zSN5*(@;mO$`^LTJy+7-HyY@;m?>p6|P0CowrnyF%-#MLM@zVKKFP+zU>AcQM=hwY- ze${(^{;S$z$@_(Nv9Wdr|KZh<8%-VY(>ZF>IY~OdV$&}{{WO0E_X*s@w*P5)T=pKq zH9B}!$E)u@_1eitz4ZUgd#3tPFE5XJ_5D$=zCY@v{}~wyss|zyM zI9uJH;Y-3!=NZ%Hio`Q8-W>dQ%;25Q?}AG`9|lrv zalggm-&OvSdGcY9n}#~YUaZN|9k1?%pQORu;2ZSb2Tp4I8N z=gLIKeLG(GiRiyZoYDraTWqRtNQX8d9Qf_ts{Mj{Lx)`7*`bWD+<0JD;z7jypI*C> zHsep%Pwl5VJO_@hYd4-EznhZ=NzWnZ?Bu1VV7asvtEOj1V@;QalE%M*_YC3AAyJs4 zldBu|7jwdHb>A@TRlaFh@_1SKtT3*3n}@V%OzIpO|Z8d_EVnD8Lndu$r^#C^n`SFZ1e-Z2e*#-4HtzUS`E zO_q3blYVdBw=~>TlsS0*#7pPWFe{E6oxG(*uB#lvR(XT{vn~f}v8i+S6ZJh*X%f*RK3D zN5PxtEXpm)7troq+EX#=&2xhON>5*@xVWcx*=VJww^T4EY?-qc;ad2f?#Mu&(S-L@ z`g04*(MjNWj~6`N?D&kB^ET$0XUwg^-8m2TEY26p6>?bY9jg?pqdlWz)rCu<^i@X2 zhWi#CA0?_%B2my*llrzO*KLyPw$|3>)k>uNok*Qke1l6S@mC@|jaCM-6xYU<* zMr@lC5LF?HN@#OTTP!uHs-7`0+PkzkI#L{~mMShyGrZ*Dmj+ksS*ngYcT+?L2NqZN zsFZs81_y>q6pF=TOBNnu^0rrx6acPg^h1_f3JY2mw9PLpXk8?iHCJd}gvKhD+QsHB zYg8WM>l)b#Ta+slzEN}Su$)yJklfCX&N_e2zbt+8=LEe`h^T;@{8UH#21dwCZ+Q%3 znfy|oO|If(aDQ%d?ui^ux+SZ02(D-~jKaq+-#wbWCYXKbgvav zaa}0odSGO@I9OV;1{1C60@#3+f&Qf~WH5SWxn#~m+I#x?qWn;fBCGPZJ+geeSl%nT zCiM%CMS;s%%@>BL-<1_n8Jde@VbO5W#Er&+sMO@5nDRM^s?gfH2(7v8=#7jnr4ky& zxh z1wkB|3s$D&uhNXPM>_3RWr3%n4KTS_xm6;iYigEAbucLTBQ++UV(Z~Ei$gt>l~UFE zj8?`<#UU%WUsF~FhL?;KO9N$7>{h-`RG}p!=KAGrwaQatR#ef}pbLYQB)MjyR4ugN zUR*-IB`3{O#iXF+ZS%{oG*9$8(d86fY2Bg(%B925CW7JOaLslnx*O0{GT%#5>QZ=2g#A%yTL+QG7PJgw5oNH1&bLda#d!7^ z814eIhN6ssAK+~x2QSKQY=%v9Ns8ZXYuECVlM}r&2 zCu?Y$5;OJR&>iFQU6QMWN1`uYj0^aasvbBXqGo@QY0=n zP^PxZX=ThV=jGRqTjDds<7bM-V3}+)w=7o27CW<<+D<8Pe$HJ?Ai7Sr>6;ncb9S1& z6o{yzQh2Mag`8X!NgmfQ8g)sePXQO2#2wMC`a*E8BCSSH7MKbGVu8c?avkPfb=*7VlfdhyS2UELE{ge2u zg3P~-sj!~kpoy}y+|nYHhI>5*unHi5v#qi>+<`K%PaJkUE(IbC9?oX*6px-7Dx zDe!UIzxo9$qF=*;6^ZN{5Ic}fxh7Gw5;v@CYNE6+iOk>@`bcE4S{gOU6EkYNX_*L8c`-&q=mK5`?MKcb@01}~D zHu55*E;Fu0HyX|{9AsP>xiDU^ZK+I2T1BZ+U2az==Qhuu+bm9QWkUv%oY_PrZHmZ@ zqebp3+bRFtme#oiaWRdyXv~i^B%#guV!q9VG^1n|JBMd1Ysz)$qp9pOWrY4?MYUWl zjrGw8uu2kmTMucpmd z?b@sKBUGYzrG-vprH;mo<;aE>6{&TmA@=%b*|GLs0IUYfE**)a`}EjzU8 z6ql73%W;bW*_9IFD6Qy~*>^Qsfu`u#@+V;zm?o5}DJLSicCZw+7g3dx#U8DLGA?$5 zQ9E&E`1_7CK)h$n0J%V1)iuok8P%_Tq9-0R=6T|@+G!phGiQ0?wAx9Yc+8mNiPLJQ zc;d0T8D0+eRVHybt}=;ZhBb5YMx3jkyNSo@rf$T$%G7N&GdF^-e&Qw`tDm=VWvVOB z+c+1El$|x%d7ET5o=Vwy8;+})x8b_#ybZ_I%-h6u)p?t^t~zhSRp)I7@6%j}rnRQ0 zr)tOLJG$Q>Ym&BIrj)O=NEDZ4t)J17la%@>4D-ck5gZr8%}m5DrN}g|YHqMBD~v^R z2Wd8p%UEGqtZ4K;wx}(qhz=;Qry8CnzpXqYk zy*jJ)frHN2ul2B%w3e588Om4P{k)+eCU{GF#s+C*hlZrb;yzrVTpqTml2I+~41cwQ zhOeP>2?!TYf4s>M7GJrAB$q3-kW75!#I6IDX3exCUE&y+ztX@<<59>}N@f%rH|%R@ zI-{bhYaF`N#z?JPs*Ij#JD;eW%IRg5ciGAv!iuWgNMWeJJVbBGnx`&))OIWer_Vk4BK3Uz{RX?^s_E$ zD@WbS&16%!xXhy?qg-=hfIDr<7i0Eea#C^ak@U8nYv2o}G@Dx1u1oaPGgF)y7@4-; zTx!nZCP1=!Wyd47c#DR+)+iQig(y%`onln!{HrO7luS8Qfl-Mla)Tu5F1*VT#pikq zXQ=2>i63RaM8S2IC<@w*M0UeTmNjiBvT{9?#;;&XOmuQYQz&hXEG%0d)ljK%#v-;N z;UCvLgko`sG9eej2{flBEkSvd#+8d#i?kP0zk4^>vggBR*WN2*ue|hc5PqWxVynXOWgb(Ovbm?Ia;(fy_%XVTHY2n z#;aB@S_l_6J0vB_#b&`9H#Z_RR*8zNjz~q%w7(=rhNL#WXxK+sH|j($TGkggd%r;9 zb6Ix7PQ4`2tq6=^$DL%--nhW6O%1ft-39SsZ9X!;y%!;FOhQ+>SY}EohHkUBhpI(; zqek59gh5j>-=(q5&Ks&ld&>yz`S!+;YPUP>`F7?|b+@TR+fEu(dx2`(xdWw~S-&j@ z^X@+zPNGX#udmGvu(*w{(nBE4()%P}b0k7HiUu)`Zm>=2s$tt}~v(0w1?b%k- z+mPrxeS)`=#nv~?e*vbaO*Q}*gojDOGM2&N4Mjf=9!B+7|bkwHq&79s7$Fp zS{-pjnp*LywpY#Ch_^v-x(z6}FRgr$v2-2s+C1LSM8V6Ih{mSN|_6xmp^G8z>JN4VF?V6rh&W3|G zl5z=Hxm1fQZ9%1E+8&r0DXf$znYp#K*ilDww0PD+C6emPFQsw!{Gy=LUdYK{UrJvK z^`zR8YvEMlgp08vmDh?bRG?^{9*y12LR1SCgXx}oT!u4Yd1favv6MK(ftrnrD~ohM z?k+^sIOK9NTN@ef&ze80tS^#W9zHdb5=kaCO_~mp%UbaYJBFjp6sw_TPD(q;Q)p&D zM*;%-fQ`^%(GBy8MKk=vdNLN2aib*HwyoTWzkNyWrd?D9XT7Kj+P7|lJK{|{z zVPxPcfkcTD+bN4Auf-0#B|1B_92!|(GN)OBzZ7(nR#VVdR??baOB#2CqDP2jN;9~a zv@?|*;BJb&Zy_m`=~Z!NUezP&!`yizWv_E{9`|M9E`C^gt*J&x-GP! zULiGifutcfw&~{q#lcc>V6-$8%^3-(&nZfU(nk*w7!8w0dtFVy=)&5riv&qf-@dj9 zaS^TT6%`Fq$T`dAspH532UyFSbV$ZrG9qpYR76c{E8bF2O#(H`(S+PY%af_B5b;pT zh&4_t_hpv>5Nu%+NTj()7qp0q(1_@+LM%V`#)Y%O~!Vfyl8~94m93M3QNz zNsxIG)H85&=2cI?bu1PKN6xT;5tdR2W67P+=o#BYXORLeZM?Y%B#ahYtVta<2DWom znSz?elAOnLKkVQ?d@N%cVsnxC&vEU(pipRTW+crDdTY!4`K|4__C>3@@#ueSSczv; zl0pjT<f`&a>>5TH;TRzjI#WwuJ(8pu@k_WkOP>C8BG0kXYIM$6; zMMYz@(mUiH_%g}j@!2&sR@G?ti^LY~eR1(>3~?i+<=$^X46dJcSZgQohC{GJFl*s!Vo5q>WO z+rj^*PoDBa>ZfdQ41W#>{}4R$?4O={eih$$a@czNj`!`b;|F)z zb(cBC-PT?2s1x=-`q-0>JNU@1vp&3ju+K4_2ON0NA%`Be@Vy@i&i=rO`yIdU5r^;j z{=NTyl>ZsFnf>myHraH`&DNX62Lv|?!gpoXUT59)H!xpq+-9pS(wnC?-YC!yx6cUs z|Df1-$GHBys_*~o_3yZBcD>_ra7BbS%@=y(_}^Zqao_BEEYD;c_C@XMEc?5O{oRb; zEx^{`Jz#sV190JYwtQE9cLzDp4CaGH!0FB3j&Ev$gTc|@WY7nOz;bX7_!zhZd=^{_ zz6x#x-vW1nd%#b?W8i7g$7dfo;H!U>=wcI>5o;XmB#<14CdrI0sw^ zE(M<^9rCxC7+04m@t za6Y&gd=`8Wd>z~Zz6b6G4}r(QZ@{0xG<^9tr-A`62F?W+ zgR8-H;1=)$@E~{`JOf?=Z-BLSY^u)&+k!cu73>2J2Pc6NI30W#Tm(J?z65RpcYu4r zqu^=qJa`R+J2lle0$YL|K_2V{4hF}89xw#X1Q&oy!L{H9a4YyRco;kh{s3MEZ-Mo8 zCjVf2usc`)_6J9SQ^5cj1LuN^!PVe8a0~bWcn~}eo&hg`H^5rEkbkf(m;+kDKHzY0 z5-5Sw!H2;`;4|P$;3jYfxEDMMo(9i@*FZRj{DUpQjvx>A0tbWRKo1xKXMzjBrQli+ zOuSR;<64OzFkcq`+#}KNW%l>)_V<-XRFSUpbN^n98YCf!1riG+7Dz1czo7-znVkK< zVXBfOB^F35kXRtGKw^Q!0*M6@3nUguEb!l9fn@yu-(l4x&cp)$XILOjGSl3vOJ_k2 zbbv0<4a%Sf#=!)b1a&Y48ekf5FF)M`vLFXKKo{r+Wl#g-U;<2nI+y|tFb#qf;XxMU zKnLgo-JlF=U>r<XGPBRt509OwXDpc|Ay4UB^cFbV2l3N*kp2zDSm z$buZ`09~LPltB%Qg9$JR>R<{qz%&SUBs|E19OwXDpc|Ay4UB^cFbV2l3N*kp2zDYo z$buZ`09~LPltB%Qg9$JR>R<{qz%&SUCOpW39OwXDpc|Ay4UB^cFbV2l3N*kp2zDVn z$buZ`09~LPltB%Qg9$JR>R<{qz%&Tv5FTU!FPBbtfG*Gt%Af|u!33BDbua}QU>fi! zT)GKlK@N0)F3=6ipa#al1egSMFa;W58U(u$9%Mldbbv0<4a%Sf#=!)b1a&Y48ekd( za|sW!AO|`?7w86MPy^#&0!)HBm;wzj4T9YX53(Q!IzSib24zqK<6r_zf;yN24KNLY zd4va9z@v}p4$uXXDq z2@kR$2Rc9(=mup_1LI%m00dgq}+#c=_%1klz!yXHUam zW8@Z3ewXM^x~Iq1Mwde$#DDqitjP9|_;!YGo#MGpep5jhwDa2;Hr4A^K7!w%KD#ba zguyz&@%(1c=Lut@e;U8Dk>xpX318#a9TNWzWFSj;NrQy{r1Rug{4eKs<8%`vhA8~! zX83;vd3L6$-bFkT|F@9uT90R8t^S=e^zRdSd^RHpIp11=JXQB=^zYzT!avUM73(+E zZ@2PO{JKNZ^LvEsJ#l_ta-RH(|7$a3c@%kQqb7Q+DEm7PGs3eA@<23AK=Lgk^fHk=WO`>kPq_0ABFt8jd?E8`k#vY$Sn4jSot*M!<(Aw z`&zk*d7+^FOB7gMdo>K=l@HQdA8fh4Uu`y+sS_t`7^Vb5l8W{oE5yl`999C zr2n7%F6HTOiWky4!P=y=vRM-|u*iQF@ z5c!JDd2SVdIsXBoXb*|+aOCn9?CHTx{7*tQPp7jLMbdXFayRj>jlaa-hn(4pXHBjC z5OPO9<=yzFf)&U$^t-M8N0Gm~O;i0KekFdE?eviIe*yUho=M#jSMk3d`7Y!wto&`{ zUm?5tdNcCxk)<6G{qG~cg6z`sAoBZmZK^M}_I?`qg57uy+R85@hr3gs_?7S(7CZ0Q zBaVM7VdP7ZU$pYakU#wX*#A+| z|83;=TK_BYKYj0}`d$1=_%HF>ydTf++w1c!(0?ud9EvAV=c=9jm{+c-TX(?_A_; zC901hXIOxI+HpMpZ_~Rk^5F4t`*H~KoyZ3ghot8yi`H$bUxC9W_+Nx9dkmcaWyrGcz{%Gj%QN3jzE1Q{X`+XZ!hZu<_9Qs} zTajfihLeAYybsUTJNW@*dA8ljKSP%N2u^+qS@vi+`47nCL}ix41KBUQDXxr&6;S$!vOf-HL)oV*RP>|=29PRL(BkUc0kNPGok*eLznBJhJQ!a`JV^vKPb2 zHzUh_A}8ODEPI}u{9|OE)EjkrpU6_$N9epS@t?Pd1qwV-{a&w^3<{>(_YS| zMQcTF3*z#!H?r(2ary@%%U&iYAA>A=WSo2|vh3q=azC={VR7>5$g)4l$!8(UUMnZh zqMXm#oBcC5NPf=8U-qUs|BI1VP=A(K|0|JYkC^kHK$iV$PQC$I<_nR$c5pNDb&S8* z(_-TPB^pPvL&&lx&dHA>e`8k{e>(Ubvg`+Q{x2ZQ z{v9X3hI}6Vsr2uXzqgTP|CRG!k8zpog>&*I$g(HR$y+1KULq&&h%EcAoV*9}%hY#g zzlF%M=g#@>hb;TAoP0R4?9p@b@yN3G%*oxzH);MdK?Pa%nmPZok(*`jI1c7|AyXE|ELzewpPUco*@OHpHD;z}sQDoVx z<@|q*Ec+du{4Da9y!^g|Ec@S_|Le%I57Nm26I$5^=H&H}&7LY8r2pO&S@xni|Mwuv z9z-YajJ!=4w@>qtW$&Q#??9IQgibyfS@yI!`55u{(t9eh>_2n<{m8OM(#d7y$y3=E zX#0;dkY&G_^FJ3^_E|dl6Uef!(8*UIufzC3#@Axc&m+qoJm>#4WZ4twWNzmMKlZ|Z z54oN8L*_Hme*6?!_Nh7jCy-^Ysgt<{9LPRHC;u0+?2mNvUywKR^7~KZOPIfm+5D|T zN44#G?8hU3r1#y(vj5YC&mzknRVU9umi={3Zbr^{^?d=d?8$Tf`ytD|Q70dUEPGp> zd>nH6*rs~FO-~Q9?5TAA%a9M_y$XwQko1ir%idDw&j#^8_A@&94if&G_{;uD=YKo$kG=EVg)IAXo&Qge*Y)i2 z81ko(BmZ@RCy-^&q|^T$vg|2!@{7o_|Io>QMV9@?PW~ryjq)k;4N2eH8_<5z{<`sM z6Y>?^vHs@BviH=5&mzknStmbE|KGSe8sE=mzPc;^vY*)bHzS`<`$x4l=i3`u_T4)F zgORuQuE){HvOn1QpNuT~q@CQ0EPH94JcKNJNu7KKvh0U-^0~+j=Esq|R`5w=+4t%E zKZE=R_3aoO#2(io_wUdCZCjqMLzcbLPXC+8vNzSqw(RI{!Z*%idilzl{7T&wl?zers#?OQRt1ugA82*`Mt6--UdA(8L|4 z$bSc9*{AFL=ON4fawpG6-jnNnA`TMY`;leuv-3X)S@xSd`6y)B`|acpAj`gVC-)-D zo@*x$BFny8Coe~qz2r_l2U+%;JNZIn+4t?_OOa(SvXietmc7?bz7DyS@%m;sNcz8n zEc?Wr{|}I7d*{C&S@zpI|3{EzFSV1OME-O-ny*WIze8TP7|mxzejZu&3p@Q+k!9bw zlixy?{l`vThlNntm+s^yWZ8r57?=@j!#A3~Nr_)b0# zS@zyL`BTXIc=BhE-+oVQ&(9&t9&)GuRb+WDfs=1S?(BB;H52>*S>8k7{O?1aq<$TY zgXHI7WZ6gW{C|lod%m6g4DvJH^>_ifXD!A9cK-GT@=ovO{QAu( zpHpMxy#C~)#c$nt&!Ctrpv?~HKr zHOR6j-^qUy+c$(td|dmfy; z9r6M%zjKi1dg*CK&Zpz?{GQ00dFeR-`4-0Cu6!PjEbj<#@t=S!@9l7MH}dx0`A(DY z-u0^@%R4rl{@KW1<@~a~Dfa&;vfR&z{MQODL6-MUL~ncd;+q(JH*M|$nri5C!dCV7~`iF9OQhbBg^|yod1WAe;UN?=O>Zn zofOXhGsyD(4kv#Rc`YwJHz3RVPMrU@kma2mPX0dfGhX=nkmY?Y&i@hQhwS|bsZUQz zcrX5Ek>y<{PX8rjdDoa*FMNUe9eCr9(v?87>V5l~PaN;J|Q+b5uwB21fYpEst@UU|C;j@mRlc?^#@2JTP1>^;B?| z5XI6!IaoF{LgGd$5@cj(sAssZ8kBn~)lyIy8}1$ILl_?D#dn}uG&JZP9O+$V)Q77h zgL2MdksOfxp5-OSD`an^QVRM?gFR;ky_M18;;|*>w>(k}diwe*#kTgA)}Xh)hrk0E ztyCH487!7o3{*#}PBK1&Wz0xsiq)~jffGzXadoPyVIwkry(7a_vNc>a2~^d}NN=&P zXS64%E*)4h+B?!$3Pwlz`v*&g4v$oZdIpDj%8|E_-ccj>F2#1Dy=-w`vAl9DTrY7I zLs&wlM8ZDhf!=}2>0-mm>BXU*>aw73KvdDdt5_|K8pqK}Pg%50c^Dn&T~-YS`iP{D z{PzXoJKQr=3Q8+_<+sWi58kJ_uw<~OziNDoeFN2Uk6iV>(vqIBL4pkpNrXN9r9!zp zYzf&e;e}(dQd*+ACOIyk2*sfi<)N$!J%e0$6RxUmODd((45#5r(Q{qgQzeJJOG~|E z+NLU!$~^^1LzJjx%X@Lt zqK?dL>LQuJ*8M|N*1$N#ISNdgimN!3`}+ne)-$Tl#=#nIXk4Ydqzo^WI8i0! z@=`B#s?bufET3Os3yU-Z1H(&3tVjENN7`JV*1W{iTRzh|EXZ5Z+-ym{&Ba^Dt6Q$! z`nEI&a+0EH=mOe|;^Lm(Wt7R@l7??}tX)}NS)t%A2NiVGX|`$tX$zwK<=Yon=5o>I z(pqS7I(c=<<*ZwqQ_nZMM9*&tqzrSFtWN8ESG%Z8ODa;EtWons?JkmaTd*LykWwUz zQZ%Fn+UA7I&h%ymUJ zdwDHi^IiV(En@4ws63g9>n!0Cl+U@76!b#pxtLauvSl zy)7u2X5aP*G`}uJXQozn5~^0Qc+9c;>|5Obh|XfsDlTyLDUgT35$Qs!WfwNz;+U4@ z`D*ooWBJy0)99CmrFpRNHmh%&%Tcq|2eK3;<(OlSF7CVkfd?O<>B$#b@r$};o0Yt~ zaBa>?g*MmmNq6LIvA}uf7qkWam7cy*T%%n+3OSc9HOqYGmv43_iVJ7XITczp^?GGm zsZJ}O#wJBui*`LryC#lME@RI2E%T)*8yy*RK3WRAma#>2h6hW-F2D0NMRDwJ4I8kt2&u@P(gy}*^L1+Mz%=eu*|7dXRH|4lE~TWMxU+vjXY zOXw2d5?W|=mm?>ZUNV5Tsa9s(RT`CXunnWNA)j;Srlv?)q&M*@K|bfA)LubrgC;eu zM{!0-O0gK7tZGln%V13b=p8CYjX0fjq@m4UA*UsR4n|5#+{Vp!+04fmFYe0dMNH}$ zZkgmq7phWX7-qAaFU&0KE^GOAWd+l&l0X|sD_g-880{LgJzwC`T%cA*;ac3qk!ID5 z5azpUosZjGT5;*VC>*w@vbvg_0v&V|TtgFcG>hn|NKzR!T8%>7PsCMTQ@y|?KOZ+i z%`R>6Aj9P(uSGLY6wT zN-{u-FNY?%5Z7C-gVt^{dy?V1--Xd0+pEbKOxhIBlOk#T;tp3kl)Tn_t(I|%rB^-Q z>f)dmi6SesIK~^0ts5^k&@KAQYW3KUKWdI^i*7fU7(q_IdlcHpbZ2AtH_UpND-}? zX3LDSMn}rlFRxXk&1FG*io7=-Qp<2gY5hzzB*q)>M<>hYS^_h*>0yxLPC|cc2MQ~9 z&DuUv^K5YXH;P!?Cl$0k%xj$~=;hHyIqs<`)KW&5R&0!1`WaoSYqtuFU+h`6d=$90 zksDow^^6-j9r@5VMI~UYu*|9z;=u@wrVRdPOgQq?9vh=hEb8(W3_|K6$ofDhxiwx~4m_mK@2i#Fw+O=b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r z3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@ z0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VK zfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5 zV8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM z7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b* z1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd z0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwA zz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEj zFkrxd0RsjM7%*VKfB^#r3>YwAz<>b*1`HT5V8DO@0|pEjFkrxd0RsjM7%*VKfB^#r b3>YwAz<>b*1`HT5V8DO@0|pEjFmMb6`gRF0 literal 0 HcmV?d00001 diff --git a/labcodes/lab2/boot/bootasm.S b/labcodes/lab2/boot/bootasm.S index 6f769b71..e41d363a 100644 --- a/labcodes/lab2/boot/bootasm.S +++ b/labcodes/lab2/boot/bootasm.S @@ -42,24 +42,24 @@ seta20.2: movb $0xdf, %al # 0xdf -> port 0x60 outb %al, $0x60 # 0xdf = 11011111, means set P2's A20 bit(the 1 bit) to 1 - +# 标识内存探测的开始位置 probe_memory: - movl $0, 0x8000 - xorl %ebx, %ebx - movw $0x8004, %di -start_probe: - movl $0xE820, %eax - movl $20, %ecx - movl $SMAP, %edx - int $0x15 - jnc cont - movw $12345, 0x8000 - jmp finish_probe + movl $0, 0x8000 # 将值 0 移动到物理地址 0x8000,初始化一个内存区域 + xorl %ebx, %ebx # 将寄存器 %ebx 清零,用于在后续逻辑中进行计数或状态标志 + movw $0x8004, %di # 将值 0x8004 移动到 %di 寄存器 +start_probe: # 定义 start_probe 的标签,探测的开始 + movl $0xE820, %eax # 将值 0xE820 移动到 %eax 中,这是用来请求内存映射信息的中断号。 + movl $20, %ecx # 将值 20 移动到 %ecx 中,这是中断处理程序返回的数据长度。 + movl $SMAP, %edx # 将 SMAP 的标签的地址移动到 %edx 中,表示将要存储内存映射结果的缓冲区地址。 + int $0x15 # 触发 0x15 中断,向BIOS请求内存映射信息。 + jnc cont # 检查中断是否成功,没有错误,程序将跳转到 cont 标签继续执行 + movw $12345, 0x8000 # 将错误码 12345 移动到物理地址 0x8000 中,表示探测失败 + jmp finish_probe # 程序将跳转到 finish_probe 标签,结束探测 cont: - addw $20, %di - incl 0x8000 - cmpl $0, %ebx - jnz start_probe + addw $20, %di # 将 %di 加 20,用于移动到下一个内存映射信息的位置 + incl 0x8000 # 将存储在物理地址 0x8000 的值加一,表示成功探测到的内存区域数量 + cmpl $0, %ebx # 检查 %ebx 是否为零,如果为零,表示已经探测到了所有内存区域,程序将跳转到 finish_probe 标签 + jnz start_probe # 如果没有,程序将跳转到 start_probe 标签,继续探测下一个内存映射信息 finish_probe: # Switch from real to protected mode, using a bootstrap GDT diff --git a/labcodes/lab2/kern/init/init.c b/labcodes/lab2/kern/init/init.c index 3d67b593..698a5c42 100644 --- a/labcodes/lab2/kern/init/init.c +++ b/labcodes/lab2/kern/init/init.c @@ -38,7 +38,7 @@ kern_init(void) { //LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test() // user/kernel mode switch test - //lab1_switch_test(); + lab1_switch_test(); /* do nothing */ while (1); @@ -85,11 +85,24 @@ lab1_print_cur_status(void) { static void lab1_switch_to_user(void) { //LAB1 CHALLENGE 1 : TODO + asm volatile ( + "sub $0x8, %%esp \n" + "int %0 \n" + "movl %%ebp, %%esp" + : + : "i"(T_SWITCH_TOU) + ); } static void lab1_switch_to_kernel(void) { //LAB1 CHALLENGE 1 : TODO + asm volatile ( + "int %0 \n" + "movl %%ebp, %%esp \n" + : + : "i"(T_SWITCH_TOK) + ); } static void diff --git a/labcodes/lab2/kern/mm/default_pmm.c b/labcodes/lab2/kern/mm/default_pmm.c index f2f54d04..c072c1c9 100644 --- a/labcodes/lab2/kern/mm/default_pmm.c +++ b/labcodes/lab2/kern/mm/default_pmm.c @@ -9,60 +9,86 @@ * the request. If the chosen block is significantly larger than requested, it * is usually splitted, and the remainder will be added into the list as * another free block. + * 在首次适应算法中,分配器维护一个空闲块列表,(称为空闲列表)。一旦收到内存的分配请求, + * 它会沿着列表扫描第一个足够大的块以满足请求。如果选中的块比请求的块大得多,通常会将其拆分, + * 剩余部分将作为另一个空闲块添加到列表中。 * Please refer to Page 196~198, Section 8.2 of Yan Wei Min's Chinese book * "Data Structure -- C programming language". */ // LAB2 EXERCISE 1: YOUR CODE // you should rewrite functions: `default_init`, `default_init_memmap`, -// `default_alloc_pages`, `default_free_pages`. +// `default_alloc_pages`, `default_free_pages`.你需要重写函数: /* * Details of FFMA * (1) Preparation: * In order to implement the First-Fit Memory Allocation (FFMA), we should * manage the free memory blocks using a list. The struct `free_area_t` is used * for the management of free memory blocks. + * 为了实现首次适应内存分配(FFMA),我们应使用一个列表来管理空闲内存块。 + * 结构体 `free_area_t` 用于管理空闲内存块。 * First, you should get familiar with the struct `list` in list.h. Struct * `list` is a simple doubly linked list implementation. You should know how to * USE `list_init`, `list_add`(`list_add_after`), `list_add_before`, `list_del`, * `list_next`, `list_prev`. + * 首先,你需要熟悉 `list.h` 中的 `list` 结构。结构体 `list` 是一个简单的双向链表实现。 + * 你需要知道如何使用 `list_init`、`list_add`(`list_add_after`)、`list_add_before`、`list_del`、 + * `list_next`, `list_prev`. * There's a tricky method that is to transform a general `list` struct to a * special struct (such as struct `page`), using the following MACROs: `le2page` * (in memlayout.h), (and in future labs: `le2vma` (in vmm.h), `le2proc` (in * proc.h), etc). + * 有一种巧妙的方法是将通用的 `list` 结构转换为特定的结构(例如 `struct page`), + * 使用以下宏:`le2page`(在 memlayout.h 中),(在未来的实验中:`le2vma`(在 vmm.h 中)、`le2proc`(在 proc.h 中)等)。 * (2) `default_init`: * You can reuse the demo `default_init` function to initialize the `free_list` * and set `nr_free` to 0. `free_list` is used to record the free memory blocks. * `nr_free` is the total number of the free memory blocks. + * 你可以重用示例 `default_init` 函数来初始化 `free_list`,并将 `nr_free` 设置为 0。 + * `free_list` 用于记录空闲内存块。`nr_free` 是空闲内存块的总数。 * (3) `default_init_memmap`: * CALL GRAPH: `kern_init` --> `pmm_init` --> `page_init` --> `init_memmap` --> * `pmm_manager` --> `init_memmap`. + * 调用图:`kern_init` --> `pmm_init` --> `page_init` --> `init_memmap` --> `pmm_manager` --> `init_memmap`。 * This function is used to initialize a free block (with parameter `addr_base`, * `page_number`). In order to initialize a free block, firstly, you should * initialize each page (defined in memlayout.h) in this free block. This * procedure includes: + * 此函数用于初始化一个空闲块(带参数 `addr_base`、`page_number`)。 + * 为了初始化一个空闲块,首先,你需要初始化此空闲块中的每一页(在 memlayout.h 中定义)。该过程包括: * - Setting the bit `PG_property` of `p->flags`, which means this page is * valid. P.S. In function `pmm_init` (in pmm.c), the bit `PG_reserved` of * `p->flags` is already set. + * 设置 `p->flags` 的 `PG_property` 位,表示该页有效。注:在 `pmm_init` 函数中(在 pmm.c 中), + * `p->flags` 的 `PG_reserved` 位已经设置。 * - If this page is free and is not the first page of a free block, * `p->property` should be set to 0. + * 如果该页是空闲的且不是空闲块的第一页,则应将 `p->property` 设置为 0。 * - If this page is free and is the first page of a free block, `p->property` * should be set to be the total number of pages in the block. + * 如果该页是空闲的并且是空闲块的第一页,则应将 `p->property` 设置为该块中的总页数。 * - `p->ref` should be 0, because now `p` is free and has no reference. + * `p->ref` 应设置为 0,因为现在 `p` 是空闲的,没有引用。 * After that, We can use `p->page_link` to link this page into `free_list`. + * 之后,我们可以使用 `p->page_link` 将此页链接到 `free_list` 中。 * (e.g.: `list_add_before(&free_list, &(p->page_link));` ) + * (例如:`list_add_before(&free_list, &(p->page_link));`) * Finally, we should update the sum of the free memory blocks: `nr_free += n`. + * 最后,我们应更新空闲内存块的总数:`nr_free += n`。 * (4) `default_alloc_pages`: * Search for the first free block (block size >= n) in the free list and reszie * the block found, returning the address of this block as the address required by * `malloc`. + * 在空闲列表中搜索第一个空闲块(块大小 >= n),并调整找到的块的大小,返回该块的地址作为 `malloc` 所需的地址。 * (4.1) - * So you should search the free list like this: + * So you should search the free list like this:所以你应这样搜索空闲列表: * list_entry_t le = &free_list; * while((le=list_next(le)) != &free_list) { * ... * (4.1.1) * In the while loop, get the struct `page` and check if `p->property` * (recording the num of free pages in this block) >= n. + * 在 while 循环中,获取 `struct page` 并检查 `p->property` + * (记录该块中空闲页的数量)是否 >= n。 * struct Page *p = le2page(le, page_link); * if(p->property >= n){ ... * (4.1.2) @@ -70,165 +96,193 @@ * >= n, whose first `n` pages can be malloced. Some flag bits of this page * should be set as the following: `PG_reserved = 1`, `PG_property = 0`. * Then, unlink the pages from `free_list`. + * 如果我们找到这个 `p`,这意味着我们找到了一个大小>= n 的空闲块,其前 `n` 页可以分配。此页面的一些标志位应设置如下: + * `PG_reserved = 1`,`PG_property = 0`。然后,从 `free_list` 中移除这些页。 * (4.1.2.1) * If `p->property > n`, we should re-calculate number of the rest * pages of this free block. (e.g.: `le2page(le,page_link))->property * = p->property - n;`) + * 如果 `p->property > n`,我们应重新计算该空闲块剩余页的数量。 * (4.1.3) * Re-caluclate `nr_free` (number of the the rest of all free block). + * 重新计算 `nr_free`(剩余所有空闲块的数量)。 * (4.1.4) * return `p`. * (4.2) * If we can not find a free block with its size >=n, then return NULL. + * 如果找不到大小 >= n 的空闲块,则返回 NULL。 * (5) `default_free_pages`: * re-link the pages into the free list, and may merge small free blocks into - * the big ones. + * the big ones. 将页重新链接到空闲列表中,并可能将小空闲块合并为大块。 * (5.1) * According to the base address of the withdrawed blocks, search the free * list for its correct position (with address from low to high), and insert * the pages. (May use `list_next`, `le2page`, `list_add_before`) + * 根据撤回块的基地址,在空闲列表中搜索其正确位置(按地址从低到高), + * 并插入页面。(可以使用 `list_next`、`le2page`、`list_add_before`) * (5.2) * Reset the fields of the pages, such as `p->ref` and `p->flags` (PageProperty) + * 重置页的字段,例如 `p->ref` 和 `p->flags`(PageProperty)。 * (5.3) * Try to merge blocks at lower or higher addresses. Notice: This should * change some pages' `p->property` correctly. + * 尝试合并低地址或高地址的块。注意:这应正确更改某些页的 `p->property`。 */ free_area_t free_area; #define free_list (free_area.free_list) #define nr_free (free_area.nr_free) +//free_list` 用于记录空闲内存块,nr_free` 是空闲内存块的总数。 +//用default_init函数来初始化 `free_list`,并将 `nr_free` 设置为 0。 static void default_init(void) { list_init(&free_list); nr_free = 0; } +//用于初始化一段连续的物理页,并将它们加入到空闲内存管理系统中. +//struct Page *base:指向要初始化的页块的起始地址。size_t n:要初始化的页的数量。 static void default_init_memmap(struct Page *base, size_t n) { - assert(n > 0); - struct Page *p = base; + assert(n > 0);//// 确保请求的页数大于零 + struct Page *p = base;// 指向当前初始化的页 + //// 遍历每一页,设置其状态 for (; p != base + n; p ++) { - assert(PageReserved(p)); - p->flags = p->property = 0; - set_page_ref(p, 0); + assert(PageReserved(p));//检查每个页是否被标记为“保留”。若没有被保留,函数将抛出错误。 + p->flags = p->property = 0;//将页的 flags 和 property 字段设置为 0,表示该页未分配、未使用。 + set_page_ref(p, 0);//将页的引用计数设置为 0,表明没有任何引用指向此页。 } + // 设置第一个页的 property 为块的总数 base->property = n; - SetPageProperty(base); - nr_free += n; - list_add(&free_list, &(base->page_link)); + SetPageProperty(base);// 设置当前页的有效标志 + nr_free += n;// 更新空闲页计数 + list_add(&free_list, &(base->page_link)); // 将该块添加到空闲列表中 } +//用于分配指定数量的连续物理页。该函数实现了首次适应内存分配算法。 static struct Page * default_alloc_pages(size_t n) { - assert(n > 0); - if (n > nr_free) { + assert(n > 0);// 确保请求的页数大于零 + if (n > nr_free) {// 检查请求的页数是否超过空闲页数 return NULL; } - struct Page *page = NULL; - list_entry_t *le = &free_list; + struct Page *page = NULL;// 初始化分配的页指针 + list_entry_t *le = &free_list; // 初始化链表迭代器 + // 遍历空闲列表,寻找第一个满足条件的块 while ((le = list_next(le)) != &free_list) { - struct Page *p = le2page(le, page_link); - if (p->property >= n) { - page = p; - break; + struct Page *p = le2page(le, page_link);// 将链表节点转换为 Page 结构体 + if (p->property >= n) {// 检查当前块的页数是否满足请求 + page = p;// 找到合适的块 + break;// 退出循环 } } - if (page != NULL) { - list_del(&(page->page_link)); + if (page != NULL) {// 如果找到合适的块 + list_del(&(page->page_link));// 从空闲列表中删除该块 if (page->property > n) { - struct Page *p = page + n; - p->property = page->property - n; - list_add(&free_list, &(p->page_link)); + struct Page *p = page + n; // 指向剩余的页 + p->property = page->property - n;// 更新剩余块的页数 + list_add(&free_list, &(p->page_link));// 将剩余块添加回空闲列表 } - nr_free -= n; - ClearPageProperty(page); + nr_free -= n;// 减少空闲页的计数 + ClearPageProperty(page); // 清除已分配页的属性 } - return page; + return page;// 返回分配的页块 } static void default_free_pages(struct Page *base, size_t n) { - assert(n > 0); + assert(n > 0);// 确保请求释放的页数大于零 struct Page *p = base; + // 遍历释放的页,检查状态并重置 for (; p != base + n; p ++) { - assert(!PageReserved(p) && !PageProperty(p)); - p->flags = 0; - set_page_ref(p, 0); + assert(!PageReserved(p) && !PageProperty(p)); // 确保页没有被保留并且没有属性 + p->flags = 0;// 清除 flags 字段 + set_page_ref(p, 0);// 清除引用计数 } + // 设置基页的属性为释放的页数 base->property = n; - SetPageProperty(base); + SetPageProperty(base);// 设置页的有效标志 + // 遍历空闲列表,检查是否需要合并 list_entry_t *le = list_next(&free_list); while (le != &free_list) { p = le2page(le, page_link); le = list_next(le); + // 如果当前页块与释放的页块相邻,合并 if (base + base->property == p) { - base->property += p->property; - ClearPageProperty(p); - list_del(&(p->page_link)); + base->property += p->property;// 合并当前页块 + ClearPageProperty(p);// 清除合并页的属性 + list_del(&(p->page_link));// 从空闲列表中删除合并页 } else if (p + p->property == base) { - p->property += base->property; - ClearPageProperty(base); - base = p; - list_del(&(p->page_link)); + p->property += base->property;// 合并前一个页块 + ClearPageProperty(base);// 清除当前页的属性 + base = p;// 更新 base 指针 + list_del(&(p->page_link)); // 从空闲列表中删除当前页 } } - nr_free += n; - list_add(&free_list, &(base->page_link)); + nr_free += n;// 更新空闲页的计数 + list_add(&free_list, &(base->page_link));// 将释放的页块添加到空闲列表中 } +//用于返回当前系统中可用的空闲页的数量。 static size_t default_nr_free_pages(void) { - return nr_free; + return nr_free;// 返回当前空闲页的数量 } +//basic_check 函数用于测试内存分配和释放的基本功能, +//确保在不同情况下内存管理系统的正确性,包括分配、释放、合并和引用计数等操作。 static void basic_check(void) { struct Page *p0, *p1, *p2; p0 = p1 = p2 = NULL; + // 分配三个页面 assert((p0 = alloc_page()) != NULL); assert((p1 = alloc_page()) != NULL); assert((p2 = alloc_page()) != NULL); - + // 确保所有分配的页面是不同的 assert(p0 != p1 && p0 != p2 && p1 != p2); + // 确保页面的引用计数为 0 assert(page_ref(p0) == 0 && page_ref(p1) == 0 && page_ref(p2) == 0); - + // 确保页面地址在合法范围内 assert(page2pa(p0) < npage * PGSIZE); assert(page2pa(p1) < npage * PGSIZE); assert(page2pa(p2) < npage * PGSIZE); - + // 保存当前的空闲页面链表和数量 list_entry_t free_list_store = free_list; - list_init(&free_list); - assert(list_empty(&free_list)); - - unsigned int nr_free_store = nr_free; - nr_free = 0; + list_init(&free_list);// 初始化空闲列表 + assert(list_empty(&free_list));// 确保空闲列表为空 + unsigned int nr_free_store = nr_free;// 保存当前空闲页数量 + nr_free = 0;// 将空闲页数量设为 0 + // 请求分配页面,但当前没有空闲页面 assert(alloc_page() == NULL); - + // 释放之前分配的页面 free_page(p0); free_page(p1); free_page(p2); - assert(nr_free == 3); - + assert(nr_free == 3);// 确保释放后空闲页数量为 3 + // 再次分配三个页面 assert((p0 = alloc_page()) != NULL); assert((p1 = alloc_page()) != NULL); assert((p2 = alloc_page()) != NULL); - +// 测试空闲页面是否不足 assert(alloc_page() == NULL); - +// 释放 p0,并检查空闲列表 free_page(p0); - assert(!list_empty(&free_list)); + assert(!list_empty(&free_list));// 确保空闲列表不为空 struct Page *p; + // 重新分配 p0,确保取回的是相同的页面 assert((p = alloc_page()) == p0); - assert(alloc_page() == NULL); + assert(alloc_page() == NULL); // 确保没有更多的页面可分配 - assert(nr_free == 0); + assert(nr_free == 0);// 确保当前空闲页面数量为 0 + // 恢复之前的空闲页面链表和数量 free_list = free_list_store; nr_free = nr_free_store; - + // 释放最后的页面 free_page(p); free_page(p1); free_page(p2); @@ -240,64 +294,66 @@ static void default_check(void) { int count = 0, total = 0; list_entry_t *le = &free_list; + // 遍历空闲列表,计算空闲页面的数量和总属性值 while ((le = list_next(le)) != &free_list) { struct Page *p = le2page(le, page_link); - assert(PageProperty(p)); - count ++, total += p->property; + assert(PageProperty(p));// 确保每个页面的属性是有效的 + count ++, total += p->property;// 累加页面属性 } + // 确保总属性值与空闲页面数量匹配 assert(total == nr_free_pages()); - + // 调用 basic_check 以验证基本的内存管理功能 basic_check(); - + // 分配 5 个页面 struct Page *p0 = alloc_pages(5), *p1, *p2; - assert(p0 != NULL); - assert(!PageProperty(p0)); - + assert(p0 != NULL);// 确保成功分配 + assert(!PageProperty(p0));// 确保分配的页面不带属性 + // 初始化并检查空闲列表 list_entry_t free_list_store = free_list; list_init(&free_list); - assert(list_empty(&free_list)); - assert(alloc_page() == NULL); - - unsigned int nr_free_store = nr_free; - nr_free = 0; + assert(list_empty(&free_list));// 确保空闲列表为空 + assert(alloc_page() == NULL);// 确保没有页面可分配 + unsigned int nr_free_store = nr_free;// 保存当前空闲页数 + nr_free = 0;// 将空闲页数设为 0 +// 释放 3 个页面并确保分配页面时没有足够的空闲页 free_pages(p0 + 2, 3); - assert(alloc_pages(4) == NULL); - assert(PageProperty(p0 + 2) && p0[2].property == 3); - assert((p1 = alloc_pages(3)) != NULL); - assert(alloc_page() == NULL); - assert(p0 + 2 == p1); - - p2 = p0 + 1; - free_page(p0); - free_pages(p1, 3); - assert(PageProperty(p0) && p0->property == 1); - assert(PageProperty(p1) && p1->property == 3); - + assert(alloc_pages(4) == NULL);// 确保无法分配 4 个页面 + assert(PageProperty(p0 + 2) && p0[2].property == 3);// 检查页面属性 + assert((p1 = alloc_pages(3)) != NULL);// 再次分配 3 个页面 + assert(alloc_page() == NULL);// 确保没有页面可分配 + assert(p0 + 2 == p1);// 确保分配的页面是释放的页面 + + p2 = p0 + 1; // 设置 p2 为 p0 的下一个页面 + free_page(p0);// 释放 p0 页面 + free_pages(p1, 3);// 释放 p1 指向的页面 + assert(PageProperty(p0) && p0->property == 1); // 检查 p0 属性 + assert(PageProperty(p1) && p1->property == 3); // 检查 p1 属性 +// 确保重分配的页面是之前释放的页面 assert((p0 = alloc_page()) == p2 - 1); - free_page(p0); - assert((p0 = alloc_pages(2)) == p2 + 1); - + free_page(p0);// 释放分配的页面 + assert((p0 = alloc_pages(2)) == p2 + 1);// 分配 2 个页面并检查 +// 释放页面并检查空闲状态 free_pages(p0, 2); free_page(p2); - +// 再次分配 5 个页面 assert((p0 = alloc_pages(5)) != NULL); - assert(alloc_page() == NULL); - - assert(nr_free == 0); - nr_free = nr_free_store; + assert(alloc_page() == NULL);// 确保没有额外页面可分配 + assert(nr_free == 0);// 确保空闲页数为 0 + nr_free = nr_free_store;// 恢复空闲页数 +// 恢复空闲列表状态 free_list = free_list_store; - free_pages(p0, 5); - + free_pages(p0, 5);// 释放所有分配的页面 + // 验证空闲列表的一致性 le = &free_list; while ((le = list_next(le)) != &free_list) { - assert(le->next->prev == le && le->prev->next == le); - struct Page *p = le2page(le, page_link); + assert(le->next->prev == le && le->prev->next == le);// 验证双向链表 + struct Page *p = le2page(le, page_link);// 更新计数和总属性值 count --, total -= p->property; } - assert(count == 0); - assert(total == 0); + assert(count == 0);// 确保所有页面都已处理 + assert(total == 0);// 确保总属性值为 0 } const struct pmm_manager default_pmm_manager = { diff --git a/labcodes/lab2/kern/mm/pmm.c b/labcodes/lab2/kern/mm/pmm.c index 5c09bb04..30b3eeaa 100644 --- a/labcodes/lab2/kern/mm/pmm.c +++ b/labcodes/lab2/kern/mm/pmm.c @@ -10,100 +10,126 @@ #include /* * - * Task State Segment: + * Task State Segment:任务状态段(TSS) * * The TSS may reside anywhere in memory. A special segment register called * the Task Register (TR) holds a segment selector that points a valid TSS * segment descriptor which resides in the GDT. Therefore, to use a TSS * the following must be done in function gdt_init: - * - create a TSS descriptor entry in GDT - * - add enough information to the TSS in memory as needed - * - load the TR register with a segment selector for that segment + * TSS 可以位于内存的任何位置。一个特殊的段寄存器称为任务寄存器(TR),它保存一个段选择子, + * 该选择子指向位于全局描述符表(GDT)中的有效 TSS 段描述符。 + * 因此,要使用 TSS,必须在 gdt_init 函数中完成以下操作: + * - create a TSS descriptor entry in GDT 在 GDT 中创建一个 TSS 描述符条目 + * - add enough information to the TSS in memory as needed 根据需要将足够的信息添加到内存中的 TSS + * - load the TR register with a segment selector for that segment 使用该段的段选择子加载 TR 寄存器 * * There are several fileds in TSS for specifying the new stack pointer when a * privilege level change happens. But only the fields SS0 and ESP0 are useful * in our os kernel. + * TSS 中有几个字段用于指定特权级变化发生时的新栈指针。 + * 但在我们的操作系统内核中,仅有 SS0 和 ESP0 字段是有用的。 * * The field SS0 contains the stack segment selector for CPL = 0, and the ESP0 * contains the new ESP value for CPL = 0. When an interrupt happens in protected * mode, the x86 CPU will look in the TSS for SS0 and ESP0 and load their value * into SS and ESP respectively. + * 字段 SS0 包含 CPL = 0 的栈段选择子,而 ESP0 包含 CPL = 0 的新 ESP 值。当在保护模式下发生中断时, + * x86 CPU 将在 TSS 中查找 SS0 和 ESP0,并将其值分别加载到 SS 和 ESP 中。 * */ +//静态任务状态结构体初始化为零 static struct taskstate ts = {0}; -// virtual address of physicall page array +// virtual address of physicall page array声明了一个指向物理页面的数组的指针,用于管理物理内存中的页面。 struct Page *pages; -// amount of physical memory (in pages) +// amount of physical memory (in pages)用于记录物理内存的总量,以页面为单位,初始值为0。 size_t npage = 0; // virtual address of boot-time page directory -extern pde_t __boot_pgdir; -pde_t *boot_pgdir = &__boot_pgdir; +extern pde_t __boot_pgdir; //声明了一个外部变量,表示启动时的页目录。 +pde_t *boot_pgdir = &__boot_pgdir; //将其指针赋值给 boot_pgdir // physical address of boot-time page directory +// 用于存储启动时页目录的物理地址,这通常用于内存管理中的页表转换 uintptr_t boot_cr3; // physical memory management +//声明了一个指向物理内存管理器结构的指针,用于管理和分配物理内存。 const struct pmm_manager *pmm_manager; /* * * The page directory entry corresponding to the virtual address range * [VPT, VPT + PTSIZE) points to the page directory itself. Thus, the page * directory is treated as a page table as well as a page directory. - * + * 对应于虚拟地址范围 [VPT, VPT + PTSIZE) 的页目录项指向页目录本身。 + * 因此,页目录既被视为页表,也被视为页目录。 + * * One result of treating the page directory as a page table is that all PTEs * can be accessed though a "virtual page table" at virtual address VPT. And the * PTE for number n is stored in vpt[n]. - * + * 将页目录视为页表的一个结果是,所有的页表项(PTE)可以通过位于虚拟地址 VPT 的“虚拟页表”进行访问。 + * 页表项编号为 n 的项存储在 vpt[n] 中。 + * * A second consequence is that the contents of the current page directory will * always available at virtual address PGADDR(PDX(VPT), PDX(VPT), 0), to which * vpd is set bellow. + * 第二个结果是,当前页目录的内容总是可以在虚拟地址 PGADDR(PDX(VPT), PDX(VPT), 0) 处获得, + * vpd 将被设置为该地址。 * */ -pte_t * const vpt = (pte_t *)VPT; -pde_t * const vpd = (pde_t *)PGADDR(PDX(VPT), PDX(VPT), 0); - +pte_t * const vpt = (pte_t *)VPT; //定义了一个常量指针 vpt,指向虚拟地址 VPT,该地址表示虚拟页表。 +pde_t * const vpd = (pde_t *)PGADDR(PDX(VPT), PDX(VPT), 0);//定义了另一个常量指针 vpd,指向当前页目录的虚拟地址。 +//PGADDR 是一个宏或函数,用于生成特定格式的虚拟地址,其中 PDX 可能用于计算虚拟地址的索引部分。 /* * * Global Descriptor Table: - * + * 全局描述符表 * The kernel and user segments are identical (except for the DPL). To load * the %ss register, the CPL must equal the DPL. Thus, we must duplicate the * segments for the user and the kernel. Defined as follows: - * - 0x0 : unused (always faults -- for trapping NULL far pointers) - * - 0x8 : kernel code segment - * - 0x10: kernel data segment - * - 0x18: user code segment - * - 0x20: user data segment - * - 0x28: defined for tss, initialized in gdt_init + * 内核和用户段是相同的(除了特权级 DPL )。要加载 %ss 寄存器,当前特权级 CPL 必须等于 DPL。 + * 因此,我们必须为用户和内核重复这些段。定义如下: + * - 0x0 : unused (always faults -- for trapping NULL far pointers)未使用(始终发生错误 -- 用于捕获 NULL 远指针) + * - 0x8 : kernel code segment 内核代码段 + * - 0x10: kernel data segment 内核数据段 + * - 0x18: user code segment 用户代码段 + * - 0x20: user data segment 用户数据段 + * - 0x28: defined for tss, initialized in gdt_init 定义用于 TSS,在 gdt_init 中初始化 * */ +//定义了一个静态的全局描述符表(GDT),用于管理内核和用户的段描述符。 static struct segdesc gdt[] = { - SEG_NULL, + SEG_NULL,//第一个段描述符,保留为 NULL,用于捕获无效的段访问。 + //内核代码段,具有执行(STA_X)和可读(STA_R)属性,基地址为 0x0,大小为 0xFFFFFFFF,特权级为内核(DPL_KERNEL)。 [SEG_KTEXT] = SEG(STA_X | STA_R, 0x0, 0xFFFFFFFF, DPL_KERNEL), + //内核数据段,具有可写(STA_W)属性,基地址为 0x0,大小为 0xFFFFFFFF,特权级为内核(DPL_KERNEL)。 [SEG_KDATA] = SEG(STA_W, 0x0, 0xFFFFFFFF, DPL_KERNEL), + //用户代码段,具有执行(STA_X)和可读(STA_R)属性,基地址为 0x0,大小为 0xFFFFFFFF,特权级为用户(DPL_USER)。 [SEG_UTEXT] = SEG(STA_X | STA_R, 0x0, 0xFFFFFFFF, DPL_USER), + //用户数据段,具有可写(STA_W)属性,基地址为 0x0,大小为 0xFFFFFFFF,特权级为用户(DPL_USER)。 [SEG_UDATA] = SEG(STA_W, 0x0, 0xFFFFFFFF, DPL_USER), - [SEG_TSS] = SEG_NULL, + [SEG_TSS] = SEG_NULL,//任务状态段(TSS),保留为 NULL,后续会在初始化时设置。 }; - +//定义了一个静态的伪描述符,用于描述 GDT 的长度和地址。 static struct pseudodesc gdt_pd = { sizeof(gdt) - 1, (uintptr_t)gdt }; -static void check_alloc_page(void); -static void check_pgdir(void); -static void check_boot_pgdir(void); +static void check_alloc_page(void);//声明一个静态函数,用于检查内存页的分配。 +static void check_pgdir(void); //声明一个静态函数,用于检查页目录的有效性。 +static void check_boot_pgdir(void); //声明一个静态函数,用于检查启动时的页目录。 /* * * lgdt - load the global descriptor table register and reset the * data/code segement registers for kernel. + * lgdt - 加载全局描述符表寄存器并重置内核的数据/代码段寄存器。 * */ +//定义了一个静态内联函数 lgdt,接收一个指向伪描述符(struct pseudodesc)的指针 pd static inline void lgdt(struct pseudodesc *pd) { - asm volatile ("lgdt (%0)" :: "r" (pd)); - asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS)); - asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS)); - asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS)); - asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS)); - asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS)); + asm volatile ("lgdt (%0)" :: "r" (pd));//这行汇编代码使用 lgdt 指令加载 GDT。%0 被替换为指向 pd 的指针,告诉处理器 GDT 的地址。 + asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS));//将 USER_DS(用户数据段)的值移动到 gs 段寄存器。 + asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS));//将 USER_DS 的值移动到 fs 段寄存器。 + asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS));//将 KERNEL_DS(内核数据段)的值移动到 es 段寄存器。 + asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ds 段寄存器 + asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ss 段寄存器 // reload cs + //通过 ljmp 指令重新加载代码段寄存器 cs,并跳转到标签 1。 asm volatile ("ljmp %0, $1f\n 1:\n" :: "i" (KERNEL_CS)); } @@ -111,62 +137,81 @@ lgdt(struct pseudodesc *pd) { * load_esp0 - change the ESP0 in default task state segment, * so that we can use different kernel stack when we trap frame * user to kernel. + * load_esp0 - 修改默认任务状态段中的 ESP0,以便在从用户态陷入内核态时能够使用不同的内核栈。 * */ +//uintptr_t esp0:这是新的堆栈指针,通常指向内核栈的顶部。 +//修改当前任务状态段(TSS)中的 ESP0 值。ESP0 是在从用户态切换到内核态时,CPU 使用的内核栈指针。 void load_esp0(uintptr_t esp0) { ts.ts_esp0 = esp0; } /* gdt_init - initialize the default GDT and TSS */ +/* gdt_init - 初始化默认的 GDT 和 TSS */ static void gdt_init(void) { + // 设置启动内核栈和默认的 SS0 // set boot kernel stack and default SS0 load_esp0((uintptr_t)bootstacktop); ts.ts_ss0 = KERNEL_DS; - + // 初始化 GDT 中的 TSS 字段 // initialize the TSS filed of the gdt gdt[SEG_TSS] = SEGTSS(STS_T32A, (uintptr_t)&ts, sizeof(ts), DPL_KERNEL); - + // 使用lgdt加载全局描述符表,更新所有段寄存器 // reload all segment registers lgdt(&gdt_pd); - + // 加载 TSS,使 CPU 在进行特权级切换时能够正确使用 TSS。 // load the TSS ltr(GD_TSS); } //init_pmm_manager - initialize a pmm_manager instance +//初始化一个 pmm_manager 实例 static void init_pmm_manager(void) { + //将 pmm_manager 指向默认的 PMM 管理器实例。 pmm_manager = &default_pmm_manager; + //使用 cprintf 打印当前内存管理器的名称。 cprintf("memory management: %s\n", pmm_manager->name); + //调用 PMM 管理器的初始化函数,以设置和准备内存管理的相关数据结构。 pmm_manager->init(); } //init_memmap - call pmm->init_memmap to build Page struct for free memory +// init_memmap - 调用 pmm->init_memmap 构建空闲内存的 Page 结构 +//struct Page *base:指向内存页的基础地址。 size_t n:要初始化的页数。 static void init_memmap(struct Page *base, size_t n) { pmm_manager->init_memmap(base, n); } //alloc_pages - call pmm->alloc_pages to allocate a continuous n*PAGESIZE memory +// alloc_pages - 调用 pmm->alloc_pages 分配连续的 n*PAGESIZE 内存 struct Page * alloc_pages(size_t n) { struct Page *page=NULL; bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在分配内存时发生中断。 local_intr_save(intr_flag); { + //调用物理内存管理器的 alloc_pages 函数分配 n 页的内存。 page = pmm_manager->alloc_pages(n); } + //恢复之前保存的中断状态。 local_intr_restore(intr_flag); return page; } //free_pages - call pmm->free_pages to free a continuous n*PAGESIZE memory +// free_pages - 调用 pmm->free_pages 释放连续的 n*PAGESIZE 内存 +//struct Page *base:指向要释放的内存页的基础地址。size_t n:要释放的页数。 void free_pages(struct Page *base, size_t n) { bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在释放内存时发生中断。 local_intr_save(intr_flag); { + //调用物理内存管理器的 free_pages 函数释放 n 页的内存。 pmm_manager->free_pages(base, n); } local_intr_restore(intr_flag); @@ -174,65 +219,68 @@ free_pages(struct Page *base, size_t n) { //nr_free_pages - call pmm->nr_free_pages to get the size (nr*PAGESIZE) //of current free memory +// nr_free_pages - 调用 pmm->nr_free_pages 获取当前空闲内存的大小 (nr * PAGESIZE) size_t nr_free_pages(void) { - size_t ret; - bool intr_flag; - local_intr_save(intr_flag); + size_t ret;// 定义变量 ret 用于存储返回的空闲内存大小 + bool intr_flag;// 定义变量 intr_flag 用于保存中断状态 + local_intr_save(intr_flag);// 保存当前中断状态,并禁用中断 { - ret = pmm_manager->nr_free_pages(); + ret = pmm_manager->nr_free_pages();// 调用物理内存管理器的函数获取空闲内存页数 } - local_intr_restore(intr_flag); - return ret; + local_intr_restore(intr_flag);// 恢复之前保存的中断状态 + return ret;// 返回空闲内存的大小 } /* pmm_init - initialize the physical memory management */ +/* pmm_init - 初始化物理内存管理 */ static void page_init(void) { + // 获取物理内存映射信息,存于特定地址 struct e820map *memmap = (struct e820map *)(0x8000 + KERNBASE); - uint64_t maxpa = 0; + uint64_t maxpa = 0;// 初始化最大物理地址为0 - cprintf("e820map:\n"); + cprintf("e820map:\n");// 打印“e820map”标题 int i; - for (i = 0; i < memmap->nr_map; i ++) { - uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size; - cprintf(" memory: %08llx, [%08llx, %08llx], type = %d.\n", + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size; // 获取每个区域的起始和结束地址 + cprintf(" memory: %08llx, [%08llx, %08llx], type = %d.\n",// 打印内存区域的信息 memmap->map[i].size, begin, end - 1, memmap->map[i].type); - if (memmap->map[i].type == E820_ARM) { - if (maxpa < end && begin < KMEMSIZE) { - maxpa = end; + if (memmap->map[i].type == E820_ARM) { // 检查内存类型是否为可用内存 + if (maxpa < end && begin < KMEMSIZE) {// 检查当前区域是否在有效范围内 + maxpa = end;// 更新最大物理地址 } } } - if (maxpa > KMEMSIZE) { - maxpa = KMEMSIZE; + if (maxpa > KMEMSIZE) {// 如果最大物理地址超过了预定义的内存上限 + maxpa = KMEMSIZE;// 将其限制为内存上限 } - extern char end[]; + extern char end[];// 引入全局变量 end,指向内存的结束位置 - npage = maxpa / PGSIZE; - pages = (struct Page *)ROUNDUP((void *)end, PGSIZE); + npage = maxpa / PGSIZE; // 计算可用页数 + pages = (struct Page *)ROUNDUP((void *)end, PGSIZE);// 将 end 对齐到页边界,指向页结构数组的开头 - for (i = 0; i < npage; i ++) { - SetPageReserved(pages + i); + for (i = 0; i < npage; i ++) {// 遍历每一页 + SetPageReserved(pages + i);// 将每一页标记为保留状态 } - uintptr_t freemem = PADDR((uintptr_t)pages + sizeof(struct Page) * npage); + uintptr_t freemem = PADDR((uintptr_t)pages + sizeof(struct Page) * npage);// 计算可用内存的起始地址 - for (i = 0; i < memmap->nr_map; i ++) { - uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size; - if (memmap->map[i].type == E820_ARM) { - if (begin < freemem) { - begin = freemem; + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址 + if (memmap->map[i].type == E820_ARM) {// 如果区域类型为可用内存 + if (begin < freemem) { // 如果起始地址小于可用内存地址 + begin = freemem;// 将起始地址设置为可用内存地址 } - if (end > KMEMSIZE) { - end = KMEMSIZE; + if (end > KMEMSIZE) {// 如果结束地址超过内存上限 + end = KMEMSIZE;// 将其限制为内存上限 } - if (begin < end) { - begin = ROUNDUP(begin, PGSIZE); - end = ROUNDDOWN(end, PGSIZE); - if (begin < end) { - init_memmap(pa2page(begin), (end - begin) / PGSIZE); + if (begin < end) {// 如果起始地址小于结束地址 + begin = ROUNDUP(begin, PGSIZE);// 将起始地址对齐到页边界 + end = ROUNDDOWN(end, PGSIZE);// 将结束地址对齐到页边界 + if (begin < end) {// 如果调整后的起始地址仍小于结束地址 + init_memmap(pa2page(begin), (end - begin) / PGSIZE);// 初始化内存页映射 } } } @@ -241,19 +289,29 @@ page_init(void) { //boot_map_segment - setup&enable the paging mechanism // parameters +// boot_map_segment - 设置并启用分页机制 // la: linear address of this memory need to map (after x86 segment map) -// size: memory size -// pa: physical address of this memory -// perm: permission of this memory +//la: 需要映射的线性地址(经过 x86 段映射后的地址) +// size: memory size size: 内存大小 +// pa: physical address of this memory pa:该内存的物理地址 +// perm: permission of this memory perm: 该内存的权限 static void boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, uintptr_t pa, uint32_t perm) { + // 确保线性地址和物理地址的页偏移相同 assert(PGOFF(la) == PGOFF(pa)); + // 计算需要映射的页数,ROUNDUP 将总大小对齐到下一个页大小的边界 size_t n = ROUNDUP(size + PGOFF(la), PGSIZE) / PGSIZE; + // 将线性地址向下对齐到页边界 la = ROUNDDOWN(la, PGSIZE); + // 将物理地址向下对齐到页边界 pa = ROUNDDOWN(pa, PGSIZE); + // 循环遍历每一页,直到映射的页数为零 for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { + // 获取当前页的页表项指针,如果不存在则创建新的页表项 pte_t *ptep = get_pte(pgdir, la, 1); + // 确保页表项指针不为空 assert(ptep != NULL); + // 设置页表项,包含物理地址、存在位和权限 *ptep = pa | PTE_P | perm; } } @@ -261,20 +319,25 @@ boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, uintptr_t pa, uint32_t //boot_alloc_page - allocate one page using pmm->alloc_pages(1) // return value: the kernel virtual address of this allocated page //note: this function is used to get the memory for PDT(Page Directory Table)&PT(Page Table) +//boot_alloc_page - 使用 pmm->alloc_pages(1) 分配一页内存.返回值: 分配的页面的内核虚拟地址 +//注意: 此函数用于获取页目录表(PDT)和页表(PT)的内存 static void * boot_alloc_page(void) { - struct Page *p = alloc_page(); - if (p == NULL) { - panic("boot_alloc_page failed.\n"); + struct Page *p = alloc_page();// 调用分配页面的函数 + if (p == NULL) {// 检查分配是否成功 + panic("boot_alloc_page failed.\n");// 如果分配失败,则触发异常 } - return page2kva(p); + return page2kva(p);// 返回分配页面的内核虚拟地址 } //pmm_init - setup a pmm to manage physical memory, build PDT&PT to setup paging mechanism // - check the correctness of pmm & paging mechanism, print PDT&PT +//pmm_init - 设置物理内存管理器,构建页目录表(PDT)和页表(PT),以设置分页机制 +// - 检查物理内存管理器和分页机制的正确性,打印页目录表和页表 void pmm_init(void) { // We've already enabled paging + // 我们已经启用了分页 boot_cr3 = PADDR(boot_pgdir); //We need to alloc/free the physical memory (granularity is 4KB or other size). @@ -282,38 +345,56 @@ pmm_init(void) { //First we should init a physical memory manager(pmm) based on the framework. //Then pmm can alloc/free the physical memory. //Now the first_fit/best_fit/worst_fit/buddy_system pmm are available. - init_pmm_manager(); + // 我们需要分配/释放物理内存(粒度为 4KB 或其他大小)。 + // 因此在 pmm.h 中定义了物理内存管理器的框架(struct pmm_manager)。 + // 首先,我们应该基于该框架初始化一个物理内存管理器(pmm)。 + // 然后 pmm 可以分配/释放物理内存。 + // 现在,first_fit/best_fit/worst_fit/buddy_system 的 pmm 都可用。 + init_pmm_manager();// 初始化物理内存管理器 // detect physical memory space, reserve already used memory, // then use pmm->init_memmap to create free page list - page_init(); + // 检测物理内存空间,保留已经使用的内存, + // 然后使用 pmm->init_memmap 创建空闲页面列表 + page_init();// 初始化页面管理 //use pmm->check to verify the correctness of the alloc/free function in a pmm - check_alloc_page(); + // 使用 pmm->check 验证 pmm 中分配/释放函数的正确性 + check_alloc_page();// 检查页面分配功能 - check_pgdir(); + check_pgdir();// 检查页目录的状态 - static_assert(KERNBASE % PTSIZE == 0 && KERNTOP % PTSIZE == 0); + static_assert(KERNBASE % PTSIZE == 0 && KERNTOP % PTSIZE == 0);// 确保 KERNBASE 和 KERNTOP 是页大小的倍数 // recursively insert boot_pgdir in itself // to form a virtual page table at virtual address VPT - boot_pgdir[PDX(VPT)] = PADDR(boot_pgdir) | PTE_P | PTE_W; + // 递归地将 boot_pgdir 插入到自身中 + // 在虚拟地址 VPT 处形成虚拟页表 + boot_pgdir[PDX(VPT)] = PADDR(boot_pgdir) | PTE_P | PTE_W;// 设置页目录项,映射自身 // map all physical memory to linear memory with base linear addr KERNBASE // linear_addr KERNBASE ~ KERNBASE + KMEMSIZE = phy_addr 0 ~ KMEMSIZE - boot_map_segment(boot_pgdir, KERNBASE, KMEMSIZE, 0, PTE_W); + // 将所有物理内存映射到线性内存,基地址为 KERNBASE + // 线性地址 KERNBASE ~ KERNBASE + KMEMSIZE = 物理地址 0 ~ KMEMSIZE + boot_map_segment(boot_pgdir, KERNBASE, KMEMSIZE, 0, PTE_W);// 映射物理内存 // Since we are using bootloader's GDT, // we should reload gdt (second time, the last time) to get user segments and the TSS // map virtual_addr 0 ~ 4G = linear_addr 0 ~ 4G // then set kernel stack (ss:esp) in TSS, setup TSS in gdt, load TSS - gdt_init(); + // 由于我们正在使用引导加载程序的 GDT, + // 我们应该重新加载 GDT(第二次,也是最后一次),以获取用户段和 TSS + // 映射虚拟地址 0 ~ 4G = 线性地址 0 ~ 4G + // 然后在 TSS 中设置内核栈 (ss:esp),在 gdt 中设置 TSS,加载 TSS + gdt_init();// 初始化全局描述符表 //now the basic virtual memory map(see memalyout.h) is established. //check the correctness of the basic virtual memory map. - check_boot_pgdir(); + // 现在基本的虚拟内存映射(见 memlayout.h)已建立。 + // 检查基础虚拟内存映射的正确性。 + check_boot_pgdir(); // 检查页目录的正确性 - print_pgdir(); + print_pgdir(); // 打印页目录表 } @@ -324,6 +405,13 @@ pmm_init(void) { // la: the linear address need to map // create: a logical value to decide if alloc a page for PT // return vaule: the kernel virtual address of this pte +// get_pte - 获取页表项(PTE),并返回该 PTE 的内核虚拟地址 +// 如果页表中不存在该 PTE,则为页表分配一页 +// 参数: +// pgdir: 页目录的内核虚拟基地址 +// la: 需要映射的线性地址 +// create: 一个逻辑值,决定是否为页表分配一页 +// 返回值:该 PTE 的内核虚拟地址 pte_t * get_pte(pde_t *pgdir, uintptr_t la, bool create) { /* LAB2 EXERCISE 2: YOUR CODE @@ -359,18 +447,42 @@ get_pte(pde_t *pgdir, uintptr_t la, bool create) { } return NULL; // (8) return page table entry #endif + // (1) 找到页目录项 + pde_t *pdep = &pgdir[PDX(la)];// 使用 PDX 宏获取页目录索引 + // (2) 检查页目录项是否存在 + if (!(*pdep & PTE_P)) {// 如果页目录项的存在位 PTE_P 没有被设置 + struct Page *page;// 声明一个指针,用于指向新分配的页面 + // 检查是否允许创建新页表,或者分配页表失败 + if (!create || (page = alloc_page()) == NULL) {// 如果不允许创建或分配失败 + return NULL;// 返回 NULL,表示无法获取页表 + } + // 设置新分配页面的引用计数为 1 + set_page_ref(page, 1); + uintptr_t pa = page2pa(page);// 获取新分配页面的物理地址 + memset(KADDR(pa), 0, PGSIZE);// 清空新分配的页表内容,初始化为零 + // 更新页目录项,设置物理地址和权限位 + *pdep = pa | PTE_U | PTE_W | PTE_P;// 将物理地址和权限位(用户可访问、可写、有效)合并设置 + } + // 返回指定线性地址 la 对应的页表项的内核虚拟地址 + return &((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)];// 计算并返回页表项的指针 } //get_page - get related Page struct for linear address la using PDT pgdir +// get_page - 获取与线性地址 la 相关的 Page 结构体,使用页目录 pgdir struct Page * get_page(pde_t *pgdir, uintptr_t la, pte_t **ptep_store) { + // 调用 get_pte 函数获取对应线性地址 la 的页表项指针 pte_t *ptep = get_pte(pgdir, la, 0); + // 如果 ptep_store 指针不为 NULL,将 ptep 存储到 ptep_store 指向的位置 if (ptep_store != NULL) { - *ptep_store = ptep; + *ptep_store = ptep; // 存储当前页表项的指针 } + // 检查 ptep 是否有效以及页表项的存在位 PTE_P 是否被设置 if (ptep != NULL && *ptep & PTE_P) { - return pte2page(*ptep); + // 返回与页表项对应的 Page 结构体 + return pte2page(*ptep);// 将页表项转换为对应的 Page 结构 } + // 如果未找到有效的页,返回 NULL return NULL; } @@ -404,12 +516,24 @@ page_remove_pte(pde_t *pgdir, uintptr_t la, pte_t *ptep) { //(6) flush tlb } #endif + if (*ptep & PTE_P) { + struct Page *page = pte2page(*ptep);// 找到对应的物理页 + // 减少物理页的引用计数,如果引用计数为零,释放该物理页 + if (page_ref_dec(page) == 0) { + free_page(page); + } + *ptep = 0;// 清除页表项 + tlb_invalidate(pgdir, la);// 刷新 TLB + } } //page_remove - free an Page which is related linear address la and has an validated pte +//移除一个虚拟地址对应的页面 void page_remove(pde_t *pgdir, uintptr_t la) { + //调用 get_pte 函数获取给定虚拟地址 la 对应的页表项指针 ptep。 pte_t *ptep = get_pte(pgdir, la, 0); + //如果 ptep 不为 NULL,则调用 page_remove_pte 函数移除该页表项。 if (ptep != NULL) { page_remove_pte(pgdir, la, ptep); } @@ -423,131 +547,182 @@ page_remove(pde_t *pgdir, uintptr_t la) { // perm: the permission of this Page which is setted in related pte // return value: always 0 //note: PT is changed, so the TLB need to be invalidate +//将一个页面插入到页表中。 int page_insert(pde_t *pgdir, struct Page *page, uintptr_t la, uint32_t perm) { + //通过 get_pte 函数获取指定虚拟地址 la 对应的页表项指针 ptep。 pte_t *ptep = get_pte(pgdir, la, 1); + //如果 ptep 为 NULL,表示内存分配失败,返回 -E_NO_MEM。 if (ptep == NULL) { return -E_NO_MEM; } + //调用 page_ref_inc 增加页面的引用计数。 page_ref_inc(page); + //如果页表项已存在且指向当前页面,则减少页面引用计数。 if (*ptep & PTE_P) { struct Page *p = pte2page(*ptep); if (p == page) { page_ref_dec(page); } + //如果页表项已存在但指向其他页面,则调用 page_remove_pte 移除旧的页表项。 else { page_remove_pte(pgdir, la, ptep); } } *ptep = page2pa(page) | PTE_P | perm; - tlb_invalidate(pgdir, la); + tlb_invalidate(pgdir, la);//刷新 TLB return 0; } // invalidate a TLB entry, but only if the page tables being // edited are the ones currently in use by the processor. +//无效化指定地址的TLB条目 void tlb_invalidate(pde_t *pgdir, uintptr_t la) { + //检查当前页目录地址是否与传入的页目录地址相同。 if (rcr3() == PADDR(pgdir)) { + //如果相同,则调用 invlpg 函数无效化指定线性地址的TLB条目。 invlpg((void *)la); } } static void check_alloc_page(void) { + //调用内存管理器的 check 方法,用于检查内存分配是否正常。 pmm_manager->check(); cprintf("check_alloc_page() succeeded!\n"); } - +//用于验证页目录和页表的正确性。 static void check_pgdir(void) { + //确保内存页面数量在合理范围内 assert(npage <= KMEMSIZE / PGSIZE); + //确保页目录不为空且对齐, assert(boot_pgdir != NULL && (uint32_t)PGOFF(boot_pgdir) == 0); + //确保虚拟地址 0x0 没有映射任何页面 assert(get_page(boot_pgdir, 0x0, NULL) == NULL); - + + //定义两个页面指针 p1 和 p2 struct Page *p1, *p2; + //分配一个页面 p1 p1 = alloc_page(); + //将 p1 插入到虚拟地址 0x0 assert(page_insert(boot_pgdir, p1, 0x0, 0) == 0); + // 获取虚拟地址 0x0 对应的页表项指针 pte_t *ptep; assert((ptep = get_pte(boot_pgdir, 0x0, 0)) != NULL); + // 验证页表项对应的页面是 p1 assert(pte2page(*ptep) == p1); + // 验证 p1 的引用计数为 1 assert(page_ref(p1) == 1); - + // 获取虚拟地址 PGSIZE 对应的页表项指针 ptep = &((pte_t *)KADDR(PDE_ADDR(boot_pgdir[0])))[1]; assert(get_pte(boot_pgdir, PGSIZE, 0) == ptep); - + // 分配一个页面 p2 p2 = alloc_page(); + // 将 p2 插入到虚拟地址 PGSIZE,并设置用户和写权限 assert(page_insert(boot_pgdir, p2, PGSIZE, PTE_U | PTE_W) == 0); + // 获取虚拟地址 PGSIZE 对应的页表项指针 assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); + // 验证页表项设置了用户权限 assert(*ptep & PTE_U); + // 验证页表项设置了写权限 assert(*ptep & PTE_W); + // 验证页目录项设置了用户权限 assert(boot_pgdir[0] & PTE_U); + // 验证 p2 的引用计数为 1 assert(page_ref(p2) == 1); + // 将 p1 插入到虚拟地址 PGSIZE,替换掉 p2 assert(page_insert(boot_pgdir, p1, PGSIZE, 0) == 0); + // 验证 p1 的引用计数增加到 2 assert(page_ref(p1) == 2); + // 验证 p2 的引用计数减少到 0 assert(page_ref(p2) == 0); + // 获取虚拟地址 PGSIZE 对应的页表项指针 assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); + // 验证页表项对应的页面是 p1 assert(pte2page(*ptep) == p1); + // 验证页表项没有设置用户权限 assert((*ptep & PTE_U) == 0); - + + //移除虚拟地址 0x0 的映射, page_remove(boot_pgdir, 0x0); + //验证 p1 的引用计数减少到 1。 assert(page_ref(p1) == 1); + //验证 p2 的引用计数减少到 0 assert(page_ref(p2) == 0); + //移除虚拟地址 PGSIZE 的映射, page_remove(boot_pgdir, PGSIZE); + //验证 p1 的引用计数减少到 0 assert(page_ref(p1) == 0); + //验证 p2 的引用计数减少到 0 assert(page_ref(p2) == 0); - + + //验证页目录的第一页表的引用计数为 1。 assert(page_ref(pde2page(boot_pgdir[0])) == 1); + //释放页目录的第一页表 free_page(pde2page(boot_pgdir[0])); + //清空页目录的第一页表 boot_pgdir[0] = 0; cprintf("check_pgdir() succeeded!\n"); } +//检查内核页表 boot_pgdir 的正确性 static void check_boot_pgdir(void) { - pte_t *ptep; + pte_t *ptep;// 定义一个指向页表项的指针 int i; - for (i = 0; i < npage; i += PGSIZE) { + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 + // 获取第 i 个页面的页表项,并确保其不为空 assert((ptep = get_pte(boot_pgdir, (uintptr_t)KADDR(i), 0)) != NULL); + // 验证页表项的物理地址是否正确 assert(PTE_ADDR(*ptep) == i); } - + // 验证页目录项的物理地址是否正确 assert(PDE_ADDR(boot_pgdir[PDX(VPT)]) == PADDR(boot_pgdir)); - assert(boot_pgdir[0] == 0); + assert(boot_pgdir[0] == 0);// 确保页目录的第一个项为0 - struct Page *p; - p = alloc_page(); + struct Page *p;// 定义一个指向页面的指针 + p = alloc_page();// 分配一个页面 + // 将页面插入到虚拟地址 0x100,并确保操作成功 assert(page_insert(boot_pgdir, p, 0x100, PTE_W) == 0); - assert(page_ref(p) == 1); + assert(page_ref(p) == 1);// 验证页面的引用计数为1 + // 将页面插入到虚拟地址 0x100 + PGSIZE,并确保操作成功 assert(page_insert(boot_pgdir, p, 0x100 + PGSIZE, PTE_W) == 0); - assert(page_ref(p) == 2); + assert(page_ref(p) == 2);// 验证页面的引用计数为2 - const char *str = "ucore: Hello world!!"; - strcpy((void *)0x100, str); + const char *str = "ucore: Hello world!!";// 定义一个字符串 + strcpy((void *)0x100, str);// 将字符串复制到虚拟地址 0x100 + // 验证两个映射地址的数据是否一致 assert(strcmp((void *)0x100, (void *)(0x100 + PGSIZE)) == 0); - + // 在页面的 0x100 偏移处设置字符串结束符 *(char *)(page2kva(p) + 0x100) = '\0'; - assert(strlen((const char *)0x100) == 0); + assert(strlen((const char *)0x100) == 0);// 验证字符串长度为0 - free_page(p); - free_page(pde2page(boot_pgdir[0])); - boot_pgdir[0] = 0; + free_page(p);// 释放页面 p + free_page(pde2page(boot_pgdir[0]));// 释放页目录项对应的页面 + boot_pgdir[0] = 0;// 将页目录的第一个项设为0 - cprintf("check_boot_pgdir() succeeded!\n"); + cprintf("check_boot_pgdir() succeeded!\n");// 输出成功信息 } //perm2str - use string 'u,r,w,-' to present the permission static const char * perm2str(int perm) { + //定义一个静态字符数组 str,长度为4 static char str[4]; + //如果 perm 与 PTE_U 按位与的结果不为0,则 str[0] 设置为 'u',否则设置为 '-' str[0] = (perm & PTE_U) ? 'u' : '-'; + //str[1] 始终设置为 'r' str[1] = 'r'; + //如果 perm 与 PTE_W 按位与的结果不为0,则 str[2] 设置为 'w',否则设置为 '-' str[2] = (perm & PTE_W) ? 'w' : '-'; + //str[3] 设置为字符串结束符 \0 str[3] = '\0'; return str; } @@ -563,40 +738,47 @@ perm2str(int perm) { // left_store: the pointer of the high side of table's next range // right_store: the pointer of the low side of table's next range // return value: 0 - not a invalid item range, perm - a valid item range with perm permission +//从页表中获取指定范围内的有效项,并根据权限进行处理。 static int get_pgtable_items(size_t left, size_t right, size_t start, uintptr_t *table, size_t *left_store, size_t *right_store) { - if (start >= right) { - return 0; + if (start >= right) {// 检查起始索引是否超出右边界 + return 0;// 如果超出右边界,返回0 } - while (start < right && !(table[start] & PTE_P)) { - start ++; + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) + start ++;// 索引递增 } - if (start < right) { - if (left_store != NULL) { - *left_store = start; + if (start < right) {// 检查是否找到有效项 + if (left_store != NULL) {// 如果left_store不为NULL + *left_store = start;// 记录左边界索引 } - int perm = (table[start ++] & PTE_USER); - while (start < right && (table[start] & PTE_USER) == perm) { - start ++; + int perm = (table[start ++] & PTE_USER);// 获取当前项的用户权限位并递增索引 + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 + start ++;// 索引递增 } - if (right_store != NULL) { - *right_store = start; + if (right_store != NULL) {// 如果right_store不为NULL + *right_store = start;// 记录右边界索引 } - return perm; + return perm;// 返回用户权限位 } - return 0; + return 0;// 如果未找到有效项,返回0 } //print_pgdir - print the PDT&PT void print_pgdir(void) { cprintf("-------------------- BEGIN --------------------\n"); + // 定义变量 left, right 和 perm size_t left, right = 0, perm; + // 遍历页目录项 while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { + // 打印页目录项的信息 cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, left * PTSIZE, right * PTSIZE, (right - left) * PTSIZE, perm2str(perm)); + // 计算页表项的起始和结束索引 size_t l, r = left * NPTEENTRY; + // 遍历页表项 while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { + // 打印页表项的信息 cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, l * PGSIZE, r * PGSIZE, (r - l) * PGSIZE, perm2str(perm)); } diff --git a/labcodes/lab2/kern/trap/trap.c b/labcodes/lab2/kern/trap/trap.c index af786765..3c6e420e 100644 --- a/labcodes/lab2/kern/trap/trap.c +++ b/labcodes/lab2/kern/trap/trap.c @@ -46,6 +46,20 @@ idt_init(void) { * You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more. * Notice: the argument of lidt is idt_pd. try to find it! */ + extern uintptr_t __vectors[];//声明了一个外部数组 __vectors,该数组存储中断服务例程(ISR)的地址。 + int i; + for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { + SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL); + } + //宏用于配置每个 IDT 条目.0 表示最高特权级(内核级)GD_KTEXT: 指向内核代码段的选择子,确保 ISR 在内核代码段中执行。 + //__vectors[i]: 对应中断的 ISR 地址,DPL_KERNEL: 描述符特权级,表示该中断只能由内核级代码触发。 + // set for switch from user to kernel + //SETGATE 这行代码特别设置了 T_SWITCH_TOK(一个特定的中断向量,用于用户态到内核态的切换)的 IDT 条目。 + //DPL_USER 表示该中断可以由用户态代码触发 + SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER); + // load the IDT + //使用 lidt 指令将 IDT 描述符加载到 CPU 中 + lidt(&idt_pd); } static const char * @@ -134,6 +148,7 @@ print_regs(struct pushregs *regs) { cprintf(" eax 0x%08x\n", regs->reg_eax); } +struct trapframe switchk2u, *switchu2k; /* trap_dispatch - dispatch based on what type of trap occurred */ static void trap_dispatch(struct trapframe *tf) { @@ -147,6 +162,11 @@ trap_dispatch(struct trapframe *tf) { * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks(). * (3) Too Simple? Yes, I think so! */ + ticks ++; //记录中断事件 + if (ticks % TICK_NUM == 0) + { + print_ticks(); + }//每经过 TICK_NUM 次周期时,调用 print_ticks() 打印信息。 break; case IRQ_OFFSET + IRQ_COM1: c = cons_getc(); @@ -157,10 +177,38 @@ trap_dispatch(struct trapframe *tf) { cprintf("kbd [%03d] %c\n", c, c); break; //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes. - case T_SWITCH_TOU: - case T_SWITCH_TOK: - panic("T_SWITCH_** ??\n"); + case T_SWITCH_TOU://表示发生了从内核模式切换到用户模式的请求。 + if (tf->tf_cs != USER_CS) {//判断当前是否在内核模式下 + switchk2u = *tf; //保存当前陷阱框架 + switchk2u.tf_cs = USER_CS;//设置用户模式的段寄存器 + //将数据段和栈段寄存器 都设置为 USER_DS(用户数据段) + switchk2u.tf_ds = switchk2u.tf_es = switchk2u.tf_ss = USER_DS; + switchk2u.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8; + + // set eflags, make sure ucore can use io under user mode. + // if CPL > IOPL, then cpu will generate a general protection. + switchk2u.tf_eflags |= FL_IOPL_MASK;//允许用户模式下进行 I/O 操作 + + // set temporary stack + // then iret will jump to the right stack + *((uint32_t *)tf - 1) = (uint32_t)&switchk2u; + } + break; + case T_SWITCH_TOK: // T_SWITCH_TOK 表示发生了从用户模式切换到内核模式的请求。 + if (tf->tf_cs != KERNEL_CS) { //判断当前是否在用户模式下 + tf->tf_cs = KERNEL_CS; + tf->tf_ds = tf->tf_es = KERNEL_DS; + //设置内核模式的段寄存器 + tf->tf_eflags &= ~FL_IOPL_MASK; //清除 I/O 权限标志 + switchu2k = (struct trapframe *)(tf->tf_esp - (sizeof(struct trapframe) - 8)); + //使用 memmove 将当前的陷阱框架(除了最后8个字节)复制到新的陷阱框架位置 switchu2k + memmove(switchu2k, tf, sizeof(struct trapframe) - 8); + //将新的陷阱框架地址 switchu2k 存储到当前陷阱框架之前的一个栈位置 + *((uint32_t *)tf - 1) = (uint32_t)switchu2k; + } break; + // panic("T_SWITCH_** ??\n"); + // break; case IRQ_OFFSET + IRQ_IDE1: case IRQ_OFFSET + IRQ_IDE2: /* do nothing */ diff --git a/labcodes/lab2/obj/boot/bootasm.d b/labcodes/lab2/obj/boot/bootasm.d new file mode 100644 index 00000000..08146746 --- /dev/null +++ b/labcodes/lab2/obj/boot/bootasm.d @@ -0,0 +1 @@ +obj/boot/bootasm.o obj/boot/bootasm.d: boot/bootasm.S boot/asm.h diff --git a/labcodes/lab2/obj/boot/bootasm.o b/labcodes/lab2/obj/boot/bootasm.o new file mode 100644 index 0000000000000000000000000000000000000000..6229f43ab2491dce3b30d5f3ab500718935228dd GIT binary patch literal 2268 zcma)-O>9(E6vzM5R)X5lY6>(;WKax6ab`+Kp|N6{zM&9XI(9%njpLgyT68*P-fN_h z#G0xxYGz?r5LYf(xNyOOMKu^_VFDXNO<0&{v1MFz4hAnwR&yom%?W)vv)3ice9}C z=bNvVu5Q3QYnOU|__}Srv>06x{Y4ieU#5q~GT(0YHnL8C;`XM6t6imr=+eR;n7z>v z+0u=UXuY&>EzvbZ zDD+$6NQi%*JOz#K5Wb_DaDvh>;NX6{1`al(Me8}(f;OwSLYGF`cFROf+wHi=>Zq)j ziSNKBs~pKBRv*MGR*%57`Vfj% zk7Cm5=TWwL0%xqwz_a=&X01MkH>`dEb5@_kn^wOVW~=xPUc$RJp2Y{$albqh&*x8{ zK6Ct7U(EZLpQ}{-IA5+;j+rmkPX2+vpDf5p3nM0XfYk=`!sG`1?c%SW$JNGe@p*{C zu2&l|5hmYQbD#Johv*NAZ}NivnD{0K=yNa3{?X@tnEj#un)oL7IAgA}*#nlJ6F*od zA^o=lnpdk`PewYW{6kX|`0`3mj33R8jXSCAa3(d<! zO~iVQ*o&EJC0ERri{(mn4xaB;{cI3IzB28jG&MctO={#+!7miOJe&A=uXqaH%+xd_ z8ny#BvFu9dWtmo&9Qr9z7N6e~k;~&fVT&AAp1+8cbDep0MwNS%`<0F|tz^Hf&wM6* z<-GDE&ne$mo>zXV z{9L)H{6@K?{8720{7uOVmh)^^b}M%(6UqT4V%}WYcXL9&8gkO8YVq}$Up(t0MpbZq z7qOh@g|6gB(8$e6by=kUY32-?`#ve{xL3wx>VZ8d@4Mw03_Qt?yTaUHjCJ_$;92Jx zrr#asy6l!K%QiidXW<3e=-r_%*{qfE--z74zc_}z= T9HHrtZJNiuER!1fk9vOrhFA1R literal 0 HcmV?d00001 diff --git a/labcodes/lab2/obj/boot/bootmain.d b/labcodes/lab2/obj/boot/bootmain.d new file mode 100644 index 00000000..c0d98e63 --- /dev/null +++ b/labcodes/lab2/obj/boot/bootmain.d @@ -0,0 +1,2 @@ +obj/boot/bootmain.o obj/boot/bootmain.d: boot/bootmain.c libs/defs.h \ + libs/x86.h libs/elf.h diff --git a/labcodes/lab2/obj/boot/bootmain.o b/labcodes/lab2/obj/boot/bootmain.o new file mode 100644 index 0000000000000000000000000000000000000000..c72e25d0a0da0d07b6a528c4edddda1156d4be4d GIT binary patch literal 3984 zcmd^CU2GIp6h7M@ElL3qO(STER_W@pbY^F_yIl&c-Ih&?q@fh3qRV!7w!6~($<8bm zqENz*E~JXa2Omt3_-0~4;)7UUAcP-%A{t+aF@yjq0igm459oT%oild_dC+%Ha_4;a zyWhQY@3}v7XJ_x~K9|b{wz;4dsyTqojaG>!Tr13hMi?qz+Az6%Uitg=yDn5veEiBR z_u0YnsmX5F?rRO@cdmVV2ibD(Ot^H-c(Z)&TFbHJU8OryH<3N!x;}La{r=vW>j!#g zrfyUH=>~y+7kHk)e+b;vGI#d*>qnZ)=dR0U%6Gn*z|Ks~pyJ-mY^8T**D0t0xccG7 zS6_Q0_WFq-<-78wDVPVa{wUyJ2B-TgmCCM8!aH%erIm*lA)NcQ--B-Q6XK6wu6O+s zx@9yS=xNw}qWM7o#RG%4pT}x2JqMpxFCK0}l^`l-r(l1jQa+oyaTMOKR8lvt{zXlY zjl#`3fZ2$W)FreX~HlzbEjuV8+ioVUzjI zlJ^7QJA+MiBBF0K5P@Od zuNIF@2qV5;;th^{F$|A7`05@RhQ}no$+0gI@T}yMuteg7Si_W!;0a-!sTQuTTOC4D zp8`C!ghfDyE{RjnBk>j(a$s6BXK?I$h{ITtMc@^PqyG{4F7!0s%ZwjFOm<8>t;czE z2IrIL=Tkc)`MjBpXL8q&3;Zr$}@>0&ojOO%YGx9>CxnV3bVk{dE2E6G9M)5x^qKE}KV16+V0c#!tG!LpD zCqM=+uh-%s-m@PL0>=%h9ztd%T?3SXHC66mP#j!9qTX`baxtl zRgY!kqnShp5IfjLD9qr&gTik?sa>zdmNI#pJ9 z>ES99ZKzZ?;P?CdVUMB)Jqn4l@kBb4v-KWD(=2|gUNkcK9QR5I*!{|x#cehjQmxJw z(zq^}R8`F)4JYXjSY&D}K5E#?V9+AD`mmIen(%Qs}!%!&ZN9`$6aB~_ywIG9PPf;Ppdl9>V z9L65!tq|K9=g|d37z(k1O@u@U3b7O(5yo~_(KLv9Sv^}Ntze_n5iP|Eb|DrY!!6C# zIoP;HaXl&lUdI>}z~~pvX1R3j<*MKz;n?Mcbca|Oc=o(V;lv|DuW|sZdU`sVTZcyQ z1S&NvidXZtEmcY)tL#u!Z=2?38jr^Xd|tY?uLalJ4X%Z=>+0UabJK%7-2urC(W84# z!`_;g8|%B@tzEmXZg+jn-V@!Yx=(kX#0pqUTDlLCR-C~?A8D*#y{~pR3I1Vx#0$0# zeycc(=_XHiQ8H?;2J_TUyY2b(fpDDTd~i#O>XF`s-&-07`9)ZTyvBYb`vQ9!GnIeF z{wVvi?5Ek&^_X-`?AzE!*>7e)&i)|#W9%=ozsG(7e$=SFG#h3`wH=L}`F0itqj3C`P z8ZiBvt_?NLCZd=*k1@0Rfl#a=nt%Fd=)y$Sj0@`wdb$^ph7!FmfXRL*LTJT?=%2_o z`&}!MAWZKkdkPz(ci2W{l%niyzR$jhF=4kycWA;iwPaD$r7b9)b{95c&N+^090%R! us9ECeaX8yT8jhfV)(*<$c&Q%MagLV+Pa|iW-9Ne~I(2tZm$F6ZZQb9wudHwY literal 0 HcmV?d00001 diff --git a/labcodes/lab2/obj/bootblock.asm b/labcodes/lab2/obj/bootblock.asm new file mode 100644 index 00000000..b7395761 --- /dev/null +++ b/labcodes/lab2/obj/bootblock.asm @@ -0,0 +1,354 @@ + +obj/bootblock.o: file format elf32-i386 + + +Disassembly of section .startup: + +00007c00 : + +# start address should be 0:7c00, in real mode, the beginning address of the running bootloader +.globl start +start: +.code16 # Assemble for 16-bit mode + cli # Disable interrupts + 7c00: fa cli + cld # String operations increment + 7c01: fc cld + + # Set up the important data segment registers (DS, ES, SS). + xorw %ax, %ax # Segment number zero + 7c02: 31 c0 xor %eax,%eax + movw %ax, %ds # -> Data Segment + 7c04: 8e d8 mov %eax,%ds + movw %ax, %es # -> Extra Segment + 7c06: 8e c0 mov %eax,%es + movw %ax, %ss # -> Stack Segment + 7c08: 8e d0 mov %eax,%ss + +00007c0a : + # Enable A20: + # For backwards compatibility with the earliest PCs, physical + # address line 20 is tied low, so that addresses higher than + # 1MB wrap around to zero by default. This code undoes this. +seta20.1: + inb $0x64, %al # Wait for not busy(8042 input buffer empty). + 7c0a: e4 64 in $0x64,%al + testb $0x2, %al + 7c0c: a8 02 test $0x2,%al + jnz seta20.1 + 7c0e: 75 fa jne 7c0a + + movb $0xd1, %al # 0xd1 -> port 0x64 + 7c10: b0 d1 mov $0xd1,%al + outb %al, $0x64 # 0xd1 means: write data to 8042's P2 port + 7c12: e6 64 out %al,$0x64 + +00007c14 : + +seta20.2: + inb $0x64, %al # Wait for not busy(8042 input buffer empty). + 7c14: e4 64 in $0x64,%al + testb $0x2, %al + 7c16: a8 02 test $0x2,%al + jnz seta20.2 + 7c18: 75 fa jne 7c14 + + movb $0xdf, %al # 0xdf -> port 0x60 + 7c1a: b0 df mov $0xdf,%al + outb %al, $0x60 # 0xdf = 11011111, means set P2's A20 bit(the 1 bit) to 1 + 7c1c: e6 60 out %al,$0x60 + +00007c1e : + +probe_memory: + movl $0, 0x8000 + 7c1e: 66 c7 06 00 80 movw $0x8000,(%esi) + 7c23: 00 00 add %al,(%eax) + 7c25: 00 00 add %al,(%eax) + xorl %ebx, %ebx + 7c27: 66 31 db xor %bx,%bx + movw $0x8004, %di + 7c2a: bf .byte 0xbf + 7c2b: 04 80 add $0x80,%al + +00007c2d : +start_probe: + movl $0xE820, %eax + 7c2d: 66 b8 20 e8 mov $0xe820,%ax + 7c31: 00 00 add %al,(%eax) + movl $20, %ecx + 7c33: 66 b9 14 00 mov $0x14,%cx + 7c37: 00 00 add %al,(%eax) + movl $SMAP, %edx + 7c39: 66 ba 50 41 mov $0x4150,%dx + 7c3d: 4d dec %ebp + 7c3e: 53 push %ebx + int $0x15 + 7c3f: cd 15 int $0x15 + jnc cont + 7c41: 73 08 jae 7c4b + movw $12345, 0x8000 + 7c43: c7 06 00 80 39 30 movl $0x30398000,(%esi) + jmp finish_probe + 7c49: eb 0e jmp 7c59 + +00007c4b : +cont: + addw $20, %di + 7c4b: 83 c7 14 add $0x14,%edi + incl 0x8000 + 7c4e: 66 ff 06 incw (%esi) + 7c51: 00 80 66 83 fb 00 add %al,0xfb8366(%eax) + cmpl $0, %ebx + jnz start_probe + 7c57: 75 d4 jne 7c2d + +00007c59 : + + # Switch from real to protected mode, using a bootstrap GDT + # and segment translation that makes virtual addresses + # identical to physical addresses, so that the + # effective memory map does not change during the switch. + lgdt gdtdesc + 7c59: 0f 01 16 lgdtl (%esi) + 7c5c: b8 7d 0f 20 c0 mov $0xc0200f7d,%eax + movl %cr0, %eax + orl $CR0_PE_ON, %eax + 7c61: 66 83 c8 01 or $0x1,%ax + movl %eax, %cr0 + 7c65: 0f 22 c0 mov %eax,%cr0 + + # Jump to next instruction, but in 32-bit code segment. + # Switches processor into 32-bit mode. + ljmp $PROT_MODE_CSEG, $protcseg + 7c68: ea .byte 0xea + 7c69: 6d insl (%dx),%es:(%edi) + 7c6a: 7c 08 jl 7c74 + ... + +00007c6d : + +.code32 # Assemble for 32-bit mode +protcseg: + # Set up the protected-mode data segment registers + movw $PROT_MODE_DSEG, %ax # Our data segment selector + 7c6d: 66 b8 10 00 mov $0x10,%ax + movw %ax, %ds # -> DS: Data Segment + 7c71: 8e d8 mov %eax,%ds + movw %ax, %es # -> ES: Extra Segment + 7c73: 8e c0 mov %eax,%es + movw %ax, %fs # -> FS + 7c75: 8e e0 mov %eax,%fs + movw %ax, %gs # -> GS + 7c77: 8e e8 mov %eax,%gs + movw %ax, %ss # -> SS: Stack Segment + 7c79: 8e d0 mov %eax,%ss + + # Set up the stack pointer and call into C. The stack region is from 0--start(0x7c00) + movl $0x0, %ebp + 7c7b: bd 00 00 00 00 mov $0x0,%ebp + movl $start, %esp + 7c80: bc 00 7c 00 00 mov $0x7c00,%esp + call bootmain + 7c85: e8 a1 00 00 00 call 7d2b + +00007c8a : + + # If bootmain returns (it shouldn't), loop. +spin: + jmp spin + 7c8a: eb fe jmp 7c8a + +Disassembly of section .text: + +00007c8c : +/* * + * readseg - read @count bytes at @offset from kernel into virtual address @va, + * might copy more than asked. + * */ +static void +readseg(uintptr_t va, uint32_t count, uint32_t offset) { + 7c8c: 55 push %ebp + 7c8d: 89 e5 mov %esp,%ebp + 7c8f: 57 push %edi + uintptr_t end_va = va + count; + 7c90: 8d 3c 10 lea (%eax,%edx,1),%edi + + // round down to sector boundary + va -= offset % SECTSIZE; + 7c93: 89 ca mov %ecx,%edx +readseg(uintptr_t va, uint32_t count, uint32_t offset) { + 7c95: 56 push %esi + va -= offset % SECTSIZE; + 7c96: 81 e2 ff 01 00 00 and $0x1ff,%edx + + // translate from bytes to sectors; kernel starts at sector 1 + uint32_t secno = (offset / SECTSIZE) + 1; + 7c9c: c1 e9 09 shr $0x9,%ecx + va -= offset % SECTSIZE; + 7c9f: 29 d0 sub %edx,%eax +readseg(uintptr_t va, uint32_t count, uint32_t offset) { + 7ca1: 53 push %ebx + va -= offset % SECTSIZE; + 7ca2: 89 c6 mov %eax,%esi + uint32_t secno = (offset / SECTSIZE) + 1; + 7ca4: 8d 41 01 lea 0x1(%ecx),%eax +readseg(uintptr_t va, uint32_t count, uint32_t offset) { + 7ca7: 83 ec 08 sub $0x8,%esp + uintptr_t end_va = va + count; + 7caa: 89 7d ec mov %edi,-0x14(%ebp) +static inline void invlpg(void *addr) __attribute__((always_inline)); + +static inline uint8_t +inb(uint16_t port) { + uint8_t data; + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 7cad: bb f7 01 00 00 mov $0x1f7,%ebx + uint32_t secno = (offset / SECTSIZE) + 1; + 7cb2: 89 45 f0 mov %eax,-0x10(%ebp) + + // If this is too slow, we could read lots of sectors at a time. + // We'd write more to memory than asked, but it doesn't matter -- + // we load in increasing order. + for (; va < end_va; va += SECTSIZE, secno ++) { + 7cb5: 3b 75 ec cmp -0x14(%ebp),%esi + 7cb8: 73 6a jae 7d24 + 7cba: 89 da mov %ebx,%edx + 7cbc: ec in (%dx),%al + while ((inb(0x1F7) & 0xC0) != 0x40) + 7cbd: 24 c0 and $0xc0,%al + 7cbf: 3c 40 cmp $0x40,%al + 7cc1: 75 f7 jne 7cba + : "memory", "cc"); +} + +static inline void +outb(uint16_t port, uint8_t data) { + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 7cc3: ba f2 01 00 00 mov $0x1f2,%edx + 7cc8: b0 01 mov $0x1,%al + 7cca: ee out %al,(%dx) + 7ccb: ba f3 01 00 00 mov $0x1f3,%edx + 7cd0: 8a 45 f0 mov -0x10(%ebp),%al + 7cd3: ee out %al,(%dx) + outb(0x1F4, (secno >> 8) & 0xFF); + 7cd4: 8b 45 f0 mov -0x10(%ebp),%eax + 7cd7: ba f4 01 00 00 mov $0x1f4,%edx + 7cdc: c1 e8 08 shr $0x8,%eax + 7cdf: ee out %al,(%dx) + outb(0x1F5, (secno >> 16) & 0xFF); + 7ce0: 8b 45 f0 mov -0x10(%ebp),%eax + 7ce3: ba f5 01 00 00 mov $0x1f5,%edx + 7ce8: c1 e8 10 shr $0x10,%eax + 7ceb: ee out %al,(%dx) + outb(0x1F6, ((secno >> 24) & 0xF) | 0xE0); + 7cec: 8b 45 f0 mov -0x10(%ebp),%eax + 7cef: ba f6 01 00 00 mov $0x1f6,%edx + 7cf4: c1 e8 18 shr $0x18,%eax + 7cf7: 24 0f and $0xf,%al + 7cf9: 0c e0 or $0xe0,%al + 7cfb: ee out %al,(%dx) + 7cfc: b0 20 mov $0x20,%al + 7cfe: 89 da mov %ebx,%edx + 7d00: ee out %al,(%dx) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 7d01: 89 da mov %ebx,%edx + 7d03: ec in (%dx),%al + while ((inb(0x1F7) & 0xC0) != 0x40) + 7d04: 24 c0 and $0xc0,%al + 7d06: 3c 40 cmp $0x40,%al + 7d08: 75 f7 jne 7d01 + asm volatile ( + 7d0a: 89 f7 mov %esi,%edi + 7d0c: b9 80 00 00 00 mov $0x80,%ecx + 7d11: ba f0 01 00 00 mov $0x1f0,%edx + 7d16: fc cld + 7d17: f2 6d repnz insl (%dx),%es:(%edi) + for (; va < end_va; va += SECTSIZE, secno ++) { + 7d19: ff 45 f0 incl -0x10(%ebp) + 7d1c: 81 c6 00 02 00 00 add $0x200,%esi + 7d22: eb 91 jmp 7cb5 + readsect((void *)va, secno); + } +} + 7d24: 58 pop %eax + 7d25: 5a pop %edx + 7d26: 5b pop %ebx + 7d27: 5e pop %esi + 7d28: 5f pop %edi + 7d29: 5d pop %ebp + 7d2a: c3 ret + +00007d2b : + +/* bootmain - the entry of bootloader */ +void +bootmain(void) { + 7d2b: 55 push %ebp + // read the 1st page off disk + readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0); + 7d2c: 31 c9 xor %ecx,%ecx +bootmain(void) { + 7d2e: 89 e5 mov %esp,%ebp + readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0); + 7d30: ba 00 10 00 00 mov $0x1000,%edx +bootmain(void) { + 7d35: 56 push %esi + readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0); + 7d36: b8 00 00 01 00 mov $0x10000,%eax +bootmain(void) { + 7d3b: 53 push %ebx + readseg((uintptr_t)ELFHDR, SECTSIZE * 8, 0); + 7d3c: e8 4b ff ff ff call 7c8c + + // is this a valid ELF? + if (ELFHDR->e_magic != ELF_MAGIC) { + 7d41: 81 3d 00 00 01 00 7f cmpl $0x464c457f,0x10000 + 7d48: 45 4c 46 + 7d4b: 75 3f jne 7d8c + } + + struct proghdr *ph, *eph; + + // load each program segment (ignores ph flags) + ph = (struct proghdr *)((uintptr_t)ELFHDR + ELFHDR->e_phoff); + 7d4d: a1 1c 00 01 00 mov 0x1001c,%eax + eph = ph + ELFHDR->e_phnum; + 7d52: 0f b7 35 2c 00 01 00 movzwl 0x1002c,%esi + ph = (struct proghdr *)((uintptr_t)ELFHDR + ELFHDR->e_phoff); + 7d59: 8d 98 00 00 01 00 lea 0x10000(%eax),%ebx + eph = ph + ELFHDR->e_phnum; + 7d5f: c1 e6 05 shl $0x5,%esi + 7d62: 01 de add %ebx,%esi + for (; ph < eph; ph ++) { + 7d64: 39 f3 cmp %esi,%ebx + 7d66: 73 18 jae 7d80 + readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset); + 7d68: 8b 43 08 mov 0x8(%ebx),%eax + for (; ph < eph; ph ++) { + 7d6b: 83 c3 20 add $0x20,%ebx + readseg(ph->p_va & 0xFFFFFF, ph->p_memsz, ph->p_offset); + 7d6e: 8b 4b e4 mov -0x1c(%ebx),%ecx + 7d71: 8b 53 f4 mov -0xc(%ebx),%edx + 7d74: 25 ff ff ff 00 and $0xffffff,%eax + 7d79: e8 0e ff ff ff call 7c8c + 7d7e: eb e4 jmp 7d64 + } + + // call the entry point from the ELF header + // note: does not return + ((void (*)(void))(ELFHDR->e_entry & 0xFFFFFF))(); + 7d80: a1 18 00 01 00 mov 0x10018,%eax + 7d85: 25 ff ff ff 00 and $0xffffff,%eax + 7d8a: ff d0 call *%eax +} + +static inline void +outw(uint16_t port, uint16_t data) { + asm volatile ("outw %0, %1" :: "a" (data), "d" (port) : "memory"); + 7d8c: ba 00 8a ff ff mov $0xffff8a00,%edx + 7d91: 89 d0 mov %edx,%eax + 7d93: 66 ef out %ax,(%dx) + 7d95: b8 00 8e ff ff mov $0xffff8e00,%eax + 7d9a: 66 ef out %ax,(%dx) + 7d9c: eb fe jmp 7d9c diff --git a/labcodes/lab2/obj/bootblock.o b/labcodes/lab2/obj/bootblock.o new file mode 100755 index 0000000000000000000000000000000000000000..9c2239c7790d23b4b950cce04bd0b65ee073d289 GIT binary patch literal 4408 zcma)AYiv}<6+UYmYAD4n1>zEvJdYP?<0Hf zQb+oX<=LR+Z{l_IrGss^=y+}h%i&{B~o+waW1 zbG#^jdaQHjJKuaWckY?Fb7%d0;=%1Mmy5Ku(IQgOvqV9VFLl~AL2^?Yt*525MAchN zL&N?$8nAx~VLSZcOI8lWCyeX6;I}?9W+wkUIWu|wV(z83#;r4dyqt5;dzYUqoLfxe z+_qr6`0_nfk*jvx7BJ-`w(J=T;V)z=dNUQseDT*XpSwo$i^! zvERBn@03aY>UkUY~IQ0YO-?)5- z>u=Ey%k-G6EG^5$&xXxWX-3^r@n&+qKc(XZizHoJlCY#N|)wz!` z9>>sv=*724mEU`d?xY_d;VKLk_I>*AA{(p8MoK>m_64rubpeYrBX|Y51h1kt!Ku9Cm^|V^Bhq?uCq`L(7&^>}T(;C4( zS|`|`4T1x-NpO$?fN5uBvF;0LKF_+csw-c3&nPLU~i4>bf2)7J&>rNe^v(KiG?O5=hbqi+gM({W%o z)`p7?X+kjuPtqWGH=Ol<6+VCwE$H79K1nI?ZaC{N2p?2)tNZ_l@JSkJ(a#DW zq_2V3`Z?i~ly1?_3m;PJMeDB$pQLPy{)X@&DuQQ=Q;43jp~7Wg-Oq=jPf}Gh5o!Rt z;rxv4YIo#**3luvy6sZo@2BU$yWy<=yzoPG3Nahc?{{nnoKkE2GU9QETjE;4Yg%v; zcr7#=(dQ#A{4KmFy6wx@uQh(X1#{PNm3>Bx_Yt~K#yq4B-bZ%`9>G~)f&aANk(PI4 zpZX?nRUEUp@Lpu;KGElpE!*OlAzs65aqJL${$OLwYn3fdd5YQ)xIq1a^J*`!H3b?F z{wW%6!MtYlyquK$@1zX)zu-Z)qU7hDckp6hwi$J`FBedlPMkyeL-ey_V4%;vet3VQ zVl~``;SG9yn~a7EjpzJ+uP^9vXrj$lxwbi*J#gUZk>P;Xr2W;ZwV5v&v+PYRgyl@B z;?2@%HtSDktL0j0ET8jIJ)g;$`O&_@dS8#>=~q`eSS{uHEC*-$hJgI4E}*VKPk$X$ z&=d2;g8pbQ8t(N+Lov!$FS;@L>-P{70lyPN-l&+R(Mmq& z2Cp=fo0|_s!rr2iM;vuX4I*q0BFuyEhj4f4AzRGURTp6o>E3#6b+0G3$!`RE zgONZu7>Nn&jj23wiu$(O&z&DD6m#{yJ%}Qnelz6Hr^}hqQnn97z|(_^KbB8J#YEK8 zpW&1kKKni>Z_f=P!-zo<@}OZ)G>o>^;aZ*>8&2MlV%3MA+lE7-Kq%H@_#-_Ai_4j8 zu~gCe9wQjE`GfhoS*li?Q5j)9u8LJZtjVa~9&D|MNpVQOKWLL?D;WygWMM2bYHDR9 zVw3rzS$alB5b$HK^879xfL4!Os?)zSwu&eMfe8fxj9CZZ|@ zwR8dRhxv@7;%QLr%K7pFX(t=fmTVbzvTNzg7}m4X+(|apDAuD9cGfYnLdbsIa?8@y z%hkXeQY-eU<$$+s1LqJgNq&KIHjI`+@3Bm^)Ac6rp&e3xy?GZfPX3NvZ}NA4q0RMX z05Sg{vIWT@N>{H>dE_DtR- z8S1km*MAE!pYLpQsk55>i-DO%^lhhx3x3`gQSw>uM=0Cy_Y;)-{o=iK1>&Ef)W09P z(7$@)d5^5p(C%G((mQv>6X}6eVn<6D=Wt-RFFlkbG78OdBl38?^(VUgbn^|sRWwGy)Su0fttn5G7qMbciD7#N0 zuX(s^W%i@A>UPPmhQr{ljT(8a{2`0Hxr~)z8H=&km+^+$A@rPv|JUw@kk^R%ZXvh) zJN;x!W4(U(tiYImlk*&KutHZlbtq_qgZZ1tbGfn&YltfxYj;XM$G0@6AapCyx&D5# zZW%o6=vdE|#6f$b4b_$VVCUZgd{1pAbo_f$o4yy9xRu!0XNb0fvkZMh9Sj{koowFsrw{SVZ#77zdc literal 0 HcmV?d00001 diff --git a/labcodes/lab2/obj/bootblock.out b/labcodes/lab2/obj/bootblock.out new file mode 100755 index 0000000000000000000000000000000000000000..4bbb6755d2289c820b5c874c4ecdfe0a93460849 GIT binary patch literal 446 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 A8~^|S literal 0 HcmV?d00001 diff --git a/labcodes/lab2/obj/kern/debug/panic.d b/labcodes/lab2/obj/kern/debug/panic.d new file mode 100644 index 00000000..084ebb66 --- /dev/null +++ b/labcodes/lab2/obj/kern/debug/panic.d @@ -0,0 +1,3 @@ +obj/kern/debug/panic.o obj/kern/debug/panic.d: kern/debug/panic.c \ + libs/defs.h libs/stdio.h libs/stdarg.h kern/driver/intr.h \ + kern/debug/kmonitor.h kern/trap/trap.h diff --git a/labcodes/lab2/obj/kern/debug/panic.o b/labcodes/lab2/obj/kern/debug/panic.o new file mode 100644 index 0000000000000000000000000000000000000000..b96eab54e3e8c064ff8fbc46dcf963bc98851cd9 GIT binary patch literal 2704 zcma)8&2Jl35T6Y$n2@hl1xka!f&}6w+1QTrft^T%*omO1g0>M7P&sRRlbHA;T5r;V zP>BSUhyo}_Bsir10yi!wQi*cl0{0$rK|*RTR5>Dr-|y{vTQ^b>BaP=bA8+Qpx3jbU zBLD83Wm#g#k|*S$CejlPJZU8cq({1CVe8K??+@Ij<<{Q%M+c{fxaiyb*{%H1cD`dP z*B9N+Mk$`gYth^B7=j7!OKQC{D z_?%n}@p<_m#Jy4qakqRD;+U+4_!U_Lz6;(2AK{Tc&=^9|o|Y7c;G1B!m${Q};9b~w z54{@m9$wd&_dv?YKmZiJ&~o-cVLT}(L*ett$*@cYX4pr-A}QqDgycTy+T)L=L&&$m zS;UyV(Up@Fg`%8{;%zWEt@cc<4E}>)&8b&Pc1c!UuRcw#SShVIp2{&6 z7iTSlmE$V?gh?YCPN7<920Iz&POdv%JriuCwd~_6n5?`HUYc8NIZHCGF4C>W)K$eC zKi1#O^p`X3F_5%N(|1a%G2g>)5u9l^@!UnFzI<|p%+JndVgn1s^}4?vOD65KofuB8 zD>ZpDm9i7*xHijKK2MPK*=4alk6OJQk;vERjdQSZ29VgxGSd~k)%I2=XI>1cjDHMfrNdc$|^`AZAK>cWFH?n)uJc@+Mi#BU3Z6V7G!iJFOe zJ$)qh8^5P-f=R#P9(Ex4Wn&EcmfwPYt($p!$|QiDWYj@m#+$e(9IdaB!Q78o11OA3 z3>=S8cB=WWdevuq;Y lA!HYr|3jFs2h3cp_p%751DheUKfar-aX+H2XM!M2+`oRge1QM} literal 0 HcmV?d00001 diff --git a/labcodes/lab2/obj/kern/driver/clock.d b/labcodes/lab2/obj/kern/driver/clock.d new file mode 100644 index 00000000..bdff3ffd --- /dev/null +++ b/labcodes/lab2/obj/kern/driver/clock.d @@ -0,0 +1,3 @@ +obj/kern/driver/clock.o obj/kern/driver/clock.d: kern/driver/clock.c \ + libs/x86.h libs/defs.h kern/trap/trap.h libs/stdio.h libs/stdarg.h \ + kern/driver/picirq.h diff --git a/labcodes/lab2/obj/kern/driver/clock.o b/labcodes/lab2/obj/kern/driver/clock.o new file mode 100644 index 0000000000000000000000000000000000000000..621e9a16d966fcd3554e8567fa51fcae9eeb6ffb GIT binary patch literal 1824 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 W2MJODv0eMv?@{#2dw!4t-hTqys%QiN literal 0 HcmV?d00001 diff --git a/labcodes/lab2/obj/kern/driver/intr.d b/labcodes/lab2/obj/kern/driver/intr.d new file mode 100644 index 00000000..d0f9177c --- /dev/null +++ b/labcodes/lab2/obj/kern/driver/intr.d @@ -0,0 +1,2 @@ +obj/kern/driver/intr.o obj/kern/driver/intr.d: kern/driver/intr.c \ + libs/x86.h libs/defs.h kern/driver/intr.h diff --git a/labcodes/lab2/obj/kern/driver/intr.o b/labcodes/lab2/obj/kern/driver/intr.o new file mode 100644 index 0000000000000000000000000000000000000000..ae30eda041cbc61fe690d88a4c1694d2a98aa496 GIT binary patch literal 1448 zcma)6U279T6uq0K60s?@_*NfU5KN`rd=QER#cI~phoVIYh$vwBTq&ZlTaUX8<)A|%ap1`Sjj0wz##*VeR9!r;p0YCt z{YH|;z0ez$$7fgU?qP})Zu{XdqalBvA?wX%W4_e#Mo}`FuU754U0JSf zaUPh%{8f!&5AXF8*8?VTid_>W!8j4ycN14^Z#Wb?4tk)aWY+^tY}|u>5P=pAlE7ZS z+FAyovz>B-ZhI?s`vKPaU*k8#KBixYNFA}dk6OU=ctP_Hz8y{YgLfJ^d;Bk61stPI z2?zceZuWte3coP+{V04DPJ63+$?uIEI@eo)n>7(i3F7=;7&B{KK!GvWr+q-eHH>kL zenq3He`7IYCcT9kV{A*=cO*A-OyK@#tYy!^&9cut2kYh>SuK=h1Hzj?_JZdlkMlSu ad)`;zEudzMI<({PEN=$MmKsSPhW8uZ9iKb^ literal 0 HcmV?d00001 diff --git a/labcodes/lab2/obj/kern/driver/picirq.d b/labcodes/lab2/obj/kern/driver/picirq.d new file mode 100644 index 00000000..2de8ab18 --- /dev/null +++ b/labcodes/lab2/obj/kern/driver/picirq.d @@ -0,0 +1,2 @@ +obj/kern/driver/picirq.o obj/kern/driver/picirq.d: kern/driver/picirq.c \ + libs/defs.h libs/x86.h kern/driver/picirq.h diff --git a/labcodes/lab2/obj/kern/driver/picirq.o b/labcodes/lab2/obj/kern/driver/picirq.o new file mode 100644 index 0000000000000000000000000000000000000000..ace5347e92cc594c1b60313b8f6615275b5e4439 GIT binary patch literal 3140 zcma)8Z){Ul6hGYxP6CuaQ;Z|hMZ`72+uFT#e+mhITIf?k%y7yFNom)PR<>@oZ)6gK zOO(h09~R>WqJ9`5(Jv-`FkyyZfDk3jKn4m1A|%W}0Lu(SP#|pn&VBdZJ&g&T^!EJj z@BHq$=bpa4_uh-GU+eLBNSTMqX=+APdeVuQ!qt$EW>ee1)%Q!4dtwzG1F_PcSgGRx z2lw;WuA_D{7~jF89VcQBs%dxZzV9H$aNC3NLEmt!bnJSCZ}_MapV*K1Bg7veJ~2Kx zI8fSrTqO4*`5`W2_pu+x21fV&IqEwy>KmTMTkNYI-G>wd-o@98larHEi=rn)oR?wq zk!t!rc5)KgPa^xs_#n8``@x-J?i9Gwf;;O6cV;fQGvLk&?mVwO=LdHV+9-GO5;jV??cQ#z~Fk>q7-*wiyFaA$2nQk z!~$59o)Wl9@*5mltewIZy#aoS)NIn41;jW4z8}7XOLQ&pVj15AJOs?=>XRB7LjGqJ z1g@g#a>lsQg=;ikNOiz_UHLf_B|kf1QK}YsK7)qO_@(CKdbcQ9^t_9o>Xp+U4sqXB zYmG&(XdI{4HMS_Bah%@L*rKAwapLQOjraY~fg=A$8e8irNyfe@doctU^rp7*g{3cY(vwkqr^`;J;O&CrvkDb5oraz1v&l#&?IangVv!6c zi*i9S1t}T0Cv;`jEOHqlW?c4e^N|FuOB;u!k*V*-o&lT5%d zHh$Lf>)}cawo&wfpGPw>Si`?RD0)H8(F$R6&8w?{zX2zGBEXmZ$1Nc2eywF&-U58oG~^fv0xz)wB^8wrR&|hlUZT* zO1l$4L`e|ZQil#(vj2b%39wWl!37;U?9h^vwn!~6pPqT(;GX;ilaRhw#oUgn0k@nJ->-FNY6?4}_l@r`s?6+wE9Ccqcqv ze!TwT_Dl62pZ=unPu5rJKkxhg>;CYw{o&vL>&cTR|MB1Zu(g&zOQ0pt5@-pu1X=L*d!;__k-R+ud;VaWj4{{LXp&;qa03_@m+X&f^!te*eJU?%Eo!M*H|v;rGwu zm%``Hi&c~m*3BKUVr^>zWp%2`mKw{;eXG+_vWLAcOE=^aCzs=hnJ6j zc=6Y#1GKIs&=P0~v;W<_SD=4C&YW65Hjq1X=WOqDdImCu zk%^hg!pcT?T0N1DM9)B`FfuVySyEPGKG)pAbR>EPGKGEPGKGI(KC=Kj7-c_7FIUGAE_tOk?0x76hWOqDdImCuk%^hg!pcVYWA#Kj z5WOqDdImCu zk%^hg!pcVYx_TlViJpN>VPs;avaqs!J^Wv7|K9$V9d6d;2ebE@U;izDy>fr{owk23 zdA0ukc(d)LYL_x^q1>NP&)c8KRs&&N~$g;W3PslR*b`&0k7r~bRA z{_@n9Q~wXA{+~|$znuE{)bD>yVShb8KlQqBYtQxrr~cyc55IqT?|!&=eEI0Q|L)D` z(VKsNak)oz@y5N&d*R~#$^GceypcBw;_aTvVYy} m*Rt=o*X_qTpVPPwA^es8rtQbs+jG2ozqg(D-M7Wu?DtEZ3G2Q9 literal 0 HcmV?d00001 diff --git a/labcodes/lab2/obj/kern/init/init.d b/labcodes/lab2/obj/kern/init/init.d new file mode 100644 index 00000000..9982ea0b --- /dev/null +++ b/labcodes/lab2/obj/kern/init/init.d @@ -0,0 +1,6 @@ +obj/kern/init/init.o obj/kern/init/init.d: kern/init/init.c libs/defs.h \ + libs/stdio.h libs/stdarg.h libs/string.h kern/driver/console.h \ + kern/debug/kdebug.h kern/trap/trap.h kern/driver/picirq.h \ + kern/driver/clock.h kern/driver/intr.h kern/mm/pmm.h kern/mm/mmu.h \ + kern/mm/memlayout.h libs/atomic.h libs/list.h kern/debug/assert.h \ + kern/debug/kmonitor.h diff --git a/labcodes/lab2/obj/kern/init/init.o b/labcodes/lab2/obj/kern/init/init.o new file mode 100644 index 0000000000000000000000000000000000000000..1dfa705f9e879f2e0dbdc1c33104a5a5908e73c4 GIT binary patch literal 4788 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 SZ1Zk@o{e@F`bt1w?|%TUJ0rLN literal 0 HcmV?d00001 diff --git a/labcodes/lab2/obj/kern/mm/pmm.d b/labcodes/lab2/obj/kern/mm/pmm.d new file mode 100644 index 00000000..b9182e26 --- /dev/null +++ b/labcodes/lab2/obj/kern/mm/pmm.d @@ -0,0 +1,5 @@ +obj/kern/mm/pmm.o obj/kern/mm/pmm.d: kern/mm/pmm.c libs/defs.h libs/x86.h \ + libs/stdio.h libs/stdarg.h libs/string.h kern/mm/mmu.h \ + kern/mm/memlayout.h libs/atomic.h libs/list.h kern/mm/pmm.h \ + kern/debug/assert.h kern/mm/default_pmm.h kern/sync/sync.h \ + kern/driver/intr.h libs/error.h diff --git a/labcodes/lab2/obj/kern/mm/pmm.o b/labcodes/lab2/obj/kern/mm/pmm.o new file mode 100644 index 0000000000000000000000000000000000000000..44e3240325c3d20299a66fbabeec5fab4cd8ac4b GIT binary patch literal 29356 zcmbV!3w&KgwfF3u6haAYz=DOs^&kNg=p#9KG-;?5IENN&p*+H?a6_7$Hj%u@IVml+ znvw#IhiU~xRIWrsLE&D&3s{h=>C09u-l$cow`lk%5Nw4CRUV?b|NqRIIde{0{Jw8~ z-C6%Nvu4fAnl)?Bp1n^$7oUG#5CqDmK;@|nr&NBIDXG+?L>;Y)RDJ&|>0`;K;{~Nd z8{Z9E2cO@uW5>0dQP8(9AG!Vc#UsBN9Ua{`T-d))@+TvI<49rurf;%p?WXP%x5bJJ zh(YtOCe1JY7|6&6sF^;BCALcc(8l2~(0{f&g(cF^tq|{zA4ta!P8V=}Pi4 zB~Y7I+7v|fh5beA9jDeU3^sVm7uUl0n7tvQ5zy46MrzcG(e; zs$J`?y0|NAA>tiJ&fBw7nd1<4F{^YemSyX!$LYWSgj69oFY0~Hr z8Wqv!QIwAFmlm$L{LMfW^9C zOS*oyzf{u;3(|A)`{M)s^$#4RbY5ZlO1S($y8eM+`_aGakKfZ@fA3hizQIW_`7JBq zXzBPp>H2&721omTIokh|{ujmyr;SoAjcGcuKUF-be`PUNHJf2HfT4=|=NISqUsGIw zNqoQ#WvnjUaNoN@&-8SBI93>-;!3f@!b<|e-(504BDs>@!=`)J;@2iqBUYsqkiHeLxmgvSokd(bX$B7%Sq`v zItmO1n5}2i@n@+^z0)%YSUM!KdJgu^keHc02YrM2+v0bzQh$7X8vp9=n)qaX89*77oo@u776PU9Ne`|Ed%m9sN6@s>ZL)pYy`ZJqRjowf0y1(?SNXHBeM)=>XJI??F$+6bp4QFP#kX^kcTDV~lW&VZ#(7BB52fRe1w-@tMqm38pYW@CbhWm>~7aUj}FJzZj$0w2WtvaB3?(kxF37nG+OIruDfWEPx zW!lQ0H>M38JHPf0`ex&8%{QR}^LJqNssnZ@xSfSv3iV?Z>7}68=*aiq8yy|_=KJ{b zr#y7$hHgKLu#Yh7Yk%(g>KUVS|GM?)%N$*K+#{IWzUT7#i!=)>7hzApDK2D( zX?2hqP&B6oY4c$O`jJ|=(@61nF-ztaL7&+;a@@K}x3D^9iR+&mtF+QvqKUUWiu}G+ zMJjb{wqf`8t=g}8#_M?X`fCtko9H`~=sVarm{Z^jf8ngtnT*?LFWRFAP#fRFP1}gI zLYXM~IW%QQnGwBd(*wk`%K(*iD(LRpemI@v0QXerzPREr+(x%2kuScR?G5L)_p34O z4Vz6OG{Qhw9hgJCBXurPqWhu;Jl4hGb}(51R#UnjJ)#q)rew^Tny4{*zXHa|-Nj*_ zTO<>ZTA(o{FVbe@z#DGXdC)GZQ#5vWtz?BeoU%lchcvt1R0e59p;{J7jvP zy?bI%;{~G0+QHLvCXWuG=9RFK4oMl)nHV!$_2#K%IvCzaC-j2#6*-M+h1ma3&>$<$ z-<4DKs)JRv4ojDzd(gHt3sma%cjPEpl%pg&036W0fG$7s;J$f)`_f$12Xa&|&QWc3 zF?x+z+?XUCY;-3htmzqPNscDO9PAx2vdCMbqqXq^W@rm?YPF21rB}~+sDtgFsne8G z=hHcLbe~hewj3o8(SZh=HVkvD84&BNEo~HoQY@P;kRNs)J`a?UIHBY;8G$nI1>3QlK&PNQ>^ICua>(6V? z!R13Me_W3IjXCl%J6;RLIW<<~)WH6QralMvX6FO5a_W30r;fEpW({D%4zUL2=ji%u zjxGu8o8Dymp-gp7o!&8Zbf3R~I(8L*KBvmfIaO?zGfU0$u@9ZXH94BxQhV}^4_Rur z9;}w07Bj?qbNahBN8a`~D`bhS?nc9Iu5#Dwx*SC^zl%}lP`3JFPL)jCo{gmK6FfbS z=ZxX596i$XYkxX)(|6}o(M_93b~mcgGamwVqur9zOtuaL9UtuOr;Bu3Q@*W`x_58{xj2(-DZsR?1pad!8SC`s2I%R_&HY zf&xsm9|*?k+iim`w|ljlj2p#ssy&?3jnz1MF>BNGe$&L8Ps6=WGkRC;lwhVqvKflCkI!vGDpqE95w6$YNL1B zu-ss2dzrQT9JE`BgRjK_=+9b<*qxeing3YN-te($_pgQapN#9r-)>!odtxg8u^V;S z=XF^cf7J%c$=Lv&iHfkL?mo&quib-^Q9NVl%p{J=irf?6q+rNCdb}v*Eq$vd>xY@i z>G~o*UKQc=y1#x*ox}U%AMDM`=soEmdi68f2UxVb`c|E&m7XX{KgfOx!ii+xzWJEP zL2D0tyz~}2F9G%U-2T_^PA?cPeXjpE8(%$+$C1C<_%i5l|1UPaL_WQ0xb%GlsYy5( zEW(jWA&vqIxKg0|&sH~|5{Jk4$9L{sD60FkYMfN8kbUR+Gqq7%Iu;njtQzX!ZV@=0QfFC0vY zsf+NY%;JUWqkwz|Qw(}Mu5G{rp!)6x8dI0zuSqd=nd0u7i5L+|r&(@-Xc_c=$L0r~W!@!iE0~y+9 z7p{d~ANUyAi#(fR>eCjYKi4}w#CnU4(wJ)FMnI<+JZh@Lo!bApq^-%Y0k_)&DCc7X@d=!c|~W zOs(?td{!Na>=Ds(0rY&}>0ynST5T$7e6v@#&$G`Oy)OB1M*BBH&xybTz?re!2F|3I zTI=cQ_w;;T>nRaE%c18S;9jYB5%3yd<}=0A5t?2n`JZ+9U-9gGj~?UoB6F*g8Skx& z@!q;P(pwjW>O|cF+nS(Gad@IC0bU869Pb0rc_;7yaAv#+T#{nYZhbX|m7JNEMR_71US&O#-Tb;W+ya(9! z?NpfC%71da$zQ1Oask-pe-*eGdC$Nm-vJ%~h6?pG@EXYnfjtlHlV(;a^EuBqdcApB zt^S2dkYeg)9O9Z3Q@42Q^j00ywn={|@msGy3=3>SEE!3eBEQ@-g*e5}jhO+F=fFR!2Gf6CF3m z#;_r$PNtapsa~fBKj+QG&r~%s+tF4pDDN-J1^f3G)?*sRH49h2*Ux*sem*2PGxlFV z+N7A;>Gk;qZ|pDV_)n>r`mN`~zf)z%dtCa%zENh7eET|74-0Pb@FNZv1dn@| zdr717h=4KnSFk7Jz%%1){;_JelQ~Yk0{oK5Y;iIL!K+TDAb8#3!r(6+KEcJ1!eF+C z;|@;<=6U!chbIP?dAQrdpLe(@_?m|wclhYw84quA_?Tda!;^yFI(%%f*Wr%_?>Rg< zI0}Bq6jPIfDu<5`>O6dn!zTnS4o?Y|dw7k9(+*Dv9`Nvk9)85(Nbn@^o8t33v5v+e zX!W8`TvNvg-Uobw;4Q%H^C15ql}P?$$gdLokSAmJ>cfzwPtFmUAy0;Wb%EsX@bYh$ zxn^DKZx&xB^4mRm>l>7z4=fg$VaRj}-sQ>D2X2!5K`)>4vPSZs_3|f)-Kf9J!<@S> zh&(?zL9w=vokz;sc_g;;Lc9re??K&S-~sG?9tR!(<~{4jf-ybnr-HfX|FvK~bNxZ^ zWMHP4Izy~RJT1uFkER9s+ea-kBe3%lQ!|1VU6bQJ zOFn&=RR(c!ynmN``ZHLaKZgKm7?-t!#fRg;v={j!p1idWWoVzHMP`pDV{Jtl+G>i( z&=0}tcCD?3!P~JD^HY~kK%V~a9XbJ0OvSx9JJqQrdavF3faeBGc=ivt_h2GsTTFOf4(1vNyfm2a@b$sP z4z~xFJKPg2@^G7nzvyAR!;Pt);C?Uv+YWywc+lZn0)FMf6jN!>_tpi!H`&PlV(>EX zl?SoUVIngO%5g0b8Q-sLpDDw>r92z10Ukger|}NKT+8{;k4k*tQ zQ=5a#*~nIJuD1pe3LwSQ*5DKafwu=|c$jB0Ow6C75%Et0&O1{~?Fbec2>g7|u6GIc*RLJ#Fl6nxh}r*FMV@Q*3 zI`lc1Xx24Ybu{n*D1GB&f;rcvf-}DHTNyd+@IRh!yy(sK?*s0KnPTdtAT!r5d2!&S z;7lW;WzKT=<=|Y0UkxsC__ct0)EN5H3z}=b6mZG zGvnfC+9t)+;h|k?#89IXF-$DDAhahIF*QE?xXT|OPILIkFf;a}!kEjS5H4`IC~N>; zhyL_}`s1?thmlX2dmzJcG4YGF0Z@+X8Nr#gd2EPmonq>v-dK(gGwbn$Ff&IdhKwg$ z4$=ovqixIhIpp=>Wv>r^_WJO5!L;q+_%i^?y#Z59m3VzS-Rs*_uW!@5zLkZUv({+% zNuvgOqG85QqG2X(RD>5enac2LhpWQH4%ddA4xbsW_3)h@{<_1n!vTjs8Ghg4v%(($ ze*|Of1@-5SA|I1{KR(;O4Wrz)OZ-DzpMbob-%pC&IKT4+XXe*DQCyDvH7Ng$6vWgf zmGRrn`q{8iWd7h}=7yLaonmTkm^l}k8=mdupYQPb+E+V8&nZXQy4&4JJkJfTLiSA} zbGnoHl(zp`scu9D) zM3Qw(pHnmpX$@PCGPIQ(RoS({IWKXv&}g?2X) zQ%{9|cljH_lifPn5T5Vw)7~0sc9e>chH-I!%QTGZcJwU)dHUo{cu-shJOIplD-)hI z#A?Jt)@&LdVMH{}`07vy6*^Hq^BnZcFmvv)GyIs7*%_Yd;mp2kr?*$!8P0GrzX>zv zv@e8pE`L`z2l!?*UIJ?O4}-uq4FjBm>wX#Uvl#CWz42}n%9CBfXM{Z%l> zQUt>ffb!nT6jQHxwi@x)^6TDxd7o#8z2Ov76?OM|d%V5g825%Voy;5Fc;EE)c>BZ5 zp5(3YVkiHWx5s-cY;pN-haC>Ougg9pZCJ= zm~7<#EqvJF55mWQi($iFP=2(;qCs5e5+DuZqWlcV&_8X8DJ83mZ3TH5Kg`QJR)k_| zTwZ2g4$nK;@$BVWaN*@vnM)u=bQJh$Uj$X#dUq5V8)HB1^atQ>PSdF z<4L<<|JnIu-IB4h?awgsmZGg5$ouQ48Tl_9k3U`Q?bDmo^@;9|8SU*e47aqYDcaD~ z+1}OKmS~=?x*C@zqFr4bvzC;UO)W2-jlWU-w?hA|)PJi=XLqBZsyRCi`p z7t~dk&ORMvX6fwZ$%W|QET#WmX7ZBJvhKu^Szu~R$7)LJrbWvuXI9o!R9Dv2IXJU! zYT49^Xx);w#-&NhSC)chPFHtlSE4($f|*sNQ>!a=CR%D}Ywft6xwU%a>=wUYr47<%c!RuM&($LYdX`BSe}vs=}cYL6t&2l zH0mjVlm4VuwP@F6;t4t-GZ^DhWUn47#>?$*pC(eYtWKw69V|7qHJejK(6w9}|s;Z)@ zjt*a5T?g5&#^&bMj-}<=BWp^h)<94fK(WrOD5c9|$!Nt+t~^?kts!bPlvi5aP@!|7 zqP*I6IGM~y)<&~+R9GF+GON9*TW3N=G^!UV$K2W_LylJ2t|k069<8a79w!=?Q&g{e z+k-@t%d67CfGV3^UX5#JvCXS2cg-Yi)0LI3jm0hx)-#q$BwMB3s`5-5E)OQMa(2j7 zGpn6ua6stLaA_sk00o=Dd^Y0QPu-PUa4BgLz2gCbsTJ$vd*%#)FK z(luqa!Pd_9#a3|*CJ%yj`j%8)ZQ~E(MzW=|I~5soBf>(_ktR87E?fuev_r=oG6;$Y z35ZNfn_IheaTLK`hg!rlT||eaD8p5IdqaC;2cnqB%B>)Z@Vq?fmu87_(NiQDt?6iN zPjDPj1ah_#MdamL2E|$~kJ=ktYe%cLLKKl!%OQg48#>mFx#3Zwp*_*w-l&~5ilCwe z5hJXixd}G5wRJY>(5t67is(VX3XId-1|%FT=}sg(v6)!o2nq1&j_!u+vI-e?1;#`b zQ5O!HS`tnAW{Z9!KIw&0riMMJq>Sf~M`*VLgPwW3Q;AhNIqE19LuN*?}8zPYQ7Q_P&IsZr+W86rQ^Na)_w zW|SlHXibgFY)!5m*6dC$(-9h#t13jjUI@&P_LfR(RaHhn52~WPA*uro1*_5bI$E{? zhStW_cc`vpqNlmjSk1%QaJ)xVcWJ}fb*GJnEb3>Tz6;Pn>QozNP23K<2D68OCu&EV zDR)}8V{PkfY&Q3~^Pqd+m; z+V|H6`@+~@%XEw|d3raY@AT|1guL~@Y8=8r^^d8Ty_Q%Pz35JuwO-0SC>9&H6w;91 z>10`h`|#>YyA3y++DfctE)`HLifQF_Dp3x8)HCwL6RA+lDH(=RMHks&FiC{oq!cbIu<8s;FBCP8hFd{!E1meam)#Aj`R=ww~ zfJmaFS^A6Ju-yqaH0T{NjL#i1x7pCnS^R&hX?5uP1dQ2$*wc>3ip)~bw-tIFZY!$I zZSJ)ZbvExzX1M?*y4y8INX&FJgKTqt=WQM~?mEg;a1gwsWnA0z21C^X@Lnz%?Niow zvu%*gE#b{(FYftE)TF-nk5SK6HKwJO3eL)JCR4t%&`QZkXp9>d`&> zr#d_pn297FTy;G@`ecnrTaFE4tQqg|{X}=ks*~=d+7?4Ao~K%yIVEAz%=Vjt8ZtVI{nl@;7!PfOubR&ZPuJduf7cj*3*+I9lWsHGEc$> z_p0pS(7I7pWCN_}%*`Dp@-IhzB{mjb$gE(*#6S1J-QQnPde zZOf-d7O^D)L$940;aw{-J929C^zmxpA^V6sgLE?c*0gZ$MdzJY($-iSnLRsVn65_b zC$J6ePPKM+M3yx2I1U|1Y6p*;JUen>{rvg4v03EMhul?EQW{D2G&Lm>&57od$D2o% z$eFVvpIQ)KaOwG1$0IY)E&;}ySrxXO$Z4lVO1M?v30jPRlNYW6KilDi`rGs}bjxT+cA9+&8l1wd%6cQrk;6@g=9TmR8bLuJ0E- z{we7y*IDJ9(}U?V20$N7O{k!M;*80})U39LV*Py+XSFVg1gulj*wd zapW|kOZnUt-h3=7yVl9b-3G&o%CHXESJ*YvCS9y-j8URqj?q`9j2Uf%GO$du#+sP- zOqLw*d6q(tF+pgu+>hTm-iZ15Fnejw(}%^Sdij^MmU5CZ#^VHV&3W_Q3Y`mMlAZC# zMGIqBmR!E@veIjHr}RqodMle9eUG87wW$v619aDN94chZe8w6w?tfZ8a)z58j>Ni9 zj-sgQY2r~~WL^S~;E@|UyW5&i*2n$`sZH%&B_%w=jhtR8eX?wc=3N_RHZW_7p|~y4 zQBu;>*^x{|_*iXg%UnYy_dc0BbJGrzBIm^Co_}HFASKff9Aoj4Q_CurmogA8pT<8L z>9EUKyK>qz+7m)mhY&iL;%Slig|UM+i8j^TbI+X>DXCxF(~;_ll$TGhoL)AqyhpR; zpN&SRmsOTZHtoW9gG|9qm#AQ6K`^B-KYuOWqwpP+eGkRgC+h481-FFf95t?fD|ATHv-6t;OfP7GcNs&u5BZ{*vYUD58&E` zYYr}_=QBoxfB0<@K5JJ;>*Gp85u7+c+;X4*n+u{Qao@4$zigkSXWyU-+9A zymrmBe`%&XhO)*FDQ`v@f3K<;Q&;*JjG+q5K?_&+^NA zGUY8O=Wj);{PM0$`C63o|Av|7m$#U5+U+5f^EXwSa5*11|F*na^ZUl-eLrvW**`gZ z+u6n>DgqJyr%D5dn{VBnd|nV3jmG!*J70ePejenVOn9~x(Rw)MeUKT+l6g5xCI*?E zc$urePq6cwSDn=se^_gUrt%GdD}-oGh80kU6%{ ze1Di3*Hc+C??Pq>G7VXJu68o?yA$)xw|gi1GS?W92=dNEIlsx{_d%|myssW+l~Cq7 z$ncvXjx8f|Tb`9+J8K}rZ#d2Yb~2welNmwQ11RS=4^Q~z;iFcCURT>8(}h69cfd}^ zdEy^e2U-3>HGX0hoATA4?I$NXEBk-^<_mldB$M*gI0ZM;iLo$Lf&NXYjf>>{l!xDI zGhW)b$npsIn{hD)k}n0d@s4~Hyp3<<&jN4b8F_w7V&fP2dEjllB3}>Q#wYTN!P|I5 zp5Ij1_(Ogb_z12RTmi`G27If-c0xX(!L`32b~~{oBFYctifn;B9On{~hoV znDOJFC030n>1VA zh4KP0R{z(4u~Z$u0_Dpce}q~Eex=8+25;{N$Dsdd@HVl3_vG;QcW;zo`4cF&v7Gfc zgSWAp{2+K6tI6}fAhn70e+k~kLze#zyp5scUj}d2D)~2a>i-qIjg>4P1#e>&`3Yer z29oD*G;O>ie;Rn3*q>=Rd}R(V--d7x%FjRa9u`mPp!#{;@OYec&s^^9KHiw%l)xNe zEirpvdH0@S@S+_jDEfGsZ`Cc9x8Zp4EpHd}n*eu&kMnH2r1DPaO@=wwHOeVro|nAy z)7+=zF%QT7qsf>ZukE!x*3(BKJkjC)d3xE{GaB=7jWKmKcC6ljzX6 zp&|2JV!DWTgM6XI7g#vxmbV(Z2*)~2*QYwWRC8iUV^3SQ6`J(P%o6|ggUWg{z(Z^M z#Osc0{qr0J8)Djw45m(HpZWPFuy*FtJ1x-EwL+8jE_t3%hz5umrzkatv>4y@lj4TJ z`#kA&p!`s933)c-fqTJ)3okmLV9Lb(y4e_}c0&cL3Q{MwvH7Fq zm*WP=^39~ke-D&;3a}3#Jqnb1s>z>$`6M5JnE#-F#yI!rCcj{$gL)ietkj8?-u%Pq2FUUHq$H}9e3MsD>dV$c3SPuCn;jb6U-!W0&=cN2j;lD2QdqVkJ zBi4U{JlfkT`Ogd8EtJ2dpxk@H2S*$IMMC-AJj+iY4?VTyG0wP@FA#c-&_ zg{~L+Whs9|_$P#J7P?)^pC^y@ULg-V@w;!1`yWD&I>zwFfU>=*!dD7CSLi$`zef0G zp-G|3rF<26w6~7@nM!?I%Ku&HvqCqr9PRBAepu+6LJvs!d*q?-2s|@VUj&r>FA+LZ z=$R~szDtE)B=pllJEc5D9{TQ-{I3iBp3p}@spkpuko!6L3jCiU!Vi<8{a2V@4!6XC z8P`KGDe^0X)__vaT=LMfh&=4yCgmxieL~l=9P-~1{$Zid2>r2?|C~J9`yW#1eM9IG z$C~yh3q1*x`pSi`6*^Do0x7?QJoH>A`7J_k6uJ_Wde)Lg5eJzM`A5mae}70GS$djY4k~nwIiAg#R{q z{E+l%Qam7UmHg+0?iTtI%b}NtdEp#9SAlXolZ2ikw1nl5t0RR!%wazIeYNln!ncv4 z{te8Be|&*_zEXDy{hrXrggzy7B@O{tZ#5|E?GpY);VW=}!15YUmTwjQIpHw^#UEr} zLW;c%+(PdMrwV;Q=uV+0%6^g0dfYdj$$b+po~x1W7dn;uBH)zJXNB_2m-##sBCQn4 z-{z5jMCbuhT;?D^0)oAO+d8+Ym5J%txeW0bCE#|m(Xe9LZuQ^B#G@Z zU4)BrWn_?^yj_6<*<@i0GW_wjbtn~q5{{Sl zpd9T>y><+MYS$vn2MV#RRWPHLLrBuPe7lS^;9lcZwEa68vcBByok}f3o=sNne*w>- BUh@C| literal 0 HcmV?d00001 diff --git a/labcodes/lab2/obj/kern/trap/trap.d b/labcodes/lab2/obj/kern/trap/trap.d new file mode 100644 index 00000000..c91f221a --- /dev/null +++ b/labcodes/lab2/obj/kern/trap/trap.d @@ -0,0 +1,5 @@ +obj/kern/trap/trap.o obj/kern/trap/trap.d: kern/trap/trap.c libs/defs.h \ + kern/mm/mmu.h kern/mm/memlayout.h libs/atomic.h libs/list.h \ + kern/driver/clock.h kern/trap/trap.h libs/x86.h libs/stdio.h \ + libs/stdarg.h kern/debug/assert.h kern/driver/console.h \ + kern/debug/kdebug.h diff --git a/labcodes/lab2/obj/kern/trap/trap.o b/labcodes/lab2/obj/kern/trap/trap.o new file mode 100644 index 0000000000000000000000000000000000000000..7939ce47ccc19fe88d749c01ea0d3077136a7570 GIT binary patch literal 10056 zcma)B4Rln;b-qF(RtT`zCNai1ywu2*97*i2et`&B2}lgc2uOm1rPc0RX`|KdX5X$5 zt^;ZW1|8Y4Qsbnj`2ic_P{-!bHeh1sxB{EVb?gKuZqqvMsgkBGSUxrBaSu8vsrub{ zciz4=uoeS-{5O~+&vWDPqm^Yu@rl`Y0m{j9dUiF)vdJeHw6s)9 zHC%Ri?))d1pj654xuv;XMbeOxRA5CmwOJ4drptb(p5q~g2lzc z-Um~)u&gRurYUMwi$&UH0d=LQzf!DTChEtE)rP2#yVRpCUhb(HlRUbud~}N!HsvE* zl{+sK*#)Kc>qXiI(Z21{@+d_;F6eN3%^B1nr1k~A|9mDC)~w7&m_c^T!y)3*$~z>T!DoV_@Ac(PP1Z`78qiQPY* zuTiF9F@AFIdPu(-}%9UTA zeP{N_g|m~hN-jLSP#sJqELEKyd3FEKJo~?ix)(q8KQl9zzQ&ACwu7x#JTGoTZoPtF z)YJEUU3@96+4T*7q>C@LfnmTLlEc%tdG`5P-dKL-Zn!r*d3EHaGwkT-!jh3OCd1=p zjsKXvj1y)Bq}%wYSr2jt4j)Bu06~Pn5Ix^a0}#p;Ge4b~894`Ggf|CN;o*y6 zHP4T8<9IZbbNAT5ymOtC-wXFkNw2cj6wQkq-w%PY!>mu{J2c0WVH z8NxK*k;3F5G^0|O7Sduc?)y&UF64)ihmbi%(eaRCM7zM*hSQ@i{eQXmEVwnKEQpr4 zc#Vs%0@r@BY1k!&Dd6%gfS|Ken1Z-7Xda-SyZApiyqSIjz6tH`10IB5oWk@K;-kps z!^C^+^J4ReqyH3Tz`rPd@?L#ZxLuQITod3Vavt`FVZ&oN1U})ie-r!&^t@J_!nDRF zitoVf$WCF};TrF~^btqDlWuWwe%Nvf(|y>qb_!#)?s9lU#ooW7U$u_X!MKz&Od|V` z%TcE1|4#5B=r{$yj{w={4ws&07i>@jA4~?7!W4InB~E-d;1s4Fx*2#5b=e;S`69UP zcLw|jbcOlJK(bSqzT}#dEOCr;3X|p3XZ}fB4Si1SFWV;P%ygLYw8gQ>)8`#NKnWMu zJ%?$RGZ)MsbZiFcxWjkTiw?h^-gNO_I{Z&)%HexRUyH-EhsqHroS1tYzL)qxZtM5b zEiS&q#SIs~%i%**>+n6a-o^P*ZMV6HHaUElw!8QjT)fla`zh<Kyf_z61aLw3x(k9~Br@XO%r&p7``ngsq0?3chs$3`vq5$FrC@em|Cg>gEeSfwz1 z6;CqFA5pQ*Qkcd_pQ~Z|8trs!{tQuLr!YNABMv`AhaLVHodRErP7Kj)bMYQ<_H$hs z(F5Q|zzcr%f8F87={pX8nvOdB8CM)WL(e+;XX&KF zPta=)KS^)6c;TG5T7s8UPu2U+UMe<4xdnGwO#iW`nIEg zg`RTpXC3}3@$JmE|1nLt`0Fly!QrnHUpZ|1pAz3UG{55Fzjyc>G~@8Ms08P?ZT}XP zyZA>O{!8*W{B2t7@Ly1!!=I)`hrdiK9R3D<%HjV)E#LtQn{G0%Q| z>zbJV4_2!brc189`3~OjiM|W_JAqwzo^XmGAA^o^*+`}~N_}QFwVb*7fubiG^>;?o z{h374jMY*mn@Ht4bBSo5)fBJvR{N?}s$UvNCt^)GnkRAt)58EjG0!ni5#}oF0&eXVx8%Dywexz^fo~kvKtIl z6*pK7f9jfHYgx7xMA1aDJz5v=SBKarYYq6sEKpw^U{!8+#uQZ$Ua6+E9IW=S9LprN zCRFWbO-9T0wgo#H@OAp?w7!9TXr_G1O7x`6n1LBoGZm^L%v5J4rY5V7=OAO5`B>VX z1sCUeK)F?yiFGCu{oHW9n)n8LA{uxi>O!GFsM($a*mXxNHI_zug}e$vRXimDKf41r ze080+EA>@m^`^5q;~FO$s+46Wmle}STM_V!?DN{gNTd?ErZ#xytDY~ zZ9pa1dmrM4Lju@bzheW6Kqs;rXu~O9dn4QySTE%6%fPs`B5j@ z8_C*H7?4Wori|SWnS)Vo!fM*i3WS`*Cf9A`DD?U5I-QABC+`C@X^#idCQWpw(@DE| ztX(c{H;si+-e5%rE#5luEPJYawka>455-n}T`u04HSJLJVezoyd8=1xuyFoRT{8^q z;`%C`QpdEFrOsM_RSXCViHi%(VcNT2; zfMY@F3`d3@L_8Uh`9o(RpI>)o>2^aw?SOp@V8EezU0ntdl6FIlYIM!yEQ4Artc(@# zV_7=Qm>sX^3+I@>S?MfChqFX0yH)?#4b^q3f3{4UwpXmh2prQvJug1LnghG1g0`;E zSG1soueybZqxJh$Z_Tt}b--`W4IjNeZ2Lld`vW?@<@|P{R5olOmPzkV`l50Yo6oKT zA1%GV73Y2B$FZV+ES&{_ZM30{!fmvbB>#R{?BI6dL*EYeCpqroytC}`! zZohkFMa=fAsJ3-&ZA87hebXuyyNl{`kh^{B9xSRGD;A^0V#Fm{W;PK?8uwOs1F@Y( zMRX4Jb;sOdK4lJO%qXr2YUS`CHSBY`7N#G(xP%h}iI{0%$y+LTV!Y>Zfa zk?y2B9M)vbNM9z6=M8NhFthPwdKazPylqq1*b+(gm`3Yh)WppsMjKKCkz^ufY|cdS zj7FmaiKuC8O6QE#1Cd0Mo276%&#kvb^2r>nO=q&{sA*a0tkGfi^qZ-i!ChqYDW|cm z9UY|0xT*H6X~B*Le~5s^hi2X0(qsMxwomlv!g-9UC@=uc?ROW>g>7-C4Ghzbo;*_oK+w z$o0s4f8B;0L*9-2Ao3H)Cy>t}{{;D0$o%c(UEqgt2fY>fkNGaTZtdD8qjFn!K9$QG zK3{FH)?4GtE77;d@2~X+t3-`2WOgdKe+!j7P+oG|+_JKRxU(;Tnlq=R{Ihy~`TkjJ z=FQ$QuWa@C`DF%F{B4fQ_*;=vUYaSfE$sSTDB|x&{B6du=|7KN?D8R~`D3;E?5X>> z$1XQeb_Dq?l=FMEQ@`|t(}w}|%g7I7-0GvPZe!Ld?S^`%y$BnAujM~GQESu1RwyWe{UYW_{EETM^{|scE z7Jzgh>-D?|$T$YJY>B#EboV`*Ma3R$eiv*z7hWO7X;>51|=81+S=_u z3B69--w7=MSw8&%nZH%(wc`HNqXe&6uJsiJJmR3egT)QBD_hGq5Fe~_g-~quyf`d&-z)Mykq?Xfq{yd4eqQ7si+n-kUy1zhB3}{ts>t&&=j_)_Ks9e7^I!TbH;TMU zgz!9_ScOYqRUT`&log+C*jMBd3VHlfKf>f{7>vmOU9mQTf@!H9A`a~ZvY{C^nB z{A^@w5ey5i7vyu0%ReXBB^VRz6-)|d1apEIg8H6TEvW1<#}BcLwR@8h2W*h{1DxjX zk&H(Kz2MycRz}3tI3w!4#)$D>L|Y};H)F8jdi%vW z@LfSZ-`I|7t=;{(NH;K-wXs*TteLFMnS(j1WfqI%B2?RLS+;0NrARl-ZB;gH+u#cz zUm~eCg&Sz?x=q_^V2taeYR2sCR3AFf_5U~VGaK$Y-zS6M>N}(~z-65H{{;SS--663 z`EkSp<_X8Es*fdCcaSQPQKZr&Vt+_DgCV>E=x%TBA7TBV~_aNrH+$!Nb zIO(crh}M>>rL=$3JdYw*^Y&OYCz2)8p7N=eAtaK*#a2@e*`8 TY5(}n;tKyCMb({5tf literal 0 HcmV?d00001 diff --git a/labcodes/lab2/obj/kern/trap/trapentry.d b/labcodes/lab2/obj/kern/trap/trapentry.d new file mode 100644 index 00000000..f37d596c --- /dev/null +++ b/labcodes/lab2/obj/kern/trap/trapentry.d @@ -0,0 +1,2 @@ +obj/kern/trap/trapentry.o obj/kern/trap/trapentry.d: \ + kern/trap/trapentry.S kern/mm/memlayout.h diff --git a/labcodes/lab2/obj/kern/trap/trapentry.o b/labcodes/lab2/obj/kern/trap/trapentry.o new file mode 100644 index 0000000000000000000000000000000000000000..af8304d12a169cca1511f832a8772cc87a07e0ce GIT binary patch literal 1180 zcma)+ziSjx5XZllXcB+kMdA;PCPs{kkv)rmVkNk0V<8$ONFdou76M*E*nNdpDQFo| zTb^K{ou!3^g@v7sg@uKMg@u1Wiop5(?#`?SB04bpnVC0l=Iz_}_VJC|H*2*TTxuA^ zZx8rBP>#$NIFEhUi;1CnxBhDBZG*9`FI(^De(dymy@jOyy8dE#^67_>Pp}$exXheU z>Pj&mm?EE=RLpWI3hoN;!VjL^h zQrhD!qLh;!>m$bOyhWEpT&vFK8KT)eE}1dJyX0Nnqh6Dxx9S0^I-l~i1I)D zhiSIn3|X>KJks@$b)tJ#gPy-{>6iQL@1b!lE+*}^`sC1)zL2E>+#z6K z5Evu%`A-=y8m|~*;~nFIan;CD#r!A6P2+RpOXC~kJL5;=XX7{HPvf=`QQlb#NsA0w z$yK+qv>k=?Q9!hkgalD5&k-q@+k~XWR2KSAnPi^!*w5E2?bCg8H6|IS>eODNO13#L zLQ0jRvnqSqd~S0g_l*v(H^YGP|COip_#D-kr|wYw4ydor#3gF~`gD=HjH$f*gbzl$2%WI*RZJrq~HhWY*VzA{gH<>K}9Kj_cvvdDE$B0cXHeGg(H literal 0 HcmV?d00001 diff --git a/labcodes/lab2/obj/kern/trap/vectors.d b/labcodes/lab2/obj/kern/trap/vectors.d new file mode 100644 index 00000000..e5813e77 --- /dev/null +++ b/labcodes/lab2/obj/kern/trap/vectors.d @@ -0,0 +1 @@ +obj/kern/trap/vectors.o obj/kern/trap/vectors.d: kern/trap/vectors.S diff --git a/labcodes/lab2/obj/kern/trap/vectors.o b/labcodes/lab2/obj/kern/trap/vectors.o new file mode 100644 index 0000000000000000000000000000000000000000..97c94cccc58446c53006fa817cc2d3d697382b5d GIT binary patch literal 30360 zcmeI5e|(nX`~T1Lx-LmVk|e`oQc3N)+iE2lZW)FonT&o|nXF7rCLx3&Bw79Izlu2)sqfPpl9Ai>wa;(X5CdZqkO-?ZBYjUDVk;zFWC!3sNQfzXn$!R91oAfg| z!=%5-nI;2F&N3Nja<)l{$vGy2OwKhaH961Ze3QW@LrjL63^TdFq|9Wv$q17RP0CF! zG8t)du}Ou=D3j49mzY$VTxv4LWUNV*$z>+vOfEO6Ho3xNyvda&6HKl$x!U9!Nclwh z24sG1!mmsC^$DMp@Ea0-W5RDrcum4@PWUYezct~L6MkF5Z%_Cg37?YiI}<)N;ddo` zTEg#6_&o`~H{rDjzc1nUC;WkgPfz%R37?VhhZ0_w@P`vVGvSXUd{)9AP5A7DKbG)0 z34c7{PbB=wgwIX*Qwg7!@TU_#KjF_Ld_lthmGFfLe>UOICH(n>FG~0e34bx+FC~0& z!e37Kl7zpK@cM+mn((Cwe=Xq+34cA|%M$)Z!j~uf&4j;|@V67bBH`~O{N04Vm++Md ze?Q?LB>cmKuS)nw316M?e!_zwyHG2uTYd`rTAPWUeg|25%T6aHJme^2-y3E!6R zKNG$^;r~haj)eb}@SO?&+g$j+*Z+P7{`WKR|LteMXFl@(1o^_f<)sXtiFU$Ca7EfR zVM@DQU4WE!O4vs?%I!R|rOw+70}zeUi6Oc7W4IZB+5G zPM`Yem6p$-KHbwR?Jjrv^i8j{t9JU7O|P`O!s*jAz0z)i)2Cf}rR6iLPqp+)yQ`f( zz0xb~u66o!Nw2iK&goMmz0&S_w=QGqH#&WqqgUG9(d#%((YELPfzqp zyU9+UlIWF|s_4@Yz0z)q)29`BrQMxQpGxSJc2k``eb6iI?shh$N=vl@Z?C`CMfCgK zZuAG-?)2$y5Bfu{CB4qIqCf0f(`UH@=#RPs>9gIz^v7Ke{R!8e{-o>i~5|4-}^eySRem{Eb_ot`)0rY&I zP4Dgxq4)4P^j^Lr{V0C~y|+J-evD7i3w<8_Sl^wV_D9iA@JG}8`eW!P`854x-ZTh+g6c)6elk>4W?Q^z(c<{d_-?KG;{#hxtqC z7x=OCGJhHULO-5f?kCVM@>kO<{Ppxv{s#JJe-r&uKbbzp-%cOvr_jgwyXlwvd+F8w zKKhk@27Q9BqhIA`(kJ@I=-2wk>DT!u={NZK^c(#G`b~Zz{TBZM{Z{`HeX@U|4e_v|4M(#Z==ui+v!jH9rOj>hxYIOzkEnv=y#z%@0-yV`R4Q&{GRm1 zejobFeqZ_$zaRZopG9Bl52C;3v+2wHVe~ir;q>LcBmHgPg}%b)(%=rvK*0)3^C+=zsca>D&GF^uK%!eW$;L z{`exmmbw$ghAztfKjw$b|pf6@7 z5%i;v3i{J4gR|+E2ItVn1n1H(3x?3g1;gl<2W9l}!A0~dgNx}Cf>HEqf-&@oK^6Vl z;0pSr;A;8}!9@Cv!434AgInmg1e58v26xhL5ALDg5!BMB1P{{h3TD!$1+(aP2anTh zgL(A(g8B6OgJex02{zFe1e@vq3Vx{}7C) z{}@c5{}fzH|0TGQ{%cS}-x}OT|09@6-xf@x{~6pz-x189{}t5HcLtBrefR`D2`gx=JeGc3*q45MSVT{U zr_xUh`_qfU0rZo?bLhq4`Ser6A@tM2;q)`Yk@Wsy1^vwMQu@Gf9R2LDnqCrKML##Z zj$Rs0qMsMuOdk^7P9GXhp$`l1rVkJAr;iAy(=QAkrjHC~(=QI^&?~~H=$C{G=#}9@ z`laCu^r~O))xQ3xhE3>qg-z+x!aeBshAru}VJrH5;r{gL z;X(8V!)*GD@G$zrVJG^`urvLUFs9EAyVD;F3+Qvgqv=nE$I<78Y5G&)N%Z;QY4m5p ze)I+5S@dVaLGMH5Iel?BivCJChF%|5(O(U(pf`k9(_arK(wBud z(BBMip}!SQroSEDNq;xIhyGqzOJ5m2NdGXLNnaJtqJI=VPG1wwqkkOEr+*SYOaCl< zk^XtOnEplhD*dZ)8U5>UIemTj4*lEk1Nz2r75%&LWBTUsbNUbAI{J^{H}s#wP4r*F z&GcWxpXtAcztjH+x6!wSf6@OF22Jhje@7V6{|a}byJ%0kk6O@!XkYp+QCoVGD2u*p z)Q;XPYER!i>OgNE9ZBCSO3_6k3OQG6@5Y<7_FtB9eqh36m6iN8*QYQMnBL8N59aA zL|f@Yqd)0o(N6mC$TrT?ZbY;THqm7tGipX388xS09PLdX9kr%k61AaMMhDWzMu*U= zq8$2VQAc`p)P;UUluI8U<23;nI= zH~Kr#cKW-~4*GkMZ)V^BKZu&pKa85vS4Df!{~fiYuZddGKaTdNuZ<3(e->raKaUQh ze;IY6e-(A6e;vj24N-Ucw^0FoV{|nA`{+3O<|s}7Av%e^B|44%bJUOiOLP|fw`dUk z_o$TqM>LeaJsLs(PgG9d5sgysS~aS&>jf7KD!Tmm{NgTS|Brm}@G+yiR*e~2*>&9T z3#u*|Gq#HzLuo9)|K(5pU#?(lF!N{&`LlWAz83PRp5s9|o#rgbcFsq0j$}L2qq(zW zeVtyK^MrO*M{{qglI@&^=Dw2cOoryu zCENK6%_WlUtcB*GlI>iD=8=-^429;glI^^N<_VJRY=q_;B-=R%&9_UoGY^{Ym2Br5 zG}lSCvkaOamu%-2G%t{BXB0HQB-zd*Xl{^fXAd;LBiYUwXkIPZ&J<|=Lb9D7(7aKy zofXjhvt&CLpn1DwI|HCOl>Ix~@7LU1vhD3_-dD2i<7+-hvhCSxK3uZx&uh+=Yq$+n$v^uKPc>Kc!jseQYmE^EAn}@1%K#WZPrXJV&zaCuv?F+4hb!>t2oR6KU2x z8ru`nyi&65|7iY1vhDR~UN719bu|Ad+4gWW>%NNZ*J#%L6x*B8++4El!)R_T+4fvC zXG^yI70sO_+g^%h-2<_G6V1B!VS6N+izM5Ai01y1ZSO;Ksbt&d&^$u2?P+M%{R-Q^ z(5(9uwpXEfl4RSL(0sdO+k?&)Kf>YDXlo1tqikZkjE&BsZ$*|_Fn$u!Kl5O^^S!dxkXV$E1*-TmUe91OH*8HO6?eb!u&jxXu3+v)WyiCEJ`& z^9IQ_)6={~vd!-_Z-e&U?&HAz1tVDBK zvdu*_pC;L6Aeu`g+q^^bFv&LC(5$mDn`3C!&xOq_G*6Ul^9jwjNVZvo=4p~`?x1;w zWV>28c``J3@X(41ohyuWje~_;Fa}d#H!u&(2fKqkzyh!*7;`~eF}5XRTQjyrV_P-0 zWn)`6wuNI`Ib|!SY~_@#oU)ZuwsOi=PT9&STRCMbr)=eJwsJRHxtp!r%~tMaD|fS% zyV=U!Y~^mYayMH!&sNT}mGf-nJX<->R?f4P^K9ijTRG2G&a;*CZRLDhIp0>!x0Um4 z<$PN?-&W4ImGf=od|SD@t=!#K?rtl0x0Sow%H3_{?zVDwTe-Wf+}&30VJr8rm3!FA zJ#6J3wsH?!xreRX!&dHLEBCOK3vA^ATe-kiF0hpgY~=!5xxiK~u$2pJ)%6 zR_#Wb8YcB*H({nZTUFY){k@T4aB+j z7UEoc6LBuzMxq`0HvVbIe>(D?mi(tD|7ps9y7Hg4WM9T?%$S`Svo&M(X3XY{*_|=l zGiHCrY|xk;8nZ=X_Gru|joGC!+cajM#%$D>of@-MWAnCl zWn=bi%%+XmwK3Z^X5Yqa+?bskvvp(kZp`M5*}XB_H)j9FY~Yw39J7UE_HfK5j@iXA z+c;()$86-7ogA~3WA<{)W{%m-G21z2KgVq7m>nInrDOJV%%+an)iK*TW?#o_?3kS$ zv$bRPcFg9E+1)YQJ7#~!Z19*J9<#+`_IS)DkJ;rh+dO8Ur`YEy_IZkZo?@S;*ykzs zd5V3WVxOnj=PCAiihZ7ntA40_uK?u5&Ip47>=e1a)6U@0$qT3{C;>180Iyf(yZy!DZlk;2Q8ta1;0| zxC7ipezeVeyx@LdHrNqNfk%O9@KkUhI2bGkF9pYg*MpP6yTKXYW8i%71#l_&Hn z4BP_$;^t zd;?qwehhvEeh+R1{{oxHj~M!K?gh31+ku_HZeVZl1n@NQY;Xv85jY0C5}X9y2Hpcc z1kM4U0bc}P19jf4@9#(8=is;C7Vu9nkol$FzdP6pJP_1*u|D1vEC7!MPX^BfOF=nV zlKFe1!SUdY;8alOxw`%n;B(+o@Lf>nvU=YJ@E33=*i62`=;N9Bs_+oxE?_UPFQ{`; zz5jf0BsdPd4%B(4-giGZ8(aV`0d;Pv_pJuM0)GUzgF1iI`&xnrft|qapw1EXzSF=# z;0SOGsPjO*?-uYLa3(kp)VZGCw+#FM{2bf_>U>V`3uF$Y+!JgIwg+|2rjPdlPX-5q z!$6&v>3!qD8^NjI3{dA@df#*4Qt(~y6Hw<@dfzYLPOzEGMfCNpL7hWs?gI7#`-1&J zohRviBf)Xtb>Quw&V}^8+28_j3HTPM^BukKEAU5fJJ>|#7y7u)X_N_sW%KuDo-AN^euLU|)a%6(ntJcn=XTtCh7q(q-z zczNR`%KcsDJcn;9ds3PYX#71jUf!v4%?HX}zw#jGDwPK}p55@-PJTOwaRRe>aQ%4`YTV8`YTVC`YYv0pq}mU#ZrIesZxLC zX;OdX=~91XKdHa+45`1eztmrOrqo|Kpz(}{KTGPbd7#u^dA8JFSt9jUo+I^F4wCvS zouef8_;Ie`T4}UpZXruN={M=EGko z_19c3^;cdb^;eFR`YSJ%`YS7>{>o8Of8}VYzw(mCvmd@v>aY1yslRfJ)L%JP>aVPl z`YSJ!`YXpt{gv{hd6lxd@eGK+Lh7%1ywqQLrPNaTgS)L(g< z)L(hK)L(gr)L%J8>aV<0>aUzC^;h22cs9gOllp7ETk5a8N9wP!kk5ho%0?nNok{BT|3mEUCZp(Z;hPezw$K z^J7wfVo zzjC3}U-_)mU-_KWU-^9F*%7};>aY0)slW0?slW0islRfu)L;3s)L*$o>aTo7>aVPC zJVWANmHKO5D)kSAuSxxt4N`yQ>r#K^GO54v4XM9!xzu0zrqo~gmegPQw$xv_Lh7%4 zN9wP9SL&~PPwKB+DfL&rFZEY`;4)`Q{D)G1&8wvT%8#V}%GFYT<-eu=$~97d<;PNg zsm#{>m?;{>pVyf901_f8|$Ff92Owf8~0qzw#TYzjA}r zU-_-nU%650ul!ExuiPZ{SAH+`S8kU2D}RvsD}R*wD}R#uE4N7fl|M`UmA^>+mA^{; zm0P9$%HO2^%HO5_%0Hz3%574A<)2c2<#wsR@;_34rY3{e4mk=`Mx5o z$LllSHza4iPY5&L7lfJb1Hw$-3!7%X4$#+A;B?b?`IfLWlPFVXw*z(TMXECKbLh~8HTP5^7b zXSi-w?0@tOh56dLBaW zn-0za7lQSmo@>zi)`085E#MAN&nM`8t-x%sGgtuXIRm|~A6N>OgH@oO7ts4AgSFr+ za6Y&gTn?@R*MXbCZD7=_aorYR7T5vI0}H`oummgvE5Qk14LA*~1LuN^zy@$7xE9<9 zZUyz1o9f5k9Bc#TfVp6Aum~Ig4go8`YH$)b1)L7f0T+Vx;0kaJxE|aB?f{!MZ+w4S zf!SbZumDVh{lHSN9IOH-f|J2oa27ZpTnsJ;SApxm&EPgL+5`0mv%n5u9#{w#gC$@Y zSP4!5Yrtt>9XJepgImBIVAH)&e=r;D3>JWCupd|omV;H`L~t@#3(f-PgNwoC;3{w(xEb6A zMlDc(FbnJe=7EJ^F<1hYftBC{um+q4)`4@uMPLKC5?l*z1h<0v%aSwo2it%-U@q7j zECL6BL%<5K8k_`90jGm=z=dEvxB^@Qt_Qb(JHVzbQGYNS>3OF5{11<#X!4=>da6PyM+yOS-7xf3T z!Oma-mQ&1x^GfgSFr+a6Y&gTn?@R*MXbCZD7R5m zP5^7bXi@*Wk5U>KQ1}A}2!0F%|a3NR^ zt^n77>%lGH4zOt()E~?SJA(ya8tey_g5_WpI1!u-)`GLZ`QT!3Ik*a32W|$pfzke` zKbQq}0Q0~?uox@>%fL!-0$2l11M9%K;3BXATnVlPH-cM1*B12$+kiP>F4!9^0tbLY zzzVP$oCHn*r-O6AgQ&1x^GfgSFr+a6Y&gTn?@R*MXbCZD4c=>JMgt z9l$)W5G)2uz%sBBoB-B<)4)1#F1QG609S%*!HwWn&>f2UgKfYZFc<6%7J&o6Az%eq z4Nd~5fYZS_;6kt-TmiZ+W3L!hHFTJ;YD^=`&BhF`=u$Pjy2^D?D;ruh)O8s)c5GuD zi@!8: + +.text +.globl kern_entry +kern_entry: + # load pa of boot pgdir + movl $REALLOC(__boot_pgdir), %eax +c0100000: b8 00 a0 11 00 mov $0x11a000,%eax + movl %eax, %cr3 +c0100005: 0f 22 d8 mov %eax,%cr3 + + # enable paging + movl %cr0, %eax +c0100008: 0f 20 c0 mov %cr0,%eax + orl $(CR0_PE | CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_TS | CR0_EM | CR0_MP), %eax +c010000b: 0d 2f 00 05 80 or $0x8005002f,%eax + andl $~(CR0_TS | CR0_EM), %eax +c0100010: 83 e0 f3 and $0xfffffff3,%eax + movl %eax, %cr0 +c0100013: 0f 22 c0 mov %eax,%cr0 + + # update eip + # now, eip = 0x1..... + leal next, %eax +c0100016: 8d 05 1e 00 10 c0 lea 0xc010001e,%eax + # set eip = KERNBASE + 0x1..... + jmp *%eax +c010001c: ff e0 jmp *%eax + +c010001e : +next: + + # unmap va 0 ~ 4M, it's temporary mapping + xorl %eax, %eax +c010001e: 31 c0 xor %eax,%eax + movl %eax, __boot_pgdir +c0100020: a3 00 a0 11 c0 mov %eax,0xc011a000 + + # set ebp, esp + movl $0x0, %ebp +c0100025: bd 00 00 00 00 mov $0x0,%ebp + # the kernel stack region is from bootstack -- bootstacktop, + # the kernel stack size is KSTACKSIZE (8KB)defined in memlayout.h + movl $bootstacktop, %esp +c010002a: bc 00 90 11 c0 mov $0xc0119000,%esp + # now kernel stack is ready , call the first C function + call kern_init +c010002f: e8 02 00 00 00 call c0100036 + +c0100034 : + +# should never get here +spin: + jmp spin +c0100034: eb fe jmp c0100034 + +c0100036 : +int kern_init(void) __attribute__((noreturn)); +void grade_backtrace(void); +static void lab1_switch_test(void); + +int +kern_init(void) { +c0100036: 55 push %ebp +c0100037: 89 e5 mov %esp,%ebp +c0100039: 83 ec 28 sub $0x28,%esp + extern char edata[], end[]; + memset(edata, 0, end - edata); +c010003c: b8 8c cf 11 c0 mov $0xc011cf8c,%eax +c0100041: 2d 00 c0 11 c0 sub $0xc011c000,%eax +c0100046: 89 44 24 08 mov %eax,0x8(%esp) +c010004a: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0100051: 00 +c0100052: c7 04 24 00 c0 11 c0 movl $0xc011c000,(%esp) +c0100059: e8 aa 5e 00 00 call c0105f08 + + cons_init(); // init the console +c010005e: e8 42 15 00 00 call c01015a5 + + const char *message = "(THU.CST) os is loading ..."; +c0100063: c7 45 f4 a0 60 10 c0 movl $0xc01060a0,-0xc(%ebp) + cprintf("%s\n\n", message); +c010006a: 8b 45 f4 mov -0xc(%ebp),%eax +c010006d: 89 44 24 04 mov %eax,0x4(%esp) +c0100071: c7 04 24 bc 60 10 c0 movl $0xc01060bc,(%esp) +c0100078: e8 e9 02 00 00 call c0100366 + + print_kerninfo(); +c010007d: e8 07 08 00 00 call c0100889 + + grade_backtrace(); +c0100082: e8 95 00 00 00 call c010011c + + pmm_init(); // init physical memory management +c0100087: e8 f3 43 00 00 call c010447f + + pic_init(); // init interrupt controller +c010008c: e8 95 16 00 00 call c0101726 + idt_init(); // init interrupt descriptor table +c0100091: e8 f9 17 00 00 call c010188f + + clock_init(); // init clock interrupt +c0100096: e8 69 0c 00 00 call c0100d04 + intr_enable(); // enable irq interrupt +c010009b: e8 e4 15 00 00 call c0101684 + + //LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test() + // user/kernel mode switch test + lab1_switch_test(); +c01000a0: e8 76 01 00 00 call c010021b + + /* do nothing */ + while (1); +c01000a5: eb fe jmp c01000a5 + +c01000a7 : +} + +void __attribute__((noinline)) +grade_backtrace2(int arg0, int arg1, int arg2, int arg3) { +c01000a7: 55 push %ebp +c01000a8: 89 e5 mov %esp,%ebp +c01000aa: 83 ec 18 sub $0x18,%esp + mon_backtrace(0, NULL, NULL); +c01000ad: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01000b4: 00 +c01000b5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c01000bc: 00 +c01000bd: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c01000c4: e8 56 0b 00 00 call c0100c1f +} +c01000c9: 90 nop +c01000ca: 89 ec mov %ebp,%esp +c01000cc: 5d pop %ebp +c01000cd: c3 ret + +c01000ce : + +void __attribute__((noinline)) +grade_backtrace1(int arg0, int arg1) { +c01000ce: 55 push %ebp +c01000cf: 89 e5 mov %esp,%ebp +c01000d1: 83 ec 18 sub $0x18,%esp +c01000d4: 89 5d fc mov %ebx,-0x4(%ebp) + grade_backtrace2(arg0, (int)&arg0, arg1, (int)&arg1); +c01000d7: 8d 4d 0c lea 0xc(%ebp),%ecx +c01000da: 8b 55 0c mov 0xc(%ebp),%edx +c01000dd: 8d 5d 08 lea 0x8(%ebp),%ebx +c01000e0: 8b 45 08 mov 0x8(%ebp),%eax +c01000e3: 89 4c 24 0c mov %ecx,0xc(%esp) +c01000e7: 89 54 24 08 mov %edx,0x8(%esp) +c01000eb: 89 5c 24 04 mov %ebx,0x4(%esp) +c01000ef: 89 04 24 mov %eax,(%esp) +c01000f2: e8 b0 ff ff ff call c01000a7 +} +c01000f7: 90 nop +c01000f8: 8b 5d fc mov -0x4(%ebp),%ebx +c01000fb: 89 ec mov %ebp,%esp +c01000fd: 5d pop %ebp +c01000fe: c3 ret + +c01000ff : + +void __attribute__((noinline)) +grade_backtrace0(int arg0, int arg1, int arg2) { +c01000ff: 55 push %ebp +c0100100: 89 e5 mov %esp,%ebp +c0100102: 83 ec 18 sub $0x18,%esp + grade_backtrace1(arg0, arg2); +c0100105: 8b 45 10 mov 0x10(%ebp),%eax +c0100108: 89 44 24 04 mov %eax,0x4(%esp) +c010010c: 8b 45 08 mov 0x8(%ebp),%eax +c010010f: 89 04 24 mov %eax,(%esp) +c0100112: e8 b7 ff ff ff call c01000ce +} +c0100117: 90 nop +c0100118: 89 ec mov %ebp,%esp +c010011a: 5d pop %ebp +c010011b: c3 ret + +c010011c : + +void +grade_backtrace(void) { +c010011c: 55 push %ebp +c010011d: 89 e5 mov %esp,%ebp +c010011f: 83 ec 18 sub $0x18,%esp + grade_backtrace0(0, (int)kern_init, 0xffff0000); +c0100122: b8 36 00 10 c0 mov $0xc0100036,%eax +c0100127: c7 44 24 08 00 00 ff movl $0xffff0000,0x8(%esp) +c010012e: ff +c010012f: 89 44 24 04 mov %eax,0x4(%esp) +c0100133: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c010013a: e8 c0 ff ff ff call c01000ff +} +c010013f: 90 nop +c0100140: 89 ec mov %ebp,%esp +c0100142: 5d pop %ebp +c0100143: c3 ret + +c0100144 : + +static void +lab1_print_cur_status(void) { +c0100144: 55 push %ebp +c0100145: 89 e5 mov %esp,%ebp +c0100147: 83 ec 28 sub $0x28,%esp + static int round = 0; + uint16_t reg1, reg2, reg3, reg4; + asm volatile ( +c010014a: 8c 4d f6 mov %cs,-0xa(%ebp) +c010014d: 8c 5d f4 mov %ds,-0xc(%ebp) +c0100150: 8c 45 f2 mov %es,-0xe(%ebp) +c0100153: 8c 55 f0 mov %ss,-0x10(%ebp) + "mov %%cs, %0;" + "mov %%ds, %1;" + "mov %%es, %2;" + "mov %%ss, %3;" + : "=m"(reg1), "=m"(reg2), "=m"(reg3), "=m"(reg4)); + cprintf("%d: @ring %d\n", round, reg1 & 3); +c0100156: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c010015a: 83 e0 03 and $0x3,%eax +c010015d: 89 c2 mov %eax,%edx +c010015f: a1 00 c0 11 c0 mov 0xc011c000,%eax +c0100164: 89 54 24 08 mov %edx,0x8(%esp) +c0100168: 89 44 24 04 mov %eax,0x4(%esp) +c010016c: c7 04 24 c1 60 10 c0 movl $0xc01060c1,(%esp) +c0100173: e8 ee 01 00 00 call c0100366 + cprintf("%d: cs = %x\n", round, reg1); +c0100178: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c010017c: 89 c2 mov %eax,%edx +c010017e: a1 00 c0 11 c0 mov 0xc011c000,%eax +c0100183: 89 54 24 08 mov %edx,0x8(%esp) +c0100187: 89 44 24 04 mov %eax,0x4(%esp) +c010018b: c7 04 24 cf 60 10 c0 movl $0xc01060cf,(%esp) +c0100192: e8 cf 01 00 00 call c0100366 + cprintf("%d: ds = %x\n", round, reg2); +c0100197: 0f b7 45 f4 movzwl -0xc(%ebp),%eax +c010019b: 89 c2 mov %eax,%edx +c010019d: a1 00 c0 11 c0 mov 0xc011c000,%eax +c01001a2: 89 54 24 08 mov %edx,0x8(%esp) +c01001a6: 89 44 24 04 mov %eax,0x4(%esp) +c01001aa: c7 04 24 dd 60 10 c0 movl $0xc01060dd,(%esp) +c01001b1: e8 b0 01 00 00 call c0100366 + cprintf("%d: es = %x\n", round, reg3); +c01001b6: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c01001ba: 89 c2 mov %eax,%edx +c01001bc: a1 00 c0 11 c0 mov 0xc011c000,%eax +c01001c1: 89 54 24 08 mov %edx,0x8(%esp) +c01001c5: 89 44 24 04 mov %eax,0x4(%esp) +c01001c9: c7 04 24 eb 60 10 c0 movl $0xc01060eb,(%esp) +c01001d0: e8 91 01 00 00 call c0100366 + cprintf("%d: ss = %x\n", round, reg4); +c01001d5: 0f b7 45 f0 movzwl -0x10(%ebp),%eax +c01001d9: 89 c2 mov %eax,%edx +c01001db: a1 00 c0 11 c0 mov 0xc011c000,%eax +c01001e0: 89 54 24 08 mov %edx,0x8(%esp) +c01001e4: 89 44 24 04 mov %eax,0x4(%esp) +c01001e8: c7 04 24 f9 60 10 c0 movl $0xc01060f9,(%esp) +c01001ef: e8 72 01 00 00 call c0100366 + round ++; +c01001f4: a1 00 c0 11 c0 mov 0xc011c000,%eax +c01001f9: 40 inc %eax +c01001fa: a3 00 c0 11 c0 mov %eax,0xc011c000 +} +c01001ff: 90 nop +c0100200: 89 ec mov %ebp,%esp +c0100202: 5d pop %ebp +c0100203: c3 ret + +c0100204 : + +static void +lab1_switch_to_user(void) { +c0100204: 55 push %ebp +c0100205: 89 e5 mov %esp,%ebp + //LAB1 CHALLENGE 1 : TODO + asm volatile ( +c0100207: 83 ec 08 sub $0x8,%esp +c010020a: cd 78 int $0x78 +c010020c: 89 ec mov %ebp,%esp + "int %0 \n" + "movl %%ebp, %%esp" + : + : "i"(T_SWITCH_TOU) + ); +} +c010020e: 90 nop +c010020f: 5d pop %ebp +c0100210: c3 ret + +c0100211 : + +static void +lab1_switch_to_kernel(void) { +c0100211: 55 push %ebp +c0100212: 89 e5 mov %esp,%ebp + //LAB1 CHALLENGE 1 : TODO + asm volatile ( +c0100214: cd 79 int $0x79 +c0100216: 89 ec mov %ebp,%esp + "int %0 \n" + "movl %%ebp, %%esp \n" + : + : "i"(T_SWITCH_TOK) + ); +} +c0100218: 90 nop +c0100219: 5d pop %ebp +c010021a: c3 ret + +c010021b : + +static void +lab1_switch_test(void) { +c010021b: 55 push %ebp +c010021c: 89 e5 mov %esp,%ebp +c010021e: 83 ec 18 sub $0x18,%esp + lab1_print_cur_status(); +c0100221: e8 1e ff ff ff call c0100144 + cprintf("+++ switch to user mode +++\n"); +c0100226: c7 04 24 08 61 10 c0 movl $0xc0106108,(%esp) +c010022d: e8 34 01 00 00 call c0100366 + lab1_switch_to_user(); +c0100232: e8 cd ff ff ff call c0100204 + lab1_print_cur_status(); +c0100237: e8 08 ff ff ff call c0100144 + cprintf("+++ switch to kernel mode +++\n"); +c010023c: c7 04 24 28 61 10 c0 movl $0xc0106128,(%esp) +c0100243: e8 1e 01 00 00 call c0100366 + lab1_switch_to_kernel(); +c0100248: e8 c4 ff ff ff call c0100211 + lab1_print_cur_status(); +c010024d: e8 f2 fe ff ff call c0100144 +} +c0100252: 90 nop +c0100253: 89 ec mov %ebp,%esp +c0100255: 5d pop %ebp +c0100256: c3 ret + +c0100257 : + * The readline() function returns the text of the line read. If some errors + * are happened, NULL is returned. The return value is a global variable, + * thus it should be copied before it is used. + * */ +char * +readline(const char *prompt) { +c0100257: 55 push %ebp +c0100258: 89 e5 mov %esp,%ebp +c010025a: 83 ec 28 sub $0x28,%esp + if (prompt != NULL) { +c010025d: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0100261: 74 13 je c0100276 + cprintf("%s", prompt); +c0100263: 8b 45 08 mov 0x8(%ebp),%eax +c0100266: 89 44 24 04 mov %eax,0x4(%esp) +c010026a: c7 04 24 47 61 10 c0 movl $0xc0106147,(%esp) +c0100271: e8 f0 00 00 00 call c0100366 + } + int i = 0, c; +c0100276: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + while (1) { + c = getchar(); +c010027d: e8 73 01 00 00 call c01003f5 +c0100282: 89 45 f0 mov %eax,-0x10(%ebp) + if (c < 0) { +c0100285: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0100289: 79 07 jns c0100292 + return NULL; +c010028b: b8 00 00 00 00 mov $0x0,%eax +c0100290: eb 78 jmp c010030a + } + else if (c >= ' ' && i < BUFSIZE - 1) { +c0100292: 83 7d f0 1f cmpl $0x1f,-0x10(%ebp) +c0100296: 7e 28 jle c01002c0 +c0100298: 81 7d f4 fe 03 00 00 cmpl $0x3fe,-0xc(%ebp) +c010029f: 7f 1f jg c01002c0 + cputchar(c); +c01002a1: 8b 45 f0 mov -0x10(%ebp),%eax +c01002a4: 89 04 24 mov %eax,(%esp) +c01002a7: e8 e2 00 00 00 call c010038e + buf[i ++] = c; +c01002ac: 8b 45 f4 mov -0xc(%ebp),%eax +c01002af: 8d 50 01 lea 0x1(%eax),%edx +c01002b2: 89 55 f4 mov %edx,-0xc(%ebp) +c01002b5: 8b 55 f0 mov -0x10(%ebp),%edx +c01002b8: 88 90 20 c0 11 c0 mov %dl,-0x3fee3fe0(%eax) +c01002be: eb 45 jmp c0100305 + } + else if (c == '\b' && i > 0) { +c01002c0: 83 7d f0 08 cmpl $0x8,-0x10(%ebp) +c01002c4: 75 16 jne c01002dc +c01002c6: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01002ca: 7e 10 jle c01002dc + cputchar(c); +c01002cc: 8b 45 f0 mov -0x10(%ebp),%eax +c01002cf: 89 04 24 mov %eax,(%esp) +c01002d2: e8 b7 00 00 00 call c010038e + i --; +c01002d7: ff 4d f4 decl -0xc(%ebp) +c01002da: eb 29 jmp c0100305 + } + else if (c == '\n' || c == '\r') { +c01002dc: 83 7d f0 0a cmpl $0xa,-0x10(%ebp) +c01002e0: 74 06 je c01002e8 +c01002e2: 83 7d f0 0d cmpl $0xd,-0x10(%ebp) +c01002e6: 75 95 jne c010027d + cputchar(c); +c01002e8: 8b 45 f0 mov -0x10(%ebp),%eax +c01002eb: 89 04 24 mov %eax,(%esp) +c01002ee: e8 9b 00 00 00 call c010038e + buf[i] = '\0'; +c01002f3: 8b 45 f4 mov -0xc(%ebp),%eax +c01002f6: 05 20 c0 11 c0 add $0xc011c020,%eax +c01002fb: c6 00 00 movb $0x0,(%eax) + return buf; +c01002fe: b8 20 c0 11 c0 mov $0xc011c020,%eax +c0100303: eb 05 jmp c010030a + c = getchar(); +c0100305: e9 73 ff ff ff jmp c010027d + } + } +} +c010030a: 89 ec mov %ebp,%esp +c010030c: 5d pop %ebp +c010030d: c3 ret + +c010030e : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { +c010030e: 55 push %ebp +c010030f: 89 e5 mov %esp,%ebp +c0100311: 83 ec 18 sub $0x18,%esp + cons_putc(c); +c0100314: 8b 45 08 mov 0x8(%ebp),%eax +c0100317: 89 04 24 mov %eax,(%esp) +c010031a: e8 b5 12 00 00 call c01015d4 + (*cnt) ++; +c010031f: 8b 45 0c mov 0xc(%ebp),%eax +c0100322: 8b 00 mov (%eax),%eax +c0100324: 8d 50 01 lea 0x1(%eax),%edx +c0100327: 8b 45 0c mov 0xc(%ebp),%eax +c010032a: 89 10 mov %edx,(%eax) +} +c010032c: 90 nop +c010032d: 89 ec mov %ebp,%esp +c010032f: 5d pop %ebp +c0100330: c3 ret + +c0100331 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { +c0100331: 55 push %ebp +c0100332: 89 e5 mov %esp,%ebp +c0100334: 83 ec 28 sub $0x28,%esp + int cnt = 0; +c0100337: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); +c010033e: 8b 45 0c mov 0xc(%ebp),%eax +c0100341: 89 44 24 0c mov %eax,0xc(%esp) +c0100345: 8b 45 08 mov 0x8(%ebp),%eax +c0100348: 89 44 24 08 mov %eax,0x8(%esp) +c010034c: 8d 45 f4 lea -0xc(%ebp),%eax +c010034f: 89 44 24 04 mov %eax,0x4(%esp) +c0100353: c7 04 24 0e 03 10 c0 movl $0xc010030e,(%esp) +c010035a: e8 d4 53 00 00 call c0105733 + return cnt; +c010035f: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0100362: 89 ec mov %ebp,%esp +c0100364: 5d pop %ebp +c0100365: c3 ret + +c0100366 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { +c0100366: 55 push %ebp +c0100367: 89 e5 mov %esp,%ebp +c0100369: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); +c010036c: 8d 45 0c lea 0xc(%ebp),%eax +c010036f: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vcprintf(fmt, ap); +c0100372: 8b 45 f0 mov -0x10(%ebp),%eax +c0100375: 89 44 24 04 mov %eax,0x4(%esp) +c0100379: 8b 45 08 mov 0x8(%ebp),%eax +c010037c: 89 04 24 mov %eax,(%esp) +c010037f: e8 ad ff ff ff call c0100331 +c0100384: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; +c0100387: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010038a: 89 ec mov %ebp,%esp +c010038c: 5d pop %ebp +c010038d: c3 ret + +c010038e : + +/* cputchar - writes a single character to stdout */ +void +cputchar(int c) { +c010038e: 55 push %ebp +c010038f: 89 e5 mov %esp,%ebp +c0100391: 83 ec 18 sub $0x18,%esp + cons_putc(c); +c0100394: 8b 45 08 mov 0x8(%ebp),%eax +c0100397: 89 04 24 mov %eax,(%esp) +c010039a: e8 35 12 00 00 call c01015d4 +} +c010039f: 90 nop +c01003a0: 89 ec mov %ebp,%esp +c01003a2: 5d pop %ebp +c01003a3: c3 ret + +c01003a4 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { +c01003a4: 55 push %ebp +c01003a5: 89 e5 mov %esp,%ebp +c01003a7: 83 ec 28 sub $0x28,%esp + int cnt = 0; +c01003aa: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { +c01003b1: eb 13 jmp c01003c6 + cputch(c, &cnt); +c01003b3: 0f be 45 f7 movsbl -0x9(%ebp),%eax +c01003b7: 8d 55 f0 lea -0x10(%ebp),%edx +c01003ba: 89 54 24 04 mov %edx,0x4(%esp) +c01003be: 89 04 24 mov %eax,(%esp) +c01003c1: e8 48 ff ff ff call c010030e + while ((c = *str ++) != '\0') { +c01003c6: 8b 45 08 mov 0x8(%ebp),%eax +c01003c9: 8d 50 01 lea 0x1(%eax),%edx +c01003cc: 89 55 08 mov %edx,0x8(%ebp) +c01003cf: 0f b6 00 movzbl (%eax),%eax +c01003d2: 88 45 f7 mov %al,-0x9(%ebp) +c01003d5: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) +c01003d9: 75 d8 jne c01003b3 + } + cputch('\n', &cnt); +c01003db: 8d 45 f0 lea -0x10(%ebp),%eax +c01003de: 89 44 24 04 mov %eax,0x4(%esp) +c01003e2: c7 04 24 0a 00 00 00 movl $0xa,(%esp) +c01003e9: e8 20 ff ff ff call c010030e + return cnt; +c01003ee: 8b 45 f0 mov -0x10(%ebp),%eax +} +c01003f1: 89 ec mov %ebp,%esp +c01003f3: 5d pop %ebp +c01003f4: c3 ret + +c01003f5 : + +/* getchar - reads a single non-zero character from stdin */ +int +getchar(void) { +c01003f5: 55 push %ebp +c01003f6: 89 e5 mov %esp,%ebp +c01003f8: 83 ec 18 sub $0x18,%esp + int c; + while ((c = cons_getc()) == 0) +c01003fb: 90 nop +c01003fc: e8 12 12 00 00 call c0101613 +c0100401: 89 45 f4 mov %eax,-0xc(%ebp) +c0100404: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0100408: 74 f2 je c01003fc + /* do nothing */; + return c; +c010040a: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010040d: 89 ec mov %ebp,%esp +c010040f: 5d pop %ebp +c0100410: c3 ret + +c0100411 : + * stab_binsearch(stabs, &left, &right, N_SO, 0xf0100184); + * will exit setting left = 118, right = 554. + * */ +static void +stab_binsearch(const struct stab *stabs, int *region_left, int *region_right, + int type, uintptr_t addr) { +c0100411: 55 push %ebp +c0100412: 89 e5 mov %esp,%ebp +c0100414: 83 ec 20 sub $0x20,%esp + int l = *region_left, r = *region_right, any_matches = 0; +c0100417: 8b 45 0c mov 0xc(%ebp),%eax +c010041a: 8b 00 mov (%eax),%eax +c010041c: 89 45 fc mov %eax,-0x4(%ebp) +c010041f: 8b 45 10 mov 0x10(%ebp),%eax +c0100422: 8b 00 mov (%eax),%eax +c0100424: 89 45 f8 mov %eax,-0x8(%ebp) +c0100427: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + + while (l <= r) { +c010042e: e9 ca 00 00 00 jmp c01004fd + int true_m = (l + r) / 2, m = true_m; +c0100433: 8b 55 fc mov -0x4(%ebp),%edx +c0100436: 8b 45 f8 mov -0x8(%ebp),%eax +c0100439: 01 d0 add %edx,%eax +c010043b: 89 c2 mov %eax,%edx +c010043d: c1 ea 1f shr $0x1f,%edx +c0100440: 01 d0 add %edx,%eax +c0100442: d1 f8 sar %eax +c0100444: 89 45 ec mov %eax,-0x14(%ebp) +c0100447: 8b 45 ec mov -0x14(%ebp),%eax +c010044a: 89 45 f0 mov %eax,-0x10(%ebp) + + // search for earliest stab with right type + while (m >= l && stabs[m].n_type != type) { +c010044d: eb 03 jmp c0100452 + m --; +c010044f: ff 4d f0 decl -0x10(%ebp) + while (m >= l && stabs[m].n_type != type) { +c0100452: 8b 45 f0 mov -0x10(%ebp),%eax +c0100455: 3b 45 fc cmp -0x4(%ebp),%eax +c0100458: 7c 1f jl c0100479 +c010045a: 8b 55 f0 mov -0x10(%ebp),%edx +c010045d: 89 d0 mov %edx,%eax +c010045f: 01 c0 add %eax,%eax +c0100461: 01 d0 add %edx,%eax +c0100463: c1 e0 02 shl $0x2,%eax +c0100466: 89 c2 mov %eax,%edx +c0100468: 8b 45 08 mov 0x8(%ebp),%eax +c010046b: 01 d0 add %edx,%eax +c010046d: 0f b6 40 04 movzbl 0x4(%eax),%eax +c0100471: 0f b6 c0 movzbl %al,%eax +c0100474: 39 45 14 cmp %eax,0x14(%ebp) +c0100477: 75 d6 jne c010044f + } + if (m < l) { // no match in [l, m] +c0100479: 8b 45 f0 mov -0x10(%ebp),%eax +c010047c: 3b 45 fc cmp -0x4(%ebp),%eax +c010047f: 7d 09 jge c010048a + l = true_m + 1; +c0100481: 8b 45 ec mov -0x14(%ebp),%eax +c0100484: 40 inc %eax +c0100485: 89 45 fc mov %eax,-0x4(%ebp) + continue; +c0100488: eb 73 jmp c01004fd + } + + // actual binary search + any_matches = 1; +c010048a: c7 45 f4 01 00 00 00 movl $0x1,-0xc(%ebp) + if (stabs[m].n_value < addr) { +c0100491: 8b 55 f0 mov -0x10(%ebp),%edx +c0100494: 89 d0 mov %edx,%eax +c0100496: 01 c0 add %eax,%eax +c0100498: 01 d0 add %edx,%eax +c010049a: c1 e0 02 shl $0x2,%eax +c010049d: 89 c2 mov %eax,%edx +c010049f: 8b 45 08 mov 0x8(%ebp),%eax +c01004a2: 01 d0 add %edx,%eax +c01004a4: 8b 40 08 mov 0x8(%eax),%eax +c01004a7: 39 45 18 cmp %eax,0x18(%ebp) +c01004aa: 76 11 jbe c01004bd + *region_left = m; +c01004ac: 8b 45 0c mov 0xc(%ebp),%eax +c01004af: 8b 55 f0 mov -0x10(%ebp),%edx +c01004b2: 89 10 mov %edx,(%eax) + l = true_m + 1; +c01004b4: 8b 45 ec mov -0x14(%ebp),%eax +c01004b7: 40 inc %eax +c01004b8: 89 45 fc mov %eax,-0x4(%ebp) +c01004bb: eb 40 jmp c01004fd + } else if (stabs[m].n_value > addr) { +c01004bd: 8b 55 f0 mov -0x10(%ebp),%edx +c01004c0: 89 d0 mov %edx,%eax +c01004c2: 01 c0 add %eax,%eax +c01004c4: 01 d0 add %edx,%eax +c01004c6: c1 e0 02 shl $0x2,%eax +c01004c9: 89 c2 mov %eax,%edx +c01004cb: 8b 45 08 mov 0x8(%ebp),%eax +c01004ce: 01 d0 add %edx,%eax +c01004d0: 8b 40 08 mov 0x8(%eax),%eax +c01004d3: 39 45 18 cmp %eax,0x18(%ebp) +c01004d6: 73 14 jae c01004ec + *region_right = m - 1; +c01004d8: 8b 45 f0 mov -0x10(%ebp),%eax +c01004db: 8d 50 ff lea -0x1(%eax),%edx +c01004de: 8b 45 10 mov 0x10(%ebp),%eax +c01004e1: 89 10 mov %edx,(%eax) + r = m - 1; +c01004e3: 8b 45 f0 mov -0x10(%ebp),%eax +c01004e6: 48 dec %eax +c01004e7: 89 45 f8 mov %eax,-0x8(%ebp) +c01004ea: eb 11 jmp c01004fd + } else { + // exact match for 'addr', but continue loop to find + // *region_right + *region_left = m; +c01004ec: 8b 45 0c mov 0xc(%ebp),%eax +c01004ef: 8b 55 f0 mov -0x10(%ebp),%edx +c01004f2: 89 10 mov %edx,(%eax) + l = m; +c01004f4: 8b 45 f0 mov -0x10(%ebp),%eax +c01004f7: 89 45 fc mov %eax,-0x4(%ebp) + addr ++; +c01004fa: ff 45 18 incl 0x18(%ebp) + while (l <= r) { +c01004fd: 8b 45 fc mov -0x4(%ebp),%eax +c0100500: 3b 45 f8 cmp -0x8(%ebp),%eax +c0100503: 0f 8e 2a ff ff ff jle c0100433 + } + } + + if (!any_matches) { +c0100509: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010050d: 75 0f jne c010051e + *region_right = *region_left - 1; +c010050f: 8b 45 0c mov 0xc(%ebp),%eax +c0100512: 8b 00 mov (%eax),%eax +c0100514: 8d 50 ff lea -0x1(%eax),%edx +c0100517: 8b 45 10 mov 0x10(%ebp),%eax +c010051a: 89 10 mov %edx,(%eax) + l = *region_right; + for (; l > *region_left && stabs[l].n_type != type; l --) + /* do nothing */; + *region_left = l; + } +} +c010051c: eb 3e jmp c010055c + l = *region_right; +c010051e: 8b 45 10 mov 0x10(%ebp),%eax +c0100521: 8b 00 mov (%eax),%eax +c0100523: 89 45 fc mov %eax,-0x4(%ebp) + for (; l > *region_left && stabs[l].n_type != type; l --) +c0100526: eb 03 jmp c010052b +c0100528: ff 4d fc decl -0x4(%ebp) +c010052b: 8b 45 0c mov 0xc(%ebp),%eax +c010052e: 8b 00 mov (%eax),%eax +c0100530: 39 45 fc cmp %eax,-0x4(%ebp) +c0100533: 7e 1f jle c0100554 +c0100535: 8b 55 fc mov -0x4(%ebp),%edx +c0100538: 89 d0 mov %edx,%eax +c010053a: 01 c0 add %eax,%eax +c010053c: 01 d0 add %edx,%eax +c010053e: c1 e0 02 shl $0x2,%eax +c0100541: 89 c2 mov %eax,%edx +c0100543: 8b 45 08 mov 0x8(%ebp),%eax +c0100546: 01 d0 add %edx,%eax +c0100548: 0f b6 40 04 movzbl 0x4(%eax),%eax +c010054c: 0f b6 c0 movzbl %al,%eax +c010054f: 39 45 14 cmp %eax,0x14(%ebp) +c0100552: 75 d4 jne c0100528 + *region_left = l; +c0100554: 8b 45 0c mov 0xc(%ebp),%eax +c0100557: 8b 55 fc mov -0x4(%ebp),%edx +c010055a: 89 10 mov %edx,(%eax) +} +c010055c: 90 nop +c010055d: 89 ec mov %ebp,%esp +c010055f: 5d pop %ebp +c0100560: c3 ret + +c0100561 : + * the specified instruction address, @addr. Returns 0 if information + * was found, and negative if not. But even if it returns negative it + * has stored some information into '*info'. + * */ +int +debuginfo_eip(uintptr_t addr, struct eipdebuginfo *info) { +c0100561: 55 push %ebp +c0100562: 89 e5 mov %esp,%ebp +c0100564: 83 ec 58 sub $0x58,%esp + const struct stab *stabs, *stab_end; + const char *stabstr, *stabstr_end; + + info->eip_file = ""; +c0100567: 8b 45 0c mov 0xc(%ebp),%eax +c010056a: c7 00 4c 61 10 c0 movl $0xc010614c,(%eax) + info->eip_line = 0; +c0100570: 8b 45 0c mov 0xc(%ebp),%eax +c0100573: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) + info->eip_fn_name = ""; +c010057a: 8b 45 0c mov 0xc(%ebp),%eax +c010057d: c7 40 08 4c 61 10 c0 movl $0xc010614c,0x8(%eax) + info->eip_fn_namelen = 9; +c0100584: 8b 45 0c mov 0xc(%ebp),%eax +c0100587: c7 40 0c 09 00 00 00 movl $0x9,0xc(%eax) + info->eip_fn_addr = addr; +c010058e: 8b 45 0c mov 0xc(%ebp),%eax +c0100591: 8b 55 08 mov 0x8(%ebp),%edx +c0100594: 89 50 10 mov %edx,0x10(%eax) + info->eip_fn_narg = 0; +c0100597: 8b 45 0c mov 0xc(%ebp),%eax +c010059a: c7 40 14 00 00 00 00 movl $0x0,0x14(%eax) + + stabs = __STAB_BEGIN__; +c01005a1: c7 45 f4 b8 73 10 c0 movl $0xc01073b8,-0xc(%ebp) + stab_end = __STAB_END__; +c01005a8: c7 45 f0 ac 2a 11 c0 movl $0xc0112aac,-0x10(%ebp) + stabstr = __STABSTR_BEGIN__; +c01005af: c7 45 ec ad 2a 11 c0 movl $0xc0112aad,-0x14(%ebp) + stabstr_end = __STABSTR_END__; +c01005b6: c7 45 e8 44 60 11 c0 movl $0xc0116044,-0x18(%ebp) + + // String table validity checks + if (stabstr_end <= stabstr || stabstr_end[-1] != 0) { +c01005bd: 8b 45 e8 mov -0x18(%ebp),%eax +c01005c0: 3b 45 ec cmp -0x14(%ebp),%eax +c01005c3: 76 0b jbe c01005d0 +c01005c5: 8b 45 e8 mov -0x18(%ebp),%eax +c01005c8: 48 dec %eax +c01005c9: 0f b6 00 movzbl (%eax),%eax +c01005cc: 84 c0 test %al,%al +c01005ce: 74 0a je c01005da + return -1; +c01005d0: b8 ff ff ff ff mov $0xffffffff,%eax +c01005d5: e9 ab 02 00 00 jmp c0100885 + // 'eip'. First, we find the basic source file containing 'eip'. + // Then, we look in that source file for the function. Then we look + // for the line number. + + // Search the entire set of stabs for the source file (type N_SO). + int lfile = 0, rfile = (stab_end - stabs) - 1; +c01005da: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) +c01005e1: 8b 45 f0 mov -0x10(%ebp),%eax +c01005e4: 2b 45 f4 sub -0xc(%ebp),%eax +c01005e7: c1 f8 02 sar $0x2,%eax +c01005ea: 69 c0 ab aa aa aa imul $0xaaaaaaab,%eax,%eax +c01005f0: 48 dec %eax +c01005f1: 89 45 e0 mov %eax,-0x20(%ebp) + stab_binsearch(stabs, &lfile, &rfile, N_SO, addr); +c01005f4: 8b 45 08 mov 0x8(%ebp),%eax +c01005f7: 89 44 24 10 mov %eax,0x10(%esp) +c01005fb: c7 44 24 0c 64 00 00 movl $0x64,0xc(%esp) +c0100602: 00 +c0100603: 8d 45 e0 lea -0x20(%ebp),%eax +c0100606: 89 44 24 08 mov %eax,0x8(%esp) +c010060a: 8d 45 e4 lea -0x1c(%ebp),%eax +c010060d: 89 44 24 04 mov %eax,0x4(%esp) +c0100611: 8b 45 f4 mov -0xc(%ebp),%eax +c0100614: 89 04 24 mov %eax,(%esp) +c0100617: e8 f5 fd ff ff call c0100411 + if (lfile == 0) +c010061c: 8b 45 e4 mov -0x1c(%ebp),%eax +c010061f: 85 c0 test %eax,%eax +c0100621: 75 0a jne c010062d + return -1; +c0100623: b8 ff ff ff ff mov $0xffffffff,%eax +c0100628: e9 58 02 00 00 jmp c0100885 + + // Search within that file's stabs for the function definition + // (N_FUN). + int lfun = lfile, rfun = rfile; +c010062d: 8b 45 e4 mov -0x1c(%ebp),%eax +c0100630: 89 45 dc mov %eax,-0x24(%ebp) +c0100633: 8b 45 e0 mov -0x20(%ebp),%eax +c0100636: 89 45 d8 mov %eax,-0x28(%ebp) + int lline, rline; + stab_binsearch(stabs, &lfun, &rfun, N_FUN, addr); +c0100639: 8b 45 08 mov 0x8(%ebp),%eax +c010063c: 89 44 24 10 mov %eax,0x10(%esp) +c0100640: c7 44 24 0c 24 00 00 movl $0x24,0xc(%esp) +c0100647: 00 +c0100648: 8d 45 d8 lea -0x28(%ebp),%eax +c010064b: 89 44 24 08 mov %eax,0x8(%esp) +c010064f: 8d 45 dc lea -0x24(%ebp),%eax +c0100652: 89 44 24 04 mov %eax,0x4(%esp) +c0100656: 8b 45 f4 mov -0xc(%ebp),%eax +c0100659: 89 04 24 mov %eax,(%esp) +c010065c: e8 b0 fd ff ff call c0100411 + + if (lfun <= rfun) { +c0100661: 8b 55 dc mov -0x24(%ebp),%edx +c0100664: 8b 45 d8 mov -0x28(%ebp),%eax +c0100667: 39 c2 cmp %eax,%edx +c0100669: 7f 78 jg c01006e3 + // stabs[lfun] points to the function name + // in the string table, but check bounds just in case. + if (stabs[lfun].n_strx < stabstr_end - stabstr) { +c010066b: 8b 45 dc mov -0x24(%ebp),%eax +c010066e: 89 c2 mov %eax,%edx +c0100670: 89 d0 mov %edx,%eax +c0100672: 01 c0 add %eax,%eax +c0100674: 01 d0 add %edx,%eax +c0100676: c1 e0 02 shl $0x2,%eax +c0100679: 89 c2 mov %eax,%edx +c010067b: 8b 45 f4 mov -0xc(%ebp),%eax +c010067e: 01 d0 add %edx,%eax +c0100680: 8b 10 mov (%eax),%edx +c0100682: 8b 45 e8 mov -0x18(%ebp),%eax +c0100685: 2b 45 ec sub -0x14(%ebp),%eax +c0100688: 39 c2 cmp %eax,%edx +c010068a: 73 22 jae c01006ae + info->eip_fn_name = stabstr + stabs[lfun].n_strx; +c010068c: 8b 45 dc mov -0x24(%ebp),%eax +c010068f: 89 c2 mov %eax,%edx +c0100691: 89 d0 mov %edx,%eax +c0100693: 01 c0 add %eax,%eax +c0100695: 01 d0 add %edx,%eax +c0100697: c1 e0 02 shl $0x2,%eax +c010069a: 89 c2 mov %eax,%edx +c010069c: 8b 45 f4 mov -0xc(%ebp),%eax +c010069f: 01 d0 add %edx,%eax +c01006a1: 8b 10 mov (%eax),%edx +c01006a3: 8b 45 ec mov -0x14(%ebp),%eax +c01006a6: 01 c2 add %eax,%edx +c01006a8: 8b 45 0c mov 0xc(%ebp),%eax +c01006ab: 89 50 08 mov %edx,0x8(%eax) + } + info->eip_fn_addr = stabs[lfun].n_value; +c01006ae: 8b 45 dc mov -0x24(%ebp),%eax +c01006b1: 89 c2 mov %eax,%edx +c01006b3: 89 d0 mov %edx,%eax +c01006b5: 01 c0 add %eax,%eax +c01006b7: 01 d0 add %edx,%eax +c01006b9: c1 e0 02 shl $0x2,%eax +c01006bc: 89 c2 mov %eax,%edx +c01006be: 8b 45 f4 mov -0xc(%ebp),%eax +c01006c1: 01 d0 add %edx,%eax +c01006c3: 8b 50 08 mov 0x8(%eax),%edx +c01006c6: 8b 45 0c mov 0xc(%ebp),%eax +c01006c9: 89 50 10 mov %edx,0x10(%eax) + addr -= info->eip_fn_addr; +c01006cc: 8b 45 0c mov 0xc(%ebp),%eax +c01006cf: 8b 40 10 mov 0x10(%eax),%eax +c01006d2: 29 45 08 sub %eax,0x8(%ebp) + // Search within the function definition for the line number. + lline = lfun; +c01006d5: 8b 45 dc mov -0x24(%ebp),%eax +c01006d8: 89 45 d4 mov %eax,-0x2c(%ebp) + rline = rfun; +c01006db: 8b 45 d8 mov -0x28(%ebp),%eax +c01006de: 89 45 d0 mov %eax,-0x30(%ebp) +c01006e1: eb 15 jmp c01006f8 + } else { + // Couldn't find function stab! Maybe we're in an assembly + // file. Search the whole file for the line number. + info->eip_fn_addr = addr; +c01006e3: 8b 45 0c mov 0xc(%ebp),%eax +c01006e6: 8b 55 08 mov 0x8(%ebp),%edx +c01006e9: 89 50 10 mov %edx,0x10(%eax) + lline = lfile; +c01006ec: 8b 45 e4 mov -0x1c(%ebp),%eax +c01006ef: 89 45 d4 mov %eax,-0x2c(%ebp) + rline = rfile; +c01006f2: 8b 45 e0 mov -0x20(%ebp),%eax +c01006f5: 89 45 d0 mov %eax,-0x30(%ebp) + } + info->eip_fn_namelen = strfind(info->eip_fn_name, ':') - info->eip_fn_name; +c01006f8: 8b 45 0c mov 0xc(%ebp),%eax +c01006fb: 8b 40 08 mov 0x8(%eax),%eax +c01006fe: c7 44 24 04 3a 00 00 movl $0x3a,0x4(%esp) +c0100705: 00 +c0100706: 89 04 24 mov %eax,(%esp) +c0100709: e8 72 56 00 00 call c0105d80 +c010070e: 8b 55 0c mov 0xc(%ebp),%edx +c0100711: 8b 4a 08 mov 0x8(%edx),%ecx +c0100714: 29 c8 sub %ecx,%eax +c0100716: 89 c2 mov %eax,%edx +c0100718: 8b 45 0c mov 0xc(%ebp),%eax +c010071b: 89 50 0c mov %edx,0xc(%eax) + + // Search within [lline, rline] for the line number stab. + // If found, set info->eip_line to the right line number. + // If not found, return -1. + stab_binsearch(stabs, &lline, &rline, N_SLINE, addr); +c010071e: 8b 45 08 mov 0x8(%ebp),%eax +c0100721: 89 44 24 10 mov %eax,0x10(%esp) +c0100725: c7 44 24 0c 44 00 00 movl $0x44,0xc(%esp) +c010072c: 00 +c010072d: 8d 45 d0 lea -0x30(%ebp),%eax +c0100730: 89 44 24 08 mov %eax,0x8(%esp) +c0100734: 8d 45 d4 lea -0x2c(%ebp),%eax +c0100737: 89 44 24 04 mov %eax,0x4(%esp) +c010073b: 8b 45 f4 mov -0xc(%ebp),%eax +c010073e: 89 04 24 mov %eax,(%esp) +c0100741: e8 cb fc ff ff call c0100411 + if (lline <= rline) { +c0100746: 8b 55 d4 mov -0x2c(%ebp),%edx +c0100749: 8b 45 d0 mov -0x30(%ebp),%eax +c010074c: 39 c2 cmp %eax,%edx +c010074e: 7f 23 jg c0100773 + info->eip_line = stabs[rline].n_desc; +c0100750: 8b 45 d0 mov -0x30(%ebp),%eax +c0100753: 89 c2 mov %eax,%edx +c0100755: 89 d0 mov %edx,%eax +c0100757: 01 c0 add %eax,%eax +c0100759: 01 d0 add %edx,%eax +c010075b: c1 e0 02 shl $0x2,%eax +c010075e: 89 c2 mov %eax,%edx +c0100760: 8b 45 f4 mov -0xc(%ebp),%eax +c0100763: 01 d0 add %edx,%eax +c0100765: 0f b7 40 06 movzwl 0x6(%eax),%eax +c0100769: 89 c2 mov %eax,%edx +c010076b: 8b 45 0c mov 0xc(%ebp),%eax +c010076e: 89 50 04 mov %edx,0x4(%eax) + + // Search backwards from the line number for the relevant filename stab. + // We can't just use the "lfile" stab because inlined functions + // can interpolate code from a different file! + // Such included source files use the N_SOL stab type. + while (lline >= lfile +c0100771: eb 11 jmp c0100784 + return -1; +c0100773: b8 ff ff ff ff mov $0xffffffff,%eax +c0100778: e9 08 01 00 00 jmp c0100885 + && stabs[lline].n_type != N_SOL + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { + lline --; +c010077d: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100780: 48 dec %eax +c0100781: 89 45 d4 mov %eax,-0x2c(%ebp) + while (lline >= lfile +c0100784: 8b 55 d4 mov -0x2c(%ebp),%edx +c0100787: 8b 45 e4 mov -0x1c(%ebp),%eax + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { +c010078a: 39 c2 cmp %eax,%edx +c010078c: 7c 56 jl c01007e4 + && stabs[lline].n_type != N_SOL +c010078e: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100791: 89 c2 mov %eax,%edx +c0100793: 89 d0 mov %edx,%eax +c0100795: 01 c0 add %eax,%eax +c0100797: 01 d0 add %edx,%eax +c0100799: c1 e0 02 shl $0x2,%eax +c010079c: 89 c2 mov %eax,%edx +c010079e: 8b 45 f4 mov -0xc(%ebp),%eax +c01007a1: 01 d0 add %edx,%eax +c01007a3: 0f b6 40 04 movzbl 0x4(%eax),%eax +c01007a7: 3c 84 cmp $0x84,%al +c01007a9: 74 39 je c01007e4 + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { +c01007ab: 8b 45 d4 mov -0x2c(%ebp),%eax +c01007ae: 89 c2 mov %eax,%edx +c01007b0: 89 d0 mov %edx,%eax +c01007b2: 01 c0 add %eax,%eax +c01007b4: 01 d0 add %edx,%eax +c01007b6: c1 e0 02 shl $0x2,%eax +c01007b9: 89 c2 mov %eax,%edx +c01007bb: 8b 45 f4 mov -0xc(%ebp),%eax +c01007be: 01 d0 add %edx,%eax +c01007c0: 0f b6 40 04 movzbl 0x4(%eax),%eax +c01007c4: 3c 64 cmp $0x64,%al +c01007c6: 75 b5 jne c010077d +c01007c8: 8b 45 d4 mov -0x2c(%ebp),%eax +c01007cb: 89 c2 mov %eax,%edx +c01007cd: 89 d0 mov %edx,%eax +c01007cf: 01 c0 add %eax,%eax +c01007d1: 01 d0 add %edx,%eax +c01007d3: c1 e0 02 shl $0x2,%eax +c01007d6: 89 c2 mov %eax,%edx +c01007d8: 8b 45 f4 mov -0xc(%ebp),%eax +c01007db: 01 d0 add %edx,%eax +c01007dd: 8b 40 08 mov 0x8(%eax),%eax +c01007e0: 85 c0 test %eax,%eax +c01007e2: 74 99 je c010077d + } + if (lline >= lfile && stabs[lline].n_strx < stabstr_end - stabstr) { +c01007e4: 8b 55 d4 mov -0x2c(%ebp),%edx +c01007e7: 8b 45 e4 mov -0x1c(%ebp),%eax +c01007ea: 39 c2 cmp %eax,%edx +c01007ec: 7c 42 jl c0100830 +c01007ee: 8b 45 d4 mov -0x2c(%ebp),%eax +c01007f1: 89 c2 mov %eax,%edx +c01007f3: 89 d0 mov %edx,%eax +c01007f5: 01 c0 add %eax,%eax +c01007f7: 01 d0 add %edx,%eax +c01007f9: c1 e0 02 shl $0x2,%eax +c01007fc: 89 c2 mov %eax,%edx +c01007fe: 8b 45 f4 mov -0xc(%ebp),%eax +c0100801: 01 d0 add %edx,%eax +c0100803: 8b 10 mov (%eax),%edx +c0100805: 8b 45 e8 mov -0x18(%ebp),%eax +c0100808: 2b 45 ec sub -0x14(%ebp),%eax +c010080b: 39 c2 cmp %eax,%edx +c010080d: 73 21 jae c0100830 + info->eip_file = stabstr + stabs[lline].n_strx; +c010080f: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100812: 89 c2 mov %eax,%edx +c0100814: 89 d0 mov %edx,%eax +c0100816: 01 c0 add %eax,%eax +c0100818: 01 d0 add %edx,%eax +c010081a: c1 e0 02 shl $0x2,%eax +c010081d: 89 c2 mov %eax,%edx +c010081f: 8b 45 f4 mov -0xc(%ebp),%eax +c0100822: 01 d0 add %edx,%eax +c0100824: 8b 10 mov (%eax),%edx +c0100826: 8b 45 ec mov -0x14(%ebp),%eax +c0100829: 01 c2 add %eax,%edx +c010082b: 8b 45 0c mov 0xc(%ebp),%eax +c010082e: 89 10 mov %edx,(%eax) + } + + // Set eip_fn_narg to the number of arguments taken by the function, + // or 0 if there was no containing function. + if (lfun < rfun) { +c0100830: 8b 55 dc mov -0x24(%ebp),%edx +c0100833: 8b 45 d8 mov -0x28(%ebp),%eax +c0100836: 39 c2 cmp %eax,%edx +c0100838: 7d 46 jge c0100880 + for (lline = lfun + 1; +c010083a: 8b 45 dc mov -0x24(%ebp),%eax +c010083d: 40 inc %eax +c010083e: 89 45 d4 mov %eax,-0x2c(%ebp) +c0100841: eb 16 jmp c0100859 + lline < rfun && stabs[lline].n_type == N_PSYM; + lline ++) { + info->eip_fn_narg ++; +c0100843: 8b 45 0c mov 0xc(%ebp),%eax +c0100846: 8b 40 14 mov 0x14(%eax),%eax +c0100849: 8d 50 01 lea 0x1(%eax),%edx +c010084c: 8b 45 0c mov 0xc(%ebp),%eax +c010084f: 89 50 14 mov %edx,0x14(%eax) + lline ++) { +c0100852: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100855: 40 inc %eax +c0100856: 89 45 d4 mov %eax,-0x2c(%ebp) + lline < rfun && stabs[lline].n_type == N_PSYM; +c0100859: 8b 55 d4 mov -0x2c(%ebp),%edx +c010085c: 8b 45 d8 mov -0x28(%ebp),%eax +c010085f: 39 c2 cmp %eax,%edx +c0100861: 7d 1d jge c0100880 +c0100863: 8b 45 d4 mov -0x2c(%ebp),%eax +c0100866: 89 c2 mov %eax,%edx +c0100868: 89 d0 mov %edx,%eax +c010086a: 01 c0 add %eax,%eax +c010086c: 01 d0 add %edx,%eax +c010086e: c1 e0 02 shl $0x2,%eax +c0100871: 89 c2 mov %eax,%edx +c0100873: 8b 45 f4 mov -0xc(%ebp),%eax +c0100876: 01 d0 add %edx,%eax +c0100878: 0f b6 40 04 movzbl 0x4(%eax),%eax +c010087c: 3c a0 cmp $0xa0,%al +c010087e: 74 c3 je c0100843 + } + } + return 0; +c0100880: b8 00 00 00 00 mov $0x0,%eax +} +c0100885: 89 ec mov %ebp,%esp +c0100887: 5d pop %ebp +c0100888: c3 ret + +c0100889 : + * print_kerninfo - print the information about kernel, including the location + * of kernel entry, the start addresses of data and text segements, the start + * address of free memory and how many memory that kernel has used. + * */ +void +print_kerninfo(void) { +c0100889: 55 push %ebp +c010088a: 89 e5 mov %esp,%ebp +c010088c: 83 ec 18 sub $0x18,%esp + extern char etext[], edata[], end[], kern_init[]; + cprintf("Special kernel symbols:\n"); +c010088f: c7 04 24 56 61 10 c0 movl $0xc0106156,(%esp) +c0100896: e8 cb fa ff ff call c0100366 + cprintf(" entry 0x%08x (phys)\n", kern_init); +c010089b: c7 44 24 04 36 00 10 movl $0xc0100036,0x4(%esp) +c01008a2: c0 +c01008a3: c7 04 24 6f 61 10 c0 movl $0xc010616f,(%esp) +c01008aa: e8 b7 fa ff ff call c0100366 + cprintf(" etext 0x%08x (phys)\n", etext); +c01008af: c7 44 24 04 94 60 10 movl $0xc0106094,0x4(%esp) +c01008b6: c0 +c01008b7: c7 04 24 87 61 10 c0 movl $0xc0106187,(%esp) +c01008be: e8 a3 fa ff ff call c0100366 + cprintf(" edata 0x%08x (phys)\n", edata); +c01008c3: c7 44 24 04 00 c0 11 movl $0xc011c000,0x4(%esp) +c01008ca: c0 +c01008cb: c7 04 24 9f 61 10 c0 movl $0xc010619f,(%esp) +c01008d2: e8 8f fa ff ff call c0100366 + cprintf(" end 0x%08x (phys)\n", end); +c01008d7: c7 44 24 04 8c cf 11 movl $0xc011cf8c,0x4(%esp) +c01008de: c0 +c01008df: c7 04 24 b7 61 10 c0 movl $0xc01061b7,(%esp) +c01008e6: e8 7b fa ff ff call c0100366 + cprintf("Kernel executable memory footprint: %dKB\n", (end - kern_init + 1023)/1024); +c01008eb: b8 8c cf 11 c0 mov $0xc011cf8c,%eax +c01008f0: 2d 36 00 10 c0 sub $0xc0100036,%eax +c01008f5: 05 ff 03 00 00 add $0x3ff,%eax +c01008fa: 8d 90 ff 03 00 00 lea 0x3ff(%eax),%edx +c0100900: 85 c0 test %eax,%eax +c0100902: 0f 48 c2 cmovs %edx,%eax +c0100905: c1 f8 0a sar $0xa,%eax +c0100908: 89 44 24 04 mov %eax,0x4(%esp) +c010090c: c7 04 24 d0 61 10 c0 movl $0xc01061d0,(%esp) +c0100913: e8 4e fa ff ff call c0100366 +} +c0100918: 90 nop +c0100919: 89 ec mov %ebp,%esp +c010091b: 5d pop %ebp +c010091c: c3 ret + +c010091d : +/* * + * print_debuginfo - read and print the stat information for the address @eip, + * and info.eip_fn_addr should be the first address of the related function. + * */ +void +print_debuginfo(uintptr_t eip) { +c010091d: 55 push %ebp +c010091e: 89 e5 mov %esp,%ebp +c0100920: 81 ec 48 01 00 00 sub $0x148,%esp + struct eipdebuginfo info; + if (debuginfo_eip(eip, &info) != 0) { +c0100926: 8d 45 dc lea -0x24(%ebp),%eax +c0100929: 89 44 24 04 mov %eax,0x4(%esp) +c010092d: 8b 45 08 mov 0x8(%ebp),%eax +c0100930: 89 04 24 mov %eax,(%esp) +c0100933: e8 29 fc ff ff call c0100561 +c0100938: 85 c0 test %eax,%eax +c010093a: 74 15 je c0100951 + cprintf(" : -- 0x%08x --\n", eip); +c010093c: 8b 45 08 mov 0x8(%ebp),%eax +c010093f: 89 44 24 04 mov %eax,0x4(%esp) +c0100943: c7 04 24 fa 61 10 c0 movl $0xc01061fa,(%esp) +c010094a: e8 17 fa ff ff call c0100366 + } + fnname[j] = '\0'; + cprintf(" %s:%d: %s+%d\n", info.eip_file, info.eip_line, + fnname, eip - info.eip_fn_addr); + } +} +c010094f: eb 6c jmp c01009bd + for (j = 0; j < info.eip_fn_namelen; j ++) { +c0100951: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0100958: eb 1b jmp c0100975 + fnname[j] = info.eip_fn_name[j]; +c010095a: 8b 55 e4 mov -0x1c(%ebp),%edx +c010095d: 8b 45 f4 mov -0xc(%ebp),%eax +c0100960: 01 d0 add %edx,%eax +c0100962: 0f b6 10 movzbl (%eax),%edx +c0100965: 8d 8d dc fe ff ff lea -0x124(%ebp),%ecx +c010096b: 8b 45 f4 mov -0xc(%ebp),%eax +c010096e: 01 c8 add %ecx,%eax +c0100970: 88 10 mov %dl,(%eax) + for (j = 0; j < info.eip_fn_namelen; j ++) { +c0100972: ff 45 f4 incl -0xc(%ebp) +c0100975: 8b 45 e8 mov -0x18(%ebp),%eax +c0100978: 39 45 f4 cmp %eax,-0xc(%ebp) +c010097b: 7c dd jl c010095a + fnname[j] = '\0'; +c010097d: 8d 95 dc fe ff ff lea -0x124(%ebp),%edx +c0100983: 8b 45 f4 mov -0xc(%ebp),%eax +c0100986: 01 d0 add %edx,%eax +c0100988: c6 00 00 movb $0x0,(%eax) + fnname, eip - info.eip_fn_addr); +c010098b: 8b 55 ec mov -0x14(%ebp),%edx + cprintf(" %s:%d: %s+%d\n", info.eip_file, info.eip_line, +c010098e: 8b 45 08 mov 0x8(%ebp),%eax +c0100991: 29 d0 sub %edx,%eax +c0100993: 89 c1 mov %eax,%ecx +c0100995: 8b 55 e0 mov -0x20(%ebp),%edx +c0100998: 8b 45 dc mov -0x24(%ebp),%eax +c010099b: 89 4c 24 10 mov %ecx,0x10(%esp) +c010099f: 8d 8d dc fe ff ff lea -0x124(%ebp),%ecx +c01009a5: 89 4c 24 0c mov %ecx,0xc(%esp) +c01009a9: 89 54 24 08 mov %edx,0x8(%esp) +c01009ad: 89 44 24 04 mov %eax,0x4(%esp) +c01009b1: c7 04 24 16 62 10 c0 movl $0xc0106216,(%esp) +c01009b8: e8 a9 f9 ff ff call c0100366 +} +c01009bd: 90 nop +c01009be: 89 ec mov %ebp,%esp +c01009c0: 5d pop %ebp +c01009c1: c3 ret + +c01009c2 : + +static __noinline uint32_t +read_eip(void) { +c01009c2: 55 push %ebp +c01009c3: 89 e5 mov %esp,%ebp +c01009c5: 83 ec 10 sub $0x10,%esp + uint32_t eip; + asm volatile("movl 4(%%ebp), %0" : "=r" (eip)); +c01009c8: 8b 45 04 mov 0x4(%ebp),%eax +c01009cb: 89 45 fc mov %eax,-0x4(%ebp) + return eip; +c01009ce: 8b 45 fc mov -0x4(%ebp),%eax +} +c01009d1: 89 ec mov %ebp,%esp +c01009d3: 5d pop %ebp +c01009d4: c3 ret + +c01009d5 : + * + * Note that, the length of ebp-chain is limited. In boot/bootasm.S, before jumping + * to the kernel entry, the value of ebp has been set to zero, that's the boundary. + * */ +void +print_stackframe(void) { +c01009d5: 55 push %ebp +c01009d6: 89 e5 mov %esp,%ebp + * (3.4) call print_debuginfo(eip-1) to print the C calling function name and line number, etc. + * (3.5) popup a calling stackframe + * NOTICE: the calling funciton's return addr eip = ss:[ebp+4] + * the calling funciton's ebp = ss:[ebp] + */ +} +c01009d8: 90 nop +c01009d9: 5d pop %ebp +c01009da: c3 ret + +c01009db : +#define MAXARGS 16 +#define WHITESPACE " \t\n\r" + +/* parse - parse the command buffer into whitespace-separated arguments */ +static int +parse(char *buf, char **argv) { +c01009db: 55 push %ebp +c01009dc: 89 e5 mov %esp,%ebp +c01009de: 83 ec 28 sub $0x28,%esp + int argc = 0; +c01009e1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + while (1) { + // find global whitespace + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { +c01009e8: eb 0c jmp c01009f6 + *buf ++ = '\0'; +c01009ea: 8b 45 08 mov 0x8(%ebp),%eax +c01009ed: 8d 50 01 lea 0x1(%eax),%edx +c01009f0: 89 55 08 mov %edx,0x8(%ebp) +c01009f3: c6 00 00 movb $0x0,(%eax) + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { +c01009f6: 8b 45 08 mov 0x8(%ebp),%eax +c01009f9: 0f b6 00 movzbl (%eax),%eax +c01009fc: 84 c0 test %al,%al +c01009fe: 74 1d je c0100a1d +c0100a00: 8b 45 08 mov 0x8(%ebp),%eax +c0100a03: 0f b6 00 movzbl (%eax),%eax +c0100a06: 0f be c0 movsbl %al,%eax +c0100a09: 89 44 24 04 mov %eax,0x4(%esp) +c0100a0d: c7 04 24 a8 62 10 c0 movl $0xc01062a8,(%esp) +c0100a14: e8 33 53 00 00 call c0105d4c +c0100a19: 85 c0 test %eax,%eax +c0100a1b: 75 cd jne c01009ea + } + if (*buf == '\0') { +c0100a1d: 8b 45 08 mov 0x8(%ebp),%eax +c0100a20: 0f b6 00 movzbl (%eax),%eax +c0100a23: 84 c0 test %al,%al +c0100a25: 74 65 je c0100a8c + break; + } + + // save and scan past next arg + if (argc == MAXARGS - 1) { +c0100a27: 83 7d f4 0f cmpl $0xf,-0xc(%ebp) +c0100a2b: 75 14 jne c0100a41 + cprintf("Too many arguments (max %d).\n", MAXARGS); +c0100a2d: c7 44 24 04 10 00 00 movl $0x10,0x4(%esp) +c0100a34: 00 +c0100a35: c7 04 24 ad 62 10 c0 movl $0xc01062ad,(%esp) +c0100a3c: e8 25 f9 ff ff call c0100366 + } + argv[argc ++] = buf; +c0100a41: 8b 45 f4 mov -0xc(%ebp),%eax +c0100a44: 8d 50 01 lea 0x1(%eax),%edx +c0100a47: 89 55 f4 mov %edx,-0xc(%ebp) +c0100a4a: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0100a51: 8b 45 0c mov 0xc(%ebp),%eax +c0100a54: 01 c2 add %eax,%edx +c0100a56: 8b 45 08 mov 0x8(%ebp),%eax +c0100a59: 89 02 mov %eax,(%edx) + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { +c0100a5b: eb 03 jmp c0100a60 + buf ++; +c0100a5d: ff 45 08 incl 0x8(%ebp) + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { +c0100a60: 8b 45 08 mov 0x8(%ebp),%eax +c0100a63: 0f b6 00 movzbl (%eax),%eax +c0100a66: 84 c0 test %al,%al +c0100a68: 74 8c je c01009f6 +c0100a6a: 8b 45 08 mov 0x8(%ebp),%eax +c0100a6d: 0f b6 00 movzbl (%eax),%eax +c0100a70: 0f be c0 movsbl %al,%eax +c0100a73: 89 44 24 04 mov %eax,0x4(%esp) +c0100a77: c7 04 24 a8 62 10 c0 movl $0xc01062a8,(%esp) +c0100a7e: e8 c9 52 00 00 call c0105d4c +c0100a83: 85 c0 test %eax,%eax +c0100a85: 74 d6 je c0100a5d + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { +c0100a87: e9 6a ff ff ff jmp c01009f6 + break; +c0100a8c: 90 nop + } + } + return argc; +c0100a8d: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0100a90: 89 ec mov %ebp,%esp +c0100a92: 5d pop %ebp +c0100a93: c3 ret + +c0100a94 : +/* * + * runcmd - parse the input string, split it into separated arguments + * and then lookup and invoke some related commands/ + * */ +static int +runcmd(char *buf, struct trapframe *tf) { +c0100a94: 55 push %ebp +c0100a95: 89 e5 mov %esp,%ebp +c0100a97: 83 ec 68 sub $0x68,%esp +c0100a9a: 89 5d fc mov %ebx,-0x4(%ebp) + char *argv[MAXARGS]; + int argc = parse(buf, argv); +c0100a9d: 8d 45 b0 lea -0x50(%ebp),%eax +c0100aa0: 89 44 24 04 mov %eax,0x4(%esp) +c0100aa4: 8b 45 08 mov 0x8(%ebp),%eax +c0100aa7: 89 04 24 mov %eax,(%esp) +c0100aaa: e8 2c ff ff ff call c01009db +c0100aaf: 89 45 f0 mov %eax,-0x10(%ebp) + if (argc == 0) { +c0100ab2: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0100ab6: 75 0a jne c0100ac2 + return 0; +c0100ab8: b8 00 00 00 00 mov $0x0,%eax +c0100abd: e9 83 00 00 00 jmp c0100b45 + } + int i; + for (i = 0; i < NCOMMANDS; i ++) { +c0100ac2: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0100ac9: eb 5a jmp c0100b25 + if (strcmp(commands[i].name, argv[0]) == 0) { +c0100acb: 8b 55 b0 mov -0x50(%ebp),%edx +c0100ace: 8b 4d f4 mov -0xc(%ebp),%ecx +c0100ad1: 89 c8 mov %ecx,%eax +c0100ad3: 01 c0 add %eax,%eax +c0100ad5: 01 c8 add %ecx,%eax +c0100ad7: c1 e0 02 shl $0x2,%eax +c0100ada: 05 00 90 11 c0 add $0xc0119000,%eax +c0100adf: 8b 00 mov (%eax),%eax +c0100ae1: 89 54 24 04 mov %edx,0x4(%esp) +c0100ae5: 89 04 24 mov %eax,(%esp) +c0100ae8: e8 c3 51 00 00 call c0105cb0 +c0100aed: 85 c0 test %eax,%eax +c0100aef: 75 31 jne c0100b22 + return commands[i].func(argc - 1, argv + 1, tf); +c0100af1: 8b 55 f4 mov -0xc(%ebp),%edx +c0100af4: 89 d0 mov %edx,%eax +c0100af6: 01 c0 add %eax,%eax +c0100af8: 01 d0 add %edx,%eax +c0100afa: c1 e0 02 shl $0x2,%eax +c0100afd: 05 08 90 11 c0 add $0xc0119008,%eax +c0100b02: 8b 10 mov (%eax),%edx +c0100b04: 8d 45 b0 lea -0x50(%ebp),%eax +c0100b07: 83 c0 04 add $0x4,%eax +c0100b0a: 8b 4d f0 mov -0x10(%ebp),%ecx +c0100b0d: 8d 59 ff lea -0x1(%ecx),%ebx +c0100b10: 8b 4d 0c mov 0xc(%ebp),%ecx +c0100b13: 89 4c 24 08 mov %ecx,0x8(%esp) +c0100b17: 89 44 24 04 mov %eax,0x4(%esp) +c0100b1b: 89 1c 24 mov %ebx,(%esp) +c0100b1e: ff d2 call *%edx +c0100b20: eb 23 jmp c0100b45 + for (i = 0; i < NCOMMANDS; i ++) { +c0100b22: ff 45 f4 incl -0xc(%ebp) +c0100b25: 8b 45 f4 mov -0xc(%ebp),%eax +c0100b28: 83 f8 02 cmp $0x2,%eax +c0100b2b: 76 9e jbe c0100acb + } + } + cprintf("Unknown command '%s'\n", argv[0]); +c0100b2d: 8b 45 b0 mov -0x50(%ebp),%eax +c0100b30: 89 44 24 04 mov %eax,0x4(%esp) +c0100b34: c7 04 24 cb 62 10 c0 movl $0xc01062cb,(%esp) +c0100b3b: e8 26 f8 ff ff call c0100366 + return 0; +c0100b40: b8 00 00 00 00 mov $0x0,%eax +} +c0100b45: 8b 5d fc mov -0x4(%ebp),%ebx +c0100b48: 89 ec mov %ebp,%esp +c0100b4a: 5d pop %ebp +c0100b4b: c3 ret + +c0100b4c : + +/***** Implementations of basic kernel monitor commands *****/ + +void +kmonitor(struct trapframe *tf) { +c0100b4c: 55 push %ebp +c0100b4d: 89 e5 mov %esp,%ebp +c0100b4f: 83 ec 28 sub $0x28,%esp + cprintf("Welcome to the kernel debug monitor!!\n"); +c0100b52: c7 04 24 e4 62 10 c0 movl $0xc01062e4,(%esp) +c0100b59: e8 08 f8 ff ff call c0100366 + cprintf("Type 'help' for a list of commands.\n"); +c0100b5e: c7 04 24 0c 63 10 c0 movl $0xc010630c,(%esp) +c0100b65: e8 fc f7 ff ff call c0100366 + + if (tf != NULL) { +c0100b6a: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0100b6e: 74 0b je c0100b7b + print_trapframe(tf); +c0100b70: 8b 45 08 mov 0x8(%ebp),%eax +c0100b73: 89 04 24 mov %eax,(%esp) +c0100b76: e8 cf 0e 00 00 call c0101a4a + } + + char *buf; + while (1) { + if ((buf = readline("K> ")) != NULL) { +c0100b7b: c7 04 24 31 63 10 c0 movl $0xc0106331,(%esp) +c0100b82: e8 d0 f6 ff ff call c0100257 +c0100b87: 89 45 f4 mov %eax,-0xc(%ebp) +c0100b8a: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0100b8e: 74 eb je c0100b7b + if (runcmd(buf, tf) < 0) { +c0100b90: 8b 45 08 mov 0x8(%ebp),%eax +c0100b93: 89 44 24 04 mov %eax,0x4(%esp) +c0100b97: 8b 45 f4 mov -0xc(%ebp),%eax +c0100b9a: 89 04 24 mov %eax,(%esp) +c0100b9d: e8 f2 fe ff ff call c0100a94 +c0100ba2: 85 c0 test %eax,%eax +c0100ba4: 78 02 js c0100ba8 + if ((buf = readline("K> ")) != NULL) { +c0100ba6: eb d3 jmp c0100b7b + break; +c0100ba8: 90 nop + } + } + } +} +c0100ba9: 90 nop +c0100baa: 89 ec mov %ebp,%esp +c0100bac: 5d pop %ebp +c0100bad: c3 ret + +c0100bae : + +/* mon_help - print the information about mon_* functions */ +int +mon_help(int argc, char **argv, struct trapframe *tf) { +c0100bae: 55 push %ebp +c0100baf: 89 e5 mov %esp,%ebp +c0100bb1: 83 ec 28 sub $0x28,%esp + int i; + for (i = 0; i < NCOMMANDS; i ++) { +c0100bb4: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0100bbb: eb 3d jmp c0100bfa + cprintf("%s - %s\n", commands[i].name, commands[i].desc); +c0100bbd: 8b 55 f4 mov -0xc(%ebp),%edx +c0100bc0: 89 d0 mov %edx,%eax +c0100bc2: 01 c0 add %eax,%eax +c0100bc4: 01 d0 add %edx,%eax +c0100bc6: c1 e0 02 shl $0x2,%eax +c0100bc9: 05 04 90 11 c0 add $0xc0119004,%eax +c0100bce: 8b 10 mov (%eax),%edx +c0100bd0: 8b 4d f4 mov -0xc(%ebp),%ecx +c0100bd3: 89 c8 mov %ecx,%eax +c0100bd5: 01 c0 add %eax,%eax +c0100bd7: 01 c8 add %ecx,%eax +c0100bd9: c1 e0 02 shl $0x2,%eax +c0100bdc: 05 00 90 11 c0 add $0xc0119000,%eax +c0100be1: 8b 00 mov (%eax),%eax +c0100be3: 89 54 24 08 mov %edx,0x8(%esp) +c0100be7: 89 44 24 04 mov %eax,0x4(%esp) +c0100beb: c7 04 24 35 63 10 c0 movl $0xc0106335,(%esp) +c0100bf2: e8 6f f7 ff ff call c0100366 + for (i = 0; i < NCOMMANDS; i ++) { +c0100bf7: ff 45 f4 incl -0xc(%ebp) +c0100bfa: 8b 45 f4 mov -0xc(%ebp),%eax +c0100bfd: 83 f8 02 cmp $0x2,%eax +c0100c00: 76 bb jbe c0100bbd + } + return 0; +c0100c02: b8 00 00 00 00 mov $0x0,%eax +} +c0100c07: 89 ec mov %ebp,%esp +c0100c09: 5d pop %ebp +c0100c0a: c3 ret + +c0100c0b : +/* * + * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to + * print the memory occupancy in kernel. + * */ +int +mon_kerninfo(int argc, char **argv, struct trapframe *tf) { +c0100c0b: 55 push %ebp +c0100c0c: 89 e5 mov %esp,%ebp +c0100c0e: 83 ec 08 sub $0x8,%esp + print_kerninfo(); +c0100c11: e8 73 fc ff ff call c0100889 + return 0; +c0100c16: b8 00 00 00 00 mov $0x0,%eax +} +c0100c1b: 89 ec mov %ebp,%esp +c0100c1d: 5d pop %ebp +c0100c1e: c3 ret + +c0100c1f : +/* * + * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to + * print a backtrace of the stack. + * */ +int +mon_backtrace(int argc, char **argv, struct trapframe *tf) { +c0100c1f: 55 push %ebp +c0100c20: 89 e5 mov %esp,%ebp +c0100c22: 83 ec 08 sub $0x8,%esp + print_stackframe(); +c0100c25: e8 ab fd ff ff call c01009d5 + return 0; +c0100c2a: b8 00 00 00 00 mov $0x0,%eax +} +c0100c2f: 89 ec mov %ebp,%esp +c0100c31: 5d pop %ebp +c0100c32: c3 ret + +c0100c33 <__panic>: +/* * + * __panic - __panic is called on unresolvable fatal errors. it prints + * "panic: 'message'", and then enters the kernel monitor. + * */ +void +__panic(const char *file, int line, const char *fmt, ...) { +c0100c33: 55 push %ebp +c0100c34: 89 e5 mov %esp,%ebp +c0100c36: 83 ec 28 sub $0x28,%esp + if (is_panic) { +c0100c39: a1 20 c4 11 c0 mov 0xc011c420,%eax +c0100c3e: 85 c0 test %eax,%eax +c0100c40: 75 5b jne c0100c9d <__panic+0x6a> + goto panic_dead; + } + is_panic = 1; +c0100c42: c7 05 20 c4 11 c0 01 movl $0x1,0xc011c420 +c0100c49: 00 00 00 + + // print the 'message' + va_list ap; + va_start(ap, fmt); +c0100c4c: 8d 45 14 lea 0x14(%ebp),%eax +c0100c4f: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("kernel panic at %s:%d:\n ", file, line); +c0100c52: 8b 45 0c mov 0xc(%ebp),%eax +c0100c55: 89 44 24 08 mov %eax,0x8(%esp) +c0100c59: 8b 45 08 mov 0x8(%ebp),%eax +c0100c5c: 89 44 24 04 mov %eax,0x4(%esp) +c0100c60: c7 04 24 3e 63 10 c0 movl $0xc010633e,(%esp) +c0100c67: e8 fa f6 ff ff call c0100366 + vcprintf(fmt, ap); +c0100c6c: 8b 45 f4 mov -0xc(%ebp),%eax +c0100c6f: 89 44 24 04 mov %eax,0x4(%esp) +c0100c73: 8b 45 10 mov 0x10(%ebp),%eax +c0100c76: 89 04 24 mov %eax,(%esp) +c0100c79: e8 b3 f6 ff ff call c0100331 + cprintf("\n"); +c0100c7e: c7 04 24 5a 63 10 c0 movl $0xc010635a,(%esp) +c0100c85: e8 dc f6 ff ff call c0100366 + + cprintf("stack trackback:\n"); +c0100c8a: c7 04 24 5c 63 10 c0 movl $0xc010635c,(%esp) +c0100c91: e8 d0 f6 ff ff call c0100366 + print_stackframe(); +c0100c96: e8 3a fd ff ff call c01009d5 +c0100c9b: eb 01 jmp c0100c9e <__panic+0x6b> + goto panic_dead; +c0100c9d: 90 nop + + va_end(ap); + +panic_dead: + intr_disable(); +c0100c9e: e8 e9 09 00 00 call c010168c + while (1) { + kmonitor(NULL); +c0100ca3: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0100caa: e8 9d fe ff ff call c0100b4c +c0100caf: eb f2 jmp c0100ca3 <__panic+0x70> + +c0100cb1 <__warn>: + } +} + +/* __warn - like panic, but don't */ +void +__warn(const char *file, int line, const char *fmt, ...) { +c0100cb1: 55 push %ebp +c0100cb2: 89 e5 mov %esp,%ebp +c0100cb4: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); +c0100cb7: 8d 45 14 lea 0x14(%ebp),%eax +c0100cba: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("kernel warning at %s:%d:\n ", file, line); +c0100cbd: 8b 45 0c mov 0xc(%ebp),%eax +c0100cc0: 89 44 24 08 mov %eax,0x8(%esp) +c0100cc4: 8b 45 08 mov 0x8(%ebp),%eax +c0100cc7: 89 44 24 04 mov %eax,0x4(%esp) +c0100ccb: c7 04 24 6e 63 10 c0 movl $0xc010636e,(%esp) +c0100cd2: e8 8f f6 ff ff call c0100366 + vcprintf(fmt, ap); +c0100cd7: 8b 45 f4 mov -0xc(%ebp),%eax +c0100cda: 89 44 24 04 mov %eax,0x4(%esp) +c0100cde: 8b 45 10 mov 0x10(%ebp),%eax +c0100ce1: 89 04 24 mov %eax,(%esp) +c0100ce4: e8 48 f6 ff ff call c0100331 + cprintf("\n"); +c0100ce9: c7 04 24 5a 63 10 c0 movl $0xc010635a,(%esp) +c0100cf0: e8 71 f6 ff ff call c0100366 + va_end(ap); +} +c0100cf5: 90 nop +c0100cf6: 89 ec mov %ebp,%esp +c0100cf8: 5d pop %ebp +c0100cf9: c3 ret + +c0100cfa : + +bool +is_kernel_panic(void) { +c0100cfa: 55 push %ebp +c0100cfb: 89 e5 mov %esp,%ebp + return is_panic; +c0100cfd: a1 20 c4 11 c0 mov 0xc011c420,%eax +} +c0100d02: 5d pop %ebp +c0100d03: c3 ret + +c0100d04 : +/* * + * clock_init - initialize 8253 clock to interrupt 100 times per second, + * and then enable IRQ_TIMER. + * */ +void +clock_init(void) { +c0100d04: 55 push %ebp +c0100d05: 89 e5 mov %esp,%ebp +c0100d07: 83 ec 28 sub $0x28,%esp +c0100d0a: 66 c7 45 ee 43 00 movw $0x43,-0x12(%ebp) +c0100d10: c6 45 ed 34 movb $0x34,-0x13(%ebp) + : "memory", "cc"); +} + +static inline void +outb(uint16_t port, uint8_t data) { + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100d14: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0100d18: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0100d1c: ee out %al,(%dx) +} +c0100d1d: 90 nop +c0100d1e: 66 c7 45 f2 40 00 movw $0x40,-0xe(%ebp) +c0100d24: c6 45 f1 9c movb $0x9c,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100d28: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0100d2c: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0100d30: ee out %al,(%dx) +} +c0100d31: 90 nop +c0100d32: 66 c7 45 f6 40 00 movw $0x40,-0xa(%ebp) +c0100d38: c6 45 f5 2e movb $0x2e,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100d3c: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c0100d40: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0100d44: ee out %al,(%dx) +} +c0100d45: 90 nop + outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); + outb(IO_TIMER1, TIMER_DIV(100) % 256); + outb(IO_TIMER1, TIMER_DIV(100) / 256); + + // initialize time counter 'ticks' to zero + ticks = 0; +c0100d46: c7 05 24 c4 11 c0 00 movl $0x0,0xc011c424 +c0100d4d: 00 00 00 + + cprintf("++ setup timer interrupts\n"); +c0100d50: c7 04 24 8c 63 10 c0 movl $0xc010638c,(%esp) +c0100d57: e8 0a f6 ff ff call c0100366 + pic_enable(IRQ_TIMER); +c0100d5c: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0100d63: e8 89 09 00 00 call c01016f1 +} +c0100d68: 90 nop +c0100d69: 89 ec mov %ebp,%esp +c0100d6b: 5d pop %ebp +c0100d6c: c3 ret + +c0100d6d <__intr_save>: +#include +#include +#include + +static inline bool +__intr_save(void) { +c0100d6d: 55 push %ebp +c0100d6e: 89 e5 mov %esp,%ebp +c0100d70: 83 ec 18 sub $0x18,%esp +} + +static inline uint32_t +read_eflags(void) { + uint32_t eflags; + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +c0100d73: 9c pushf +c0100d74: 58 pop %eax +c0100d75: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; +c0100d78: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { +c0100d7b: 25 00 02 00 00 and $0x200,%eax +c0100d80: 85 c0 test %eax,%eax +c0100d82: 74 0c je c0100d90 <__intr_save+0x23> + intr_disable(); +c0100d84: e8 03 09 00 00 call c010168c + return 1; +c0100d89: b8 01 00 00 00 mov $0x1,%eax +c0100d8e: eb 05 jmp c0100d95 <__intr_save+0x28> + } + return 0; +c0100d90: b8 00 00 00 00 mov $0x0,%eax +} +c0100d95: 89 ec mov %ebp,%esp +c0100d97: 5d pop %ebp +c0100d98: c3 ret + +c0100d99 <__intr_restore>: + +static inline void +__intr_restore(bool flag) { +c0100d99: 55 push %ebp +c0100d9a: 89 e5 mov %esp,%ebp +c0100d9c: 83 ec 08 sub $0x8,%esp + if (flag) { +c0100d9f: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0100da3: 74 05 je c0100daa <__intr_restore+0x11> + intr_enable(); +c0100da5: e8 da 08 00 00 call c0101684 + } +} +c0100daa: 90 nop +c0100dab: 89 ec mov %ebp,%esp +c0100dad: 5d pop %ebp +c0100dae: c3 ret + +c0100daf : +#include +#include + +/* stupid I/O delay routine necessitated by historical PC design flaws */ +static void +delay(void) { +c0100daf: 55 push %ebp +c0100db0: 89 e5 mov %esp,%ebp +c0100db2: 83 ec 10 sub $0x10,%esp +c0100db5: 66 c7 45 f2 84 00 movw $0x84,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100dbb: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0100dbf: 89 c2 mov %eax,%edx +c0100dc1: ec in (%dx),%al +c0100dc2: 88 45 f1 mov %al,-0xf(%ebp) +c0100dc5: 66 c7 45 f6 84 00 movw $0x84,-0xa(%ebp) +c0100dcb: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c0100dcf: 89 c2 mov %eax,%edx +c0100dd1: ec in (%dx),%al +c0100dd2: 88 45 f5 mov %al,-0xb(%ebp) +c0100dd5: 66 c7 45 fa 84 00 movw $0x84,-0x6(%ebp) +c0100ddb: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c0100ddf: 89 c2 mov %eax,%edx +c0100de1: ec in (%dx),%al +c0100de2: 88 45 f9 mov %al,-0x7(%ebp) +c0100de5: 66 c7 45 fe 84 00 movw $0x84,-0x2(%ebp) +c0100deb: 0f b7 45 fe movzwl -0x2(%ebp),%eax +c0100def: 89 c2 mov %eax,%edx +c0100df1: ec in (%dx),%al +c0100df2: 88 45 fd mov %al,-0x3(%ebp) + inb(0x84); + inb(0x84); + inb(0x84); + inb(0x84); +} +c0100df5: 90 nop +c0100df6: 89 ec mov %ebp,%esp +c0100df8: 5d pop %ebp +c0100df9: c3 ret + +c0100dfa : +static uint16_t addr_6845; + +/* TEXT-mode CGA/VGA display output */ + +static void +cga_init(void) { +c0100dfa: 55 push %ebp +c0100dfb: 89 e5 mov %esp,%ebp +c0100dfd: 83 ec 20 sub $0x20,%esp + volatile uint16_t *cp = (uint16_t *)(CGA_BUF + KERNBASE); +c0100e00: c7 45 fc 00 80 0b c0 movl $0xc00b8000,-0x4(%ebp) + uint16_t was = *cp; +c0100e07: 8b 45 fc mov -0x4(%ebp),%eax +c0100e0a: 0f b7 00 movzwl (%eax),%eax +c0100e0d: 66 89 45 fa mov %ax,-0x6(%ebp) + *cp = (uint16_t) 0xA55A; +c0100e11: 8b 45 fc mov -0x4(%ebp),%eax +c0100e14: 66 c7 00 5a a5 movw $0xa55a,(%eax) + if (*cp != 0xA55A) { +c0100e19: 8b 45 fc mov -0x4(%ebp),%eax +c0100e1c: 0f b7 00 movzwl (%eax),%eax +c0100e1f: 0f b7 c0 movzwl %ax,%eax +c0100e22: 3d 5a a5 00 00 cmp $0xa55a,%eax +c0100e27: 74 12 je c0100e3b + cp = (uint16_t*)(MONO_BUF + KERNBASE); +c0100e29: c7 45 fc 00 00 0b c0 movl $0xc00b0000,-0x4(%ebp) + addr_6845 = MONO_BASE; +c0100e30: 66 c7 05 46 c4 11 c0 movw $0x3b4,0xc011c446 +c0100e37: b4 03 +c0100e39: eb 13 jmp c0100e4e + } else { + *cp = was; +c0100e3b: 8b 45 fc mov -0x4(%ebp),%eax +c0100e3e: 0f b7 55 fa movzwl -0x6(%ebp),%edx +c0100e42: 66 89 10 mov %dx,(%eax) + addr_6845 = CGA_BASE; +c0100e45: 66 c7 05 46 c4 11 c0 movw $0x3d4,0xc011c446 +c0100e4c: d4 03 + } + + // Extract cursor location + uint32_t pos; + outb(addr_6845, 14); +c0100e4e: 0f b7 05 46 c4 11 c0 movzwl 0xc011c446,%eax +c0100e55: 66 89 45 e6 mov %ax,-0x1a(%ebp) +c0100e59: c6 45 e5 0e movb $0xe,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100e5d: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0100e61: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0100e65: ee out %al,(%dx) +} +c0100e66: 90 nop + pos = inb(addr_6845 + 1) << 8; +c0100e67: 0f b7 05 46 c4 11 c0 movzwl 0xc011c446,%eax +c0100e6e: 40 inc %eax +c0100e6f: 0f b7 c0 movzwl %ax,%eax +c0100e72: 66 89 45 ea mov %ax,-0x16(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100e76: 0f b7 45 ea movzwl -0x16(%ebp),%eax +c0100e7a: 89 c2 mov %eax,%edx +c0100e7c: ec in (%dx),%al +c0100e7d: 88 45 e9 mov %al,-0x17(%ebp) + return data; +c0100e80: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0100e84: 0f b6 c0 movzbl %al,%eax +c0100e87: c1 e0 08 shl $0x8,%eax +c0100e8a: 89 45 f4 mov %eax,-0xc(%ebp) + outb(addr_6845, 15); +c0100e8d: 0f b7 05 46 c4 11 c0 movzwl 0xc011c446,%eax +c0100e94: 66 89 45 ee mov %ax,-0x12(%ebp) +c0100e98: c6 45 ed 0f movb $0xf,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100e9c: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0100ea0: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0100ea4: ee out %al,(%dx) +} +c0100ea5: 90 nop + pos |= inb(addr_6845 + 1); +c0100ea6: 0f b7 05 46 c4 11 c0 movzwl 0xc011c446,%eax +c0100ead: 40 inc %eax +c0100eae: 0f b7 c0 movzwl %ax,%eax +c0100eb1: 66 89 45 f2 mov %ax,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100eb5: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0100eb9: 89 c2 mov %eax,%edx +c0100ebb: ec in (%dx),%al +c0100ebc: 88 45 f1 mov %al,-0xf(%ebp) + return data; +c0100ebf: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0100ec3: 0f b6 c0 movzbl %al,%eax +c0100ec6: 09 45 f4 or %eax,-0xc(%ebp) + + crt_buf = (uint16_t*) cp; +c0100ec9: 8b 45 fc mov -0x4(%ebp),%eax +c0100ecc: a3 40 c4 11 c0 mov %eax,0xc011c440 + crt_pos = pos; +c0100ed1: 8b 45 f4 mov -0xc(%ebp),%eax +c0100ed4: 0f b7 c0 movzwl %ax,%eax +c0100ed7: 66 a3 44 c4 11 c0 mov %ax,0xc011c444 +} +c0100edd: 90 nop +c0100ede: 89 ec mov %ebp,%esp +c0100ee0: 5d pop %ebp +c0100ee1: c3 ret + +c0100ee2 : + +static bool serial_exists = 0; + +static void +serial_init(void) { +c0100ee2: 55 push %ebp +c0100ee3: 89 e5 mov %esp,%ebp +c0100ee5: 83 ec 48 sub $0x48,%esp +c0100ee8: 66 c7 45 d2 fa 03 movw $0x3fa,-0x2e(%ebp) +c0100eee: c6 45 d1 00 movb $0x0,-0x2f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100ef2: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax +c0100ef6: 0f b7 55 d2 movzwl -0x2e(%ebp),%edx +c0100efa: ee out %al,(%dx) +} +c0100efb: 90 nop +c0100efc: 66 c7 45 d6 fb 03 movw $0x3fb,-0x2a(%ebp) +c0100f02: c6 45 d5 80 movb $0x80,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f06: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax +c0100f0a: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx +c0100f0e: ee out %al,(%dx) +} +c0100f0f: 90 nop +c0100f10: 66 c7 45 da f8 03 movw $0x3f8,-0x26(%ebp) +c0100f16: c6 45 d9 0c movb $0xc,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f1a: 0f b6 45 d9 movzbl -0x27(%ebp),%eax +c0100f1e: 0f b7 55 da movzwl -0x26(%ebp),%edx +c0100f22: ee out %al,(%dx) +} +c0100f23: 90 nop +c0100f24: 66 c7 45 de f9 03 movw $0x3f9,-0x22(%ebp) +c0100f2a: c6 45 dd 00 movb $0x0,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f2e: 0f b6 45 dd movzbl -0x23(%ebp),%eax +c0100f32: 0f b7 55 de movzwl -0x22(%ebp),%edx +c0100f36: ee out %al,(%dx) +} +c0100f37: 90 nop +c0100f38: 66 c7 45 e2 fb 03 movw $0x3fb,-0x1e(%ebp) +c0100f3e: c6 45 e1 03 movb $0x3,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f42: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax +c0100f46: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx +c0100f4a: ee out %al,(%dx) +} +c0100f4b: 90 nop +c0100f4c: 66 c7 45 e6 fc 03 movw $0x3fc,-0x1a(%ebp) +c0100f52: c6 45 e5 00 movb $0x0,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f56: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c0100f5a: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0100f5e: ee out %al,(%dx) +} +c0100f5f: 90 nop +c0100f60: 66 c7 45 ea f9 03 movw $0x3f9,-0x16(%ebp) +c0100f66: c6 45 e9 01 movb $0x1,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0100f6a: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0100f6e: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c0100f72: ee out %al,(%dx) +} +c0100f73: 90 nop +c0100f74: 66 c7 45 ee fd 03 movw $0x3fd,-0x12(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100f7a: 0f b7 45 ee movzwl -0x12(%ebp),%eax +c0100f7e: 89 c2 mov %eax,%edx +c0100f80: ec in (%dx),%al +c0100f81: 88 45 ed mov %al,-0x13(%ebp) + return data; +c0100f84: 0f b6 45 ed movzbl -0x13(%ebp),%eax + // Enable rcv interrupts + outb(COM1 + COM_IER, COM_IER_RDI); + + // Clear any preexisting overrun indications and interrupts + // Serial port doesn't exist if COM_LSR returns 0xFF + serial_exists = (inb(COM1 + COM_LSR) != 0xFF); +c0100f88: 3c ff cmp $0xff,%al +c0100f8a: 0f 95 c0 setne %al +c0100f8d: 0f b6 c0 movzbl %al,%eax +c0100f90: a3 48 c4 11 c0 mov %eax,0xc011c448 +c0100f95: 66 c7 45 f2 fa 03 movw $0x3fa,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c0100f9b: 0f b7 45 f2 movzwl -0xe(%ebp),%eax +c0100f9f: 89 c2 mov %eax,%edx +c0100fa1: ec in (%dx),%al +c0100fa2: 88 45 f1 mov %al,-0xf(%ebp) +c0100fa5: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) +c0100fab: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c0100faf: 89 c2 mov %eax,%edx +c0100fb1: ec in (%dx),%al +c0100fb2: 88 45 f5 mov %al,-0xb(%ebp) + (void) inb(COM1+COM_IIR); + (void) inb(COM1+COM_RX); + + if (serial_exists) { +c0100fb5: a1 48 c4 11 c0 mov 0xc011c448,%eax +c0100fba: 85 c0 test %eax,%eax +c0100fbc: 74 0c je c0100fca + pic_enable(IRQ_COM1); +c0100fbe: c7 04 24 04 00 00 00 movl $0x4,(%esp) +c0100fc5: e8 27 07 00 00 call c01016f1 + } +} +c0100fca: 90 nop +c0100fcb: 89 ec mov %ebp,%esp +c0100fcd: 5d pop %ebp +c0100fce: c3 ret + +c0100fcf : + +static void +lpt_putc_sub(int c) { +c0100fcf: 55 push %ebp +c0100fd0: 89 e5 mov %esp,%ebp +c0100fd2: 83 ec 20 sub $0x20,%esp + int i; + for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) { +c0100fd5: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) +c0100fdc: eb 08 jmp c0100fe6 + delay(); +c0100fde: e8 cc fd ff ff call c0100daf + for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) { +c0100fe3: ff 45 fc incl -0x4(%ebp) +c0100fe6: 66 c7 45 fa 79 03 movw $0x379,-0x6(%ebp) +c0100fec: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c0100ff0: 89 c2 mov %eax,%edx +c0100ff2: ec in (%dx),%al +c0100ff3: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c0100ff6: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c0100ffa: 84 c0 test %al,%al +c0100ffc: 78 09 js c0101007 +c0100ffe: 81 7d fc ff 31 00 00 cmpl $0x31ff,-0x4(%ebp) +c0101005: 7e d7 jle c0100fde + } + outb(LPTPORT + 0, c); +c0101007: 8b 45 08 mov 0x8(%ebp),%eax +c010100a: 0f b6 c0 movzbl %al,%eax +c010100d: 66 c7 45 ee 78 03 movw $0x378,-0x12(%ebp) +c0101013: 88 45 ed mov %al,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101016: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c010101a: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c010101e: ee out %al,(%dx) +} +c010101f: 90 nop +c0101020: 66 c7 45 f2 7a 03 movw $0x37a,-0xe(%ebp) +c0101026: c6 45 f1 0d movb $0xd,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010102a: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c010102e: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101032: ee out %al,(%dx) +} +c0101033: 90 nop +c0101034: 66 c7 45 f6 7a 03 movw $0x37a,-0xa(%ebp) +c010103a: c6 45 f5 08 movb $0x8,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010103e: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c0101042: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0101046: ee out %al,(%dx) +} +c0101047: 90 nop + outb(LPTPORT + 2, 0x08 | 0x04 | 0x01); + outb(LPTPORT + 2, 0x08); +} +c0101048: 90 nop +c0101049: 89 ec mov %ebp,%esp +c010104b: 5d pop %ebp +c010104c: c3 ret + +c010104d : + +/* lpt_putc - copy console output to parallel port */ +static void +lpt_putc(int c) { +c010104d: 55 push %ebp +c010104e: 89 e5 mov %esp,%ebp +c0101050: 83 ec 04 sub $0x4,%esp + if (c != '\b') { +c0101053: 83 7d 08 08 cmpl $0x8,0x8(%ebp) +c0101057: 74 0d je c0101066 + lpt_putc_sub(c); +c0101059: 8b 45 08 mov 0x8(%ebp),%eax +c010105c: 89 04 24 mov %eax,(%esp) +c010105f: e8 6b ff ff ff call c0100fcf + else { + lpt_putc_sub('\b'); + lpt_putc_sub(' '); + lpt_putc_sub('\b'); + } +} +c0101064: eb 24 jmp c010108a + lpt_putc_sub('\b'); +c0101066: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c010106d: e8 5d ff ff ff call c0100fcf + lpt_putc_sub(' '); +c0101072: c7 04 24 20 00 00 00 movl $0x20,(%esp) +c0101079: e8 51 ff ff ff call c0100fcf + lpt_putc_sub('\b'); +c010107e: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c0101085: e8 45 ff ff ff call c0100fcf +} +c010108a: 90 nop +c010108b: 89 ec mov %ebp,%esp +c010108d: 5d pop %ebp +c010108e: c3 ret + +c010108f : + +/* cga_putc - print character to console */ +static void +cga_putc(int c) { +c010108f: 55 push %ebp +c0101090: 89 e5 mov %esp,%ebp +c0101092: 83 ec 38 sub $0x38,%esp +c0101095: 89 5d fc mov %ebx,-0x4(%ebp) + // set black on white + if (!(c & ~0xFF)) { +c0101098: 8b 45 08 mov 0x8(%ebp),%eax +c010109b: 25 00 ff ff ff and $0xffffff00,%eax +c01010a0: 85 c0 test %eax,%eax +c01010a2: 75 07 jne c01010ab + c |= 0x0700; +c01010a4: 81 4d 08 00 07 00 00 orl $0x700,0x8(%ebp) + } + + switch (c & 0xff) { +c01010ab: 8b 45 08 mov 0x8(%ebp),%eax +c01010ae: 0f b6 c0 movzbl %al,%eax +c01010b1: 83 f8 0d cmp $0xd,%eax +c01010b4: 74 72 je c0101128 +c01010b6: 83 f8 0d cmp $0xd,%eax +c01010b9: 0f 8f a3 00 00 00 jg c0101162 +c01010bf: 83 f8 08 cmp $0x8,%eax +c01010c2: 74 0a je c01010ce +c01010c4: 83 f8 0a cmp $0xa,%eax +c01010c7: 74 4c je c0101115 +c01010c9: e9 94 00 00 00 jmp c0101162 + case '\b': + if (crt_pos > 0) { +c01010ce: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c01010d5: 85 c0 test %eax,%eax +c01010d7: 0f 84 af 00 00 00 je c010118c + crt_pos --; +c01010dd: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c01010e4: 48 dec %eax +c01010e5: 0f b7 c0 movzwl %ax,%eax +c01010e8: 66 a3 44 c4 11 c0 mov %ax,0xc011c444 + crt_buf[crt_pos] = (c & ~0xff) | ' '; +c01010ee: 8b 45 08 mov 0x8(%ebp),%eax +c01010f1: 98 cwtl +c01010f2: 25 00 ff ff ff and $0xffffff00,%eax +c01010f7: 98 cwtl +c01010f8: 83 c8 20 or $0x20,%eax +c01010fb: 98 cwtl +c01010fc: 8b 0d 40 c4 11 c0 mov 0xc011c440,%ecx +c0101102: 0f b7 15 44 c4 11 c0 movzwl 0xc011c444,%edx +c0101109: 01 d2 add %edx,%edx +c010110b: 01 ca add %ecx,%edx +c010110d: 0f b7 c0 movzwl %ax,%eax +c0101110: 66 89 02 mov %ax,(%edx) + } + break; +c0101113: eb 77 jmp c010118c + case '\n': + crt_pos += CRT_COLS; +c0101115: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c010111c: 83 c0 50 add $0x50,%eax +c010111f: 0f b7 c0 movzwl %ax,%eax +c0101122: 66 a3 44 c4 11 c0 mov %ax,0xc011c444 + case '\r': + crt_pos -= (crt_pos % CRT_COLS); +c0101128: 0f b7 1d 44 c4 11 c0 movzwl 0xc011c444,%ebx +c010112f: 0f b7 0d 44 c4 11 c0 movzwl 0xc011c444,%ecx +c0101136: ba cd cc cc cc mov $0xcccccccd,%edx +c010113b: 89 c8 mov %ecx,%eax +c010113d: f7 e2 mul %edx +c010113f: c1 ea 06 shr $0x6,%edx +c0101142: 89 d0 mov %edx,%eax +c0101144: c1 e0 02 shl $0x2,%eax +c0101147: 01 d0 add %edx,%eax +c0101149: c1 e0 04 shl $0x4,%eax +c010114c: 29 c1 sub %eax,%ecx +c010114e: 89 ca mov %ecx,%edx +c0101150: 0f b7 d2 movzwl %dx,%edx +c0101153: 89 d8 mov %ebx,%eax +c0101155: 29 d0 sub %edx,%eax +c0101157: 0f b7 c0 movzwl %ax,%eax +c010115a: 66 a3 44 c4 11 c0 mov %ax,0xc011c444 + break; +c0101160: eb 2b jmp c010118d + default: + crt_buf[crt_pos ++] = c; // write the character +c0101162: 8b 0d 40 c4 11 c0 mov 0xc011c440,%ecx +c0101168: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c010116f: 8d 50 01 lea 0x1(%eax),%edx +c0101172: 0f b7 d2 movzwl %dx,%edx +c0101175: 66 89 15 44 c4 11 c0 mov %dx,0xc011c444 +c010117c: 01 c0 add %eax,%eax +c010117e: 8d 14 01 lea (%ecx,%eax,1),%edx +c0101181: 8b 45 08 mov 0x8(%ebp),%eax +c0101184: 0f b7 c0 movzwl %ax,%eax +c0101187: 66 89 02 mov %ax,(%edx) + break; +c010118a: eb 01 jmp c010118d + break; +c010118c: 90 nop + } + + // What is the purpose of this? + if (crt_pos >= CRT_SIZE) { +c010118d: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c0101194: 3d cf 07 00 00 cmp $0x7cf,%eax +c0101199: 76 5e jbe c01011f9 + int i; + memmove(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t)); +c010119b: a1 40 c4 11 c0 mov 0xc011c440,%eax +c01011a0: 8d 90 a0 00 00 00 lea 0xa0(%eax),%edx +c01011a6: a1 40 c4 11 c0 mov 0xc011c440,%eax +c01011ab: c7 44 24 08 00 0f 00 movl $0xf00,0x8(%esp) +c01011b2: 00 +c01011b3: 89 54 24 04 mov %edx,0x4(%esp) +c01011b7: 89 04 24 mov %eax,(%esp) +c01011ba: e8 8b 4d 00 00 call c0105f4a + for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) { +c01011bf: c7 45 f4 80 07 00 00 movl $0x780,-0xc(%ebp) +c01011c6: eb 15 jmp c01011dd + crt_buf[i] = 0x0700 | ' '; +c01011c8: 8b 15 40 c4 11 c0 mov 0xc011c440,%edx +c01011ce: 8b 45 f4 mov -0xc(%ebp),%eax +c01011d1: 01 c0 add %eax,%eax +c01011d3: 01 d0 add %edx,%eax +c01011d5: 66 c7 00 20 07 movw $0x720,(%eax) + for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) { +c01011da: ff 45 f4 incl -0xc(%ebp) +c01011dd: 81 7d f4 cf 07 00 00 cmpl $0x7cf,-0xc(%ebp) +c01011e4: 7e e2 jle c01011c8 + } + crt_pos -= CRT_COLS; +c01011e6: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c01011ed: 83 e8 50 sub $0x50,%eax +c01011f0: 0f b7 c0 movzwl %ax,%eax +c01011f3: 66 a3 44 c4 11 c0 mov %ax,0xc011c444 + } + + // move that little blinky thing + outb(addr_6845, 14); +c01011f9: 0f b7 05 46 c4 11 c0 movzwl 0xc011c446,%eax +c0101200: 66 89 45 e6 mov %ax,-0x1a(%ebp) +c0101204: c6 45 e5 0e movb $0xe,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101208: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c010120c: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c0101210: ee out %al,(%dx) +} +c0101211: 90 nop + outb(addr_6845 + 1, crt_pos >> 8); +c0101212: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c0101219: c1 e8 08 shr $0x8,%eax +c010121c: 0f b7 c0 movzwl %ax,%eax +c010121f: 0f b6 c0 movzbl %al,%eax +c0101222: 0f b7 15 46 c4 11 c0 movzwl 0xc011c446,%edx +c0101229: 42 inc %edx +c010122a: 0f b7 d2 movzwl %dx,%edx +c010122d: 66 89 55 ea mov %dx,-0x16(%ebp) +c0101231: 88 45 e9 mov %al,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101234: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c0101238: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c010123c: ee out %al,(%dx) +} +c010123d: 90 nop + outb(addr_6845, 15); +c010123e: 0f b7 05 46 c4 11 c0 movzwl 0xc011c446,%eax +c0101245: 66 89 45 ee mov %ax,-0x12(%ebp) +c0101249: c6 45 ed 0f movb $0xf,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010124d: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c0101251: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c0101255: ee out %al,(%dx) +} +c0101256: 90 nop + outb(addr_6845 + 1, crt_pos); +c0101257: 0f b7 05 44 c4 11 c0 movzwl 0xc011c444,%eax +c010125e: 0f b6 c0 movzbl %al,%eax +c0101261: 0f b7 15 46 c4 11 c0 movzwl 0xc011c446,%edx +c0101268: 42 inc %edx +c0101269: 0f b7 d2 movzwl %dx,%edx +c010126c: 66 89 55 f2 mov %dx,-0xe(%ebp) +c0101270: 88 45 f1 mov %al,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101273: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c0101277: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c010127b: ee out %al,(%dx) +} +c010127c: 90 nop +} +c010127d: 90 nop +c010127e: 8b 5d fc mov -0x4(%ebp),%ebx +c0101281: 89 ec mov %ebp,%esp +c0101283: 5d pop %ebp +c0101284: c3 ret + +c0101285 : + +static void +serial_putc_sub(int c) { +c0101285: 55 push %ebp +c0101286: 89 e5 mov %esp,%ebp +c0101288: 83 ec 10 sub $0x10,%esp + int i; + for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) { +c010128b: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) +c0101292: eb 08 jmp c010129c + delay(); +c0101294: e8 16 fb ff ff call c0100daf + for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) { +c0101299: ff 45 fc incl -0x4(%ebp) +c010129c: 66 c7 45 fa fd 03 movw $0x3fd,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01012a2: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c01012a6: 89 c2 mov %eax,%edx +c01012a8: ec in (%dx),%al +c01012a9: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c01012ac: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c01012b0: 0f b6 c0 movzbl %al,%eax +c01012b3: 83 e0 20 and $0x20,%eax +c01012b6: 85 c0 test %eax,%eax +c01012b8: 75 09 jne c01012c3 +c01012ba: 81 7d fc ff 31 00 00 cmpl $0x31ff,-0x4(%ebp) +c01012c1: 7e d1 jle c0101294 + } + outb(COM1 + COM_TX, c); +c01012c3: 8b 45 08 mov 0x8(%ebp),%eax +c01012c6: 0f b6 c0 movzbl %al,%eax +c01012c9: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) +c01012cf: 88 45 f5 mov %al,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01012d2: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c01012d6: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c01012da: ee out %al,(%dx) +} +c01012db: 90 nop +} +c01012dc: 90 nop +c01012dd: 89 ec mov %ebp,%esp +c01012df: 5d pop %ebp +c01012e0: c3 ret + +c01012e1 : + +/* serial_putc - print character to serial port */ +static void +serial_putc(int c) { +c01012e1: 55 push %ebp +c01012e2: 89 e5 mov %esp,%ebp +c01012e4: 83 ec 04 sub $0x4,%esp + if (c != '\b') { +c01012e7: 83 7d 08 08 cmpl $0x8,0x8(%ebp) +c01012eb: 74 0d je c01012fa + serial_putc_sub(c); +c01012ed: 8b 45 08 mov 0x8(%ebp),%eax +c01012f0: 89 04 24 mov %eax,(%esp) +c01012f3: e8 8d ff ff ff call c0101285 + else { + serial_putc_sub('\b'); + serial_putc_sub(' '); + serial_putc_sub('\b'); + } +} +c01012f8: eb 24 jmp c010131e + serial_putc_sub('\b'); +c01012fa: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c0101301: e8 7f ff ff ff call c0101285 + serial_putc_sub(' '); +c0101306: c7 04 24 20 00 00 00 movl $0x20,(%esp) +c010130d: e8 73 ff ff ff call c0101285 + serial_putc_sub('\b'); +c0101312: c7 04 24 08 00 00 00 movl $0x8,(%esp) +c0101319: e8 67 ff ff ff call c0101285 +} +c010131e: 90 nop +c010131f: 89 ec mov %ebp,%esp +c0101321: 5d pop %ebp +c0101322: c3 ret + +c0101323 : +/* * + * cons_intr - called by device interrupt routines to feed input + * characters into the circular console input buffer. + * */ +static void +cons_intr(int (*proc)(void)) { +c0101323: 55 push %ebp +c0101324: 89 e5 mov %esp,%ebp +c0101326: 83 ec 18 sub $0x18,%esp + int c; + while ((c = (*proc)()) != -1) { +c0101329: eb 33 jmp c010135e + if (c != 0) { +c010132b: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c010132f: 74 2d je c010135e + cons.buf[cons.wpos ++] = c; +c0101331: a1 64 c6 11 c0 mov 0xc011c664,%eax +c0101336: 8d 50 01 lea 0x1(%eax),%edx +c0101339: 89 15 64 c6 11 c0 mov %edx,0xc011c664 +c010133f: 8b 55 f4 mov -0xc(%ebp),%edx +c0101342: 88 90 60 c4 11 c0 mov %dl,-0x3fee3ba0(%eax) + if (cons.wpos == CONSBUFSIZE) { +c0101348: a1 64 c6 11 c0 mov 0xc011c664,%eax +c010134d: 3d 00 02 00 00 cmp $0x200,%eax +c0101352: 75 0a jne c010135e + cons.wpos = 0; +c0101354: c7 05 64 c6 11 c0 00 movl $0x0,0xc011c664 +c010135b: 00 00 00 + while ((c = (*proc)()) != -1) { +c010135e: 8b 45 08 mov 0x8(%ebp),%eax +c0101361: ff d0 call *%eax +c0101363: 89 45 f4 mov %eax,-0xc(%ebp) +c0101366: 83 7d f4 ff cmpl $0xffffffff,-0xc(%ebp) +c010136a: 75 bf jne c010132b + } + } + } +} +c010136c: 90 nop +c010136d: 90 nop +c010136e: 89 ec mov %ebp,%esp +c0101370: 5d pop %ebp +c0101371: c3 ret + +c0101372 : + +/* serial_proc_data - get data from serial port */ +static int +serial_proc_data(void) { +c0101372: 55 push %ebp +c0101373: 89 e5 mov %esp,%ebp +c0101375: 83 ec 10 sub $0x10,%esp +c0101378: 66 c7 45 fa fd 03 movw $0x3fd,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c010137e: 0f b7 45 fa movzwl -0x6(%ebp),%eax +c0101382: 89 c2 mov %eax,%edx +c0101384: ec in (%dx),%al +c0101385: 88 45 f9 mov %al,-0x7(%ebp) + return data; +c0101388: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + if (!(inb(COM1 + COM_LSR) & COM_LSR_DATA)) { +c010138c: 0f b6 c0 movzbl %al,%eax +c010138f: 83 e0 01 and $0x1,%eax +c0101392: 85 c0 test %eax,%eax +c0101394: 75 07 jne c010139d + return -1; +c0101396: b8 ff ff ff ff mov $0xffffffff,%eax +c010139b: eb 2a jmp c01013c7 +c010139d: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01013a3: 0f b7 45 f6 movzwl -0xa(%ebp),%eax +c01013a7: 89 c2 mov %eax,%edx +c01013a9: ec in (%dx),%al +c01013aa: 88 45 f5 mov %al,-0xb(%ebp) + return data; +c01013ad: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + } + int c = inb(COM1 + COM_RX); +c01013b1: 0f b6 c0 movzbl %al,%eax +c01013b4: 89 45 fc mov %eax,-0x4(%ebp) + if (c == 127) { +c01013b7: 83 7d fc 7f cmpl $0x7f,-0x4(%ebp) +c01013bb: 75 07 jne c01013c4 + c = '\b'; +c01013bd: c7 45 fc 08 00 00 00 movl $0x8,-0x4(%ebp) + } + return c; +c01013c4: 8b 45 fc mov -0x4(%ebp),%eax +} +c01013c7: 89 ec mov %ebp,%esp +c01013c9: 5d pop %ebp +c01013ca: c3 ret + +c01013cb : + +/* serial_intr - try to feed input characters from serial port */ +void +serial_intr(void) { +c01013cb: 55 push %ebp +c01013cc: 89 e5 mov %esp,%ebp +c01013ce: 83 ec 18 sub $0x18,%esp + if (serial_exists) { +c01013d1: a1 48 c4 11 c0 mov 0xc011c448,%eax +c01013d6: 85 c0 test %eax,%eax +c01013d8: 74 0c je c01013e6 + cons_intr(serial_proc_data); +c01013da: c7 04 24 72 13 10 c0 movl $0xc0101372,(%esp) +c01013e1: e8 3d ff ff ff call c0101323 + } +} +c01013e6: 90 nop +c01013e7: 89 ec mov %ebp,%esp +c01013e9: 5d pop %ebp +c01013ea: c3 ret + +c01013eb : + * + * The kbd_proc_data() function gets data from the keyboard. + * If we finish a character, return it, else 0. And return -1 if no data. + * */ +static int +kbd_proc_data(void) { +c01013eb: 55 push %ebp +c01013ec: 89 e5 mov %esp,%ebp +c01013ee: 83 ec 38 sub $0x38,%esp +c01013f1: 66 c7 45 f0 64 00 movw $0x64,-0x10(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c01013f7: 8b 45 f0 mov -0x10(%ebp),%eax +c01013fa: 89 c2 mov %eax,%edx +c01013fc: ec in (%dx),%al +c01013fd: 88 45 ef mov %al,-0x11(%ebp) + return data; +c0101400: 0f b6 45 ef movzbl -0x11(%ebp),%eax + int c; + uint8_t data; + static uint32_t shift; + + if ((inb(KBSTATP) & KBS_DIB) == 0) { +c0101404: 0f b6 c0 movzbl %al,%eax +c0101407: 83 e0 01 and $0x1,%eax +c010140a: 85 c0 test %eax,%eax +c010140c: 75 0a jne c0101418 + return -1; +c010140e: b8 ff ff ff ff mov $0xffffffff,%eax +c0101413: e9 56 01 00 00 jmp c010156e +c0101418: 66 c7 45 ec 60 00 movw $0x60,-0x14(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); +c010141e: 8b 45 ec mov -0x14(%ebp),%eax +c0101421: 89 c2 mov %eax,%edx +c0101423: ec in (%dx),%al +c0101424: 88 45 eb mov %al,-0x15(%ebp) + return data; +c0101427: 0f b6 45 eb movzbl -0x15(%ebp),%eax + } + + data = inb(KBDATAP); +c010142b: 88 45 f3 mov %al,-0xd(%ebp) + + if (data == 0xE0) { +c010142e: 80 7d f3 e0 cmpb $0xe0,-0xd(%ebp) +c0101432: 75 17 jne c010144b + // E0 escape character + shift |= E0ESC; +c0101434: a1 68 c6 11 c0 mov 0xc011c668,%eax +c0101439: 83 c8 40 or $0x40,%eax +c010143c: a3 68 c6 11 c0 mov %eax,0xc011c668 + return 0; +c0101441: b8 00 00 00 00 mov $0x0,%eax +c0101446: e9 23 01 00 00 jmp c010156e + } else if (data & 0x80) { +c010144b: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c010144f: 84 c0 test %al,%al +c0101451: 79 45 jns c0101498 + // Key released + data = (shift & E0ESC ? data : data & 0x7F); +c0101453: a1 68 c6 11 c0 mov 0xc011c668,%eax +c0101458: 83 e0 40 and $0x40,%eax +c010145b: 85 c0 test %eax,%eax +c010145d: 75 08 jne c0101467 +c010145f: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c0101463: 24 7f and $0x7f,%al +c0101465: eb 04 jmp c010146b +c0101467: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c010146b: 88 45 f3 mov %al,-0xd(%ebp) + shift &= ~(shiftcode[data] | E0ESC); +c010146e: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c0101472: 0f b6 80 40 90 11 c0 movzbl -0x3fee6fc0(%eax),%eax +c0101479: 0c 40 or $0x40,%al +c010147b: 0f b6 c0 movzbl %al,%eax +c010147e: f7 d0 not %eax +c0101480: 89 c2 mov %eax,%edx +c0101482: a1 68 c6 11 c0 mov 0xc011c668,%eax +c0101487: 21 d0 and %edx,%eax +c0101489: a3 68 c6 11 c0 mov %eax,0xc011c668 + return 0; +c010148e: b8 00 00 00 00 mov $0x0,%eax +c0101493: e9 d6 00 00 00 jmp c010156e + } else if (shift & E0ESC) { +c0101498: a1 68 c6 11 c0 mov 0xc011c668,%eax +c010149d: 83 e0 40 and $0x40,%eax +c01014a0: 85 c0 test %eax,%eax +c01014a2: 74 11 je c01014b5 + // Last character was an E0 escape; or with 0x80 + data |= 0x80; +c01014a4: 80 4d f3 80 orb $0x80,-0xd(%ebp) + shift &= ~E0ESC; +c01014a8: a1 68 c6 11 c0 mov 0xc011c668,%eax +c01014ad: 83 e0 bf and $0xffffffbf,%eax +c01014b0: a3 68 c6 11 c0 mov %eax,0xc011c668 + } + + shift |= shiftcode[data]; +c01014b5: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c01014b9: 0f b6 80 40 90 11 c0 movzbl -0x3fee6fc0(%eax),%eax +c01014c0: 0f b6 d0 movzbl %al,%edx +c01014c3: a1 68 c6 11 c0 mov 0xc011c668,%eax +c01014c8: 09 d0 or %edx,%eax +c01014ca: a3 68 c6 11 c0 mov %eax,0xc011c668 + shift ^= togglecode[data]; +c01014cf: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c01014d3: 0f b6 80 40 91 11 c0 movzbl -0x3fee6ec0(%eax),%eax +c01014da: 0f b6 d0 movzbl %al,%edx +c01014dd: a1 68 c6 11 c0 mov 0xc011c668,%eax +c01014e2: 31 d0 xor %edx,%eax +c01014e4: a3 68 c6 11 c0 mov %eax,0xc011c668 + + c = charcode[shift & (CTL | SHIFT)][data]; +c01014e9: a1 68 c6 11 c0 mov 0xc011c668,%eax +c01014ee: 83 e0 03 and $0x3,%eax +c01014f1: 8b 14 85 40 95 11 c0 mov -0x3fee6ac0(,%eax,4),%edx +c01014f8: 0f b6 45 f3 movzbl -0xd(%ebp),%eax +c01014fc: 01 d0 add %edx,%eax +c01014fe: 0f b6 00 movzbl (%eax),%eax +c0101501: 0f b6 c0 movzbl %al,%eax +c0101504: 89 45 f4 mov %eax,-0xc(%ebp) + if (shift & CAPSLOCK) { +c0101507: a1 68 c6 11 c0 mov 0xc011c668,%eax +c010150c: 83 e0 08 and $0x8,%eax +c010150f: 85 c0 test %eax,%eax +c0101511: 74 22 je c0101535 + if ('a' <= c && c <= 'z') +c0101513: 83 7d f4 60 cmpl $0x60,-0xc(%ebp) +c0101517: 7e 0c jle c0101525 +c0101519: 83 7d f4 7a cmpl $0x7a,-0xc(%ebp) +c010151d: 7f 06 jg c0101525 + c += 'A' - 'a'; +c010151f: 83 6d f4 20 subl $0x20,-0xc(%ebp) +c0101523: eb 10 jmp c0101535 + else if ('A' <= c && c <= 'Z') +c0101525: 83 7d f4 40 cmpl $0x40,-0xc(%ebp) +c0101529: 7e 0a jle c0101535 +c010152b: 83 7d f4 5a cmpl $0x5a,-0xc(%ebp) +c010152f: 7f 04 jg c0101535 + c += 'a' - 'A'; +c0101531: 83 45 f4 20 addl $0x20,-0xc(%ebp) + } + + // Process special keys + // Ctrl-Alt-Del: reboot + if (!(~shift & (CTL | ALT)) && c == KEY_DEL) { +c0101535: a1 68 c6 11 c0 mov 0xc011c668,%eax +c010153a: f7 d0 not %eax +c010153c: 83 e0 06 and $0x6,%eax +c010153f: 85 c0 test %eax,%eax +c0101541: 75 28 jne c010156b +c0101543: 81 7d f4 e9 00 00 00 cmpl $0xe9,-0xc(%ebp) +c010154a: 75 1f jne c010156b + cprintf("Rebooting!\n"); +c010154c: c7 04 24 a7 63 10 c0 movl $0xc01063a7,(%esp) +c0101553: e8 0e ee ff ff call c0100366 +c0101558: 66 c7 45 e8 92 00 movw $0x92,-0x18(%ebp) +c010155e: c6 45 e7 03 movb $0x3,-0x19(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101562: 0f b6 45 e7 movzbl -0x19(%ebp),%eax +c0101566: 8b 55 e8 mov -0x18(%ebp),%edx +c0101569: ee out %al,(%dx) +} +c010156a: 90 nop + outb(0x92, 0x3); // courtesy of Chris Frost + } + return c; +c010156b: 8b 45 f4 mov -0xc(%ebp),%eax +} +c010156e: 89 ec mov %ebp,%esp +c0101570: 5d pop %ebp +c0101571: c3 ret + +c0101572 : + +/* kbd_intr - try to feed input characters from keyboard */ +static void +kbd_intr(void) { +c0101572: 55 push %ebp +c0101573: 89 e5 mov %esp,%ebp +c0101575: 83 ec 18 sub $0x18,%esp + cons_intr(kbd_proc_data); +c0101578: c7 04 24 eb 13 10 c0 movl $0xc01013eb,(%esp) +c010157f: e8 9f fd ff ff call c0101323 +} +c0101584: 90 nop +c0101585: 89 ec mov %ebp,%esp +c0101587: 5d pop %ebp +c0101588: c3 ret + +c0101589 : + +static void +kbd_init(void) { +c0101589: 55 push %ebp +c010158a: 89 e5 mov %esp,%ebp +c010158c: 83 ec 18 sub $0x18,%esp + // drain the kbd buffer + kbd_intr(); +c010158f: e8 de ff ff ff call c0101572 + pic_enable(IRQ_KBD); +c0101594: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010159b: e8 51 01 00 00 call c01016f1 +} +c01015a0: 90 nop +c01015a1: 89 ec mov %ebp,%esp +c01015a3: 5d pop %ebp +c01015a4: c3 ret + +c01015a5 : + +/* cons_init - initializes the console devices */ +void +cons_init(void) { +c01015a5: 55 push %ebp +c01015a6: 89 e5 mov %esp,%ebp +c01015a8: 83 ec 18 sub $0x18,%esp + cga_init(); +c01015ab: e8 4a f8 ff ff call c0100dfa + serial_init(); +c01015b0: e8 2d f9 ff ff call c0100ee2 + kbd_init(); +c01015b5: e8 cf ff ff ff call c0101589 + if (!serial_exists) { +c01015ba: a1 48 c4 11 c0 mov 0xc011c448,%eax +c01015bf: 85 c0 test %eax,%eax +c01015c1: 75 0c jne c01015cf + cprintf("serial port does not exist!!\n"); +c01015c3: c7 04 24 b3 63 10 c0 movl $0xc01063b3,(%esp) +c01015ca: e8 97 ed ff ff call c0100366 + } +} +c01015cf: 90 nop +c01015d0: 89 ec mov %ebp,%esp +c01015d2: 5d pop %ebp +c01015d3: c3 ret + +c01015d4 : + +/* cons_putc - print a single character @c to console devices */ +void +cons_putc(int c) { +c01015d4: 55 push %ebp +c01015d5: 89 e5 mov %esp,%ebp +c01015d7: 83 ec 28 sub $0x28,%esp + bool intr_flag; + local_intr_save(intr_flag); +c01015da: e8 8e f7 ff ff call c0100d6d <__intr_save> +c01015df: 89 45 f4 mov %eax,-0xc(%ebp) + { + lpt_putc(c); +c01015e2: 8b 45 08 mov 0x8(%ebp),%eax +c01015e5: 89 04 24 mov %eax,(%esp) +c01015e8: e8 60 fa ff ff call c010104d + cga_putc(c); +c01015ed: 8b 45 08 mov 0x8(%ebp),%eax +c01015f0: 89 04 24 mov %eax,(%esp) +c01015f3: e8 97 fa ff ff call c010108f + serial_putc(c); +c01015f8: 8b 45 08 mov 0x8(%ebp),%eax +c01015fb: 89 04 24 mov %eax,(%esp) +c01015fe: e8 de fc ff ff call c01012e1 + } + local_intr_restore(intr_flag); +c0101603: 8b 45 f4 mov -0xc(%ebp),%eax +c0101606: 89 04 24 mov %eax,(%esp) +c0101609: e8 8b f7 ff ff call c0100d99 <__intr_restore> +} +c010160e: 90 nop +c010160f: 89 ec mov %ebp,%esp +c0101611: 5d pop %ebp +c0101612: c3 ret + +c0101613 : +/* * + * cons_getc - return the next input character from console, + * or 0 if none waiting. + * */ +int +cons_getc(void) { +c0101613: 55 push %ebp +c0101614: 89 e5 mov %esp,%ebp +c0101616: 83 ec 28 sub $0x28,%esp + int c = 0; +c0101619: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + bool intr_flag; + local_intr_save(intr_flag); +c0101620: e8 48 f7 ff ff call c0100d6d <__intr_save> +c0101625: 89 45 f0 mov %eax,-0x10(%ebp) + { + // poll for any pending input characters, + // so that this function works even when interrupts are disabled + // (e.g., when called from the kernel monitor). + serial_intr(); +c0101628: e8 9e fd ff ff call c01013cb + kbd_intr(); +c010162d: e8 40 ff ff ff call c0101572 + + // grab the next character from the input buffer. + if (cons.rpos != cons.wpos) { +c0101632: 8b 15 60 c6 11 c0 mov 0xc011c660,%edx +c0101638: a1 64 c6 11 c0 mov 0xc011c664,%eax +c010163d: 39 c2 cmp %eax,%edx +c010163f: 74 31 je c0101672 + c = cons.buf[cons.rpos ++]; +c0101641: a1 60 c6 11 c0 mov 0xc011c660,%eax +c0101646: 8d 50 01 lea 0x1(%eax),%edx +c0101649: 89 15 60 c6 11 c0 mov %edx,0xc011c660 +c010164f: 0f b6 80 60 c4 11 c0 movzbl -0x3fee3ba0(%eax),%eax +c0101656: 0f b6 c0 movzbl %al,%eax +c0101659: 89 45 f4 mov %eax,-0xc(%ebp) + if (cons.rpos == CONSBUFSIZE) { +c010165c: a1 60 c6 11 c0 mov 0xc011c660,%eax +c0101661: 3d 00 02 00 00 cmp $0x200,%eax +c0101666: 75 0a jne c0101672 + cons.rpos = 0; +c0101668: c7 05 60 c6 11 c0 00 movl $0x0,0xc011c660 +c010166f: 00 00 00 + } + } + } + local_intr_restore(intr_flag); +c0101672: 8b 45 f0 mov -0x10(%ebp),%eax +c0101675: 89 04 24 mov %eax,(%esp) +c0101678: e8 1c f7 ff ff call c0100d99 <__intr_restore> + return c; +c010167d: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0101680: 89 ec mov %ebp,%esp +c0101682: 5d pop %ebp +c0101683: c3 ret + +c0101684 : +#include +#include + +/* intr_enable - enable irq interrupt */ +void +intr_enable(void) { +c0101684: 55 push %ebp +c0101685: 89 e5 mov %esp,%ebp + asm volatile ("sti"); +c0101687: fb sti +} +c0101688: 90 nop + sti(); +} +c0101689: 90 nop +c010168a: 5d pop %ebp +c010168b: c3 ret + +c010168c : + +/* intr_disable - disable irq interrupt */ +void +intr_disable(void) { +c010168c: 55 push %ebp +c010168d: 89 e5 mov %esp,%ebp + asm volatile ("cli" ::: "memory"); +c010168f: fa cli +} +c0101690: 90 nop + cli(); +} +c0101691: 90 nop +c0101692: 5d pop %ebp +c0101693: c3 ret + +c0101694 : +// Initial IRQ mask has interrupt 2 enabled (for slave 8259A). +static uint16_t irq_mask = 0xFFFF & ~(1 << IRQ_SLAVE); +static bool did_init = 0; + +static void +pic_setmask(uint16_t mask) { +c0101694: 55 push %ebp +c0101695: 89 e5 mov %esp,%ebp +c0101697: 83 ec 14 sub $0x14,%esp +c010169a: 8b 45 08 mov 0x8(%ebp),%eax +c010169d: 66 89 45 ec mov %ax,-0x14(%ebp) + irq_mask = mask; +c01016a1: 8b 45 ec mov -0x14(%ebp),%eax +c01016a4: 66 a3 50 95 11 c0 mov %ax,0xc0119550 + if (did_init) { +c01016aa: a1 6c c6 11 c0 mov 0xc011c66c,%eax +c01016af: 85 c0 test %eax,%eax +c01016b1: 74 39 je c01016ec + outb(IO_PIC1 + 1, mask); +c01016b3: 8b 45 ec mov -0x14(%ebp),%eax +c01016b6: 0f b6 c0 movzbl %al,%eax +c01016b9: 66 c7 45 fa 21 00 movw $0x21,-0x6(%ebp) +c01016bf: 88 45 f9 mov %al,-0x7(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01016c2: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c01016c6: 0f b7 55 fa movzwl -0x6(%ebp),%edx +c01016ca: ee out %al,(%dx) +} +c01016cb: 90 nop + outb(IO_PIC2 + 1, mask >> 8); +c01016cc: 0f b7 45 ec movzwl -0x14(%ebp),%eax +c01016d0: c1 e8 08 shr $0x8,%eax +c01016d3: 0f b7 c0 movzwl %ax,%eax +c01016d6: 0f b6 c0 movzbl %al,%eax +c01016d9: 66 c7 45 fe a1 00 movw $0xa1,-0x2(%ebp) +c01016df: 88 45 fd mov %al,-0x3(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01016e2: 0f b6 45 fd movzbl -0x3(%ebp),%eax +c01016e6: 0f b7 55 fe movzwl -0x2(%ebp),%edx +c01016ea: ee out %al,(%dx) +} +c01016eb: 90 nop + } +} +c01016ec: 90 nop +c01016ed: 89 ec mov %ebp,%esp +c01016ef: 5d pop %ebp +c01016f0: c3 ret + +c01016f1 : + +void +pic_enable(unsigned int irq) { +c01016f1: 55 push %ebp +c01016f2: 89 e5 mov %esp,%ebp +c01016f4: 83 ec 04 sub $0x4,%esp + pic_setmask(irq_mask & ~(1 << irq)); +c01016f7: 8b 45 08 mov 0x8(%ebp),%eax +c01016fa: ba 01 00 00 00 mov $0x1,%edx +c01016ff: 88 c1 mov %al,%cl +c0101701: d3 e2 shl %cl,%edx +c0101703: 89 d0 mov %edx,%eax +c0101705: 98 cwtl +c0101706: f7 d0 not %eax +c0101708: 0f bf d0 movswl %ax,%edx +c010170b: 0f b7 05 50 95 11 c0 movzwl 0xc0119550,%eax +c0101712: 98 cwtl +c0101713: 21 d0 and %edx,%eax +c0101715: 98 cwtl +c0101716: 0f b7 c0 movzwl %ax,%eax +c0101719: 89 04 24 mov %eax,(%esp) +c010171c: e8 73 ff ff ff call c0101694 +} +c0101721: 90 nop +c0101722: 89 ec mov %ebp,%esp +c0101724: 5d pop %ebp +c0101725: c3 ret + +c0101726 : + +/* pic_init - initialize the 8259A interrupt controllers */ +void +pic_init(void) { +c0101726: 55 push %ebp +c0101727: 89 e5 mov %esp,%ebp +c0101729: 83 ec 44 sub $0x44,%esp + did_init = 1; +c010172c: c7 05 6c c6 11 c0 01 movl $0x1,0xc011c66c +c0101733: 00 00 00 +c0101736: 66 c7 45 ca 21 00 movw $0x21,-0x36(%ebp) +c010173c: c6 45 c9 ff movb $0xff,-0x37(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101740: 0f b6 45 c9 movzbl -0x37(%ebp),%eax +c0101744: 0f b7 55 ca movzwl -0x36(%ebp),%edx +c0101748: ee out %al,(%dx) +} +c0101749: 90 nop +c010174a: 66 c7 45 ce a1 00 movw $0xa1,-0x32(%ebp) +c0101750: c6 45 cd ff movb $0xff,-0x33(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101754: 0f b6 45 cd movzbl -0x33(%ebp),%eax +c0101758: 0f b7 55 ce movzwl -0x32(%ebp),%edx +c010175c: ee out %al,(%dx) +} +c010175d: 90 nop +c010175e: 66 c7 45 d2 20 00 movw $0x20,-0x2e(%ebp) +c0101764: c6 45 d1 11 movb $0x11,-0x2f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101768: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax +c010176c: 0f b7 55 d2 movzwl -0x2e(%ebp),%edx +c0101770: ee out %al,(%dx) +} +c0101771: 90 nop +c0101772: 66 c7 45 d6 21 00 movw $0x21,-0x2a(%ebp) +c0101778: c6 45 d5 20 movb $0x20,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010177c: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax +c0101780: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx +c0101784: ee out %al,(%dx) +} +c0101785: 90 nop +c0101786: 66 c7 45 da 21 00 movw $0x21,-0x26(%ebp) +c010178c: c6 45 d9 04 movb $0x4,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101790: 0f b6 45 d9 movzbl -0x27(%ebp),%eax +c0101794: 0f b7 55 da movzwl -0x26(%ebp),%edx +c0101798: ee out %al,(%dx) +} +c0101799: 90 nop +c010179a: 66 c7 45 de 21 00 movw $0x21,-0x22(%ebp) +c01017a0: c6 45 dd 03 movb $0x3,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01017a4: 0f b6 45 dd movzbl -0x23(%ebp),%eax +c01017a8: 0f b7 55 de movzwl -0x22(%ebp),%edx +c01017ac: ee out %al,(%dx) +} +c01017ad: 90 nop +c01017ae: 66 c7 45 e2 a0 00 movw $0xa0,-0x1e(%ebp) +c01017b4: c6 45 e1 11 movb $0x11,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01017b8: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax +c01017bc: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx +c01017c0: ee out %al,(%dx) +} +c01017c1: 90 nop +c01017c2: 66 c7 45 e6 a1 00 movw $0xa1,-0x1a(%ebp) +c01017c8: c6 45 e5 28 movb $0x28,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01017cc: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax +c01017d0: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx +c01017d4: ee out %al,(%dx) +} +c01017d5: 90 nop +c01017d6: 66 c7 45 ea a1 00 movw $0xa1,-0x16(%ebp) +c01017dc: c6 45 e9 02 movb $0x2,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01017e0: 0f b6 45 e9 movzbl -0x17(%ebp),%eax +c01017e4: 0f b7 55 ea movzwl -0x16(%ebp),%edx +c01017e8: ee out %al,(%dx) +} +c01017e9: 90 nop +c01017ea: 66 c7 45 ee a1 00 movw $0xa1,-0x12(%ebp) +c01017f0: c6 45 ed 03 movb $0x3,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c01017f4: 0f b6 45 ed movzbl -0x13(%ebp),%eax +c01017f8: 0f b7 55 ee movzwl -0x12(%ebp),%edx +c01017fc: ee out %al,(%dx) +} +c01017fd: 90 nop +c01017fe: 66 c7 45 f2 20 00 movw $0x20,-0xe(%ebp) +c0101804: c6 45 f1 68 movb $0x68,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101808: 0f b6 45 f1 movzbl -0xf(%ebp),%eax +c010180c: 0f b7 55 f2 movzwl -0xe(%ebp),%edx +c0101810: ee out %al,(%dx) +} +c0101811: 90 nop +c0101812: 66 c7 45 f6 20 00 movw $0x20,-0xa(%ebp) +c0101818: c6 45 f5 0a movb $0xa,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c010181c: 0f b6 45 f5 movzbl -0xb(%ebp),%eax +c0101820: 0f b7 55 f6 movzwl -0xa(%ebp),%edx +c0101824: ee out %al,(%dx) +} +c0101825: 90 nop +c0101826: 66 c7 45 fa a0 00 movw $0xa0,-0x6(%ebp) +c010182c: c6 45 f9 68 movb $0x68,-0x7(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101830: 0f b6 45 f9 movzbl -0x7(%ebp),%eax +c0101834: 0f b7 55 fa movzwl -0x6(%ebp),%edx +c0101838: ee out %al,(%dx) +} +c0101839: 90 nop +c010183a: 66 c7 45 fe a0 00 movw $0xa0,-0x2(%ebp) +c0101840: c6 45 fd 0a movb $0xa,-0x3(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); +c0101844: 0f b6 45 fd movzbl -0x3(%ebp),%eax +c0101848: 0f b7 55 fe movzwl -0x2(%ebp),%edx +c010184c: ee out %al,(%dx) +} +c010184d: 90 nop + outb(IO_PIC1, 0x0a); // read IRR by default + + outb(IO_PIC2, 0x68); // OCW3 + outb(IO_PIC2, 0x0a); // OCW3 + + if (irq_mask != 0xFFFF) { +c010184e: 0f b7 05 50 95 11 c0 movzwl 0xc0119550,%eax +c0101855: 3d ff ff 00 00 cmp $0xffff,%eax +c010185a: 74 0f je c010186b + pic_setmask(irq_mask); +c010185c: 0f b7 05 50 95 11 c0 movzwl 0xc0119550,%eax +c0101863: 89 04 24 mov %eax,(%esp) +c0101866: e8 29 fe ff ff call c0101694 + } +} +c010186b: 90 nop +c010186c: 89 ec mov %ebp,%esp +c010186e: 5d pop %ebp +c010186f: c3 ret + +c0101870 : +#include +#include + +#define TICK_NUM 100 + +static void print_ticks() { +c0101870: 55 push %ebp +c0101871: 89 e5 mov %esp,%ebp +c0101873: 83 ec 18 sub $0x18,%esp + cprintf("%d ticks\n",TICK_NUM); +c0101876: c7 44 24 04 64 00 00 movl $0x64,0x4(%esp) +c010187d: 00 +c010187e: c7 04 24 e0 63 10 c0 movl $0xc01063e0,(%esp) +c0101885: e8 dc ea ff ff call c0100366 +#ifdef DEBUG_GRADE + cprintf("End of Test.\n"); + panic("EOT: kernel seems ok."); +#endif +} +c010188a: 90 nop +c010188b: 89 ec mov %ebp,%esp +c010188d: 5d pop %ebp +c010188e: c3 ret + +c010188f : + sizeof(idt) - 1, (uintptr_t)idt +}; + +/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */ +void +idt_init(void) { +c010188f: 55 push %ebp +c0101890: 89 e5 mov %esp,%ebp +c0101892: 83 ec 10 sub $0x10,%esp + * You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more. + * Notice: the argument of lidt is idt_pd. try to find it! + */ + extern uintptr_t __vectors[];//声明了一个外部数组 __vectors,该数组存储中断服务例程(ISR)的地址。 + int i; + for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { +c0101895: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) +c010189c: e9 c4 00 00 00 jmp c0101965 + SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL); +c01018a1: 8b 45 fc mov -0x4(%ebp),%eax +c01018a4: 8b 04 85 e0 95 11 c0 mov -0x3fee6a20(,%eax,4),%eax +c01018ab: 0f b7 d0 movzwl %ax,%edx +c01018ae: 8b 45 fc mov -0x4(%ebp),%eax +c01018b1: 66 89 14 c5 e0 c6 11 mov %dx,-0x3fee3920(,%eax,8) +c01018b8: c0 +c01018b9: 8b 45 fc mov -0x4(%ebp),%eax +c01018bc: 66 c7 04 c5 e2 c6 11 movw $0x8,-0x3fee391e(,%eax,8) +c01018c3: c0 08 00 +c01018c6: 8b 45 fc mov -0x4(%ebp),%eax +c01018c9: 0f b6 14 c5 e4 c6 11 movzbl -0x3fee391c(,%eax,8),%edx +c01018d0: c0 +c01018d1: 80 e2 e0 and $0xe0,%dl +c01018d4: 88 14 c5 e4 c6 11 c0 mov %dl,-0x3fee391c(,%eax,8) +c01018db: 8b 45 fc mov -0x4(%ebp),%eax +c01018de: 0f b6 14 c5 e4 c6 11 movzbl -0x3fee391c(,%eax,8),%edx +c01018e5: c0 +c01018e6: 80 e2 1f and $0x1f,%dl +c01018e9: 88 14 c5 e4 c6 11 c0 mov %dl,-0x3fee391c(,%eax,8) +c01018f0: 8b 45 fc mov -0x4(%ebp),%eax +c01018f3: 0f b6 14 c5 e5 c6 11 movzbl -0x3fee391b(,%eax,8),%edx +c01018fa: c0 +c01018fb: 80 e2 f0 and $0xf0,%dl +c01018fe: 80 ca 0e or $0xe,%dl +c0101901: 88 14 c5 e5 c6 11 c0 mov %dl,-0x3fee391b(,%eax,8) +c0101908: 8b 45 fc mov -0x4(%ebp),%eax +c010190b: 0f b6 14 c5 e5 c6 11 movzbl -0x3fee391b(,%eax,8),%edx +c0101912: c0 +c0101913: 80 e2 ef and $0xef,%dl +c0101916: 88 14 c5 e5 c6 11 c0 mov %dl,-0x3fee391b(,%eax,8) +c010191d: 8b 45 fc mov -0x4(%ebp),%eax +c0101920: 0f b6 14 c5 e5 c6 11 movzbl -0x3fee391b(,%eax,8),%edx +c0101927: c0 +c0101928: 80 e2 9f and $0x9f,%dl +c010192b: 88 14 c5 e5 c6 11 c0 mov %dl,-0x3fee391b(,%eax,8) +c0101932: 8b 45 fc mov -0x4(%ebp),%eax +c0101935: 0f b6 14 c5 e5 c6 11 movzbl -0x3fee391b(,%eax,8),%edx +c010193c: c0 +c010193d: 80 ca 80 or $0x80,%dl +c0101940: 88 14 c5 e5 c6 11 c0 mov %dl,-0x3fee391b(,%eax,8) +c0101947: 8b 45 fc mov -0x4(%ebp),%eax +c010194a: 8b 04 85 e0 95 11 c0 mov -0x3fee6a20(,%eax,4),%eax +c0101951: c1 e8 10 shr $0x10,%eax +c0101954: 0f b7 d0 movzwl %ax,%edx +c0101957: 8b 45 fc mov -0x4(%ebp),%eax +c010195a: 66 89 14 c5 e6 c6 11 mov %dx,-0x3fee391a(,%eax,8) +c0101961: c0 + for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { +c0101962: ff 45 fc incl -0x4(%ebp) +c0101965: 8b 45 fc mov -0x4(%ebp),%eax +c0101968: 3d ff 00 00 00 cmp $0xff,%eax +c010196d: 0f 86 2e ff ff ff jbe c01018a1 + //宏用于配置每个 IDT 条目.0 表示最高特权级(内核级)GD_KTEXT: 指向内核代码段的选择子,确保 ISR 在内核代码段中执行。 + //__vectors[i]: 对应中断的 ISR 地址,DPL_KERNEL: 描述符特权级,表示该中断只能由内核级代码触发。 + // set for switch from user to kernel + //SETGATE 这行代码特别设置了 T_SWITCH_TOK(一个特定的中断向量,用于用户态到内核态的切换)的 IDT 条目。 + //DPL_USER 表示该中断可以由用户态代码触发 + SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER); +c0101973: a1 c4 97 11 c0 mov 0xc01197c4,%eax +c0101978: 0f b7 c0 movzwl %ax,%eax +c010197b: 66 a3 a8 ca 11 c0 mov %ax,0xc011caa8 +c0101981: 66 c7 05 aa ca 11 c0 movw $0x8,0xc011caaa +c0101988: 08 00 +c010198a: 0f b6 05 ac ca 11 c0 movzbl 0xc011caac,%eax +c0101991: 24 e0 and $0xe0,%al +c0101993: a2 ac ca 11 c0 mov %al,0xc011caac +c0101998: 0f b6 05 ac ca 11 c0 movzbl 0xc011caac,%eax +c010199f: 24 1f and $0x1f,%al +c01019a1: a2 ac ca 11 c0 mov %al,0xc011caac +c01019a6: 0f b6 05 ad ca 11 c0 movzbl 0xc011caad,%eax +c01019ad: 24 f0 and $0xf0,%al +c01019af: 0c 0e or $0xe,%al +c01019b1: a2 ad ca 11 c0 mov %al,0xc011caad +c01019b6: 0f b6 05 ad ca 11 c0 movzbl 0xc011caad,%eax +c01019bd: 24 ef and $0xef,%al +c01019bf: a2 ad ca 11 c0 mov %al,0xc011caad +c01019c4: 0f b6 05 ad ca 11 c0 movzbl 0xc011caad,%eax +c01019cb: 0c 60 or $0x60,%al +c01019cd: a2 ad ca 11 c0 mov %al,0xc011caad +c01019d2: 0f b6 05 ad ca 11 c0 movzbl 0xc011caad,%eax +c01019d9: 0c 80 or $0x80,%al +c01019db: a2 ad ca 11 c0 mov %al,0xc011caad +c01019e0: a1 c4 97 11 c0 mov 0xc01197c4,%eax +c01019e5: c1 e8 10 shr $0x10,%eax +c01019e8: 0f b7 c0 movzwl %ax,%eax +c01019eb: 66 a3 ae ca 11 c0 mov %ax,0xc011caae +c01019f1: c7 45 f8 60 95 11 c0 movl $0xc0119560,-0x8(%ebp) + asm volatile ("lidt (%0)" :: "r" (pd) : "memory"); +c01019f8: 8b 45 f8 mov -0x8(%ebp),%eax +c01019fb: 0f 01 18 lidtl (%eax) +} +c01019fe: 90 nop + // load the IDT + //使用 lidt 指令将 IDT 描述符加载到 CPU 中 + lidt(&idt_pd); +} +c01019ff: 90 nop +c0101a00: 89 ec mov %ebp,%esp +c0101a02: 5d pop %ebp +c0101a03: c3 ret + +c0101a04 : + +static const char * +trapname(int trapno) { +c0101a04: 55 push %ebp +c0101a05: 89 e5 mov %esp,%ebp + "Alignment Check", + "Machine-Check", + "SIMD Floating-Point Exception" + }; + + if (trapno < sizeof(excnames)/sizeof(const char * const)) { +c0101a07: 8b 45 08 mov 0x8(%ebp),%eax +c0101a0a: 83 f8 13 cmp $0x13,%eax +c0101a0d: 77 0c ja c0101a1b + return excnames[trapno]; +c0101a0f: 8b 45 08 mov 0x8(%ebp),%eax +c0101a12: 8b 04 85 40 67 10 c0 mov -0x3fef98c0(,%eax,4),%eax +c0101a19: eb 18 jmp c0101a33 + } + if (trapno >= IRQ_OFFSET && trapno < IRQ_OFFSET + 16) { +c0101a1b: 83 7d 08 1f cmpl $0x1f,0x8(%ebp) +c0101a1f: 7e 0d jle c0101a2e +c0101a21: 83 7d 08 2f cmpl $0x2f,0x8(%ebp) +c0101a25: 7f 07 jg c0101a2e + return "Hardware Interrupt"; +c0101a27: b8 ea 63 10 c0 mov $0xc01063ea,%eax +c0101a2c: eb 05 jmp c0101a33 + } + return "(unknown trap)"; +c0101a2e: b8 fd 63 10 c0 mov $0xc01063fd,%eax +} +c0101a33: 5d pop %ebp +c0101a34: c3 ret + +c0101a35 : + +/* trap_in_kernel - test if trap happened in kernel */ +bool +trap_in_kernel(struct trapframe *tf) { +c0101a35: 55 push %ebp +c0101a36: 89 e5 mov %esp,%ebp + return (tf->tf_cs == (uint16_t)KERNEL_CS); +c0101a38: 8b 45 08 mov 0x8(%ebp),%eax +c0101a3b: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c0101a3f: 83 f8 08 cmp $0x8,%eax +c0101a42: 0f 94 c0 sete %al +c0101a45: 0f b6 c0 movzbl %al,%eax +} +c0101a48: 5d pop %ebp +c0101a49: c3 ret + +c0101a4a : + "TF", "IF", "DF", "OF", NULL, NULL, "NT", NULL, + "RF", "VM", "AC", "VIF", "VIP", "ID", NULL, NULL, +}; + +void +print_trapframe(struct trapframe *tf) { +c0101a4a: 55 push %ebp +c0101a4b: 89 e5 mov %esp,%ebp +c0101a4d: 83 ec 28 sub $0x28,%esp + cprintf("trapframe at %p\n", tf); +c0101a50: 8b 45 08 mov 0x8(%ebp),%eax +c0101a53: 89 44 24 04 mov %eax,0x4(%esp) +c0101a57: c7 04 24 3e 64 10 c0 movl $0xc010643e,(%esp) +c0101a5e: e8 03 e9 ff ff call c0100366 + print_regs(&tf->tf_regs); +c0101a63: 8b 45 08 mov 0x8(%ebp),%eax +c0101a66: 89 04 24 mov %eax,(%esp) +c0101a69: e8 8f 01 00 00 call c0101bfd + cprintf(" ds 0x----%04x\n", tf->tf_ds); +c0101a6e: 8b 45 08 mov 0x8(%ebp),%eax +c0101a71: 0f b7 40 2c movzwl 0x2c(%eax),%eax +c0101a75: 89 44 24 04 mov %eax,0x4(%esp) +c0101a79: c7 04 24 4f 64 10 c0 movl $0xc010644f,(%esp) +c0101a80: e8 e1 e8 ff ff call c0100366 + cprintf(" es 0x----%04x\n", tf->tf_es); +c0101a85: 8b 45 08 mov 0x8(%ebp),%eax +c0101a88: 0f b7 40 28 movzwl 0x28(%eax),%eax +c0101a8c: 89 44 24 04 mov %eax,0x4(%esp) +c0101a90: c7 04 24 62 64 10 c0 movl $0xc0106462,(%esp) +c0101a97: e8 ca e8 ff ff call c0100366 + cprintf(" fs 0x----%04x\n", tf->tf_fs); +c0101a9c: 8b 45 08 mov 0x8(%ebp),%eax +c0101a9f: 0f b7 40 24 movzwl 0x24(%eax),%eax +c0101aa3: 89 44 24 04 mov %eax,0x4(%esp) +c0101aa7: c7 04 24 75 64 10 c0 movl $0xc0106475,(%esp) +c0101aae: e8 b3 e8 ff ff call c0100366 + cprintf(" gs 0x----%04x\n", tf->tf_gs); +c0101ab3: 8b 45 08 mov 0x8(%ebp),%eax +c0101ab6: 0f b7 40 20 movzwl 0x20(%eax),%eax +c0101aba: 89 44 24 04 mov %eax,0x4(%esp) +c0101abe: c7 04 24 88 64 10 c0 movl $0xc0106488,(%esp) +c0101ac5: e8 9c e8 ff ff call c0100366 + cprintf(" trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno)); +c0101aca: 8b 45 08 mov 0x8(%ebp),%eax +c0101acd: 8b 40 30 mov 0x30(%eax),%eax +c0101ad0: 89 04 24 mov %eax,(%esp) +c0101ad3: e8 2c ff ff ff call c0101a04 +c0101ad8: 8b 55 08 mov 0x8(%ebp),%edx +c0101adb: 8b 52 30 mov 0x30(%edx),%edx +c0101ade: 89 44 24 08 mov %eax,0x8(%esp) +c0101ae2: 89 54 24 04 mov %edx,0x4(%esp) +c0101ae6: c7 04 24 9b 64 10 c0 movl $0xc010649b,(%esp) +c0101aed: e8 74 e8 ff ff call c0100366 + cprintf(" err 0x%08x\n", tf->tf_err); +c0101af2: 8b 45 08 mov 0x8(%ebp),%eax +c0101af5: 8b 40 34 mov 0x34(%eax),%eax +c0101af8: 89 44 24 04 mov %eax,0x4(%esp) +c0101afc: c7 04 24 ad 64 10 c0 movl $0xc01064ad,(%esp) +c0101b03: e8 5e e8 ff ff call c0100366 + cprintf(" eip 0x%08x\n", tf->tf_eip); +c0101b08: 8b 45 08 mov 0x8(%ebp),%eax +c0101b0b: 8b 40 38 mov 0x38(%eax),%eax +c0101b0e: 89 44 24 04 mov %eax,0x4(%esp) +c0101b12: c7 04 24 bc 64 10 c0 movl $0xc01064bc,(%esp) +c0101b19: e8 48 e8 ff ff call c0100366 + cprintf(" cs 0x----%04x\n", tf->tf_cs); +c0101b1e: 8b 45 08 mov 0x8(%ebp),%eax +c0101b21: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c0101b25: 89 44 24 04 mov %eax,0x4(%esp) +c0101b29: c7 04 24 cb 64 10 c0 movl $0xc01064cb,(%esp) +c0101b30: e8 31 e8 ff ff call c0100366 + cprintf(" flag 0x%08x ", tf->tf_eflags); +c0101b35: 8b 45 08 mov 0x8(%ebp),%eax +c0101b38: 8b 40 40 mov 0x40(%eax),%eax +c0101b3b: 89 44 24 04 mov %eax,0x4(%esp) +c0101b3f: c7 04 24 de 64 10 c0 movl $0xc01064de,(%esp) +c0101b46: e8 1b e8 ff ff call c0100366 + + int i, j; + for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) { +c0101b4b: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0101b52: c7 45 f0 01 00 00 00 movl $0x1,-0x10(%ebp) +c0101b59: eb 3d jmp c0101b98 + if ((tf->tf_eflags & j) && IA32flags[i] != NULL) { +c0101b5b: 8b 45 08 mov 0x8(%ebp),%eax +c0101b5e: 8b 50 40 mov 0x40(%eax),%edx +c0101b61: 8b 45 f0 mov -0x10(%ebp),%eax +c0101b64: 21 d0 and %edx,%eax +c0101b66: 85 c0 test %eax,%eax +c0101b68: 74 28 je c0101b92 +c0101b6a: 8b 45 f4 mov -0xc(%ebp),%eax +c0101b6d: 8b 04 85 80 95 11 c0 mov -0x3fee6a80(,%eax,4),%eax +c0101b74: 85 c0 test %eax,%eax +c0101b76: 74 1a je c0101b92 + cprintf("%s,", IA32flags[i]); +c0101b78: 8b 45 f4 mov -0xc(%ebp),%eax +c0101b7b: 8b 04 85 80 95 11 c0 mov -0x3fee6a80(,%eax,4),%eax +c0101b82: 89 44 24 04 mov %eax,0x4(%esp) +c0101b86: c7 04 24 ed 64 10 c0 movl $0xc01064ed,(%esp) +c0101b8d: e8 d4 e7 ff ff call c0100366 + for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) { +c0101b92: ff 45 f4 incl -0xc(%ebp) +c0101b95: d1 65 f0 shll -0x10(%ebp) +c0101b98: 8b 45 f4 mov -0xc(%ebp),%eax +c0101b9b: 83 f8 17 cmp $0x17,%eax +c0101b9e: 76 bb jbe c0101b5b + } + } + cprintf("IOPL=%d\n", (tf->tf_eflags & FL_IOPL_MASK) >> 12); +c0101ba0: 8b 45 08 mov 0x8(%ebp),%eax +c0101ba3: 8b 40 40 mov 0x40(%eax),%eax +c0101ba6: c1 e8 0c shr $0xc,%eax +c0101ba9: 83 e0 03 and $0x3,%eax +c0101bac: 89 44 24 04 mov %eax,0x4(%esp) +c0101bb0: c7 04 24 f1 64 10 c0 movl $0xc01064f1,(%esp) +c0101bb7: e8 aa e7 ff ff call c0100366 + + if (!trap_in_kernel(tf)) { +c0101bbc: 8b 45 08 mov 0x8(%ebp),%eax +c0101bbf: 89 04 24 mov %eax,(%esp) +c0101bc2: e8 6e fe ff ff call c0101a35 +c0101bc7: 85 c0 test %eax,%eax +c0101bc9: 75 2d jne c0101bf8 + cprintf(" esp 0x%08x\n", tf->tf_esp); +c0101bcb: 8b 45 08 mov 0x8(%ebp),%eax +c0101bce: 8b 40 44 mov 0x44(%eax),%eax +c0101bd1: 89 44 24 04 mov %eax,0x4(%esp) +c0101bd5: c7 04 24 fa 64 10 c0 movl $0xc01064fa,(%esp) +c0101bdc: e8 85 e7 ff ff call c0100366 + cprintf(" ss 0x----%04x\n", tf->tf_ss); +c0101be1: 8b 45 08 mov 0x8(%ebp),%eax +c0101be4: 0f b7 40 48 movzwl 0x48(%eax),%eax +c0101be8: 89 44 24 04 mov %eax,0x4(%esp) +c0101bec: c7 04 24 09 65 10 c0 movl $0xc0106509,(%esp) +c0101bf3: e8 6e e7 ff ff call c0100366 + } +} +c0101bf8: 90 nop +c0101bf9: 89 ec mov %ebp,%esp +c0101bfb: 5d pop %ebp +c0101bfc: c3 ret + +c0101bfd : + +void +print_regs(struct pushregs *regs) { +c0101bfd: 55 push %ebp +c0101bfe: 89 e5 mov %esp,%ebp +c0101c00: 83 ec 18 sub $0x18,%esp + cprintf(" edi 0x%08x\n", regs->reg_edi); +c0101c03: 8b 45 08 mov 0x8(%ebp),%eax +c0101c06: 8b 00 mov (%eax),%eax +c0101c08: 89 44 24 04 mov %eax,0x4(%esp) +c0101c0c: c7 04 24 1c 65 10 c0 movl $0xc010651c,(%esp) +c0101c13: e8 4e e7 ff ff call c0100366 + cprintf(" esi 0x%08x\n", regs->reg_esi); +c0101c18: 8b 45 08 mov 0x8(%ebp),%eax +c0101c1b: 8b 40 04 mov 0x4(%eax),%eax +c0101c1e: 89 44 24 04 mov %eax,0x4(%esp) +c0101c22: c7 04 24 2b 65 10 c0 movl $0xc010652b,(%esp) +c0101c29: e8 38 e7 ff ff call c0100366 + cprintf(" ebp 0x%08x\n", regs->reg_ebp); +c0101c2e: 8b 45 08 mov 0x8(%ebp),%eax +c0101c31: 8b 40 08 mov 0x8(%eax),%eax +c0101c34: 89 44 24 04 mov %eax,0x4(%esp) +c0101c38: c7 04 24 3a 65 10 c0 movl $0xc010653a,(%esp) +c0101c3f: e8 22 e7 ff ff call c0100366 + cprintf(" oesp 0x%08x\n", regs->reg_oesp); +c0101c44: 8b 45 08 mov 0x8(%ebp),%eax +c0101c47: 8b 40 0c mov 0xc(%eax),%eax +c0101c4a: 89 44 24 04 mov %eax,0x4(%esp) +c0101c4e: c7 04 24 49 65 10 c0 movl $0xc0106549,(%esp) +c0101c55: e8 0c e7 ff ff call c0100366 + cprintf(" ebx 0x%08x\n", regs->reg_ebx); +c0101c5a: 8b 45 08 mov 0x8(%ebp),%eax +c0101c5d: 8b 40 10 mov 0x10(%eax),%eax +c0101c60: 89 44 24 04 mov %eax,0x4(%esp) +c0101c64: c7 04 24 58 65 10 c0 movl $0xc0106558,(%esp) +c0101c6b: e8 f6 e6 ff ff call c0100366 + cprintf(" edx 0x%08x\n", regs->reg_edx); +c0101c70: 8b 45 08 mov 0x8(%ebp),%eax +c0101c73: 8b 40 14 mov 0x14(%eax),%eax +c0101c76: 89 44 24 04 mov %eax,0x4(%esp) +c0101c7a: c7 04 24 67 65 10 c0 movl $0xc0106567,(%esp) +c0101c81: e8 e0 e6 ff ff call c0100366 + cprintf(" ecx 0x%08x\n", regs->reg_ecx); +c0101c86: 8b 45 08 mov 0x8(%ebp),%eax +c0101c89: 8b 40 18 mov 0x18(%eax),%eax +c0101c8c: 89 44 24 04 mov %eax,0x4(%esp) +c0101c90: c7 04 24 76 65 10 c0 movl $0xc0106576,(%esp) +c0101c97: e8 ca e6 ff ff call c0100366 + cprintf(" eax 0x%08x\n", regs->reg_eax); +c0101c9c: 8b 45 08 mov 0x8(%ebp),%eax +c0101c9f: 8b 40 1c mov 0x1c(%eax),%eax +c0101ca2: 89 44 24 04 mov %eax,0x4(%esp) +c0101ca6: c7 04 24 85 65 10 c0 movl $0xc0106585,(%esp) +c0101cad: e8 b4 e6 ff ff call c0100366 +} +c0101cb2: 90 nop +c0101cb3: 89 ec mov %ebp,%esp +c0101cb5: 5d pop %ebp +c0101cb6: c3 ret + +c0101cb7 : + +struct trapframe switchk2u, *switchu2k; +/* trap_dispatch - dispatch based on what type of trap occurred */ +static void +trap_dispatch(struct trapframe *tf) { +c0101cb7: 55 push %ebp +c0101cb8: 89 e5 mov %esp,%ebp +c0101cba: 83 ec 28 sub $0x28,%esp +c0101cbd: 89 5d fc mov %ebx,-0x4(%ebp) + char c; + + switch (tf->tf_trapno) { +c0101cc0: 8b 45 08 mov 0x8(%ebp),%eax +c0101cc3: 8b 40 30 mov 0x30(%eax),%eax +c0101cc6: 83 f8 79 cmp $0x79,%eax +c0101cc9: 0f 84 6c 01 00 00 je c0101e3b +c0101ccf: 83 f8 79 cmp $0x79,%eax +c0101cd2: 0f 87 e0 01 00 00 ja c0101eb8 +c0101cd8: 83 f8 78 cmp $0x78,%eax +c0101cdb: 0f 84 d0 00 00 00 je c0101db1 +c0101ce1: 83 f8 78 cmp $0x78,%eax +c0101ce4: 0f 87 ce 01 00 00 ja c0101eb8 +c0101cea: 83 f8 2f cmp $0x2f,%eax +c0101ced: 0f 87 c5 01 00 00 ja c0101eb8 +c0101cf3: 83 f8 2e cmp $0x2e,%eax +c0101cf6: 0f 83 f1 01 00 00 jae c0101eed +c0101cfc: 83 f8 24 cmp $0x24,%eax +c0101cff: 74 5e je c0101d5f +c0101d01: 83 f8 24 cmp $0x24,%eax +c0101d04: 0f 87 ae 01 00 00 ja c0101eb8 +c0101d0a: 83 f8 20 cmp $0x20,%eax +c0101d0d: 74 0a je c0101d19 +c0101d0f: 83 f8 21 cmp $0x21,%eax +c0101d12: 74 74 je c0101d88 +c0101d14: e9 9f 01 00 00 jmp c0101eb8 + /* handle the timer interrupt */ + /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c + * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks(). + * (3) Too Simple? Yes, I think so! + */ + ticks ++; //记录中断事件 +c0101d19: a1 24 c4 11 c0 mov 0xc011c424,%eax +c0101d1e: 40 inc %eax +c0101d1f: a3 24 c4 11 c0 mov %eax,0xc011c424 + if (ticks % TICK_NUM == 0) +c0101d24: 8b 0d 24 c4 11 c0 mov 0xc011c424,%ecx +c0101d2a: ba 1f 85 eb 51 mov $0x51eb851f,%edx +c0101d2f: 89 c8 mov %ecx,%eax +c0101d31: f7 e2 mul %edx +c0101d33: c1 ea 05 shr $0x5,%edx +c0101d36: 89 d0 mov %edx,%eax +c0101d38: c1 e0 02 shl $0x2,%eax +c0101d3b: 01 d0 add %edx,%eax +c0101d3d: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c0101d44: 01 d0 add %edx,%eax +c0101d46: c1 e0 02 shl $0x2,%eax +c0101d49: 29 c1 sub %eax,%ecx +c0101d4b: 89 ca mov %ecx,%edx +c0101d4d: 85 d2 test %edx,%edx +c0101d4f: 0f 85 9b 01 00 00 jne c0101ef0 + { + print_ticks(); +c0101d55: e8 16 fb ff ff call c0101870 + }//每经过 TICK_NUM 次周期时,调用 print_ticks() 打印信息。 + break; +c0101d5a: e9 91 01 00 00 jmp c0101ef0 + case IRQ_OFFSET + IRQ_COM1: + c = cons_getc(); +c0101d5f: e8 af f8 ff ff call c0101613 +c0101d64: 88 45 f7 mov %al,-0x9(%ebp) + cprintf("serial [%03d] %c\n", c, c); +c0101d67: 0f be 55 f7 movsbl -0x9(%ebp),%edx +c0101d6b: 0f be 45 f7 movsbl -0x9(%ebp),%eax +c0101d6f: 89 54 24 08 mov %edx,0x8(%esp) +c0101d73: 89 44 24 04 mov %eax,0x4(%esp) +c0101d77: c7 04 24 94 65 10 c0 movl $0xc0106594,(%esp) +c0101d7e: e8 e3 e5 ff ff call c0100366 + break; +c0101d83: e9 6f 01 00 00 jmp c0101ef7 + case IRQ_OFFSET + IRQ_KBD: + c = cons_getc(); +c0101d88: e8 86 f8 ff ff call c0101613 +c0101d8d: 88 45 f7 mov %al,-0x9(%ebp) + cprintf("kbd [%03d] %c\n", c, c); +c0101d90: 0f be 55 f7 movsbl -0x9(%ebp),%edx +c0101d94: 0f be 45 f7 movsbl -0x9(%ebp),%eax +c0101d98: 89 54 24 08 mov %edx,0x8(%esp) +c0101d9c: 89 44 24 04 mov %eax,0x4(%esp) +c0101da0: c7 04 24 a6 65 10 c0 movl $0xc01065a6,(%esp) +c0101da7: e8 ba e5 ff ff call c0100366 + break; +c0101dac: e9 46 01 00 00 jmp c0101ef7 + //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes. + case T_SWITCH_TOU://表示发生了从内核模式切换到用户模式的请求。 + if (tf->tf_cs != USER_CS) {//判断当前是否在内核模式下 +c0101db1: 8b 45 08 mov 0x8(%ebp),%eax +c0101db4: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c0101db8: 83 f8 1b cmp $0x1b,%eax +c0101dbb: 0f 84 32 01 00 00 je c0101ef3 + switchk2u = *tf; //保存当前陷阱框架 +c0101dc1: 8b 4d 08 mov 0x8(%ebp),%ecx +c0101dc4: b8 4c 00 00 00 mov $0x4c,%eax +c0101dc9: 83 e0 fc and $0xfffffffc,%eax +c0101dcc: 89 c3 mov %eax,%ebx +c0101dce: b8 00 00 00 00 mov $0x0,%eax +c0101dd3: 8b 14 01 mov (%ecx,%eax,1),%edx +c0101dd6: 89 90 80 c6 11 c0 mov %edx,-0x3fee3980(%eax) +c0101ddc: 83 c0 04 add $0x4,%eax +c0101ddf: 39 d8 cmp %ebx,%eax +c0101de1: 72 f0 jb c0101dd3 + switchk2u.tf_cs = USER_CS;//设置用户模式的段寄存器 +c0101de3: 66 c7 05 bc c6 11 c0 movw $0x1b,0xc011c6bc +c0101dea: 1b 00 + //将数据段和栈段寄存器 都设置为 USER_DS(用户数据段) + switchk2u.tf_ds = switchk2u.tf_es = switchk2u.tf_ss = USER_DS; +c0101dec: 66 c7 05 c8 c6 11 c0 movw $0x23,0xc011c6c8 +c0101df3: 23 00 +c0101df5: 0f b7 05 c8 c6 11 c0 movzwl 0xc011c6c8,%eax +c0101dfc: 66 a3 a8 c6 11 c0 mov %ax,0xc011c6a8 +c0101e02: 0f b7 05 a8 c6 11 c0 movzwl 0xc011c6a8,%eax +c0101e09: 66 a3 ac c6 11 c0 mov %ax,0xc011c6ac + switchk2u.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8; +c0101e0f: 8b 45 08 mov 0x8(%ebp),%eax +c0101e12: 83 c0 44 add $0x44,%eax +c0101e15: a3 c4 c6 11 c0 mov %eax,0xc011c6c4 + + // set eflags, make sure ucore can use io under user mode. + // if CPL > IOPL, then cpu will generate a general protection. + switchk2u.tf_eflags |= FL_IOPL_MASK;//允许用户模式下进行 I/O 操作 +c0101e1a: a1 c0 c6 11 c0 mov 0xc011c6c0,%eax +c0101e1f: 0d 00 30 00 00 or $0x3000,%eax +c0101e24: a3 c0 c6 11 c0 mov %eax,0xc011c6c0 + + // set temporary stack + // then iret will jump to the right stack + *((uint32_t *)tf - 1) = (uint32_t)&switchk2u; +c0101e29: 8b 45 08 mov 0x8(%ebp),%eax +c0101e2c: 83 e8 04 sub $0x4,%eax +c0101e2f: ba 80 c6 11 c0 mov $0xc011c680,%edx +c0101e34: 89 10 mov %edx,(%eax) + } + break; +c0101e36: e9 b8 00 00 00 jmp c0101ef3 + case T_SWITCH_TOK: // T_SWITCH_TOK 表示发生了从用户模式切换到内核模式的请求。 + if (tf->tf_cs != KERNEL_CS) { //判断当前是否在用户模式下 +c0101e3b: 8b 45 08 mov 0x8(%ebp),%eax +c0101e3e: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c0101e42: 83 f8 08 cmp $0x8,%eax +c0101e45: 0f 84 ab 00 00 00 je c0101ef6 + tf->tf_cs = KERNEL_CS; +c0101e4b: 8b 45 08 mov 0x8(%ebp),%eax +c0101e4e: 66 c7 40 3c 08 00 movw $0x8,0x3c(%eax) + tf->tf_ds = tf->tf_es = KERNEL_DS; +c0101e54: 8b 45 08 mov 0x8(%ebp),%eax +c0101e57: 66 c7 40 28 10 00 movw $0x10,0x28(%eax) +c0101e5d: 8b 45 08 mov 0x8(%ebp),%eax +c0101e60: 0f b7 50 28 movzwl 0x28(%eax),%edx +c0101e64: 8b 45 08 mov 0x8(%ebp),%eax +c0101e67: 66 89 50 2c mov %dx,0x2c(%eax) + //设置内核模式的段寄存器 + tf->tf_eflags &= ~FL_IOPL_MASK; //清除 I/O 权限标志 +c0101e6b: 8b 45 08 mov 0x8(%ebp),%eax +c0101e6e: 8b 40 40 mov 0x40(%eax),%eax +c0101e71: 25 ff cf ff ff and $0xffffcfff,%eax +c0101e76: 89 c2 mov %eax,%edx +c0101e78: 8b 45 08 mov 0x8(%ebp),%eax +c0101e7b: 89 50 40 mov %edx,0x40(%eax) + switchu2k = (struct trapframe *)(tf->tf_esp - (sizeof(struct trapframe) - 8)); +c0101e7e: 8b 45 08 mov 0x8(%ebp),%eax +c0101e81: 8b 40 44 mov 0x44(%eax),%eax +c0101e84: 83 e8 44 sub $0x44,%eax +c0101e87: a3 cc c6 11 c0 mov %eax,0xc011c6cc + //使用 memmove 将当前的陷阱框架(除了最后8个字节)复制到新的陷阱框架位置 switchu2k + memmove(switchu2k, tf, sizeof(struct trapframe) - 8); +c0101e8c: a1 cc c6 11 c0 mov 0xc011c6cc,%eax +c0101e91: c7 44 24 08 44 00 00 movl $0x44,0x8(%esp) +c0101e98: 00 +c0101e99: 8b 55 08 mov 0x8(%ebp),%edx +c0101e9c: 89 54 24 04 mov %edx,0x4(%esp) +c0101ea0: 89 04 24 mov %eax,(%esp) +c0101ea3: e8 a2 40 00 00 call c0105f4a + //将新的陷阱框架地址 switchu2k 存储到当前陷阱框架之前的一个栈位置 + *((uint32_t *)tf - 1) = (uint32_t)switchu2k; +c0101ea8: 8b 15 cc c6 11 c0 mov 0xc011c6cc,%edx +c0101eae: 8b 45 08 mov 0x8(%ebp),%eax +c0101eb1: 83 e8 04 sub $0x4,%eax +c0101eb4: 89 10 mov %edx,(%eax) + } + break; +c0101eb6: eb 3e jmp c0101ef6 + case IRQ_OFFSET + IRQ_IDE2: + /* do nothing */ + break; + default: + // in kernel, it must be a mistake + if ((tf->tf_cs & 3) == 0) { +c0101eb8: 8b 45 08 mov 0x8(%ebp),%eax +c0101ebb: 0f b7 40 3c movzwl 0x3c(%eax),%eax +c0101ebf: 83 e0 03 and $0x3,%eax +c0101ec2: 85 c0 test %eax,%eax +c0101ec4: 75 31 jne c0101ef7 + print_trapframe(tf); +c0101ec6: 8b 45 08 mov 0x8(%ebp),%eax +c0101ec9: 89 04 24 mov %eax,(%esp) +c0101ecc: e8 79 fb ff ff call c0101a4a + panic("unexpected trap in kernel.\n"); +c0101ed1: c7 44 24 08 b5 65 10 movl $0xc01065b5,0x8(%esp) +c0101ed8: c0 +c0101ed9: c7 44 24 04 dc 00 00 movl $0xdc,0x4(%esp) +c0101ee0: 00 +c0101ee1: c7 04 24 d1 65 10 c0 movl $0xc01065d1,(%esp) +c0101ee8: e8 46 ed ff ff call c0100c33 <__panic> + break; +c0101eed: 90 nop +c0101eee: eb 07 jmp c0101ef7 + break; +c0101ef0: 90 nop +c0101ef1: eb 04 jmp c0101ef7 + break; +c0101ef3: 90 nop +c0101ef4: eb 01 jmp c0101ef7 + break; +c0101ef6: 90 nop + } + } +} +c0101ef7: 90 nop +c0101ef8: 8b 5d fc mov -0x4(%ebp),%ebx +c0101efb: 89 ec mov %ebp,%esp +c0101efd: 5d pop %ebp +c0101efe: c3 ret + +c0101eff : + * trap - handles or dispatches an exception/interrupt. if and when trap() returns, + * the code in kern/trap/trapentry.S restores the old CPU state saved in the + * trapframe and then uses the iret instruction to return from the exception. + * */ +void +trap(struct trapframe *tf) { +c0101eff: 55 push %ebp +c0101f00: 89 e5 mov %esp,%ebp +c0101f02: 83 ec 18 sub $0x18,%esp + // dispatch based on what type of trap occurred + trap_dispatch(tf); +c0101f05: 8b 45 08 mov 0x8(%ebp),%eax +c0101f08: 89 04 24 mov %eax,(%esp) +c0101f0b: e8 a7 fd ff ff call c0101cb7 +} +c0101f10: 90 nop +c0101f11: 89 ec mov %ebp,%esp +c0101f13: 5d pop %ebp +c0101f14: c3 ret + +c0101f15 <__alltraps>: +.text +.globl __alltraps +__alltraps: + # push registers to build a trap frame + # therefore make the stack look like a struct trapframe + pushl %ds +c0101f15: 1e push %ds + pushl %es +c0101f16: 06 push %es + pushl %fs +c0101f17: 0f a0 push %fs + pushl %gs +c0101f19: 0f a8 push %gs + pushal +c0101f1b: 60 pusha + + # load GD_KDATA into %ds and %es to set up data segments for kernel + movl $GD_KDATA, %eax +c0101f1c: b8 10 00 00 00 mov $0x10,%eax + movw %ax, %ds +c0101f21: 8e d8 mov %eax,%ds + movw %ax, %es +c0101f23: 8e c0 mov %eax,%es + + # push %esp to pass a pointer to the trapframe as an argument to trap() + pushl %esp +c0101f25: 54 push %esp + + # call trap(tf), where tf=%esp + call trap +c0101f26: e8 d4 ff ff ff call c0101eff + + # pop the pushed stack pointer + popl %esp +c0101f2b: 5c pop %esp + +c0101f2c <__trapret>: + + # return falls through to trapret... +.globl __trapret +__trapret: + # restore registers from stack + popal +c0101f2c: 61 popa + + # restore %ds, %es, %fs and %gs + popl %gs +c0101f2d: 0f a9 pop %gs + popl %fs +c0101f2f: 0f a1 pop %fs + popl %es +c0101f31: 07 pop %es + popl %ds +c0101f32: 1f pop %ds + + # get rid of the trap number and error code + addl $0x8, %esp +c0101f33: 83 c4 08 add $0x8,%esp + iret +c0101f36: cf iret + +c0101f37 : +# handler +.text +.globl __alltraps +.globl vector0 +vector0: + pushl $0 +c0101f37: 6a 00 push $0x0 + pushl $0 +c0101f39: 6a 00 push $0x0 + jmp __alltraps +c0101f3b: e9 d5 ff ff ff jmp c0101f15 <__alltraps> + +c0101f40 : +.globl vector1 +vector1: + pushl $0 +c0101f40: 6a 00 push $0x0 + pushl $1 +c0101f42: 6a 01 push $0x1 + jmp __alltraps +c0101f44: e9 cc ff ff ff jmp c0101f15 <__alltraps> + +c0101f49 : +.globl vector2 +vector2: + pushl $0 +c0101f49: 6a 00 push $0x0 + pushl $2 +c0101f4b: 6a 02 push $0x2 + jmp __alltraps +c0101f4d: e9 c3 ff ff ff jmp c0101f15 <__alltraps> + +c0101f52 : +.globl vector3 +vector3: + pushl $0 +c0101f52: 6a 00 push $0x0 + pushl $3 +c0101f54: 6a 03 push $0x3 + jmp __alltraps +c0101f56: e9 ba ff ff ff jmp c0101f15 <__alltraps> + +c0101f5b : +.globl vector4 +vector4: + pushl $0 +c0101f5b: 6a 00 push $0x0 + pushl $4 +c0101f5d: 6a 04 push $0x4 + jmp __alltraps +c0101f5f: e9 b1 ff ff ff jmp c0101f15 <__alltraps> + +c0101f64 : +.globl vector5 +vector5: + pushl $0 +c0101f64: 6a 00 push $0x0 + pushl $5 +c0101f66: 6a 05 push $0x5 + jmp __alltraps +c0101f68: e9 a8 ff ff ff jmp c0101f15 <__alltraps> + +c0101f6d : +.globl vector6 +vector6: + pushl $0 +c0101f6d: 6a 00 push $0x0 + pushl $6 +c0101f6f: 6a 06 push $0x6 + jmp __alltraps +c0101f71: e9 9f ff ff ff jmp c0101f15 <__alltraps> + +c0101f76 : +.globl vector7 +vector7: + pushl $0 +c0101f76: 6a 00 push $0x0 + pushl $7 +c0101f78: 6a 07 push $0x7 + jmp __alltraps +c0101f7a: e9 96 ff ff ff jmp c0101f15 <__alltraps> + +c0101f7f : +.globl vector8 +vector8: + pushl $8 +c0101f7f: 6a 08 push $0x8 + jmp __alltraps +c0101f81: e9 8f ff ff ff jmp c0101f15 <__alltraps> + +c0101f86 : +.globl vector9 +vector9: + pushl $0 +c0101f86: 6a 00 push $0x0 + pushl $9 +c0101f88: 6a 09 push $0x9 + jmp __alltraps +c0101f8a: e9 86 ff ff ff jmp c0101f15 <__alltraps> + +c0101f8f : +.globl vector10 +vector10: + pushl $10 +c0101f8f: 6a 0a push $0xa + jmp __alltraps +c0101f91: e9 7f ff ff ff jmp c0101f15 <__alltraps> + +c0101f96 : +.globl vector11 +vector11: + pushl $11 +c0101f96: 6a 0b push $0xb + jmp __alltraps +c0101f98: e9 78 ff ff ff jmp c0101f15 <__alltraps> + +c0101f9d : +.globl vector12 +vector12: + pushl $12 +c0101f9d: 6a 0c push $0xc + jmp __alltraps +c0101f9f: e9 71 ff ff ff jmp c0101f15 <__alltraps> + +c0101fa4 : +.globl vector13 +vector13: + pushl $13 +c0101fa4: 6a 0d push $0xd + jmp __alltraps +c0101fa6: e9 6a ff ff ff jmp c0101f15 <__alltraps> + +c0101fab : +.globl vector14 +vector14: + pushl $14 +c0101fab: 6a 0e push $0xe + jmp __alltraps +c0101fad: e9 63 ff ff ff jmp c0101f15 <__alltraps> + +c0101fb2 : +.globl vector15 +vector15: + pushl $0 +c0101fb2: 6a 00 push $0x0 + pushl $15 +c0101fb4: 6a 0f push $0xf + jmp __alltraps +c0101fb6: e9 5a ff ff ff jmp c0101f15 <__alltraps> + +c0101fbb : +.globl vector16 +vector16: + pushl $0 +c0101fbb: 6a 00 push $0x0 + pushl $16 +c0101fbd: 6a 10 push $0x10 + jmp __alltraps +c0101fbf: e9 51 ff ff ff jmp c0101f15 <__alltraps> + +c0101fc4 : +.globl vector17 +vector17: + pushl $17 +c0101fc4: 6a 11 push $0x11 + jmp __alltraps +c0101fc6: e9 4a ff ff ff jmp c0101f15 <__alltraps> + +c0101fcb : +.globl vector18 +vector18: + pushl $0 +c0101fcb: 6a 00 push $0x0 + pushl $18 +c0101fcd: 6a 12 push $0x12 + jmp __alltraps +c0101fcf: e9 41 ff ff ff jmp c0101f15 <__alltraps> + +c0101fd4 : +.globl vector19 +vector19: + pushl $0 +c0101fd4: 6a 00 push $0x0 + pushl $19 +c0101fd6: 6a 13 push $0x13 + jmp __alltraps +c0101fd8: e9 38 ff ff ff jmp c0101f15 <__alltraps> + +c0101fdd : +.globl vector20 +vector20: + pushl $0 +c0101fdd: 6a 00 push $0x0 + pushl $20 +c0101fdf: 6a 14 push $0x14 + jmp __alltraps +c0101fe1: e9 2f ff ff ff jmp c0101f15 <__alltraps> + +c0101fe6 : +.globl vector21 +vector21: + pushl $0 +c0101fe6: 6a 00 push $0x0 + pushl $21 +c0101fe8: 6a 15 push $0x15 + jmp __alltraps +c0101fea: e9 26 ff ff ff jmp c0101f15 <__alltraps> + +c0101fef : +.globl vector22 +vector22: + pushl $0 +c0101fef: 6a 00 push $0x0 + pushl $22 +c0101ff1: 6a 16 push $0x16 + jmp __alltraps +c0101ff3: e9 1d ff ff ff jmp c0101f15 <__alltraps> + +c0101ff8 : +.globl vector23 +vector23: + pushl $0 +c0101ff8: 6a 00 push $0x0 + pushl $23 +c0101ffa: 6a 17 push $0x17 + jmp __alltraps +c0101ffc: e9 14 ff ff ff jmp c0101f15 <__alltraps> + +c0102001 : +.globl vector24 +vector24: + pushl $0 +c0102001: 6a 00 push $0x0 + pushl $24 +c0102003: 6a 18 push $0x18 + jmp __alltraps +c0102005: e9 0b ff ff ff jmp c0101f15 <__alltraps> + +c010200a : +.globl vector25 +vector25: + pushl $0 +c010200a: 6a 00 push $0x0 + pushl $25 +c010200c: 6a 19 push $0x19 + jmp __alltraps +c010200e: e9 02 ff ff ff jmp c0101f15 <__alltraps> + +c0102013 : +.globl vector26 +vector26: + pushl $0 +c0102013: 6a 00 push $0x0 + pushl $26 +c0102015: 6a 1a push $0x1a + jmp __alltraps +c0102017: e9 f9 fe ff ff jmp c0101f15 <__alltraps> + +c010201c : +.globl vector27 +vector27: + pushl $0 +c010201c: 6a 00 push $0x0 + pushl $27 +c010201e: 6a 1b push $0x1b + jmp __alltraps +c0102020: e9 f0 fe ff ff jmp c0101f15 <__alltraps> + +c0102025 : +.globl vector28 +vector28: + pushl $0 +c0102025: 6a 00 push $0x0 + pushl $28 +c0102027: 6a 1c push $0x1c + jmp __alltraps +c0102029: e9 e7 fe ff ff jmp c0101f15 <__alltraps> + +c010202e : +.globl vector29 +vector29: + pushl $0 +c010202e: 6a 00 push $0x0 + pushl $29 +c0102030: 6a 1d push $0x1d + jmp __alltraps +c0102032: e9 de fe ff ff jmp c0101f15 <__alltraps> + +c0102037 : +.globl vector30 +vector30: + pushl $0 +c0102037: 6a 00 push $0x0 + pushl $30 +c0102039: 6a 1e push $0x1e + jmp __alltraps +c010203b: e9 d5 fe ff ff jmp c0101f15 <__alltraps> + +c0102040 : +.globl vector31 +vector31: + pushl $0 +c0102040: 6a 00 push $0x0 + pushl $31 +c0102042: 6a 1f push $0x1f + jmp __alltraps +c0102044: e9 cc fe ff ff jmp c0101f15 <__alltraps> + +c0102049 : +.globl vector32 +vector32: + pushl $0 +c0102049: 6a 00 push $0x0 + pushl $32 +c010204b: 6a 20 push $0x20 + jmp __alltraps +c010204d: e9 c3 fe ff ff jmp c0101f15 <__alltraps> + +c0102052 : +.globl vector33 +vector33: + pushl $0 +c0102052: 6a 00 push $0x0 + pushl $33 +c0102054: 6a 21 push $0x21 + jmp __alltraps +c0102056: e9 ba fe ff ff jmp c0101f15 <__alltraps> + +c010205b : +.globl vector34 +vector34: + pushl $0 +c010205b: 6a 00 push $0x0 + pushl $34 +c010205d: 6a 22 push $0x22 + jmp __alltraps +c010205f: e9 b1 fe ff ff jmp c0101f15 <__alltraps> + +c0102064 : +.globl vector35 +vector35: + pushl $0 +c0102064: 6a 00 push $0x0 + pushl $35 +c0102066: 6a 23 push $0x23 + jmp __alltraps +c0102068: e9 a8 fe ff ff jmp c0101f15 <__alltraps> + +c010206d : +.globl vector36 +vector36: + pushl $0 +c010206d: 6a 00 push $0x0 + pushl $36 +c010206f: 6a 24 push $0x24 + jmp __alltraps +c0102071: e9 9f fe ff ff jmp c0101f15 <__alltraps> + +c0102076 : +.globl vector37 +vector37: + pushl $0 +c0102076: 6a 00 push $0x0 + pushl $37 +c0102078: 6a 25 push $0x25 + jmp __alltraps +c010207a: e9 96 fe ff ff jmp c0101f15 <__alltraps> + +c010207f : +.globl vector38 +vector38: + pushl $0 +c010207f: 6a 00 push $0x0 + pushl $38 +c0102081: 6a 26 push $0x26 + jmp __alltraps +c0102083: e9 8d fe ff ff jmp c0101f15 <__alltraps> + +c0102088 : +.globl vector39 +vector39: + pushl $0 +c0102088: 6a 00 push $0x0 + pushl $39 +c010208a: 6a 27 push $0x27 + jmp __alltraps +c010208c: e9 84 fe ff ff jmp c0101f15 <__alltraps> + +c0102091 : +.globl vector40 +vector40: + pushl $0 +c0102091: 6a 00 push $0x0 + pushl $40 +c0102093: 6a 28 push $0x28 + jmp __alltraps +c0102095: e9 7b fe ff ff jmp c0101f15 <__alltraps> + +c010209a : +.globl vector41 +vector41: + pushl $0 +c010209a: 6a 00 push $0x0 + pushl $41 +c010209c: 6a 29 push $0x29 + jmp __alltraps +c010209e: e9 72 fe ff ff jmp c0101f15 <__alltraps> + +c01020a3 : +.globl vector42 +vector42: + pushl $0 +c01020a3: 6a 00 push $0x0 + pushl $42 +c01020a5: 6a 2a push $0x2a + jmp __alltraps +c01020a7: e9 69 fe ff ff jmp c0101f15 <__alltraps> + +c01020ac : +.globl vector43 +vector43: + pushl $0 +c01020ac: 6a 00 push $0x0 + pushl $43 +c01020ae: 6a 2b push $0x2b + jmp __alltraps +c01020b0: e9 60 fe ff ff jmp c0101f15 <__alltraps> + +c01020b5 : +.globl vector44 +vector44: + pushl $0 +c01020b5: 6a 00 push $0x0 + pushl $44 +c01020b7: 6a 2c push $0x2c + jmp __alltraps +c01020b9: e9 57 fe ff ff jmp c0101f15 <__alltraps> + +c01020be : +.globl vector45 +vector45: + pushl $0 +c01020be: 6a 00 push $0x0 + pushl $45 +c01020c0: 6a 2d push $0x2d + jmp __alltraps +c01020c2: e9 4e fe ff ff jmp c0101f15 <__alltraps> + +c01020c7 : +.globl vector46 +vector46: + pushl $0 +c01020c7: 6a 00 push $0x0 + pushl $46 +c01020c9: 6a 2e push $0x2e + jmp __alltraps +c01020cb: e9 45 fe ff ff jmp c0101f15 <__alltraps> + +c01020d0 : +.globl vector47 +vector47: + pushl $0 +c01020d0: 6a 00 push $0x0 + pushl $47 +c01020d2: 6a 2f push $0x2f + jmp __alltraps +c01020d4: e9 3c fe ff ff jmp c0101f15 <__alltraps> + +c01020d9 : +.globl vector48 +vector48: + pushl $0 +c01020d9: 6a 00 push $0x0 + pushl $48 +c01020db: 6a 30 push $0x30 + jmp __alltraps +c01020dd: e9 33 fe ff ff jmp c0101f15 <__alltraps> + +c01020e2 : +.globl vector49 +vector49: + pushl $0 +c01020e2: 6a 00 push $0x0 + pushl $49 +c01020e4: 6a 31 push $0x31 + jmp __alltraps +c01020e6: e9 2a fe ff ff jmp c0101f15 <__alltraps> + +c01020eb : +.globl vector50 +vector50: + pushl $0 +c01020eb: 6a 00 push $0x0 + pushl $50 +c01020ed: 6a 32 push $0x32 + jmp __alltraps +c01020ef: e9 21 fe ff ff jmp c0101f15 <__alltraps> + +c01020f4 : +.globl vector51 +vector51: + pushl $0 +c01020f4: 6a 00 push $0x0 + pushl $51 +c01020f6: 6a 33 push $0x33 + jmp __alltraps +c01020f8: e9 18 fe ff ff jmp c0101f15 <__alltraps> + +c01020fd : +.globl vector52 +vector52: + pushl $0 +c01020fd: 6a 00 push $0x0 + pushl $52 +c01020ff: 6a 34 push $0x34 + jmp __alltraps +c0102101: e9 0f fe ff ff jmp c0101f15 <__alltraps> + +c0102106 : +.globl vector53 +vector53: + pushl $0 +c0102106: 6a 00 push $0x0 + pushl $53 +c0102108: 6a 35 push $0x35 + jmp __alltraps +c010210a: e9 06 fe ff ff jmp c0101f15 <__alltraps> + +c010210f : +.globl vector54 +vector54: + pushl $0 +c010210f: 6a 00 push $0x0 + pushl $54 +c0102111: 6a 36 push $0x36 + jmp __alltraps +c0102113: e9 fd fd ff ff jmp c0101f15 <__alltraps> + +c0102118 : +.globl vector55 +vector55: + pushl $0 +c0102118: 6a 00 push $0x0 + pushl $55 +c010211a: 6a 37 push $0x37 + jmp __alltraps +c010211c: e9 f4 fd ff ff jmp c0101f15 <__alltraps> + +c0102121 : +.globl vector56 +vector56: + pushl $0 +c0102121: 6a 00 push $0x0 + pushl $56 +c0102123: 6a 38 push $0x38 + jmp __alltraps +c0102125: e9 eb fd ff ff jmp c0101f15 <__alltraps> + +c010212a : +.globl vector57 +vector57: + pushl $0 +c010212a: 6a 00 push $0x0 + pushl $57 +c010212c: 6a 39 push $0x39 + jmp __alltraps +c010212e: e9 e2 fd ff ff jmp c0101f15 <__alltraps> + +c0102133 : +.globl vector58 +vector58: + pushl $0 +c0102133: 6a 00 push $0x0 + pushl $58 +c0102135: 6a 3a push $0x3a + jmp __alltraps +c0102137: e9 d9 fd ff ff jmp c0101f15 <__alltraps> + +c010213c : +.globl vector59 +vector59: + pushl $0 +c010213c: 6a 00 push $0x0 + pushl $59 +c010213e: 6a 3b push $0x3b + jmp __alltraps +c0102140: e9 d0 fd ff ff jmp c0101f15 <__alltraps> + +c0102145 : +.globl vector60 +vector60: + pushl $0 +c0102145: 6a 00 push $0x0 + pushl $60 +c0102147: 6a 3c push $0x3c + jmp __alltraps +c0102149: e9 c7 fd ff ff jmp c0101f15 <__alltraps> + +c010214e : +.globl vector61 +vector61: + pushl $0 +c010214e: 6a 00 push $0x0 + pushl $61 +c0102150: 6a 3d push $0x3d + jmp __alltraps +c0102152: e9 be fd ff ff jmp c0101f15 <__alltraps> + +c0102157 : +.globl vector62 +vector62: + pushl $0 +c0102157: 6a 00 push $0x0 + pushl $62 +c0102159: 6a 3e push $0x3e + jmp __alltraps +c010215b: e9 b5 fd ff ff jmp c0101f15 <__alltraps> + +c0102160 : +.globl vector63 +vector63: + pushl $0 +c0102160: 6a 00 push $0x0 + pushl $63 +c0102162: 6a 3f push $0x3f + jmp __alltraps +c0102164: e9 ac fd ff ff jmp c0101f15 <__alltraps> + +c0102169 : +.globl vector64 +vector64: + pushl $0 +c0102169: 6a 00 push $0x0 + pushl $64 +c010216b: 6a 40 push $0x40 + jmp __alltraps +c010216d: e9 a3 fd ff ff jmp c0101f15 <__alltraps> + +c0102172 : +.globl vector65 +vector65: + pushl $0 +c0102172: 6a 00 push $0x0 + pushl $65 +c0102174: 6a 41 push $0x41 + jmp __alltraps +c0102176: e9 9a fd ff ff jmp c0101f15 <__alltraps> + +c010217b : +.globl vector66 +vector66: + pushl $0 +c010217b: 6a 00 push $0x0 + pushl $66 +c010217d: 6a 42 push $0x42 + jmp __alltraps +c010217f: e9 91 fd ff ff jmp c0101f15 <__alltraps> + +c0102184 : +.globl vector67 +vector67: + pushl $0 +c0102184: 6a 00 push $0x0 + pushl $67 +c0102186: 6a 43 push $0x43 + jmp __alltraps +c0102188: e9 88 fd ff ff jmp c0101f15 <__alltraps> + +c010218d : +.globl vector68 +vector68: + pushl $0 +c010218d: 6a 00 push $0x0 + pushl $68 +c010218f: 6a 44 push $0x44 + jmp __alltraps +c0102191: e9 7f fd ff ff jmp c0101f15 <__alltraps> + +c0102196 : +.globl vector69 +vector69: + pushl $0 +c0102196: 6a 00 push $0x0 + pushl $69 +c0102198: 6a 45 push $0x45 + jmp __alltraps +c010219a: e9 76 fd ff ff jmp c0101f15 <__alltraps> + +c010219f : +.globl vector70 +vector70: + pushl $0 +c010219f: 6a 00 push $0x0 + pushl $70 +c01021a1: 6a 46 push $0x46 + jmp __alltraps +c01021a3: e9 6d fd ff ff jmp c0101f15 <__alltraps> + +c01021a8 : +.globl vector71 +vector71: + pushl $0 +c01021a8: 6a 00 push $0x0 + pushl $71 +c01021aa: 6a 47 push $0x47 + jmp __alltraps +c01021ac: e9 64 fd ff ff jmp c0101f15 <__alltraps> + +c01021b1 : +.globl vector72 +vector72: + pushl $0 +c01021b1: 6a 00 push $0x0 + pushl $72 +c01021b3: 6a 48 push $0x48 + jmp __alltraps +c01021b5: e9 5b fd ff ff jmp c0101f15 <__alltraps> + +c01021ba : +.globl vector73 +vector73: + pushl $0 +c01021ba: 6a 00 push $0x0 + pushl $73 +c01021bc: 6a 49 push $0x49 + jmp __alltraps +c01021be: e9 52 fd ff ff jmp c0101f15 <__alltraps> + +c01021c3 : +.globl vector74 +vector74: + pushl $0 +c01021c3: 6a 00 push $0x0 + pushl $74 +c01021c5: 6a 4a push $0x4a + jmp __alltraps +c01021c7: e9 49 fd ff ff jmp c0101f15 <__alltraps> + +c01021cc : +.globl vector75 +vector75: + pushl $0 +c01021cc: 6a 00 push $0x0 + pushl $75 +c01021ce: 6a 4b push $0x4b + jmp __alltraps +c01021d0: e9 40 fd ff ff jmp c0101f15 <__alltraps> + +c01021d5 : +.globl vector76 +vector76: + pushl $0 +c01021d5: 6a 00 push $0x0 + pushl $76 +c01021d7: 6a 4c push $0x4c + jmp __alltraps +c01021d9: e9 37 fd ff ff jmp c0101f15 <__alltraps> + +c01021de : +.globl vector77 +vector77: + pushl $0 +c01021de: 6a 00 push $0x0 + pushl $77 +c01021e0: 6a 4d push $0x4d + jmp __alltraps +c01021e2: e9 2e fd ff ff jmp c0101f15 <__alltraps> + +c01021e7 : +.globl vector78 +vector78: + pushl $0 +c01021e7: 6a 00 push $0x0 + pushl $78 +c01021e9: 6a 4e push $0x4e + jmp __alltraps +c01021eb: e9 25 fd ff ff jmp c0101f15 <__alltraps> + +c01021f0 : +.globl vector79 +vector79: + pushl $0 +c01021f0: 6a 00 push $0x0 + pushl $79 +c01021f2: 6a 4f push $0x4f + jmp __alltraps +c01021f4: e9 1c fd ff ff jmp c0101f15 <__alltraps> + +c01021f9 : +.globl vector80 +vector80: + pushl $0 +c01021f9: 6a 00 push $0x0 + pushl $80 +c01021fb: 6a 50 push $0x50 + jmp __alltraps +c01021fd: e9 13 fd ff ff jmp c0101f15 <__alltraps> + +c0102202 : +.globl vector81 +vector81: + pushl $0 +c0102202: 6a 00 push $0x0 + pushl $81 +c0102204: 6a 51 push $0x51 + jmp __alltraps +c0102206: e9 0a fd ff ff jmp c0101f15 <__alltraps> + +c010220b : +.globl vector82 +vector82: + pushl $0 +c010220b: 6a 00 push $0x0 + pushl $82 +c010220d: 6a 52 push $0x52 + jmp __alltraps +c010220f: e9 01 fd ff ff jmp c0101f15 <__alltraps> + +c0102214 : +.globl vector83 +vector83: + pushl $0 +c0102214: 6a 00 push $0x0 + pushl $83 +c0102216: 6a 53 push $0x53 + jmp __alltraps +c0102218: e9 f8 fc ff ff jmp c0101f15 <__alltraps> + +c010221d : +.globl vector84 +vector84: + pushl $0 +c010221d: 6a 00 push $0x0 + pushl $84 +c010221f: 6a 54 push $0x54 + jmp __alltraps +c0102221: e9 ef fc ff ff jmp c0101f15 <__alltraps> + +c0102226 : +.globl vector85 +vector85: + pushl $0 +c0102226: 6a 00 push $0x0 + pushl $85 +c0102228: 6a 55 push $0x55 + jmp __alltraps +c010222a: e9 e6 fc ff ff jmp c0101f15 <__alltraps> + +c010222f : +.globl vector86 +vector86: + pushl $0 +c010222f: 6a 00 push $0x0 + pushl $86 +c0102231: 6a 56 push $0x56 + jmp __alltraps +c0102233: e9 dd fc ff ff jmp c0101f15 <__alltraps> + +c0102238 : +.globl vector87 +vector87: + pushl $0 +c0102238: 6a 00 push $0x0 + pushl $87 +c010223a: 6a 57 push $0x57 + jmp __alltraps +c010223c: e9 d4 fc ff ff jmp c0101f15 <__alltraps> + +c0102241 : +.globl vector88 +vector88: + pushl $0 +c0102241: 6a 00 push $0x0 + pushl $88 +c0102243: 6a 58 push $0x58 + jmp __alltraps +c0102245: e9 cb fc ff ff jmp c0101f15 <__alltraps> + +c010224a : +.globl vector89 +vector89: + pushl $0 +c010224a: 6a 00 push $0x0 + pushl $89 +c010224c: 6a 59 push $0x59 + jmp __alltraps +c010224e: e9 c2 fc ff ff jmp c0101f15 <__alltraps> + +c0102253 : +.globl vector90 +vector90: + pushl $0 +c0102253: 6a 00 push $0x0 + pushl $90 +c0102255: 6a 5a push $0x5a + jmp __alltraps +c0102257: e9 b9 fc ff ff jmp c0101f15 <__alltraps> + +c010225c : +.globl vector91 +vector91: + pushl $0 +c010225c: 6a 00 push $0x0 + pushl $91 +c010225e: 6a 5b push $0x5b + jmp __alltraps +c0102260: e9 b0 fc ff ff jmp c0101f15 <__alltraps> + +c0102265 : +.globl vector92 +vector92: + pushl $0 +c0102265: 6a 00 push $0x0 + pushl $92 +c0102267: 6a 5c push $0x5c + jmp __alltraps +c0102269: e9 a7 fc ff ff jmp c0101f15 <__alltraps> + +c010226e : +.globl vector93 +vector93: + pushl $0 +c010226e: 6a 00 push $0x0 + pushl $93 +c0102270: 6a 5d push $0x5d + jmp __alltraps +c0102272: e9 9e fc ff ff jmp c0101f15 <__alltraps> + +c0102277 : +.globl vector94 +vector94: + pushl $0 +c0102277: 6a 00 push $0x0 + pushl $94 +c0102279: 6a 5e push $0x5e + jmp __alltraps +c010227b: e9 95 fc ff ff jmp c0101f15 <__alltraps> + +c0102280 : +.globl vector95 +vector95: + pushl $0 +c0102280: 6a 00 push $0x0 + pushl $95 +c0102282: 6a 5f push $0x5f + jmp __alltraps +c0102284: e9 8c fc ff ff jmp c0101f15 <__alltraps> + +c0102289 : +.globl vector96 +vector96: + pushl $0 +c0102289: 6a 00 push $0x0 + pushl $96 +c010228b: 6a 60 push $0x60 + jmp __alltraps +c010228d: e9 83 fc ff ff jmp c0101f15 <__alltraps> + +c0102292 : +.globl vector97 +vector97: + pushl $0 +c0102292: 6a 00 push $0x0 + pushl $97 +c0102294: 6a 61 push $0x61 + jmp __alltraps +c0102296: e9 7a fc ff ff jmp c0101f15 <__alltraps> + +c010229b : +.globl vector98 +vector98: + pushl $0 +c010229b: 6a 00 push $0x0 + pushl $98 +c010229d: 6a 62 push $0x62 + jmp __alltraps +c010229f: e9 71 fc ff ff jmp c0101f15 <__alltraps> + +c01022a4 : +.globl vector99 +vector99: + pushl $0 +c01022a4: 6a 00 push $0x0 + pushl $99 +c01022a6: 6a 63 push $0x63 + jmp __alltraps +c01022a8: e9 68 fc ff ff jmp c0101f15 <__alltraps> + +c01022ad : +.globl vector100 +vector100: + pushl $0 +c01022ad: 6a 00 push $0x0 + pushl $100 +c01022af: 6a 64 push $0x64 + jmp __alltraps +c01022b1: e9 5f fc ff ff jmp c0101f15 <__alltraps> + +c01022b6 : +.globl vector101 +vector101: + pushl $0 +c01022b6: 6a 00 push $0x0 + pushl $101 +c01022b8: 6a 65 push $0x65 + jmp __alltraps +c01022ba: e9 56 fc ff ff jmp c0101f15 <__alltraps> + +c01022bf : +.globl vector102 +vector102: + pushl $0 +c01022bf: 6a 00 push $0x0 + pushl $102 +c01022c1: 6a 66 push $0x66 + jmp __alltraps +c01022c3: e9 4d fc ff ff jmp c0101f15 <__alltraps> + +c01022c8 : +.globl vector103 +vector103: + pushl $0 +c01022c8: 6a 00 push $0x0 + pushl $103 +c01022ca: 6a 67 push $0x67 + jmp __alltraps +c01022cc: e9 44 fc ff ff jmp c0101f15 <__alltraps> + +c01022d1 : +.globl vector104 +vector104: + pushl $0 +c01022d1: 6a 00 push $0x0 + pushl $104 +c01022d3: 6a 68 push $0x68 + jmp __alltraps +c01022d5: e9 3b fc ff ff jmp c0101f15 <__alltraps> + +c01022da : +.globl vector105 +vector105: + pushl $0 +c01022da: 6a 00 push $0x0 + pushl $105 +c01022dc: 6a 69 push $0x69 + jmp __alltraps +c01022de: e9 32 fc ff ff jmp c0101f15 <__alltraps> + +c01022e3 : +.globl vector106 +vector106: + pushl $0 +c01022e3: 6a 00 push $0x0 + pushl $106 +c01022e5: 6a 6a push $0x6a + jmp __alltraps +c01022e7: e9 29 fc ff ff jmp c0101f15 <__alltraps> + +c01022ec : +.globl vector107 +vector107: + pushl $0 +c01022ec: 6a 00 push $0x0 + pushl $107 +c01022ee: 6a 6b push $0x6b + jmp __alltraps +c01022f0: e9 20 fc ff ff jmp c0101f15 <__alltraps> + +c01022f5 : +.globl vector108 +vector108: + pushl $0 +c01022f5: 6a 00 push $0x0 + pushl $108 +c01022f7: 6a 6c push $0x6c + jmp __alltraps +c01022f9: e9 17 fc ff ff jmp c0101f15 <__alltraps> + +c01022fe : +.globl vector109 +vector109: + pushl $0 +c01022fe: 6a 00 push $0x0 + pushl $109 +c0102300: 6a 6d push $0x6d + jmp __alltraps +c0102302: e9 0e fc ff ff jmp c0101f15 <__alltraps> + +c0102307 : +.globl vector110 +vector110: + pushl $0 +c0102307: 6a 00 push $0x0 + pushl $110 +c0102309: 6a 6e push $0x6e + jmp __alltraps +c010230b: e9 05 fc ff ff jmp c0101f15 <__alltraps> + +c0102310 : +.globl vector111 +vector111: + pushl $0 +c0102310: 6a 00 push $0x0 + pushl $111 +c0102312: 6a 6f push $0x6f + jmp __alltraps +c0102314: e9 fc fb ff ff jmp c0101f15 <__alltraps> + +c0102319 : +.globl vector112 +vector112: + pushl $0 +c0102319: 6a 00 push $0x0 + pushl $112 +c010231b: 6a 70 push $0x70 + jmp __alltraps +c010231d: e9 f3 fb ff ff jmp c0101f15 <__alltraps> + +c0102322 : +.globl vector113 +vector113: + pushl $0 +c0102322: 6a 00 push $0x0 + pushl $113 +c0102324: 6a 71 push $0x71 + jmp __alltraps +c0102326: e9 ea fb ff ff jmp c0101f15 <__alltraps> + +c010232b : +.globl vector114 +vector114: + pushl $0 +c010232b: 6a 00 push $0x0 + pushl $114 +c010232d: 6a 72 push $0x72 + jmp __alltraps +c010232f: e9 e1 fb ff ff jmp c0101f15 <__alltraps> + +c0102334 : +.globl vector115 +vector115: + pushl $0 +c0102334: 6a 00 push $0x0 + pushl $115 +c0102336: 6a 73 push $0x73 + jmp __alltraps +c0102338: e9 d8 fb ff ff jmp c0101f15 <__alltraps> + +c010233d : +.globl vector116 +vector116: + pushl $0 +c010233d: 6a 00 push $0x0 + pushl $116 +c010233f: 6a 74 push $0x74 + jmp __alltraps +c0102341: e9 cf fb ff ff jmp c0101f15 <__alltraps> + +c0102346 : +.globl vector117 +vector117: + pushl $0 +c0102346: 6a 00 push $0x0 + pushl $117 +c0102348: 6a 75 push $0x75 + jmp __alltraps +c010234a: e9 c6 fb ff ff jmp c0101f15 <__alltraps> + +c010234f : +.globl vector118 +vector118: + pushl $0 +c010234f: 6a 00 push $0x0 + pushl $118 +c0102351: 6a 76 push $0x76 + jmp __alltraps +c0102353: e9 bd fb ff ff jmp c0101f15 <__alltraps> + +c0102358 : +.globl vector119 +vector119: + pushl $0 +c0102358: 6a 00 push $0x0 + pushl $119 +c010235a: 6a 77 push $0x77 + jmp __alltraps +c010235c: e9 b4 fb ff ff jmp c0101f15 <__alltraps> + +c0102361 : +.globl vector120 +vector120: + pushl $0 +c0102361: 6a 00 push $0x0 + pushl $120 +c0102363: 6a 78 push $0x78 + jmp __alltraps +c0102365: e9 ab fb ff ff jmp c0101f15 <__alltraps> + +c010236a : +.globl vector121 +vector121: + pushl $0 +c010236a: 6a 00 push $0x0 + pushl $121 +c010236c: 6a 79 push $0x79 + jmp __alltraps +c010236e: e9 a2 fb ff ff jmp c0101f15 <__alltraps> + +c0102373 : +.globl vector122 +vector122: + pushl $0 +c0102373: 6a 00 push $0x0 + pushl $122 +c0102375: 6a 7a push $0x7a + jmp __alltraps +c0102377: e9 99 fb ff ff jmp c0101f15 <__alltraps> + +c010237c : +.globl vector123 +vector123: + pushl $0 +c010237c: 6a 00 push $0x0 + pushl $123 +c010237e: 6a 7b push $0x7b + jmp __alltraps +c0102380: e9 90 fb ff ff jmp c0101f15 <__alltraps> + +c0102385 : +.globl vector124 +vector124: + pushl $0 +c0102385: 6a 00 push $0x0 + pushl $124 +c0102387: 6a 7c push $0x7c + jmp __alltraps +c0102389: e9 87 fb ff ff jmp c0101f15 <__alltraps> + +c010238e : +.globl vector125 +vector125: + pushl $0 +c010238e: 6a 00 push $0x0 + pushl $125 +c0102390: 6a 7d push $0x7d + jmp __alltraps +c0102392: e9 7e fb ff ff jmp c0101f15 <__alltraps> + +c0102397 : +.globl vector126 +vector126: + pushl $0 +c0102397: 6a 00 push $0x0 + pushl $126 +c0102399: 6a 7e push $0x7e + jmp __alltraps +c010239b: e9 75 fb ff ff jmp c0101f15 <__alltraps> + +c01023a0 : +.globl vector127 +vector127: + pushl $0 +c01023a0: 6a 00 push $0x0 + pushl $127 +c01023a2: 6a 7f push $0x7f + jmp __alltraps +c01023a4: e9 6c fb ff ff jmp c0101f15 <__alltraps> + +c01023a9 : +.globl vector128 +vector128: + pushl $0 +c01023a9: 6a 00 push $0x0 + pushl $128 +c01023ab: 68 80 00 00 00 push $0x80 + jmp __alltraps +c01023b0: e9 60 fb ff ff jmp c0101f15 <__alltraps> + +c01023b5 : +.globl vector129 +vector129: + pushl $0 +c01023b5: 6a 00 push $0x0 + pushl $129 +c01023b7: 68 81 00 00 00 push $0x81 + jmp __alltraps +c01023bc: e9 54 fb ff ff jmp c0101f15 <__alltraps> + +c01023c1 : +.globl vector130 +vector130: + pushl $0 +c01023c1: 6a 00 push $0x0 + pushl $130 +c01023c3: 68 82 00 00 00 push $0x82 + jmp __alltraps +c01023c8: e9 48 fb ff ff jmp c0101f15 <__alltraps> + +c01023cd : +.globl vector131 +vector131: + pushl $0 +c01023cd: 6a 00 push $0x0 + pushl $131 +c01023cf: 68 83 00 00 00 push $0x83 + jmp __alltraps +c01023d4: e9 3c fb ff ff jmp c0101f15 <__alltraps> + +c01023d9 : +.globl vector132 +vector132: + pushl $0 +c01023d9: 6a 00 push $0x0 + pushl $132 +c01023db: 68 84 00 00 00 push $0x84 + jmp __alltraps +c01023e0: e9 30 fb ff ff jmp c0101f15 <__alltraps> + +c01023e5 : +.globl vector133 +vector133: + pushl $0 +c01023e5: 6a 00 push $0x0 + pushl $133 +c01023e7: 68 85 00 00 00 push $0x85 + jmp __alltraps +c01023ec: e9 24 fb ff ff jmp c0101f15 <__alltraps> + +c01023f1 : +.globl vector134 +vector134: + pushl $0 +c01023f1: 6a 00 push $0x0 + pushl $134 +c01023f3: 68 86 00 00 00 push $0x86 + jmp __alltraps +c01023f8: e9 18 fb ff ff jmp c0101f15 <__alltraps> + +c01023fd : +.globl vector135 +vector135: + pushl $0 +c01023fd: 6a 00 push $0x0 + pushl $135 +c01023ff: 68 87 00 00 00 push $0x87 + jmp __alltraps +c0102404: e9 0c fb ff ff jmp c0101f15 <__alltraps> + +c0102409 : +.globl vector136 +vector136: + pushl $0 +c0102409: 6a 00 push $0x0 + pushl $136 +c010240b: 68 88 00 00 00 push $0x88 + jmp __alltraps +c0102410: e9 00 fb ff ff jmp c0101f15 <__alltraps> + +c0102415 : +.globl vector137 +vector137: + pushl $0 +c0102415: 6a 00 push $0x0 + pushl $137 +c0102417: 68 89 00 00 00 push $0x89 + jmp __alltraps +c010241c: e9 f4 fa ff ff jmp c0101f15 <__alltraps> + +c0102421 : +.globl vector138 +vector138: + pushl $0 +c0102421: 6a 00 push $0x0 + pushl $138 +c0102423: 68 8a 00 00 00 push $0x8a + jmp __alltraps +c0102428: e9 e8 fa ff ff jmp c0101f15 <__alltraps> + +c010242d : +.globl vector139 +vector139: + pushl $0 +c010242d: 6a 00 push $0x0 + pushl $139 +c010242f: 68 8b 00 00 00 push $0x8b + jmp __alltraps +c0102434: e9 dc fa ff ff jmp c0101f15 <__alltraps> + +c0102439 : +.globl vector140 +vector140: + pushl $0 +c0102439: 6a 00 push $0x0 + pushl $140 +c010243b: 68 8c 00 00 00 push $0x8c + jmp __alltraps +c0102440: e9 d0 fa ff ff jmp c0101f15 <__alltraps> + +c0102445 : +.globl vector141 +vector141: + pushl $0 +c0102445: 6a 00 push $0x0 + pushl $141 +c0102447: 68 8d 00 00 00 push $0x8d + jmp __alltraps +c010244c: e9 c4 fa ff ff jmp c0101f15 <__alltraps> + +c0102451 : +.globl vector142 +vector142: + pushl $0 +c0102451: 6a 00 push $0x0 + pushl $142 +c0102453: 68 8e 00 00 00 push $0x8e + jmp __alltraps +c0102458: e9 b8 fa ff ff jmp c0101f15 <__alltraps> + +c010245d : +.globl vector143 +vector143: + pushl $0 +c010245d: 6a 00 push $0x0 + pushl $143 +c010245f: 68 8f 00 00 00 push $0x8f + jmp __alltraps +c0102464: e9 ac fa ff ff jmp c0101f15 <__alltraps> + +c0102469 : +.globl vector144 +vector144: + pushl $0 +c0102469: 6a 00 push $0x0 + pushl $144 +c010246b: 68 90 00 00 00 push $0x90 + jmp __alltraps +c0102470: e9 a0 fa ff ff jmp c0101f15 <__alltraps> + +c0102475 : +.globl vector145 +vector145: + pushl $0 +c0102475: 6a 00 push $0x0 + pushl $145 +c0102477: 68 91 00 00 00 push $0x91 + jmp __alltraps +c010247c: e9 94 fa ff ff jmp c0101f15 <__alltraps> + +c0102481 : +.globl vector146 +vector146: + pushl $0 +c0102481: 6a 00 push $0x0 + pushl $146 +c0102483: 68 92 00 00 00 push $0x92 + jmp __alltraps +c0102488: e9 88 fa ff ff jmp c0101f15 <__alltraps> + +c010248d : +.globl vector147 +vector147: + pushl $0 +c010248d: 6a 00 push $0x0 + pushl $147 +c010248f: 68 93 00 00 00 push $0x93 + jmp __alltraps +c0102494: e9 7c fa ff ff jmp c0101f15 <__alltraps> + +c0102499 : +.globl vector148 +vector148: + pushl $0 +c0102499: 6a 00 push $0x0 + pushl $148 +c010249b: 68 94 00 00 00 push $0x94 + jmp __alltraps +c01024a0: e9 70 fa ff ff jmp c0101f15 <__alltraps> + +c01024a5 : +.globl vector149 +vector149: + pushl $0 +c01024a5: 6a 00 push $0x0 + pushl $149 +c01024a7: 68 95 00 00 00 push $0x95 + jmp __alltraps +c01024ac: e9 64 fa ff ff jmp c0101f15 <__alltraps> + +c01024b1 : +.globl vector150 +vector150: + pushl $0 +c01024b1: 6a 00 push $0x0 + pushl $150 +c01024b3: 68 96 00 00 00 push $0x96 + jmp __alltraps +c01024b8: e9 58 fa ff ff jmp c0101f15 <__alltraps> + +c01024bd : +.globl vector151 +vector151: + pushl $0 +c01024bd: 6a 00 push $0x0 + pushl $151 +c01024bf: 68 97 00 00 00 push $0x97 + jmp __alltraps +c01024c4: e9 4c fa ff ff jmp c0101f15 <__alltraps> + +c01024c9 : +.globl vector152 +vector152: + pushl $0 +c01024c9: 6a 00 push $0x0 + pushl $152 +c01024cb: 68 98 00 00 00 push $0x98 + jmp __alltraps +c01024d0: e9 40 fa ff ff jmp c0101f15 <__alltraps> + +c01024d5 : +.globl vector153 +vector153: + pushl $0 +c01024d5: 6a 00 push $0x0 + pushl $153 +c01024d7: 68 99 00 00 00 push $0x99 + jmp __alltraps +c01024dc: e9 34 fa ff ff jmp c0101f15 <__alltraps> + +c01024e1 : +.globl vector154 +vector154: + pushl $0 +c01024e1: 6a 00 push $0x0 + pushl $154 +c01024e3: 68 9a 00 00 00 push $0x9a + jmp __alltraps +c01024e8: e9 28 fa ff ff jmp c0101f15 <__alltraps> + +c01024ed : +.globl vector155 +vector155: + pushl $0 +c01024ed: 6a 00 push $0x0 + pushl $155 +c01024ef: 68 9b 00 00 00 push $0x9b + jmp __alltraps +c01024f4: e9 1c fa ff ff jmp c0101f15 <__alltraps> + +c01024f9 : +.globl vector156 +vector156: + pushl $0 +c01024f9: 6a 00 push $0x0 + pushl $156 +c01024fb: 68 9c 00 00 00 push $0x9c + jmp __alltraps +c0102500: e9 10 fa ff ff jmp c0101f15 <__alltraps> + +c0102505 : +.globl vector157 +vector157: + pushl $0 +c0102505: 6a 00 push $0x0 + pushl $157 +c0102507: 68 9d 00 00 00 push $0x9d + jmp __alltraps +c010250c: e9 04 fa ff ff jmp c0101f15 <__alltraps> + +c0102511 : +.globl vector158 +vector158: + pushl $0 +c0102511: 6a 00 push $0x0 + pushl $158 +c0102513: 68 9e 00 00 00 push $0x9e + jmp __alltraps +c0102518: e9 f8 f9 ff ff jmp c0101f15 <__alltraps> + +c010251d : +.globl vector159 +vector159: + pushl $0 +c010251d: 6a 00 push $0x0 + pushl $159 +c010251f: 68 9f 00 00 00 push $0x9f + jmp __alltraps +c0102524: e9 ec f9 ff ff jmp c0101f15 <__alltraps> + +c0102529 : +.globl vector160 +vector160: + pushl $0 +c0102529: 6a 00 push $0x0 + pushl $160 +c010252b: 68 a0 00 00 00 push $0xa0 + jmp __alltraps +c0102530: e9 e0 f9 ff ff jmp c0101f15 <__alltraps> + +c0102535 : +.globl vector161 +vector161: + pushl $0 +c0102535: 6a 00 push $0x0 + pushl $161 +c0102537: 68 a1 00 00 00 push $0xa1 + jmp __alltraps +c010253c: e9 d4 f9 ff ff jmp c0101f15 <__alltraps> + +c0102541 : +.globl vector162 +vector162: + pushl $0 +c0102541: 6a 00 push $0x0 + pushl $162 +c0102543: 68 a2 00 00 00 push $0xa2 + jmp __alltraps +c0102548: e9 c8 f9 ff ff jmp c0101f15 <__alltraps> + +c010254d : +.globl vector163 +vector163: + pushl $0 +c010254d: 6a 00 push $0x0 + pushl $163 +c010254f: 68 a3 00 00 00 push $0xa3 + jmp __alltraps +c0102554: e9 bc f9 ff ff jmp c0101f15 <__alltraps> + +c0102559 : +.globl vector164 +vector164: + pushl $0 +c0102559: 6a 00 push $0x0 + pushl $164 +c010255b: 68 a4 00 00 00 push $0xa4 + jmp __alltraps +c0102560: e9 b0 f9 ff ff jmp c0101f15 <__alltraps> + +c0102565 : +.globl vector165 +vector165: + pushl $0 +c0102565: 6a 00 push $0x0 + pushl $165 +c0102567: 68 a5 00 00 00 push $0xa5 + jmp __alltraps +c010256c: e9 a4 f9 ff ff jmp c0101f15 <__alltraps> + +c0102571 : +.globl vector166 +vector166: + pushl $0 +c0102571: 6a 00 push $0x0 + pushl $166 +c0102573: 68 a6 00 00 00 push $0xa6 + jmp __alltraps +c0102578: e9 98 f9 ff ff jmp c0101f15 <__alltraps> + +c010257d : +.globl vector167 +vector167: + pushl $0 +c010257d: 6a 00 push $0x0 + pushl $167 +c010257f: 68 a7 00 00 00 push $0xa7 + jmp __alltraps +c0102584: e9 8c f9 ff ff jmp c0101f15 <__alltraps> + +c0102589 : +.globl vector168 +vector168: + pushl $0 +c0102589: 6a 00 push $0x0 + pushl $168 +c010258b: 68 a8 00 00 00 push $0xa8 + jmp __alltraps +c0102590: e9 80 f9 ff ff jmp c0101f15 <__alltraps> + +c0102595 : +.globl vector169 +vector169: + pushl $0 +c0102595: 6a 00 push $0x0 + pushl $169 +c0102597: 68 a9 00 00 00 push $0xa9 + jmp __alltraps +c010259c: e9 74 f9 ff ff jmp c0101f15 <__alltraps> + +c01025a1 : +.globl vector170 +vector170: + pushl $0 +c01025a1: 6a 00 push $0x0 + pushl $170 +c01025a3: 68 aa 00 00 00 push $0xaa + jmp __alltraps +c01025a8: e9 68 f9 ff ff jmp c0101f15 <__alltraps> + +c01025ad : +.globl vector171 +vector171: + pushl $0 +c01025ad: 6a 00 push $0x0 + pushl $171 +c01025af: 68 ab 00 00 00 push $0xab + jmp __alltraps +c01025b4: e9 5c f9 ff ff jmp c0101f15 <__alltraps> + +c01025b9 : +.globl vector172 +vector172: + pushl $0 +c01025b9: 6a 00 push $0x0 + pushl $172 +c01025bb: 68 ac 00 00 00 push $0xac + jmp __alltraps +c01025c0: e9 50 f9 ff ff jmp c0101f15 <__alltraps> + +c01025c5 : +.globl vector173 +vector173: + pushl $0 +c01025c5: 6a 00 push $0x0 + pushl $173 +c01025c7: 68 ad 00 00 00 push $0xad + jmp __alltraps +c01025cc: e9 44 f9 ff ff jmp c0101f15 <__alltraps> + +c01025d1 : +.globl vector174 +vector174: + pushl $0 +c01025d1: 6a 00 push $0x0 + pushl $174 +c01025d3: 68 ae 00 00 00 push $0xae + jmp __alltraps +c01025d8: e9 38 f9 ff ff jmp c0101f15 <__alltraps> + +c01025dd : +.globl vector175 +vector175: + pushl $0 +c01025dd: 6a 00 push $0x0 + pushl $175 +c01025df: 68 af 00 00 00 push $0xaf + jmp __alltraps +c01025e4: e9 2c f9 ff ff jmp c0101f15 <__alltraps> + +c01025e9 : +.globl vector176 +vector176: + pushl $0 +c01025e9: 6a 00 push $0x0 + pushl $176 +c01025eb: 68 b0 00 00 00 push $0xb0 + jmp __alltraps +c01025f0: e9 20 f9 ff ff jmp c0101f15 <__alltraps> + +c01025f5 : +.globl vector177 +vector177: + pushl $0 +c01025f5: 6a 00 push $0x0 + pushl $177 +c01025f7: 68 b1 00 00 00 push $0xb1 + jmp __alltraps +c01025fc: e9 14 f9 ff ff jmp c0101f15 <__alltraps> + +c0102601 : +.globl vector178 +vector178: + pushl $0 +c0102601: 6a 00 push $0x0 + pushl $178 +c0102603: 68 b2 00 00 00 push $0xb2 + jmp __alltraps +c0102608: e9 08 f9 ff ff jmp c0101f15 <__alltraps> + +c010260d : +.globl vector179 +vector179: + pushl $0 +c010260d: 6a 00 push $0x0 + pushl $179 +c010260f: 68 b3 00 00 00 push $0xb3 + jmp __alltraps +c0102614: e9 fc f8 ff ff jmp c0101f15 <__alltraps> + +c0102619 : +.globl vector180 +vector180: + pushl $0 +c0102619: 6a 00 push $0x0 + pushl $180 +c010261b: 68 b4 00 00 00 push $0xb4 + jmp __alltraps +c0102620: e9 f0 f8 ff ff jmp c0101f15 <__alltraps> + +c0102625 : +.globl vector181 +vector181: + pushl $0 +c0102625: 6a 00 push $0x0 + pushl $181 +c0102627: 68 b5 00 00 00 push $0xb5 + jmp __alltraps +c010262c: e9 e4 f8 ff ff jmp c0101f15 <__alltraps> + +c0102631 : +.globl vector182 +vector182: + pushl $0 +c0102631: 6a 00 push $0x0 + pushl $182 +c0102633: 68 b6 00 00 00 push $0xb6 + jmp __alltraps +c0102638: e9 d8 f8 ff ff jmp c0101f15 <__alltraps> + +c010263d : +.globl vector183 +vector183: + pushl $0 +c010263d: 6a 00 push $0x0 + pushl $183 +c010263f: 68 b7 00 00 00 push $0xb7 + jmp __alltraps +c0102644: e9 cc f8 ff ff jmp c0101f15 <__alltraps> + +c0102649 : +.globl vector184 +vector184: + pushl $0 +c0102649: 6a 00 push $0x0 + pushl $184 +c010264b: 68 b8 00 00 00 push $0xb8 + jmp __alltraps +c0102650: e9 c0 f8 ff ff jmp c0101f15 <__alltraps> + +c0102655 : +.globl vector185 +vector185: + pushl $0 +c0102655: 6a 00 push $0x0 + pushl $185 +c0102657: 68 b9 00 00 00 push $0xb9 + jmp __alltraps +c010265c: e9 b4 f8 ff ff jmp c0101f15 <__alltraps> + +c0102661 : +.globl vector186 +vector186: + pushl $0 +c0102661: 6a 00 push $0x0 + pushl $186 +c0102663: 68 ba 00 00 00 push $0xba + jmp __alltraps +c0102668: e9 a8 f8 ff ff jmp c0101f15 <__alltraps> + +c010266d : +.globl vector187 +vector187: + pushl $0 +c010266d: 6a 00 push $0x0 + pushl $187 +c010266f: 68 bb 00 00 00 push $0xbb + jmp __alltraps +c0102674: e9 9c f8 ff ff jmp c0101f15 <__alltraps> + +c0102679 : +.globl vector188 +vector188: + pushl $0 +c0102679: 6a 00 push $0x0 + pushl $188 +c010267b: 68 bc 00 00 00 push $0xbc + jmp __alltraps +c0102680: e9 90 f8 ff ff jmp c0101f15 <__alltraps> + +c0102685 : +.globl vector189 +vector189: + pushl $0 +c0102685: 6a 00 push $0x0 + pushl $189 +c0102687: 68 bd 00 00 00 push $0xbd + jmp __alltraps +c010268c: e9 84 f8 ff ff jmp c0101f15 <__alltraps> + +c0102691 : +.globl vector190 +vector190: + pushl $0 +c0102691: 6a 00 push $0x0 + pushl $190 +c0102693: 68 be 00 00 00 push $0xbe + jmp __alltraps +c0102698: e9 78 f8 ff ff jmp c0101f15 <__alltraps> + +c010269d : +.globl vector191 +vector191: + pushl $0 +c010269d: 6a 00 push $0x0 + pushl $191 +c010269f: 68 bf 00 00 00 push $0xbf + jmp __alltraps +c01026a4: e9 6c f8 ff ff jmp c0101f15 <__alltraps> + +c01026a9 : +.globl vector192 +vector192: + pushl $0 +c01026a9: 6a 00 push $0x0 + pushl $192 +c01026ab: 68 c0 00 00 00 push $0xc0 + jmp __alltraps +c01026b0: e9 60 f8 ff ff jmp c0101f15 <__alltraps> + +c01026b5 : +.globl vector193 +vector193: + pushl $0 +c01026b5: 6a 00 push $0x0 + pushl $193 +c01026b7: 68 c1 00 00 00 push $0xc1 + jmp __alltraps +c01026bc: e9 54 f8 ff ff jmp c0101f15 <__alltraps> + +c01026c1 : +.globl vector194 +vector194: + pushl $0 +c01026c1: 6a 00 push $0x0 + pushl $194 +c01026c3: 68 c2 00 00 00 push $0xc2 + jmp __alltraps +c01026c8: e9 48 f8 ff ff jmp c0101f15 <__alltraps> + +c01026cd : +.globl vector195 +vector195: + pushl $0 +c01026cd: 6a 00 push $0x0 + pushl $195 +c01026cf: 68 c3 00 00 00 push $0xc3 + jmp __alltraps +c01026d4: e9 3c f8 ff ff jmp c0101f15 <__alltraps> + +c01026d9 : +.globl vector196 +vector196: + pushl $0 +c01026d9: 6a 00 push $0x0 + pushl $196 +c01026db: 68 c4 00 00 00 push $0xc4 + jmp __alltraps +c01026e0: e9 30 f8 ff ff jmp c0101f15 <__alltraps> + +c01026e5 : +.globl vector197 +vector197: + pushl $0 +c01026e5: 6a 00 push $0x0 + pushl $197 +c01026e7: 68 c5 00 00 00 push $0xc5 + jmp __alltraps +c01026ec: e9 24 f8 ff ff jmp c0101f15 <__alltraps> + +c01026f1 : +.globl vector198 +vector198: + pushl $0 +c01026f1: 6a 00 push $0x0 + pushl $198 +c01026f3: 68 c6 00 00 00 push $0xc6 + jmp __alltraps +c01026f8: e9 18 f8 ff ff jmp c0101f15 <__alltraps> + +c01026fd : +.globl vector199 +vector199: + pushl $0 +c01026fd: 6a 00 push $0x0 + pushl $199 +c01026ff: 68 c7 00 00 00 push $0xc7 + jmp __alltraps +c0102704: e9 0c f8 ff ff jmp c0101f15 <__alltraps> + +c0102709 : +.globl vector200 +vector200: + pushl $0 +c0102709: 6a 00 push $0x0 + pushl $200 +c010270b: 68 c8 00 00 00 push $0xc8 + jmp __alltraps +c0102710: e9 00 f8 ff ff jmp c0101f15 <__alltraps> + +c0102715 : +.globl vector201 +vector201: + pushl $0 +c0102715: 6a 00 push $0x0 + pushl $201 +c0102717: 68 c9 00 00 00 push $0xc9 + jmp __alltraps +c010271c: e9 f4 f7 ff ff jmp c0101f15 <__alltraps> + +c0102721 : +.globl vector202 +vector202: + pushl $0 +c0102721: 6a 00 push $0x0 + pushl $202 +c0102723: 68 ca 00 00 00 push $0xca + jmp __alltraps +c0102728: e9 e8 f7 ff ff jmp c0101f15 <__alltraps> + +c010272d : +.globl vector203 +vector203: + pushl $0 +c010272d: 6a 00 push $0x0 + pushl $203 +c010272f: 68 cb 00 00 00 push $0xcb + jmp __alltraps +c0102734: e9 dc f7 ff ff jmp c0101f15 <__alltraps> + +c0102739 : +.globl vector204 +vector204: + pushl $0 +c0102739: 6a 00 push $0x0 + pushl $204 +c010273b: 68 cc 00 00 00 push $0xcc + jmp __alltraps +c0102740: e9 d0 f7 ff ff jmp c0101f15 <__alltraps> + +c0102745 : +.globl vector205 +vector205: + pushl $0 +c0102745: 6a 00 push $0x0 + pushl $205 +c0102747: 68 cd 00 00 00 push $0xcd + jmp __alltraps +c010274c: e9 c4 f7 ff ff jmp c0101f15 <__alltraps> + +c0102751 : +.globl vector206 +vector206: + pushl $0 +c0102751: 6a 00 push $0x0 + pushl $206 +c0102753: 68 ce 00 00 00 push $0xce + jmp __alltraps +c0102758: e9 b8 f7 ff ff jmp c0101f15 <__alltraps> + +c010275d : +.globl vector207 +vector207: + pushl $0 +c010275d: 6a 00 push $0x0 + pushl $207 +c010275f: 68 cf 00 00 00 push $0xcf + jmp __alltraps +c0102764: e9 ac f7 ff ff jmp c0101f15 <__alltraps> + +c0102769 : +.globl vector208 +vector208: + pushl $0 +c0102769: 6a 00 push $0x0 + pushl $208 +c010276b: 68 d0 00 00 00 push $0xd0 + jmp __alltraps +c0102770: e9 a0 f7 ff ff jmp c0101f15 <__alltraps> + +c0102775 : +.globl vector209 +vector209: + pushl $0 +c0102775: 6a 00 push $0x0 + pushl $209 +c0102777: 68 d1 00 00 00 push $0xd1 + jmp __alltraps +c010277c: e9 94 f7 ff ff jmp c0101f15 <__alltraps> + +c0102781 : +.globl vector210 +vector210: + pushl $0 +c0102781: 6a 00 push $0x0 + pushl $210 +c0102783: 68 d2 00 00 00 push $0xd2 + jmp __alltraps +c0102788: e9 88 f7 ff ff jmp c0101f15 <__alltraps> + +c010278d : +.globl vector211 +vector211: + pushl $0 +c010278d: 6a 00 push $0x0 + pushl $211 +c010278f: 68 d3 00 00 00 push $0xd3 + jmp __alltraps +c0102794: e9 7c f7 ff ff jmp c0101f15 <__alltraps> + +c0102799 : +.globl vector212 +vector212: + pushl $0 +c0102799: 6a 00 push $0x0 + pushl $212 +c010279b: 68 d4 00 00 00 push $0xd4 + jmp __alltraps +c01027a0: e9 70 f7 ff ff jmp c0101f15 <__alltraps> + +c01027a5 : +.globl vector213 +vector213: + pushl $0 +c01027a5: 6a 00 push $0x0 + pushl $213 +c01027a7: 68 d5 00 00 00 push $0xd5 + jmp __alltraps +c01027ac: e9 64 f7 ff ff jmp c0101f15 <__alltraps> + +c01027b1 : +.globl vector214 +vector214: + pushl $0 +c01027b1: 6a 00 push $0x0 + pushl $214 +c01027b3: 68 d6 00 00 00 push $0xd6 + jmp __alltraps +c01027b8: e9 58 f7 ff ff jmp c0101f15 <__alltraps> + +c01027bd : +.globl vector215 +vector215: + pushl $0 +c01027bd: 6a 00 push $0x0 + pushl $215 +c01027bf: 68 d7 00 00 00 push $0xd7 + jmp __alltraps +c01027c4: e9 4c f7 ff ff jmp c0101f15 <__alltraps> + +c01027c9 : +.globl vector216 +vector216: + pushl $0 +c01027c9: 6a 00 push $0x0 + pushl $216 +c01027cb: 68 d8 00 00 00 push $0xd8 + jmp __alltraps +c01027d0: e9 40 f7 ff ff jmp c0101f15 <__alltraps> + +c01027d5 : +.globl vector217 +vector217: + pushl $0 +c01027d5: 6a 00 push $0x0 + pushl $217 +c01027d7: 68 d9 00 00 00 push $0xd9 + jmp __alltraps +c01027dc: e9 34 f7 ff ff jmp c0101f15 <__alltraps> + +c01027e1 : +.globl vector218 +vector218: + pushl $0 +c01027e1: 6a 00 push $0x0 + pushl $218 +c01027e3: 68 da 00 00 00 push $0xda + jmp __alltraps +c01027e8: e9 28 f7 ff ff jmp c0101f15 <__alltraps> + +c01027ed : +.globl vector219 +vector219: + pushl $0 +c01027ed: 6a 00 push $0x0 + pushl $219 +c01027ef: 68 db 00 00 00 push $0xdb + jmp __alltraps +c01027f4: e9 1c f7 ff ff jmp c0101f15 <__alltraps> + +c01027f9 : +.globl vector220 +vector220: + pushl $0 +c01027f9: 6a 00 push $0x0 + pushl $220 +c01027fb: 68 dc 00 00 00 push $0xdc + jmp __alltraps +c0102800: e9 10 f7 ff ff jmp c0101f15 <__alltraps> + +c0102805 : +.globl vector221 +vector221: + pushl $0 +c0102805: 6a 00 push $0x0 + pushl $221 +c0102807: 68 dd 00 00 00 push $0xdd + jmp __alltraps +c010280c: e9 04 f7 ff ff jmp c0101f15 <__alltraps> + +c0102811 : +.globl vector222 +vector222: + pushl $0 +c0102811: 6a 00 push $0x0 + pushl $222 +c0102813: 68 de 00 00 00 push $0xde + jmp __alltraps +c0102818: e9 f8 f6 ff ff jmp c0101f15 <__alltraps> + +c010281d : +.globl vector223 +vector223: + pushl $0 +c010281d: 6a 00 push $0x0 + pushl $223 +c010281f: 68 df 00 00 00 push $0xdf + jmp __alltraps +c0102824: e9 ec f6 ff ff jmp c0101f15 <__alltraps> + +c0102829 : +.globl vector224 +vector224: + pushl $0 +c0102829: 6a 00 push $0x0 + pushl $224 +c010282b: 68 e0 00 00 00 push $0xe0 + jmp __alltraps +c0102830: e9 e0 f6 ff ff jmp c0101f15 <__alltraps> + +c0102835 : +.globl vector225 +vector225: + pushl $0 +c0102835: 6a 00 push $0x0 + pushl $225 +c0102837: 68 e1 00 00 00 push $0xe1 + jmp __alltraps +c010283c: e9 d4 f6 ff ff jmp c0101f15 <__alltraps> + +c0102841 : +.globl vector226 +vector226: + pushl $0 +c0102841: 6a 00 push $0x0 + pushl $226 +c0102843: 68 e2 00 00 00 push $0xe2 + jmp __alltraps +c0102848: e9 c8 f6 ff ff jmp c0101f15 <__alltraps> + +c010284d : +.globl vector227 +vector227: + pushl $0 +c010284d: 6a 00 push $0x0 + pushl $227 +c010284f: 68 e3 00 00 00 push $0xe3 + jmp __alltraps +c0102854: e9 bc f6 ff ff jmp c0101f15 <__alltraps> + +c0102859 : +.globl vector228 +vector228: + pushl $0 +c0102859: 6a 00 push $0x0 + pushl $228 +c010285b: 68 e4 00 00 00 push $0xe4 + jmp __alltraps +c0102860: e9 b0 f6 ff ff jmp c0101f15 <__alltraps> + +c0102865 : +.globl vector229 +vector229: + pushl $0 +c0102865: 6a 00 push $0x0 + pushl $229 +c0102867: 68 e5 00 00 00 push $0xe5 + jmp __alltraps +c010286c: e9 a4 f6 ff ff jmp c0101f15 <__alltraps> + +c0102871 : +.globl vector230 +vector230: + pushl $0 +c0102871: 6a 00 push $0x0 + pushl $230 +c0102873: 68 e6 00 00 00 push $0xe6 + jmp __alltraps +c0102878: e9 98 f6 ff ff jmp c0101f15 <__alltraps> + +c010287d : +.globl vector231 +vector231: + pushl $0 +c010287d: 6a 00 push $0x0 + pushl $231 +c010287f: 68 e7 00 00 00 push $0xe7 + jmp __alltraps +c0102884: e9 8c f6 ff ff jmp c0101f15 <__alltraps> + +c0102889 : +.globl vector232 +vector232: + pushl $0 +c0102889: 6a 00 push $0x0 + pushl $232 +c010288b: 68 e8 00 00 00 push $0xe8 + jmp __alltraps +c0102890: e9 80 f6 ff ff jmp c0101f15 <__alltraps> + +c0102895 : +.globl vector233 +vector233: + pushl $0 +c0102895: 6a 00 push $0x0 + pushl $233 +c0102897: 68 e9 00 00 00 push $0xe9 + jmp __alltraps +c010289c: e9 74 f6 ff ff jmp c0101f15 <__alltraps> + +c01028a1 : +.globl vector234 +vector234: + pushl $0 +c01028a1: 6a 00 push $0x0 + pushl $234 +c01028a3: 68 ea 00 00 00 push $0xea + jmp __alltraps +c01028a8: e9 68 f6 ff ff jmp c0101f15 <__alltraps> + +c01028ad : +.globl vector235 +vector235: + pushl $0 +c01028ad: 6a 00 push $0x0 + pushl $235 +c01028af: 68 eb 00 00 00 push $0xeb + jmp __alltraps +c01028b4: e9 5c f6 ff ff jmp c0101f15 <__alltraps> + +c01028b9 : +.globl vector236 +vector236: + pushl $0 +c01028b9: 6a 00 push $0x0 + pushl $236 +c01028bb: 68 ec 00 00 00 push $0xec + jmp __alltraps +c01028c0: e9 50 f6 ff ff jmp c0101f15 <__alltraps> + +c01028c5 : +.globl vector237 +vector237: + pushl $0 +c01028c5: 6a 00 push $0x0 + pushl $237 +c01028c7: 68 ed 00 00 00 push $0xed + jmp __alltraps +c01028cc: e9 44 f6 ff ff jmp c0101f15 <__alltraps> + +c01028d1 : +.globl vector238 +vector238: + pushl $0 +c01028d1: 6a 00 push $0x0 + pushl $238 +c01028d3: 68 ee 00 00 00 push $0xee + jmp __alltraps +c01028d8: e9 38 f6 ff ff jmp c0101f15 <__alltraps> + +c01028dd : +.globl vector239 +vector239: + pushl $0 +c01028dd: 6a 00 push $0x0 + pushl $239 +c01028df: 68 ef 00 00 00 push $0xef + jmp __alltraps +c01028e4: e9 2c f6 ff ff jmp c0101f15 <__alltraps> + +c01028e9 : +.globl vector240 +vector240: + pushl $0 +c01028e9: 6a 00 push $0x0 + pushl $240 +c01028eb: 68 f0 00 00 00 push $0xf0 + jmp __alltraps +c01028f0: e9 20 f6 ff ff jmp c0101f15 <__alltraps> + +c01028f5 : +.globl vector241 +vector241: + pushl $0 +c01028f5: 6a 00 push $0x0 + pushl $241 +c01028f7: 68 f1 00 00 00 push $0xf1 + jmp __alltraps +c01028fc: e9 14 f6 ff ff jmp c0101f15 <__alltraps> + +c0102901 : +.globl vector242 +vector242: + pushl $0 +c0102901: 6a 00 push $0x0 + pushl $242 +c0102903: 68 f2 00 00 00 push $0xf2 + jmp __alltraps +c0102908: e9 08 f6 ff ff jmp c0101f15 <__alltraps> + +c010290d : +.globl vector243 +vector243: + pushl $0 +c010290d: 6a 00 push $0x0 + pushl $243 +c010290f: 68 f3 00 00 00 push $0xf3 + jmp __alltraps +c0102914: e9 fc f5 ff ff jmp c0101f15 <__alltraps> + +c0102919 : +.globl vector244 +vector244: + pushl $0 +c0102919: 6a 00 push $0x0 + pushl $244 +c010291b: 68 f4 00 00 00 push $0xf4 + jmp __alltraps +c0102920: e9 f0 f5 ff ff jmp c0101f15 <__alltraps> + +c0102925 : +.globl vector245 +vector245: + pushl $0 +c0102925: 6a 00 push $0x0 + pushl $245 +c0102927: 68 f5 00 00 00 push $0xf5 + jmp __alltraps +c010292c: e9 e4 f5 ff ff jmp c0101f15 <__alltraps> + +c0102931 : +.globl vector246 +vector246: + pushl $0 +c0102931: 6a 00 push $0x0 + pushl $246 +c0102933: 68 f6 00 00 00 push $0xf6 + jmp __alltraps +c0102938: e9 d8 f5 ff ff jmp c0101f15 <__alltraps> + +c010293d : +.globl vector247 +vector247: + pushl $0 +c010293d: 6a 00 push $0x0 + pushl $247 +c010293f: 68 f7 00 00 00 push $0xf7 + jmp __alltraps +c0102944: e9 cc f5 ff ff jmp c0101f15 <__alltraps> + +c0102949 : +.globl vector248 +vector248: + pushl $0 +c0102949: 6a 00 push $0x0 + pushl $248 +c010294b: 68 f8 00 00 00 push $0xf8 + jmp __alltraps +c0102950: e9 c0 f5 ff ff jmp c0101f15 <__alltraps> + +c0102955 : +.globl vector249 +vector249: + pushl $0 +c0102955: 6a 00 push $0x0 + pushl $249 +c0102957: 68 f9 00 00 00 push $0xf9 + jmp __alltraps +c010295c: e9 b4 f5 ff ff jmp c0101f15 <__alltraps> + +c0102961 : +.globl vector250 +vector250: + pushl $0 +c0102961: 6a 00 push $0x0 + pushl $250 +c0102963: 68 fa 00 00 00 push $0xfa + jmp __alltraps +c0102968: e9 a8 f5 ff ff jmp c0101f15 <__alltraps> + +c010296d : +.globl vector251 +vector251: + pushl $0 +c010296d: 6a 00 push $0x0 + pushl $251 +c010296f: 68 fb 00 00 00 push $0xfb + jmp __alltraps +c0102974: e9 9c f5 ff ff jmp c0101f15 <__alltraps> + +c0102979 : +.globl vector252 +vector252: + pushl $0 +c0102979: 6a 00 push $0x0 + pushl $252 +c010297b: 68 fc 00 00 00 push $0xfc + jmp __alltraps +c0102980: e9 90 f5 ff ff jmp c0101f15 <__alltraps> + +c0102985 : +.globl vector253 +vector253: + pushl $0 +c0102985: 6a 00 push $0x0 + pushl $253 +c0102987: 68 fd 00 00 00 push $0xfd + jmp __alltraps +c010298c: e9 84 f5 ff ff jmp c0101f15 <__alltraps> + +c0102991 : +.globl vector254 +vector254: + pushl $0 +c0102991: 6a 00 push $0x0 + pushl $254 +c0102993: 68 fe 00 00 00 push $0xfe + jmp __alltraps +c0102998: e9 78 f5 ff ff jmp c0101f15 <__alltraps> + +c010299d : +.globl vector255 +vector255: + pushl $0 +c010299d: 6a 00 push $0x0 + pushl $255 +c010299f: 68 ff 00 00 00 push $0xff + jmp __alltraps +c01029a4: e9 6c f5 ff ff jmp c0101f15 <__alltraps> + +c01029a9 : + +extern struct Page *pages; +extern size_t npage; + +static inline ppn_t +page2ppn(struct Page *page) { +c01029a9: 55 push %ebp +c01029aa: 89 e5 mov %esp,%ebp + return page - pages; +c01029ac: 8b 15 00 cf 11 c0 mov 0xc011cf00,%edx +c01029b2: 8b 45 08 mov 0x8(%ebp),%eax +c01029b5: 29 d0 sub %edx,%eax +c01029b7: c1 f8 02 sar $0x2,%eax +c01029ba: 69 c0 cd cc cc cc imul $0xcccccccd,%eax,%eax +} +c01029c0: 5d pop %ebp +c01029c1: c3 ret + +c01029c2 : + +static inline uintptr_t +page2pa(struct Page *page) { +c01029c2: 55 push %ebp +c01029c3: 89 e5 mov %esp,%ebp +c01029c5: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; +c01029c8: 8b 45 08 mov 0x8(%ebp),%eax +c01029cb: 89 04 24 mov %eax,(%esp) +c01029ce: e8 d6 ff ff ff call c01029a9 +c01029d3: c1 e0 0c shl $0xc,%eax +} +c01029d6: 89 ec mov %ebp,%esp +c01029d8: 5d pop %ebp +c01029d9: c3 ret + +c01029da : +pde2page(pde_t pde) { + return pa2page(PDE_ADDR(pde)); +} + +static inline int +page_ref(struct Page *page) { +c01029da: 55 push %ebp +c01029db: 89 e5 mov %esp,%ebp + return page->ref; +c01029dd: 8b 45 08 mov 0x8(%ebp),%eax +c01029e0: 8b 00 mov (%eax),%eax +} +c01029e2: 5d pop %ebp +c01029e3: c3 ret + +c01029e4 : + +static inline void +set_page_ref(struct Page *page, int val) { +c01029e4: 55 push %ebp +c01029e5: 89 e5 mov %esp,%ebp + page->ref = val; +c01029e7: 8b 45 08 mov 0x8(%ebp),%eax +c01029ea: 8b 55 0c mov 0xc(%ebp),%edx +c01029ed: 89 10 mov %edx,(%eax) +} +c01029ef: 90 nop +c01029f0: 5d pop %ebp +c01029f1: c3 ret + +c01029f2 : +#define nr_free (free_area.nr_free) + +//free_list` 用于记录空闲内存块,nr_free` 是空闲内存块的总数。 +//用default_init函数来初始化 `free_list`,并将 `nr_free` 设置为 0。 +static void +default_init(void) { +c01029f2: 55 push %ebp +c01029f3: 89 e5 mov %esp,%ebp +c01029f5: 83 ec 10 sub $0x10,%esp +c01029f8: c7 45 fc e0 ce 11 c0 movl $0xc011cee0,-0x4(%ebp) + * list_init - initialize a new entry + * @elm: new entry to be initialized + * */ +static inline void +list_init(list_entry_t *elm) { + elm->prev = elm->next = elm; +c01029ff: 8b 45 fc mov -0x4(%ebp),%eax +c0102a02: 8b 55 fc mov -0x4(%ebp),%edx +c0102a05: 89 50 04 mov %edx,0x4(%eax) +c0102a08: 8b 45 fc mov -0x4(%ebp),%eax +c0102a0b: 8b 50 04 mov 0x4(%eax),%edx +c0102a0e: 8b 45 fc mov -0x4(%ebp),%eax +c0102a11: 89 10 mov %edx,(%eax) +} +c0102a13: 90 nop + list_init(&free_list); + nr_free = 0; +c0102a14: c7 05 e8 ce 11 c0 00 movl $0x0,0xc011cee8 +c0102a1b: 00 00 00 +} +c0102a1e: 90 nop +c0102a1f: 89 ec mov %ebp,%esp +c0102a21: 5d pop %ebp +c0102a22: c3 ret + +c0102a23 : + +//用于初始化一段连续的物理页,并将它们加入到空闲内存管理系统中. +//struct Page *base:指向要初始化的页块的起始地址。size_t n:要初始化的页的数量。 +static void +default_init_memmap(struct Page *base, size_t n) { +c0102a23: 55 push %ebp +c0102a24: 89 e5 mov %esp,%ebp +c0102a26: 83 ec 58 sub $0x58,%esp + assert(n > 0);//// 确保请求的页数大于零 +c0102a29: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c0102a2d: 75 24 jne c0102a53 +c0102a2f: c7 44 24 0c 90 67 10 movl $0xc0106790,0xc(%esp) +c0102a36: c0 +c0102a37: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0102a3e: c0 +c0102a3f: c7 44 24 04 94 00 00 movl $0x94,0x4(%esp) +c0102a46: 00 +c0102a47: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0102a4e: e8 e0 e1 ff ff call c0100c33 <__panic> + struct Page *p = base;// 指向当前初始化的页 +c0102a53: 8b 45 08 mov 0x8(%ebp),%eax +c0102a56: 89 45 f4 mov %eax,-0xc(%ebp) + //// 遍历每一页,设置其状态 + for (; p != base + n; p ++) { +c0102a59: eb 7d jmp c0102ad8 + assert(PageReserved(p));//检查每个页是否被标记为“保留”。若没有被保留,函数将抛出错误。 +c0102a5b: 8b 45 f4 mov -0xc(%ebp),%eax +c0102a5e: 83 c0 04 add $0x4,%eax +c0102a61: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) +c0102a68: 89 45 ec mov %eax,-0x14(%ebp) + * @addr: the address to count from + * */ +static inline bool +test_bit(int nr, volatile void *addr) { + int oldbit; + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0102a6b: 8b 45 ec mov -0x14(%ebp),%eax +c0102a6e: 8b 55 f0 mov -0x10(%ebp),%edx +c0102a71: 0f a3 10 bt %edx,(%eax) +c0102a74: 19 c0 sbb %eax,%eax +c0102a76: 89 45 e8 mov %eax,-0x18(%ebp) + return oldbit != 0; +c0102a79: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c0102a7d: 0f 95 c0 setne %al +c0102a80: 0f b6 c0 movzbl %al,%eax +c0102a83: 85 c0 test %eax,%eax +c0102a85: 75 24 jne c0102aab +c0102a87: c7 44 24 0c c1 67 10 movl $0xc01067c1,0xc(%esp) +c0102a8e: c0 +c0102a8f: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0102a96: c0 +c0102a97: c7 44 24 04 98 00 00 movl $0x98,0x4(%esp) +c0102a9e: 00 +c0102a9f: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0102aa6: e8 88 e1 ff ff call c0100c33 <__panic> + p->flags = p->property = 0;//将页的 flags 和 property 字段设置为 0,表示该页未分配、未使用。 +c0102aab: 8b 45 f4 mov -0xc(%ebp),%eax +c0102aae: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax) +c0102ab5: 8b 45 f4 mov -0xc(%ebp),%eax +c0102ab8: 8b 50 08 mov 0x8(%eax),%edx +c0102abb: 8b 45 f4 mov -0xc(%ebp),%eax +c0102abe: 89 50 04 mov %edx,0x4(%eax) + set_page_ref(p, 0);//将页的引用计数设置为 0,表明没有任何引用指向此页。 +c0102ac1: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0102ac8: 00 +c0102ac9: 8b 45 f4 mov -0xc(%ebp),%eax +c0102acc: 89 04 24 mov %eax,(%esp) +c0102acf: e8 10 ff ff ff call c01029e4 + for (; p != base + n; p ++) { +c0102ad4: 83 45 f4 14 addl $0x14,-0xc(%ebp) +c0102ad8: 8b 55 0c mov 0xc(%ebp),%edx +c0102adb: 89 d0 mov %edx,%eax +c0102add: c1 e0 02 shl $0x2,%eax +c0102ae0: 01 d0 add %edx,%eax +c0102ae2: c1 e0 02 shl $0x2,%eax +c0102ae5: 89 c2 mov %eax,%edx +c0102ae7: 8b 45 08 mov 0x8(%ebp),%eax +c0102aea: 01 d0 add %edx,%eax +c0102aec: 39 45 f4 cmp %eax,-0xc(%ebp) +c0102aef: 0f 85 66 ff ff ff jne c0102a5b + } + // 设置第一个页的 property 为块的总数 + base->property = n; +c0102af5: 8b 45 08 mov 0x8(%ebp),%eax +c0102af8: 8b 55 0c mov 0xc(%ebp),%edx +c0102afb: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(base);// 设置当前页的有效标志 +c0102afe: 8b 45 08 mov 0x8(%ebp),%eax +c0102b01: 83 c0 04 add $0x4,%eax +c0102b04: c7 45 c8 01 00 00 00 movl $0x1,-0x38(%ebp) +c0102b0b: 89 45 c4 mov %eax,-0x3c(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0102b0e: 8b 45 c4 mov -0x3c(%ebp),%eax +c0102b11: 8b 55 c8 mov -0x38(%ebp),%edx +c0102b14: 0f ab 10 bts %edx,(%eax) +} +c0102b17: 90 nop + nr_free += n;// 更新空闲页计数 +c0102b18: 8b 15 e8 ce 11 c0 mov 0xc011cee8,%edx +c0102b1e: 8b 45 0c mov 0xc(%ebp),%eax +c0102b21: 01 d0 add %edx,%eax +c0102b23: a3 e8 ce 11 c0 mov %eax,0xc011cee8 + list_add(&free_list, &(base->page_link)); // 将该块添加到空闲列表中 +c0102b28: 8b 45 08 mov 0x8(%ebp),%eax +c0102b2b: 83 c0 0c add $0xc,%eax +c0102b2e: c7 45 e4 e0 ce 11 c0 movl $0xc011cee0,-0x1c(%ebp) +c0102b35: 89 45 e0 mov %eax,-0x20(%ebp) +c0102b38: 8b 45 e4 mov -0x1c(%ebp),%eax +c0102b3b: 89 45 dc mov %eax,-0x24(%ebp) +c0102b3e: 8b 45 e0 mov -0x20(%ebp),%eax +c0102b41: 89 45 d8 mov %eax,-0x28(%ebp) + * Insert the new element @elm *after* the element @listelm which + * is already in the list. + * */ +static inline void +list_add_after(list_entry_t *listelm, list_entry_t *elm) { + __list_add(elm, listelm, listelm->next); +c0102b44: 8b 45 dc mov -0x24(%ebp),%eax +c0102b47: 8b 40 04 mov 0x4(%eax),%eax +c0102b4a: 8b 55 d8 mov -0x28(%ebp),%edx +c0102b4d: 89 55 d4 mov %edx,-0x2c(%ebp) +c0102b50: 8b 55 dc mov -0x24(%ebp),%edx +c0102b53: 89 55 d0 mov %edx,-0x30(%ebp) +c0102b56: 89 45 cc mov %eax,-0x34(%ebp) + * This is only for internal list manipulation where we know + * the prev/next entries already! + * */ +static inline void +__list_add(list_entry_t *elm, list_entry_t *prev, list_entry_t *next) { + prev->next = next->prev = elm; +c0102b59: 8b 45 cc mov -0x34(%ebp),%eax +c0102b5c: 8b 55 d4 mov -0x2c(%ebp),%edx +c0102b5f: 89 10 mov %edx,(%eax) +c0102b61: 8b 45 cc mov -0x34(%ebp),%eax +c0102b64: 8b 10 mov (%eax),%edx +c0102b66: 8b 45 d0 mov -0x30(%ebp),%eax +c0102b69: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0102b6c: 8b 45 d4 mov -0x2c(%ebp),%eax +c0102b6f: 8b 55 cc mov -0x34(%ebp),%edx +c0102b72: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c0102b75: 8b 45 d4 mov -0x2c(%ebp),%eax +c0102b78: 8b 55 d0 mov -0x30(%ebp),%edx +c0102b7b: 89 10 mov %edx,(%eax) +} +c0102b7d: 90 nop +} +c0102b7e: 90 nop +} +c0102b7f: 90 nop +} +c0102b80: 90 nop +c0102b81: 89 ec mov %ebp,%esp +c0102b83: 5d pop %ebp +c0102b84: c3 ret + +c0102b85 : + +//用于分配指定数量的连续物理页。该函数实现了首次适应内存分配算法。 +static struct Page * +default_alloc_pages(size_t n) { +c0102b85: 55 push %ebp +c0102b86: 89 e5 mov %esp,%ebp +c0102b88: 83 ec 68 sub $0x68,%esp + assert(n > 0);// 确保请求的页数大于零 +c0102b8b: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0102b8f: 75 24 jne c0102bb5 +c0102b91: c7 44 24 0c 90 67 10 movl $0xc0106790,0xc(%esp) +c0102b98: c0 +c0102b99: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0102ba0: c0 +c0102ba1: c7 44 24 04 a6 00 00 movl $0xa6,0x4(%esp) +c0102ba8: 00 +c0102ba9: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0102bb0: e8 7e e0 ff ff call c0100c33 <__panic> + if (n > nr_free) {// 检查请求的页数是否超过空闲页数 +c0102bb5: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c0102bba: 39 45 08 cmp %eax,0x8(%ebp) +c0102bbd: 76 0a jbe c0102bc9 + return NULL; +c0102bbf: b8 00 00 00 00 mov $0x0,%eax +c0102bc4: e9 34 01 00 00 jmp c0102cfd + } + struct Page *page = NULL;// 初始化分配的页指针 +c0102bc9: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + list_entry_t *le = &free_list; // 初始化链表迭代器 +c0102bd0: c7 45 f0 e0 ce 11 c0 movl $0xc011cee0,-0x10(%ebp) + // 遍历空闲列表,寻找第一个满足条件的块 + while ((le = list_next(le)) != &free_list) { +c0102bd7: eb 1c jmp c0102bf5 + struct Page *p = le2page(le, page_link);// 将链表节点转换为 Page 结构体 +c0102bd9: 8b 45 f0 mov -0x10(%ebp),%eax +c0102bdc: 83 e8 0c sub $0xc,%eax +c0102bdf: 89 45 ec mov %eax,-0x14(%ebp) + if (p->property >= n) {// 检查当前块的页数是否满足请求 +c0102be2: 8b 45 ec mov -0x14(%ebp),%eax +c0102be5: 8b 40 08 mov 0x8(%eax),%eax +c0102be8: 39 45 08 cmp %eax,0x8(%ebp) +c0102beb: 77 08 ja c0102bf5 + page = p;// 找到合适的块 +c0102bed: 8b 45 ec mov -0x14(%ebp),%eax +c0102bf0: 89 45 f4 mov %eax,-0xc(%ebp) + break;// 退出循环 +c0102bf3: eb 18 jmp c0102c0d +c0102bf5: 8b 45 f0 mov -0x10(%ebp),%eax +c0102bf8: 89 45 e4 mov %eax,-0x1c(%ebp) + return listelm->next; +c0102bfb: 8b 45 e4 mov -0x1c(%ebp),%eax +c0102bfe: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c0102c01: 89 45 f0 mov %eax,-0x10(%ebp) +c0102c04: 81 7d f0 e0 ce 11 c0 cmpl $0xc011cee0,-0x10(%ebp) +c0102c0b: 75 cc jne c0102bd9 + } + } + if (page != NULL) {// 如果找到合适的块 +c0102c0d: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0102c11: 0f 84 e3 00 00 00 je c0102cfa + list_del(&(page->page_link));// 从空闲列表中删除该块 +c0102c17: 8b 45 f4 mov -0xc(%ebp),%eax +c0102c1a: 83 c0 0c add $0xc,%eax +c0102c1d: 89 45 e0 mov %eax,-0x20(%ebp) + __list_del(listelm->prev, listelm->next); +c0102c20: 8b 45 e0 mov -0x20(%ebp),%eax +c0102c23: 8b 40 04 mov 0x4(%eax),%eax +c0102c26: 8b 55 e0 mov -0x20(%ebp),%edx +c0102c29: 8b 12 mov (%edx),%edx +c0102c2b: 89 55 dc mov %edx,-0x24(%ebp) +c0102c2e: 89 45 d8 mov %eax,-0x28(%ebp) + * This is only for internal list manipulation where we know + * the prev/next entries already! + * */ +static inline void +__list_del(list_entry_t *prev, list_entry_t *next) { + prev->next = next; +c0102c31: 8b 45 dc mov -0x24(%ebp),%eax +c0102c34: 8b 55 d8 mov -0x28(%ebp),%edx +c0102c37: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c0102c3a: 8b 45 d8 mov -0x28(%ebp),%eax +c0102c3d: 8b 55 dc mov -0x24(%ebp),%edx +c0102c40: 89 10 mov %edx,(%eax) +} +c0102c42: 90 nop +} +c0102c43: 90 nop + if (page->property > n) { +c0102c44: 8b 45 f4 mov -0xc(%ebp),%eax +c0102c47: 8b 40 08 mov 0x8(%eax),%eax +c0102c4a: 39 45 08 cmp %eax,0x8(%ebp) +c0102c4d: 0f 83 80 00 00 00 jae c0102cd3 + struct Page *p = page + n; // 指向剩余的页 +c0102c53: 8b 55 08 mov 0x8(%ebp),%edx +c0102c56: 89 d0 mov %edx,%eax +c0102c58: c1 e0 02 shl $0x2,%eax +c0102c5b: 01 d0 add %edx,%eax +c0102c5d: c1 e0 02 shl $0x2,%eax +c0102c60: 89 c2 mov %eax,%edx +c0102c62: 8b 45 f4 mov -0xc(%ebp),%eax +c0102c65: 01 d0 add %edx,%eax +c0102c67: 89 45 e8 mov %eax,-0x18(%ebp) + p->property = page->property - n;// 更新剩余块的页数 +c0102c6a: 8b 45 f4 mov -0xc(%ebp),%eax +c0102c6d: 8b 40 08 mov 0x8(%eax),%eax +c0102c70: 2b 45 08 sub 0x8(%ebp),%eax +c0102c73: 89 c2 mov %eax,%edx +c0102c75: 8b 45 e8 mov -0x18(%ebp),%eax +c0102c78: 89 50 08 mov %edx,0x8(%eax) + list_add(&free_list, &(p->page_link));// 将剩余块添加回空闲列表 +c0102c7b: 8b 45 e8 mov -0x18(%ebp),%eax +c0102c7e: 83 c0 0c add $0xc,%eax +c0102c81: c7 45 d4 e0 ce 11 c0 movl $0xc011cee0,-0x2c(%ebp) +c0102c88: 89 45 d0 mov %eax,-0x30(%ebp) +c0102c8b: 8b 45 d4 mov -0x2c(%ebp),%eax +c0102c8e: 89 45 cc mov %eax,-0x34(%ebp) +c0102c91: 8b 45 d0 mov -0x30(%ebp),%eax +c0102c94: 89 45 c8 mov %eax,-0x38(%ebp) + __list_add(elm, listelm, listelm->next); +c0102c97: 8b 45 cc mov -0x34(%ebp),%eax +c0102c9a: 8b 40 04 mov 0x4(%eax),%eax +c0102c9d: 8b 55 c8 mov -0x38(%ebp),%edx +c0102ca0: 89 55 c4 mov %edx,-0x3c(%ebp) +c0102ca3: 8b 55 cc mov -0x34(%ebp),%edx +c0102ca6: 89 55 c0 mov %edx,-0x40(%ebp) +c0102ca9: 89 45 bc mov %eax,-0x44(%ebp) + prev->next = next->prev = elm; +c0102cac: 8b 45 bc mov -0x44(%ebp),%eax +c0102caf: 8b 55 c4 mov -0x3c(%ebp),%edx +c0102cb2: 89 10 mov %edx,(%eax) +c0102cb4: 8b 45 bc mov -0x44(%ebp),%eax +c0102cb7: 8b 10 mov (%eax),%edx +c0102cb9: 8b 45 c0 mov -0x40(%ebp),%eax +c0102cbc: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0102cbf: 8b 45 c4 mov -0x3c(%ebp),%eax +c0102cc2: 8b 55 bc mov -0x44(%ebp),%edx +c0102cc5: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c0102cc8: 8b 45 c4 mov -0x3c(%ebp),%eax +c0102ccb: 8b 55 c0 mov -0x40(%ebp),%edx +c0102cce: 89 10 mov %edx,(%eax) +} +c0102cd0: 90 nop +} +c0102cd1: 90 nop +} +c0102cd2: 90 nop + } + nr_free -= n;// 减少空闲页的计数 +c0102cd3: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c0102cd8: 2b 45 08 sub 0x8(%ebp),%eax +c0102cdb: a3 e8 ce 11 c0 mov %eax,0xc011cee8 + ClearPageProperty(page); // 清除已分配页的属性 +c0102ce0: 8b 45 f4 mov -0xc(%ebp),%eax +c0102ce3: 83 c0 04 add $0x4,%eax +c0102ce6: c7 45 b8 01 00 00 00 movl $0x1,-0x48(%ebp) +c0102ced: 89 45 b4 mov %eax,-0x4c(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0102cf0: 8b 45 b4 mov -0x4c(%ebp),%eax +c0102cf3: 8b 55 b8 mov -0x48(%ebp),%edx +c0102cf6: 0f b3 10 btr %edx,(%eax) +} +c0102cf9: 90 nop + } + return page;// 返回分配的页块 +c0102cfa: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0102cfd: 89 ec mov %ebp,%esp +c0102cff: 5d pop %ebp +c0102d00: c3 ret + +c0102d01 : + +static void +default_free_pages(struct Page *base, size_t n) { +c0102d01: 55 push %ebp +c0102d02: 89 e5 mov %esp,%ebp +c0102d04: 81 ec 98 00 00 00 sub $0x98,%esp + assert(n > 0);// 确保请求释放的页数大于零 +c0102d0a: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c0102d0e: 75 24 jne c0102d34 +c0102d10: c7 44 24 0c 90 67 10 movl $0xc0106790,0xc(%esp) +c0102d17: c0 +c0102d18: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0102d1f: c0 +c0102d20: c7 44 24 04 c3 00 00 movl $0xc3,0x4(%esp) +c0102d27: 00 +c0102d28: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0102d2f: e8 ff de ff ff call c0100c33 <__panic> + struct Page *p = base; +c0102d34: 8b 45 08 mov 0x8(%ebp),%eax +c0102d37: 89 45 f4 mov %eax,-0xc(%ebp) + // 遍历释放的页,检查状态并重置 + for (; p != base + n; p ++) { +c0102d3a: e9 9d 00 00 00 jmp c0102ddc + assert(!PageReserved(p) && !PageProperty(p)); // 确保页没有被保留并且没有属性 +c0102d3f: 8b 45 f4 mov -0xc(%ebp),%eax +c0102d42: 83 c0 04 add $0x4,%eax +c0102d45: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp) +c0102d4c: 89 45 e8 mov %eax,-0x18(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0102d4f: 8b 45 e8 mov -0x18(%ebp),%eax +c0102d52: 8b 55 ec mov -0x14(%ebp),%edx +c0102d55: 0f a3 10 bt %edx,(%eax) +c0102d58: 19 c0 sbb %eax,%eax +c0102d5a: 89 45 e4 mov %eax,-0x1c(%ebp) + return oldbit != 0; +c0102d5d: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0102d61: 0f 95 c0 setne %al +c0102d64: 0f b6 c0 movzbl %al,%eax +c0102d67: 85 c0 test %eax,%eax +c0102d69: 75 2c jne c0102d97 +c0102d6b: 8b 45 f4 mov -0xc(%ebp),%eax +c0102d6e: 83 c0 04 add $0x4,%eax +c0102d71: c7 45 e0 01 00 00 00 movl $0x1,-0x20(%ebp) +c0102d78: 89 45 dc mov %eax,-0x24(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0102d7b: 8b 45 dc mov -0x24(%ebp),%eax +c0102d7e: 8b 55 e0 mov -0x20(%ebp),%edx +c0102d81: 0f a3 10 bt %edx,(%eax) +c0102d84: 19 c0 sbb %eax,%eax +c0102d86: 89 45 d8 mov %eax,-0x28(%ebp) + return oldbit != 0; +c0102d89: 83 7d d8 00 cmpl $0x0,-0x28(%ebp) +c0102d8d: 0f 95 c0 setne %al +c0102d90: 0f b6 c0 movzbl %al,%eax +c0102d93: 85 c0 test %eax,%eax +c0102d95: 74 24 je c0102dbb +c0102d97: c7 44 24 0c d4 67 10 movl $0xc01067d4,0xc(%esp) +c0102d9e: c0 +c0102d9f: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0102da6: c0 +c0102da7: c7 44 24 04 c7 00 00 movl $0xc7,0x4(%esp) +c0102dae: 00 +c0102daf: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0102db6: e8 78 de ff ff call c0100c33 <__panic> + p->flags = 0;// 清除 flags 字段 +c0102dbb: 8b 45 f4 mov -0xc(%ebp),%eax +c0102dbe: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) + set_page_ref(p, 0);// 清除引用计数 +c0102dc5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0102dcc: 00 +c0102dcd: 8b 45 f4 mov -0xc(%ebp),%eax +c0102dd0: 89 04 24 mov %eax,(%esp) +c0102dd3: e8 0c fc ff ff call c01029e4 + for (; p != base + n; p ++) { +c0102dd8: 83 45 f4 14 addl $0x14,-0xc(%ebp) +c0102ddc: 8b 55 0c mov 0xc(%ebp),%edx +c0102ddf: 89 d0 mov %edx,%eax +c0102de1: c1 e0 02 shl $0x2,%eax +c0102de4: 01 d0 add %edx,%eax +c0102de6: c1 e0 02 shl $0x2,%eax +c0102de9: 89 c2 mov %eax,%edx +c0102deb: 8b 45 08 mov 0x8(%ebp),%eax +c0102dee: 01 d0 add %edx,%eax +c0102df0: 39 45 f4 cmp %eax,-0xc(%ebp) +c0102df3: 0f 85 46 ff ff ff jne c0102d3f + } + // 设置基页的属性为释放的页数 + base->property = n; +c0102df9: 8b 45 08 mov 0x8(%ebp),%eax +c0102dfc: 8b 55 0c mov 0xc(%ebp),%edx +c0102dff: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(base);// 设置页的有效标志 +c0102e02: 8b 45 08 mov 0x8(%ebp),%eax +c0102e05: 83 c0 04 add $0x4,%eax +c0102e08: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) +c0102e0f: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0102e12: 8b 45 cc mov -0x34(%ebp),%eax +c0102e15: 8b 55 d0 mov -0x30(%ebp),%edx +c0102e18: 0f ab 10 bts %edx,(%eax) +} +c0102e1b: 90 nop +c0102e1c: c7 45 d4 e0 ce 11 c0 movl $0xc011cee0,-0x2c(%ebp) + return listelm->next; +c0102e23: 8b 45 d4 mov -0x2c(%ebp),%eax +c0102e26: 8b 40 04 mov 0x4(%eax),%eax + // 遍历空闲列表,检查是否需要合并 + list_entry_t *le = list_next(&free_list); +c0102e29: 89 45 f0 mov %eax,-0x10(%ebp) + while (le != &free_list) { +c0102e2c: e9 0e 01 00 00 jmp c0102f3f + p = le2page(le, page_link); +c0102e31: 8b 45 f0 mov -0x10(%ebp),%eax +c0102e34: 83 e8 0c sub $0xc,%eax +c0102e37: 89 45 f4 mov %eax,-0xc(%ebp) +c0102e3a: 8b 45 f0 mov -0x10(%ebp),%eax +c0102e3d: 89 45 c8 mov %eax,-0x38(%ebp) +c0102e40: 8b 45 c8 mov -0x38(%ebp),%eax +c0102e43: 8b 40 04 mov 0x4(%eax),%eax + le = list_next(le); +c0102e46: 89 45 f0 mov %eax,-0x10(%ebp) + // 如果当前页块与释放的页块相邻,合并 + if (base + base->property == p) { +c0102e49: 8b 45 08 mov 0x8(%ebp),%eax +c0102e4c: 8b 50 08 mov 0x8(%eax),%edx +c0102e4f: 89 d0 mov %edx,%eax +c0102e51: c1 e0 02 shl $0x2,%eax +c0102e54: 01 d0 add %edx,%eax +c0102e56: c1 e0 02 shl $0x2,%eax +c0102e59: 89 c2 mov %eax,%edx +c0102e5b: 8b 45 08 mov 0x8(%ebp),%eax +c0102e5e: 01 d0 add %edx,%eax +c0102e60: 39 45 f4 cmp %eax,-0xc(%ebp) +c0102e63: 75 5d jne c0102ec2 + base->property += p->property;// 合并当前页块 +c0102e65: 8b 45 08 mov 0x8(%ebp),%eax +c0102e68: 8b 50 08 mov 0x8(%eax),%edx +c0102e6b: 8b 45 f4 mov -0xc(%ebp),%eax +c0102e6e: 8b 40 08 mov 0x8(%eax),%eax +c0102e71: 01 c2 add %eax,%edx +c0102e73: 8b 45 08 mov 0x8(%ebp),%eax +c0102e76: 89 50 08 mov %edx,0x8(%eax) + ClearPageProperty(p);// 清除合并页的属性 +c0102e79: 8b 45 f4 mov -0xc(%ebp),%eax +c0102e7c: 83 c0 04 add $0x4,%eax +c0102e7f: c7 45 b8 01 00 00 00 movl $0x1,-0x48(%ebp) +c0102e86: 89 45 b4 mov %eax,-0x4c(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0102e89: 8b 45 b4 mov -0x4c(%ebp),%eax +c0102e8c: 8b 55 b8 mov -0x48(%ebp),%edx +c0102e8f: 0f b3 10 btr %edx,(%eax) +} +c0102e92: 90 nop + list_del(&(p->page_link));// 从空闲列表中删除合并页 +c0102e93: 8b 45 f4 mov -0xc(%ebp),%eax +c0102e96: 83 c0 0c add $0xc,%eax +c0102e99: 89 45 c4 mov %eax,-0x3c(%ebp) + __list_del(listelm->prev, listelm->next); +c0102e9c: 8b 45 c4 mov -0x3c(%ebp),%eax +c0102e9f: 8b 40 04 mov 0x4(%eax),%eax +c0102ea2: 8b 55 c4 mov -0x3c(%ebp),%edx +c0102ea5: 8b 12 mov (%edx),%edx +c0102ea7: 89 55 c0 mov %edx,-0x40(%ebp) +c0102eaa: 89 45 bc mov %eax,-0x44(%ebp) + prev->next = next; +c0102ead: 8b 45 c0 mov -0x40(%ebp),%eax +c0102eb0: 8b 55 bc mov -0x44(%ebp),%edx +c0102eb3: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c0102eb6: 8b 45 bc mov -0x44(%ebp),%eax +c0102eb9: 8b 55 c0 mov -0x40(%ebp),%edx +c0102ebc: 89 10 mov %edx,(%eax) +} +c0102ebe: 90 nop +} +c0102ebf: 90 nop +c0102ec0: eb 7d jmp c0102f3f + } + else if (p + p->property == base) { +c0102ec2: 8b 45 f4 mov -0xc(%ebp),%eax +c0102ec5: 8b 50 08 mov 0x8(%eax),%edx +c0102ec8: 89 d0 mov %edx,%eax +c0102eca: c1 e0 02 shl $0x2,%eax +c0102ecd: 01 d0 add %edx,%eax +c0102ecf: c1 e0 02 shl $0x2,%eax +c0102ed2: 89 c2 mov %eax,%edx +c0102ed4: 8b 45 f4 mov -0xc(%ebp),%eax +c0102ed7: 01 d0 add %edx,%eax +c0102ed9: 39 45 08 cmp %eax,0x8(%ebp) +c0102edc: 75 61 jne c0102f3f + p->property += base->property;// 合并前一个页块 +c0102ede: 8b 45 f4 mov -0xc(%ebp),%eax +c0102ee1: 8b 50 08 mov 0x8(%eax),%edx +c0102ee4: 8b 45 08 mov 0x8(%ebp),%eax +c0102ee7: 8b 40 08 mov 0x8(%eax),%eax +c0102eea: 01 c2 add %eax,%edx +c0102eec: 8b 45 f4 mov -0xc(%ebp),%eax +c0102eef: 89 50 08 mov %edx,0x8(%eax) + ClearPageProperty(base);// 清除当前页的属性 +c0102ef2: 8b 45 08 mov 0x8(%ebp),%eax +c0102ef5: 83 c0 04 add $0x4,%eax +c0102ef8: c7 45 a4 01 00 00 00 movl $0x1,-0x5c(%ebp) +c0102eff: 89 45 a0 mov %eax,-0x60(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c0102f02: 8b 45 a0 mov -0x60(%ebp),%eax +c0102f05: 8b 55 a4 mov -0x5c(%ebp),%edx +c0102f08: 0f b3 10 btr %edx,(%eax) +} +c0102f0b: 90 nop + base = p;// 更新 base 指针 +c0102f0c: 8b 45 f4 mov -0xc(%ebp),%eax +c0102f0f: 89 45 08 mov %eax,0x8(%ebp) + list_del(&(p->page_link)); // 从空闲列表中删除当前页 +c0102f12: 8b 45 f4 mov -0xc(%ebp),%eax +c0102f15: 83 c0 0c add $0xc,%eax +c0102f18: 89 45 b0 mov %eax,-0x50(%ebp) + __list_del(listelm->prev, listelm->next); +c0102f1b: 8b 45 b0 mov -0x50(%ebp),%eax +c0102f1e: 8b 40 04 mov 0x4(%eax),%eax +c0102f21: 8b 55 b0 mov -0x50(%ebp),%edx +c0102f24: 8b 12 mov (%edx),%edx +c0102f26: 89 55 ac mov %edx,-0x54(%ebp) +c0102f29: 89 45 a8 mov %eax,-0x58(%ebp) + prev->next = next; +c0102f2c: 8b 45 ac mov -0x54(%ebp),%eax +c0102f2f: 8b 55 a8 mov -0x58(%ebp),%edx +c0102f32: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; +c0102f35: 8b 45 a8 mov -0x58(%ebp),%eax +c0102f38: 8b 55 ac mov -0x54(%ebp),%edx +c0102f3b: 89 10 mov %edx,(%eax) +} +c0102f3d: 90 nop +} +c0102f3e: 90 nop + while (le != &free_list) { +c0102f3f: 81 7d f0 e0 ce 11 c0 cmpl $0xc011cee0,-0x10(%ebp) +c0102f46: 0f 85 e5 fe ff ff jne c0102e31 + } + } + nr_free += n;// 更新空闲页的计数 +c0102f4c: 8b 15 e8 ce 11 c0 mov 0xc011cee8,%edx +c0102f52: 8b 45 0c mov 0xc(%ebp),%eax +c0102f55: 01 d0 add %edx,%eax +c0102f57: a3 e8 ce 11 c0 mov %eax,0xc011cee8 + list_add(&free_list, &(base->page_link));// 将释放的页块添加到空闲列表中 +c0102f5c: 8b 45 08 mov 0x8(%ebp),%eax +c0102f5f: 83 c0 0c add $0xc,%eax +c0102f62: c7 45 9c e0 ce 11 c0 movl $0xc011cee0,-0x64(%ebp) +c0102f69: 89 45 98 mov %eax,-0x68(%ebp) +c0102f6c: 8b 45 9c mov -0x64(%ebp),%eax +c0102f6f: 89 45 94 mov %eax,-0x6c(%ebp) +c0102f72: 8b 45 98 mov -0x68(%ebp),%eax +c0102f75: 89 45 90 mov %eax,-0x70(%ebp) + __list_add(elm, listelm, listelm->next); +c0102f78: 8b 45 94 mov -0x6c(%ebp),%eax +c0102f7b: 8b 40 04 mov 0x4(%eax),%eax +c0102f7e: 8b 55 90 mov -0x70(%ebp),%edx +c0102f81: 89 55 8c mov %edx,-0x74(%ebp) +c0102f84: 8b 55 94 mov -0x6c(%ebp),%edx +c0102f87: 89 55 88 mov %edx,-0x78(%ebp) +c0102f8a: 89 45 84 mov %eax,-0x7c(%ebp) + prev->next = next->prev = elm; +c0102f8d: 8b 45 84 mov -0x7c(%ebp),%eax +c0102f90: 8b 55 8c mov -0x74(%ebp),%edx +c0102f93: 89 10 mov %edx,(%eax) +c0102f95: 8b 45 84 mov -0x7c(%ebp),%eax +c0102f98: 8b 10 mov (%eax),%edx +c0102f9a: 8b 45 88 mov -0x78(%ebp),%eax +c0102f9d: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; +c0102fa0: 8b 45 8c mov -0x74(%ebp),%eax +c0102fa3: 8b 55 84 mov -0x7c(%ebp),%edx +c0102fa6: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; +c0102fa9: 8b 45 8c mov -0x74(%ebp),%eax +c0102fac: 8b 55 88 mov -0x78(%ebp),%edx +c0102faf: 89 10 mov %edx,(%eax) +} +c0102fb1: 90 nop +} +c0102fb2: 90 nop +} +c0102fb3: 90 nop +} +c0102fb4: 90 nop +c0102fb5: 89 ec mov %ebp,%esp +c0102fb7: 5d pop %ebp +c0102fb8: c3 ret + +c0102fb9 : + +//用于返回当前系统中可用的空闲页的数量。 +static size_t +default_nr_free_pages(void) { +c0102fb9: 55 push %ebp +c0102fba: 89 e5 mov %esp,%ebp + return nr_free;// 返回当前空闲页的数量 +c0102fbc: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +} +c0102fc1: 5d pop %ebp +c0102fc2: c3 ret + +c0102fc3 : + +//basic_check 函数用于测试内存分配和释放的基本功能, +//确保在不同情况下内存管理系统的正确性,包括分配、释放、合并和引用计数等操作。 +static void +basic_check(void) { +c0102fc3: 55 push %ebp +c0102fc4: 89 e5 mov %esp,%ebp +c0102fc6: 83 ec 48 sub $0x48,%esp + struct Page *p0, *p1, *p2; + p0 = p1 = p2 = NULL; +c0102fc9: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0102fd0: 8b 45 f4 mov -0xc(%ebp),%eax +c0102fd3: 89 45 f0 mov %eax,-0x10(%ebp) +c0102fd6: 8b 45 f0 mov -0x10(%ebp),%eax +c0102fd9: 89 45 ec mov %eax,-0x14(%ebp) + // 分配三个页面 + assert((p0 = alloc_page()) != NULL); +c0102fdc: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0102fe3: e8 ed 0e 00 00 call c0103ed5 +c0102fe8: 89 45 ec mov %eax,-0x14(%ebp) +c0102feb: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c0102fef: 75 24 jne c0103015 +c0102ff1: c7 44 24 0c f9 67 10 movl $0xc01067f9,0xc(%esp) +c0102ff8: c0 +c0102ff9: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103000: c0 +c0103001: c7 44 24 04 f1 00 00 movl $0xf1,0x4(%esp) +c0103008: 00 +c0103009: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103010: e8 1e dc ff ff call c0100c33 <__panic> + assert((p1 = alloc_page()) != NULL); +c0103015: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010301c: e8 b4 0e 00 00 call c0103ed5 +c0103021: 89 45 f0 mov %eax,-0x10(%ebp) +c0103024: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0103028: 75 24 jne c010304e +c010302a: c7 44 24 0c 15 68 10 movl $0xc0106815,0xc(%esp) +c0103031: c0 +c0103032: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103039: c0 +c010303a: c7 44 24 04 f2 00 00 movl $0xf2,0x4(%esp) +c0103041: 00 +c0103042: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103049: e8 e5 db ff ff call c0100c33 <__panic> + assert((p2 = alloc_page()) != NULL); +c010304e: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103055: e8 7b 0e 00 00 call c0103ed5 +c010305a: 89 45 f4 mov %eax,-0xc(%ebp) +c010305d: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0103061: 75 24 jne c0103087 +c0103063: c7 44 24 0c 31 68 10 movl $0xc0106831,0xc(%esp) +c010306a: c0 +c010306b: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103072: c0 +c0103073: c7 44 24 04 f3 00 00 movl $0xf3,0x4(%esp) +c010307a: 00 +c010307b: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103082: e8 ac db ff ff call c0100c33 <__panic> + // 确保所有分配的页面是不同的 + assert(p0 != p1 && p0 != p2 && p1 != p2); +c0103087: 8b 45 ec mov -0x14(%ebp),%eax +c010308a: 3b 45 f0 cmp -0x10(%ebp),%eax +c010308d: 74 10 je c010309f +c010308f: 8b 45 ec mov -0x14(%ebp),%eax +c0103092: 3b 45 f4 cmp -0xc(%ebp),%eax +c0103095: 74 08 je c010309f +c0103097: 8b 45 f0 mov -0x10(%ebp),%eax +c010309a: 3b 45 f4 cmp -0xc(%ebp),%eax +c010309d: 75 24 jne c01030c3 +c010309f: c7 44 24 0c 50 68 10 movl $0xc0106850,0xc(%esp) +c01030a6: c0 +c01030a7: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01030ae: c0 +c01030af: c7 44 24 04 f5 00 00 movl $0xf5,0x4(%esp) +c01030b6: 00 +c01030b7: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01030be: e8 70 db ff ff call c0100c33 <__panic> + // 确保页面的引用计数为 0 + assert(page_ref(p0) == 0 && page_ref(p1) == 0 && page_ref(p2) == 0); +c01030c3: 8b 45 ec mov -0x14(%ebp),%eax +c01030c6: 89 04 24 mov %eax,(%esp) +c01030c9: e8 0c f9 ff ff call c01029da +c01030ce: 85 c0 test %eax,%eax +c01030d0: 75 1e jne c01030f0 +c01030d2: 8b 45 f0 mov -0x10(%ebp),%eax +c01030d5: 89 04 24 mov %eax,(%esp) +c01030d8: e8 fd f8 ff ff call c01029da +c01030dd: 85 c0 test %eax,%eax +c01030df: 75 0f jne c01030f0 +c01030e1: 8b 45 f4 mov -0xc(%ebp),%eax +c01030e4: 89 04 24 mov %eax,(%esp) +c01030e7: e8 ee f8 ff ff call c01029da +c01030ec: 85 c0 test %eax,%eax +c01030ee: 74 24 je c0103114 +c01030f0: c7 44 24 0c 74 68 10 movl $0xc0106874,0xc(%esp) +c01030f7: c0 +c01030f8: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01030ff: c0 +c0103100: c7 44 24 04 f7 00 00 movl $0xf7,0x4(%esp) +c0103107: 00 +c0103108: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010310f: e8 1f db ff ff call c0100c33 <__panic> + // 确保页面地址在合法范围内 + assert(page2pa(p0) < npage * PGSIZE); +c0103114: 8b 45 ec mov -0x14(%ebp),%eax +c0103117: 89 04 24 mov %eax,(%esp) +c010311a: e8 a3 f8 ff ff call c01029c2 +c010311f: 8b 15 04 cf 11 c0 mov 0xc011cf04,%edx +c0103125: c1 e2 0c shl $0xc,%edx +c0103128: 39 d0 cmp %edx,%eax +c010312a: 72 24 jb c0103150 +c010312c: c7 44 24 0c b0 68 10 movl $0xc01068b0,0xc(%esp) +c0103133: c0 +c0103134: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010313b: c0 +c010313c: c7 44 24 04 f9 00 00 movl $0xf9,0x4(%esp) +c0103143: 00 +c0103144: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010314b: e8 e3 da ff ff call c0100c33 <__panic> + assert(page2pa(p1) < npage * PGSIZE); +c0103150: 8b 45 f0 mov -0x10(%ebp),%eax +c0103153: 89 04 24 mov %eax,(%esp) +c0103156: e8 67 f8 ff ff call c01029c2 +c010315b: 8b 15 04 cf 11 c0 mov 0xc011cf04,%edx +c0103161: c1 e2 0c shl $0xc,%edx +c0103164: 39 d0 cmp %edx,%eax +c0103166: 72 24 jb c010318c +c0103168: c7 44 24 0c cd 68 10 movl $0xc01068cd,0xc(%esp) +c010316f: c0 +c0103170: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103177: c0 +c0103178: c7 44 24 04 fa 00 00 movl $0xfa,0x4(%esp) +c010317f: 00 +c0103180: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103187: e8 a7 da ff ff call c0100c33 <__panic> + assert(page2pa(p2) < npage * PGSIZE); +c010318c: 8b 45 f4 mov -0xc(%ebp),%eax +c010318f: 89 04 24 mov %eax,(%esp) +c0103192: e8 2b f8 ff ff call c01029c2 +c0103197: 8b 15 04 cf 11 c0 mov 0xc011cf04,%edx +c010319d: c1 e2 0c shl $0xc,%edx +c01031a0: 39 d0 cmp %edx,%eax +c01031a2: 72 24 jb c01031c8 +c01031a4: c7 44 24 0c ea 68 10 movl $0xc01068ea,0xc(%esp) +c01031ab: c0 +c01031ac: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01031b3: c0 +c01031b4: c7 44 24 04 fb 00 00 movl $0xfb,0x4(%esp) +c01031bb: 00 +c01031bc: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01031c3: e8 6b da ff ff call c0100c33 <__panic> + // 保存当前的空闲页面链表和数量 + list_entry_t free_list_store = free_list; +c01031c8: a1 e0 ce 11 c0 mov 0xc011cee0,%eax +c01031cd: 8b 15 e4 ce 11 c0 mov 0xc011cee4,%edx +c01031d3: 89 45 d0 mov %eax,-0x30(%ebp) +c01031d6: 89 55 d4 mov %edx,-0x2c(%ebp) +c01031d9: c7 45 dc e0 ce 11 c0 movl $0xc011cee0,-0x24(%ebp) + elm->prev = elm->next = elm; +c01031e0: 8b 45 dc mov -0x24(%ebp),%eax +c01031e3: 8b 55 dc mov -0x24(%ebp),%edx +c01031e6: 89 50 04 mov %edx,0x4(%eax) +c01031e9: 8b 45 dc mov -0x24(%ebp),%eax +c01031ec: 8b 50 04 mov 0x4(%eax),%edx +c01031ef: 8b 45 dc mov -0x24(%ebp),%eax +c01031f2: 89 10 mov %edx,(%eax) +} +c01031f4: 90 nop +c01031f5: c7 45 e0 e0 ce 11 c0 movl $0xc011cee0,-0x20(%ebp) + return list->next == list; +c01031fc: 8b 45 e0 mov -0x20(%ebp),%eax +c01031ff: 8b 40 04 mov 0x4(%eax),%eax +c0103202: 39 45 e0 cmp %eax,-0x20(%ebp) +c0103205: 0f 94 c0 sete %al +c0103208: 0f b6 c0 movzbl %al,%eax + list_init(&free_list);// 初始化空闲列表 + assert(list_empty(&free_list));// 确保空闲列表为空 +c010320b: 85 c0 test %eax,%eax +c010320d: 75 24 jne c0103233 +c010320f: c7 44 24 0c 07 69 10 movl $0xc0106907,0xc(%esp) +c0103216: c0 +c0103217: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010321e: c0 +c010321f: c7 44 24 04 ff 00 00 movl $0xff,0x4(%esp) +c0103226: 00 +c0103227: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010322e: e8 00 da ff ff call c0100c33 <__panic> + + unsigned int nr_free_store = nr_free;// 保存当前空闲页数量 +c0103233: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c0103238: 89 45 e8 mov %eax,-0x18(%ebp) + nr_free = 0;// 将空闲页数量设为 0 +c010323b: c7 05 e8 ce 11 c0 00 movl $0x0,0xc011cee8 +c0103242: 00 00 00 + // 请求分配页面,但当前没有空闲页面 + assert(alloc_page() == NULL); +c0103245: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010324c: e8 84 0c 00 00 call c0103ed5 +c0103251: 85 c0 test %eax,%eax +c0103253: 74 24 je c0103279 +c0103255: c7 44 24 0c 1e 69 10 movl $0xc010691e,0xc(%esp) +c010325c: c0 +c010325d: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103264: c0 +c0103265: c7 44 24 04 04 01 00 movl $0x104,0x4(%esp) +c010326c: 00 +c010326d: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103274: e8 ba d9 ff ff call c0100c33 <__panic> + // 释放之前分配的页面 + free_page(p0); +c0103279: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103280: 00 +c0103281: 8b 45 ec mov -0x14(%ebp),%eax +c0103284: 89 04 24 mov %eax,(%esp) +c0103287: e8 83 0c 00 00 call c0103f0f + free_page(p1); +c010328c: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103293: 00 +c0103294: 8b 45 f0 mov -0x10(%ebp),%eax +c0103297: 89 04 24 mov %eax,(%esp) +c010329a: e8 70 0c 00 00 call c0103f0f + free_page(p2); +c010329f: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01032a6: 00 +c01032a7: 8b 45 f4 mov -0xc(%ebp),%eax +c01032aa: 89 04 24 mov %eax,(%esp) +c01032ad: e8 5d 0c 00 00 call c0103f0f + assert(nr_free == 3);// 确保释放后空闲页数量为 3 +c01032b2: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c01032b7: 83 f8 03 cmp $0x3,%eax +c01032ba: 74 24 je c01032e0 +c01032bc: c7 44 24 0c 33 69 10 movl $0xc0106933,0xc(%esp) +c01032c3: c0 +c01032c4: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01032cb: c0 +c01032cc: c7 44 24 04 09 01 00 movl $0x109,0x4(%esp) +c01032d3: 00 +c01032d4: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01032db: e8 53 d9 ff ff call c0100c33 <__panic> + // 再次分配三个页面 + assert((p0 = alloc_page()) != NULL); +c01032e0: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01032e7: e8 e9 0b 00 00 call c0103ed5 +c01032ec: 89 45 ec mov %eax,-0x14(%ebp) +c01032ef: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) +c01032f3: 75 24 jne c0103319 +c01032f5: c7 44 24 0c f9 67 10 movl $0xc01067f9,0xc(%esp) +c01032fc: c0 +c01032fd: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103304: c0 +c0103305: c7 44 24 04 0b 01 00 movl $0x10b,0x4(%esp) +c010330c: 00 +c010330d: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103314: e8 1a d9 ff ff call c0100c33 <__panic> + assert((p1 = alloc_page()) != NULL); +c0103319: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103320: e8 b0 0b 00 00 call c0103ed5 +c0103325: 89 45 f0 mov %eax,-0x10(%ebp) +c0103328: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c010332c: 75 24 jne c0103352 +c010332e: c7 44 24 0c 15 68 10 movl $0xc0106815,0xc(%esp) +c0103335: c0 +c0103336: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010333d: c0 +c010333e: c7 44 24 04 0c 01 00 movl $0x10c,0x4(%esp) +c0103345: 00 +c0103346: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010334d: e8 e1 d8 ff ff call c0100c33 <__panic> + assert((p2 = alloc_page()) != NULL); +c0103352: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103359: e8 77 0b 00 00 call c0103ed5 +c010335e: 89 45 f4 mov %eax,-0xc(%ebp) +c0103361: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0103365: 75 24 jne c010338b +c0103367: c7 44 24 0c 31 68 10 movl $0xc0106831,0xc(%esp) +c010336e: c0 +c010336f: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103376: c0 +c0103377: c7 44 24 04 0d 01 00 movl $0x10d,0x4(%esp) +c010337e: 00 +c010337f: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103386: e8 a8 d8 ff ff call c0100c33 <__panic> +// 测试空闲页面是否不足 + assert(alloc_page() == NULL); +c010338b: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103392: e8 3e 0b 00 00 call c0103ed5 +c0103397: 85 c0 test %eax,%eax +c0103399: 74 24 je c01033bf +c010339b: c7 44 24 0c 1e 69 10 movl $0xc010691e,0xc(%esp) +c01033a2: c0 +c01033a3: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01033aa: c0 +c01033ab: c7 44 24 04 0f 01 00 movl $0x10f,0x4(%esp) +c01033b2: 00 +c01033b3: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01033ba: e8 74 d8 ff ff call c0100c33 <__panic> +// 释放 p0,并检查空闲列表 + free_page(p0); +c01033bf: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01033c6: 00 +c01033c7: 8b 45 ec mov -0x14(%ebp),%eax +c01033ca: 89 04 24 mov %eax,(%esp) +c01033cd: e8 3d 0b 00 00 call c0103f0f +c01033d2: c7 45 d8 e0 ce 11 c0 movl $0xc011cee0,-0x28(%ebp) +c01033d9: 8b 45 d8 mov -0x28(%ebp),%eax +c01033dc: 8b 40 04 mov 0x4(%eax),%eax +c01033df: 39 45 d8 cmp %eax,-0x28(%ebp) +c01033e2: 0f 94 c0 sete %al +c01033e5: 0f b6 c0 movzbl %al,%eax + assert(!list_empty(&free_list));// 确保空闲列表不为空 +c01033e8: 85 c0 test %eax,%eax +c01033ea: 74 24 je c0103410 +c01033ec: c7 44 24 0c 40 69 10 movl $0xc0106940,0xc(%esp) +c01033f3: c0 +c01033f4: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01033fb: c0 +c01033fc: c7 44 24 04 12 01 00 movl $0x112,0x4(%esp) +c0103403: 00 +c0103404: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010340b: e8 23 d8 ff ff call c0100c33 <__panic> + + struct Page *p; + // 重新分配 p0,确保取回的是相同的页面 + assert((p = alloc_page()) == p0); +c0103410: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103417: e8 b9 0a 00 00 call c0103ed5 +c010341c: 89 45 e4 mov %eax,-0x1c(%ebp) +c010341f: 8b 45 e4 mov -0x1c(%ebp),%eax +c0103422: 3b 45 ec cmp -0x14(%ebp),%eax +c0103425: 74 24 je c010344b +c0103427: c7 44 24 0c 58 69 10 movl $0xc0106958,0xc(%esp) +c010342e: c0 +c010342f: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103436: c0 +c0103437: c7 44 24 04 16 01 00 movl $0x116,0x4(%esp) +c010343e: 00 +c010343f: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103446: e8 e8 d7 ff ff call c0100c33 <__panic> + assert(alloc_page() == NULL); // 确保没有更多的页面可分配 +c010344b: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103452: e8 7e 0a 00 00 call c0103ed5 +c0103457: 85 c0 test %eax,%eax +c0103459: 74 24 je c010347f +c010345b: c7 44 24 0c 1e 69 10 movl $0xc010691e,0xc(%esp) +c0103462: c0 +c0103463: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010346a: c0 +c010346b: c7 44 24 04 17 01 00 movl $0x117,0x4(%esp) +c0103472: 00 +c0103473: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010347a: e8 b4 d7 ff ff call c0100c33 <__panic> + + assert(nr_free == 0);// 确保当前空闲页面数量为 0 +c010347f: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c0103484: 85 c0 test %eax,%eax +c0103486: 74 24 je c01034ac +c0103488: c7 44 24 0c 71 69 10 movl $0xc0106971,0xc(%esp) +c010348f: c0 +c0103490: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103497: c0 +c0103498: c7 44 24 04 19 01 00 movl $0x119,0x4(%esp) +c010349f: 00 +c01034a0: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01034a7: e8 87 d7 ff ff call c0100c33 <__panic> + // 恢复之前的空闲页面链表和数量 + free_list = free_list_store; +c01034ac: 8b 45 d0 mov -0x30(%ebp),%eax +c01034af: 8b 55 d4 mov -0x2c(%ebp),%edx +c01034b2: a3 e0 ce 11 c0 mov %eax,0xc011cee0 +c01034b7: 89 15 e4 ce 11 c0 mov %edx,0xc011cee4 + nr_free = nr_free_store; +c01034bd: 8b 45 e8 mov -0x18(%ebp),%eax +c01034c0: a3 e8 ce 11 c0 mov %eax,0xc011cee8 + // 释放最后的页面 + free_page(p); +c01034c5: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01034cc: 00 +c01034cd: 8b 45 e4 mov -0x1c(%ebp),%eax +c01034d0: 89 04 24 mov %eax,(%esp) +c01034d3: e8 37 0a 00 00 call c0103f0f + free_page(p1); +c01034d8: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01034df: 00 +c01034e0: 8b 45 f0 mov -0x10(%ebp),%eax +c01034e3: 89 04 24 mov %eax,(%esp) +c01034e6: e8 24 0a 00 00 call c0103f0f + free_page(p2); +c01034eb: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01034f2: 00 +c01034f3: 8b 45 f4 mov -0xc(%ebp),%eax +c01034f6: 89 04 24 mov %eax,(%esp) +c01034f9: e8 11 0a 00 00 call c0103f0f +} +c01034fe: 90 nop +c01034ff: 89 ec mov %ebp,%esp +c0103501: 5d pop %ebp +c0103502: c3 ret + +c0103503 : + +// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) +// NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions! +static void +default_check(void) { +c0103503: 55 push %ebp +c0103504: 89 e5 mov %esp,%ebp +c0103506: 81 ec 98 00 00 00 sub $0x98,%esp + int count = 0, total = 0; +c010350c: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0103513: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + list_entry_t *le = &free_list; +c010351a: c7 45 ec e0 ce 11 c0 movl $0xc011cee0,-0x14(%ebp) + // 遍历空闲列表,计算空闲页面的数量和总属性值 + while ((le = list_next(le)) != &free_list) { +c0103521: eb 6a jmp c010358d + struct Page *p = le2page(le, page_link); +c0103523: 8b 45 ec mov -0x14(%ebp),%eax +c0103526: 83 e8 0c sub $0xc,%eax +c0103529: 89 45 d4 mov %eax,-0x2c(%ebp) + assert(PageProperty(p));// 确保每个页面的属性是有效的 +c010352c: 8b 45 d4 mov -0x2c(%ebp),%eax +c010352f: 83 c0 04 add $0x4,%eax +c0103532: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) +c0103539: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c010353c: 8b 45 cc mov -0x34(%ebp),%eax +c010353f: 8b 55 d0 mov -0x30(%ebp),%edx +c0103542: 0f a3 10 bt %edx,(%eax) +c0103545: 19 c0 sbb %eax,%eax +c0103547: 89 45 c8 mov %eax,-0x38(%ebp) + return oldbit != 0; +c010354a: 83 7d c8 00 cmpl $0x0,-0x38(%ebp) +c010354e: 0f 95 c0 setne %al +c0103551: 0f b6 c0 movzbl %al,%eax +c0103554: 85 c0 test %eax,%eax +c0103556: 75 24 jne c010357c +c0103558: c7 44 24 0c 7e 69 10 movl $0xc010697e,0xc(%esp) +c010355f: c0 +c0103560: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103567: c0 +c0103568: c7 44 24 04 2c 01 00 movl $0x12c,0x4(%esp) +c010356f: 00 +c0103570: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103577: e8 b7 d6 ff ff call c0100c33 <__panic> + count ++, total += p->property;// 累加页面属性 +c010357c: ff 45 f4 incl -0xc(%ebp) +c010357f: 8b 45 d4 mov -0x2c(%ebp),%eax +c0103582: 8b 50 08 mov 0x8(%eax),%edx +c0103585: 8b 45 f0 mov -0x10(%ebp),%eax +c0103588: 01 d0 add %edx,%eax +c010358a: 89 45 f0 mov %eax,-0x10(%ebp) +c010358d: 8b 45 ec mov -0x14(%ebp),%eax +c0103590: 89 45 c4 mov %eax,-0x3c(%ebp) + return listelm->next; +c0103593: 8b 45 c4 mov -0x3c(%ebp),%eax +c0103596: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c0103599: 89 45 ec mov %eax,-0x14(%ebp) +c010359c: 81 7d ec e0 ce 11 c0 cmpl $0xc011cee0,-0x14(%ebp) +c01035a3: 0f 85 7a ff ff ff jne c0103523 + } + // 确保总属性值与空闲页面数量匹配 + assert(total == nr_free_pages()); +c01035a9: e8 96 09 00 00 call c0103f44 +c01035ae: 8b 55 f0 mov -0x10(%ebp),%edx +c01035b1: 39 d0 cmp %edx,%eax +c01035b3: 74 24 je c01035d9 +c01035b5: c7 44 24 0c 8e 69 10 movl $0xc010698e,0xc(%esp) +c01035bc: c0 +c01035bd: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01035c4: c0 +c01035c5: c7 44 24 04 30 01 00 movl $0x130,0x4(%esp) +c01035cc: 00 +c01035cd: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01035d4: e8 5a d6 ff ff call c0100c33 <__panic> + // 调用 basic_check 以验证基本的内存管理功能 + basic_check(); +c01035d9: e8 e5 f9 ff ff call c0102fc3 + // 分配 5 个页面 + struct Page *p0 = alloc_pages(5), *p1, *p2; +c01035de: c7 04 24 05 00 00 00 movl $0x5,(%esp) +c01035e5: e8 eb 08 00 00 call c0103ed5 +c01035ea: 89 45 e8 mov %eax,-0x18(%ebp) + assert(p0 != NULL);// 确保成功分配 +c01035ed: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c01035f1: 75 24 jne c0103617 +c01035f3: c7 44 24 0c a7 69 10 movl $0xc01069a7,0xc(%esp) +c01035fa: c0 +c01035fb: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103602: c0 +c0103603: c7 44 24 04 35 01 00 movl $0x135,0x4(%esp) +c010360a: 00 +c010360b: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103612: e8 1c d6 ff ff call c0100c33 <__panic> + assert(!PageProperty(p0));// 确保分配的页面不带属性 +c0103617: 8b 45 e8 mov -0x18(%ebp),%eax +c010361a: 83 c0 04 add $0x4,%eax +c010361d: c7 45 c0 01 00 00 00 movl $0x1,-0x40(%ebp) +c0103624: 89 45 bc mov %eax,-0x44(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0103627: 8b 45 bc mov -0x44(%ebp),%eax +c010362a: 8b 55 c0 mov -0x40(%ebp),%edx +c010362d: 0f a3 10 bt %edx,(%eax) +c0103630: 19 c0 sbb %eax,%eax +c0103632: 89 45 b8 mov %eax,-0x48(%ebp) + return oldbit != 0; +c0103635: 83 7d b8 00 cmpl $0x0,-0x48(%ebp) +c0103639: 0f 95 c0 setne %al +c010363c: 0f b6 c0 movzbl %al,%eax +c010363f: 85 c0 test %eax,%eax +c0103641: 74 24 je c0103667 +c0103643: c7 44 24 0c b2 69 10 movl $0xc01069b2,0xc(%esp) +c010364a: c0 +c010364b: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103652: c0 +c0103653: c7 44 24 04 36 01 00 movl $0x136,0x4(%esp) +c010365a: 00 +c010365b: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103662: e8 cc d5 ff ff call c0100c33 <__panic> + // 初始化并检查空闲列表 + list_entry_t free_list_store = free_list; +c0103667: a1 e0 ce 11 c0 mov 0xc011cee0,%eax +c010366c: 8b 15 e4 ce 11 c0 mov 0xc011cee4,%edx +c0103672: 89 45 80 mov %eax,-0x80(%ebp) +c0103675: 89 55 84 mov %edx,-0x7c(%ebp) +c0103678: c7 45 b0 e0 ce 11 c0 movl $0xc011cee0,-0x50(%ebp) + elm->prev = elm->next = elm; +c010367f: 8b 45 b0 mov -0x50(%ebp),%eax +c0103682: 8b 55 b0 mov -0x50(%ebp),%edx +c0103685: 89 50 04 mov %edx,0x4(%eax) +c0103688: 8b 45 b0 mov -0x50(%ebp),%eax +c010368b: 8b 50 04 mov 0x4(%eax),%edx +c010368e: 8b 45 b0 mov -0x50(%ebp),%eax +c0103691: 89 10 mov %edx,(%eax) +} +c0103693: 90 nop +c0103694: c7 45 b4 e0 ce 11 c0 movl $0xc011cee0,-0x4c(%ebp) + return list->next == list; +c010369b: 8b 45 b4 mov -0x4c(%ebp),%eax +c010369e: 8b 40 04 mov 0x4(%eax),%eax +c01036a1: 39 45 b4 cmp %eax,-0x4c(%ebp) +c01036a4: 0f 94 c0 sete %al +c01036a7: 0f b6 c0 movzbl %al,%eax + list_init(&free_list); + assert(list_empty(&free_list));// 确保空闲列表为空 +c01036aa: 85 c0 test %eax,%eax +c01036ac: 75 24 jne c01036d2 +c01036ae: c7 44 24 0c 07 69 10 movl $0xc0106907,0xc(%esp) +c01036b5: c0 +c01036b6: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01036bd: c0 +c01036be: c7 44 24 04 3a 01 00 movl $0x13a,0x4(%esp) +c01036c5: 00 +c01036c6: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01036cd: e8 61 d5 ff ff call c0100c33 <__panic> + assert(alloc_page() == NULL);// 确保没有页面可分配 +c01036d2: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01036d9: e8 f7 07 00 00 call c0103ed5 +c01036de: 85 c0 test %eax,%eax +c01036e0: 74 24 je c0103706 +c01036e2: c7 44 24 0c 1e 69 10 movl $0xc010691e,0xc(%esp) +c01036e9: c0 +c01036ea: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01036f1: c0 +c01036f2: c7 44 24 04 3b 01 00 movl $0x13b,0x4(%esp) +c01036f9: 00 +c01036fa: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103701: e8 2d d5 ff ff call c0100c33 <__panic> + + unsigned int nr_free_store = nr_free;// 保存当前空闲页数 +c0103706: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c010370b: 89 45 e4 mov %eax,-0x1c(%ebp) + nr_free = 0;// 将空闲页数设为 0 +c010370e: c7 05 e8 ce 11 c0 00 movl $0x0,0xc011cee8 +c0103715: 00 00 00 +// 释放 3 个页面并确保分配页面时没有足够的空闲页 + free_pages(p0 + 2, 3); +c0103718: 8b 45 e8 mov -0x18(%ebp),%eax +c010371b: 83 c0 28 add $0x28,%eax +c010371e: c7 44 24 04 03 00 00 movl $0x3,0x4(%esp) +c0103725: 00 +c0103726: 89 04 24 mov %eax,(%esp) +c0103729: e8 e1 07 00 00 call c0103f0f + assert(alloc_pages(4) == NULL);// 确保无法分配 4 个页面 +c010372e: c7 04 24 04 00 00 00 movl $0x4,(%esp) +c0103735: e8 9b 07 00 00 call c0103ed5 +c010373a: 85 c0 test %eax,%eax +c010373c: 74 24 je c0103762 +c010373e: c7 44 24 0c c4 69 10 movl $0xc01069c4,0xc(%esp) +c0103745: c0 +c0103746: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010374d: c0 +c010374e: c7 44 24 04 41 01 00 movl $0x141,0x4(%esp) +c0103755: 00 +c0103756: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010375d: e8 d1 d4 ff ff call c0100c33 <__panic> + assert(PageProperty(p0 + 2) && p0[2].property == 3);// 检查页面属性 +c0103762: 8b 45 e8 mov -0x18(%ebp),%eax +c0103765: 83 c0 28 add $0x28,%eax +c0103768: 83 c0 04 add $0x4,%eax +c010376b: c7 45 ac 01 00 00 00 movl $0x1,-0x54(%ebp) +c0103772: 89 45 a8 mov %eax,-0x58(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c0103775: 8b 45 a8 mov -0x58(%ebp),%eax +c0103778: 8b 55 ac mov -0x54(%ebp),%edx +c010377b: 0f a3 10 bt %edx,(%eax) +c010377e: 19 c0 sbb %eax,%eax +c0103780: 89 45 a4 mov %eax,-0x5c(%ebp) + return oldbit != 0; +c0103783: 83 7d a4 00 cmpl $0x0,-0x5c(%ebp) +c0103787: 0f 95 c0 setne %al +c010378a: 0f b6 c0 movzbl %al,%eax +c010378d: 85 c0 test %eax,%eax +c010378f: 74 0e je c010379f +c0103791: 8b 45 e8 mov -0x18(%ebp),%eax +c0103794: 83 c0 28 add $0x28,%eax +c0103797: 8b 40 08 mov 0x8(%eax),%eax +c010379a: 83 f8 03 cmp $0x3,%eax +c010379d: 74 24 je c01037c3 +c010379f: c7 44 24 0c dc 69 10 movl $0xc01069dc,0xc(%esp) +c01037a6: c0 +c01037a7: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01037ae: c0 +c01037af: c7 44 24 04 42 01 00 movl $0x142,0x4(%esp) +c01037b6: 00 +c01037b7: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01037be: e8 70 d4 ff ff call c0100c33 <__panic> + assert((p1 = alloc_pages(3)) != NULL);// 再次分配 3 个页面 +c01037c3: c7 04 24 03 00 00 00 movl $0x3,(%esp) +c01037ca: e8 06 07 00 00 call c0103ed5 +c01037cf: 89 45 e0 mov %eax,-0x20(%ebp) +c01037d2: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) +c01037d6: 75 24 jne c01037fc +c01037d8: c7 44 24 0c 08 6a 10 movl $0xc0106a08,0xc(%esp) +c01037df: c0 +c01037e0: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01037e7: c0 +c01037e8: c7 44 24 04 43 01 00 movl $0x143,0x4(%esp) +c01037ef: 00 +c01037f0: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01037f7: e8 37 d4 ff ff call c0100c33 <__panic> + assert(alloc_page() == NULL);// 确保没有页面可分配 +c01037fc: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103803: e8 cd 06 00 00 call c0103ed5 +c0103808: 85 c0 test %eax,%eax +c010380a: 74 24 je c0103830 +c010380c: c7 44 24 0c 1e 69 10 movl $0xc010691e,0xc(%esp) +c0103813: c0 +c0103814: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010381b: c0 +c010381c: c7 44 24 04 44 01 00 movl $0x144,0x4(%esp) +c0103823: 00 +c0103824: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010382b: e8 03 d4 ff ff call c0100c33 <__panic> + assert(p0 + 2 == p1);// 确保分配的页面是释放的页面 +c0103830: 8b 45 e8 mov -0x18(%ebp),%eax +c0103833: 83 c0 28 add $0x28,%eax +c0103836: 39 45 e0 cmp %eax,-0x20(%ebp) +c0103839: 74 24 je c010385f +c010383b: c7 44 24 0c 26 6a 10 movl $0xc0106a26,0xc(%esp) +c0103842: c0 +c0103843: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010384a: c0 +c010384b: c7 44 24 04 45 01 00 movl $0x145,0x4(%esp) +c0103852: 00 +c0103853: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010385a: e8 d4 d3 ff ff call c0100c33 <__panic> + + p2 = p0 + 1; // 设置 p2 为 p0 的下一个页面 +c010385f: 8b 45 e8 mov -0x18(%ebp),%eax +c0103862: 83 c0 14 add $0x14,%eax +c0103865: 89 45 dc mov %eax,-0x24(%ebp) + free_page(p0);// 释放 p0 页面 +c0103868: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c010386f: 00 +c0103870: 8b 45 e8 mov -0x18(%ebp),%eax +c0103873: 89 04 24 mov %eax,(%esp) +c0103876: e8 94 06 00 00 call c0103f0f + free_pages(p1, 3);// 释放 p1 指向的页面 +c010387b: c7 44 24 04 03 00 00 movl $0x3,0x4(%esp) +c0103882: 00 +c0103883: 8b 45 e0 mov -0x20(%ebp),%eax +c0103886: 89 04 24 mov %eax,(%esp) +c0103889: e8 81 06 00 00 call c0103f0f + assert(PageProperty(p0) && p0->property == 1); // 检查 p0 属性 +c010388e: 8b 45 e8 mov -0x18(%ebp),%eax +c0103891: 83 c0 04 add $0x4,%eax +c0103894: c7 45 a0 01 00 00 00 movl $0x1,-0x60(%ebp) +c010389b: 89 45 9c mov %eax,-0x64(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c010389e: 8b 45 9c mov -0x64(%ebp),%eax +c01038a1: 8b 55 a0 mov -0x60(%ebp),%edx +c01038a4: 0f a3 10 bt %edx,(%eax) +c01038a7: 19 c0 sbb %eax,%eax +c01038a9: 89 45 98 mov %eax,-0x68(%ebp) + return oldbit != 0; +c01038ac: 83 7d 98 00 cmpl $0x0,-0x68(%ebp) +c01038b0: 0f 95 c0 setne %al +c01038b3: 0f b6 c0 movzbl %al,%eax +c01038b6: 85 c0 test %eax,%eax +c01038b8: 74 0b je c01038c5 +c01038ba: 8b 45 e8 mov -0x18(%ebp),%eax +c01038bd: 8b 40 08 mov 0x8(%eax),%eax +c01038c0: 83 f8 01 cmp $0x1,%eax +c01038c3: 74 24 je c01038e9 +c01038c5: c7 44 24 0c 34 6a 10 movl $0xc0106a34,0xc(%esp) +c01038cc: c0 +c01038cd: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01038d4: c0 +c01038d5: c7 44 24 04 4a 01 00 movl $0x14a,0x4(%esp) +c01038dc: 00 +c01038dd: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01038e4: e8 4a d3 ff ff call c0100c33 <__panic> + assert(PageProperty(p1) && p1->property == 3); // 检查 p1 属性 +c01038e9: 8b 45 e0 mov -0x20(%ebp),%eax +c01038ec: 83 c0 04 add $0x4,%eax +c01038ef: c7 45 94 01 00 00 00 movl $0x1,-0x6c(%ebp) +c01038f6: 89 45 90 mov %eax,-0x70(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); +c01038f9: 8b 45 90 mov -0x70(%ebp),%eax +c01038fc: 8b 55 94 mov -0x6c(%ebp),%edx +c01038ff: 0f a3 10 bt %edx,(%eax) +c0103902: 19 c0 sbb %eax,%eax +c0103904: 89 45 8c mov %eax,-0x74(%ebp) + return oldbit != 0; +c0103907: 83 7d 8c 00 cmpl $0x0,-0x74(%ebp) +c010390b: 0f 95 c0 setne %al +c010390e: 0f b6 c0 movzbl %al,%eax +c0103911: 85 c0 test %eax,%eax +c0103913: 74 0b je c0103920 +c0103915: 8b 45 e0 mov -0x20(%ebp),%eax +c0103918: 8b 40 08 mov 0x8(%eax),%eax +c010391b: 83 f8 03 cmp $0x3,%eax +c010391e: 74 24 je c0103944 +c0103920: c7 44 24 0c 5c 6a 10 movl $0xc0106a5c,0xc(%esp) +c0103927: c0 +c0103928: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010392f: c0 +c0103930: c7 44 24 04 4b 01 00 movl $0x14b,0x4(%esp) +c0103937: 00 +c0103938: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010393f: e8 ef d2 ff ff call c0100c33 <__panic> +// 确保重分配的页面是之前释放的页面 + assert((p0 = alloc_page()) == p2 - 1); +c0103944: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010394b: e8 85 05 00 00 call c0103ed5 +c0103950: 89 45 e8 mov %eax,-0x18(%ebp) +c0103953: 8b 45 dc mov -0x24(%ebp),%eax +c0103956: 83 e8 14 sub $0x14,%eax +c0103959: 39 45 e8 cmp %eax,-0x18(%ebp) +c010395c: 74 24 je c0103982 +c010395e: c7 44 24 0c 82 6a 10 movl $0xc0106a82,0xc(%esp) +c0103965: c0 +c0103966: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c010396d: c0 +c010396e: c7 44 24 04 4d 01 00 movl $0x14d,0x4(%esp) +c0103975: 00 +c0103976: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c010397d: e8 b1 d2 ff ff call c0100c33 <__panic> + free_page(p0);// 释放分配的页面 +c0103982: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0103989: 00 +c010398a: 8b 45 e8 mov -0x18(%ebp),%eax +c010398d: 89 04 24 mov %eax,(%esp) +c0103990: e8 7a 05 00 00 call c0103f0f + assert((p0 = alloc_pages(2)) == p2 + 1);// 分配 2 个页面并检查 +c0103995: c7 04 24 02 00 00 00 movl $0x2,(%esp) +c010399c: e8 34 05 00 00 call c0103ed5 +c01039a1: 89 45 e8 mov %eax,-0x18(%ebp) +c01039a4: 8b 45 dc mov -0x24(%ebp),%eax +c01039a7: 83 c0 14 add $0x14,%eax +c01039aa: 39 45 e8 cmp %eax,-0x18(%ebp) +c01039ad: 74 24 je c01039d3 +c01039af: c7 44 24 0c a0 6a 10 movl $0xc0106aa0,0xc(%esp) +c01039b6: c0 +c01039b7: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c01039be: c0 +c01039bf: c7 44 24 04 4f 01 00 movl $0x14f,0x4(%esp) +c01039c6: 00 +c01039c7: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c01039ce: e8 60 d2 ff ff call c0100c33 <__panic> +// 释放页面并检查空闲状态 + free_pages(p0, 2); +c01039d3: c7 44 24 04 02 00 00 movl $0x2,0x4(%esp) +c01039da: 00 +c01039db: 8b 45 e8 mov -0x18(%ebp),%eax +c01039de: 89 04 24 mov %eax,(%esp) +c01039e1: e8 29 05 00 00 call c0103f0f + free_page(p2); +c01039e6: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01039ed: 00 +c01039ee: 8b 45 dc mov -0x24(%ebp),%eax +c01039f1: 89 04 24 mov %eax,(%esp) +c01039f4: e8 16 05 00 00 call c0103f0f +// 再次分配 5 个页面 + assert((p0 = alloc_pages(5)) != NULL); +c01039f9: c7 04 24 05 00 00 00 movl $0x5,(%esp) +c0103a00: e8 d0 04 00 00 call c0103ed5 +c0103a05: 89 45 e8 mov %eax,-0x18(%ebp) +c0103a08: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c0103a0c: 75 24 jne c0103a32 +c0103a0e: c7 44 24 0c c0 6a 10 movl $0xc0106ac0,0xc(%esp) +c0103a15: c0 +c0103a16: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103a1d: c0 +c0103a1e: c7 44 24 04 54 01 00 movl $0x154,0x4(%esp) +c0103a25: 00 +c0103a26: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103a2d: e8 01 d2 ff ff call c0100c33 <__panic> + assert(alloc_page() == NULL);// 确保没有额外页面可分配 +c0103a32: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0103a39: e8 97 04 00 00 call c0103ed5 +c0103a3e: 85 c0 test %eax,%eax +c0103a40: 74 24 je c0103a66 +c0103a42: c7 44 24 0c 1e 69 10 movl $0xc010691e,0xc(%esp) +c0103a49: c0 +c0103a4a: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103a51: c0 +c0103a52: c7 44 24 04 55 01 00 movl $0x155,0x4(%esp) +c0103a59: 00 +c0103a5a: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103a61: e8 cd d1 ff ff call c0100c33 <__panic> + + assert(nr_free == 0);// 确保空闲页数为 0 +c0103a66: a1 e8 ce 11 c0 mov 0xc011cee8,%eax +c0103a6b: 85 c0 test %eax,%eax +c0103a6d: 74 24 je c0103a93 +c0103a6f: c7 44 24 0c 71 69 10 movl $0xc0106971,0xc(%esp) +c0103a76: c0 +c0103a77: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103a7e: c0 +c0103a7f: c7 44 24 04 57 01 00 movl $0x157,0x4(%esp) +c0103a86: 00 +c0103a87: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103a8e: e8 a0 d1 ff ff call c0100c33 <__panic> + nr_free = nr_free_store;// 恢复空闲页数 +c0103a93: 8b 45 e4 mov -0x1c(%ebp),%eax +c0103a96: a3 e8 ce 11 c0 mov %eax,0xc011cee8 +// 恢复空闲列表状态 + free_list = free_list_store; +c0103a9b: 8b 45 80 mov -0x80(%ebp),%eax +c0103a9e: 8b 55 84 mov -0x7c(%ebp),%edx +c0103aa1: a3 e0 ce 11 c0 mov %eax,0xc011cee0 +c0103aa6: 89 15 e4 ce 11 c0 mov %edx,0xc011cee4 + free_pages(p0, 5);// 释放所有分配的页面 +c0103aac: c7 44 24 04 05 00 00 movl $0x5,0x4(%esp) +c0103ab3: 00 +c0103ab4: 8b 45 e8 mov -0x18(%ebp),%eax +c0103ab7: 89 04 24 mov %eax,(%esp) +c0103aba: e8 50 04 00 00 call c0103f0f + // 验证空闲列表的一致性 + le = &free_list; +c0103abf: c7 45 ec e0 ce 11 c0 movl $0xc011cee0,-0x14(%ebp) + while ((le = list_next(le)) != &free_list) { +c0103ac6: eb 5a jmp c0103b22 + assert(le->next->prev == le && le->prev->next == le);// 验证双向链表 +c0103ac8: 8b 45 ec mov -0x14(%ebp),%eax +c0103acb: 8b 40 04 mov 0x4(%eax),%eax +c0103ace: 8b 00 mov (%eax),%eax +c0103ad0: 39 45 ec cmp %eax,-0x14(%ebp) +c0103ad3: 75 0d jne c0103ae2 +c0103ad5: 8b 45 ec mov -0x14(%ebp),%eax +c0103ad8: 8b 00 mov (%eax),%eax +c0103ada: 8b 40 04 mov 0x4(%eax),%eax +c0103add: 39 45 ec cmp %eax,-0x14(%ebp) +c0103ae0: 74 24 je c0103b06 +c0103ae2: c7 44 24 0c e0 6a 10 movl $0xc0106ae0,0xc(%esp) +c0103ae9: c0 +c0103aea: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103af1: c0 +c0103af2: c7 44 24 04 5f 01 00 movl $0x15f,0x4(%esp) +c0103af9: 00 +c0103afa: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103b01: e8 2d d1 ff ff call c0100c33 <__panic> + struct Page *p = le2page(le, page_link);// 更新计数和总属性值 +c0103b06: 8b 45 ec mov -0x14(%ebp),%eax +c0103b09: 83 e8 0c sub $0xc,%eax +c0103b0c: 89 45 d8 mov %eax,-0x28(%ebp) + count --, total -= p->property; +c0103b0f: ff 4d f4 decl -0xc(%ebp) +c0103b12: 8b 55 f0 mov -0x10(%ebp),%edx +c0103b15: 8b 45 d8 mov -0x28(%ebp),%eax +c0103b18: 8b 48 08 mov 0x8(%eax),%ecx +c0103b1b: 89 d0 mov %edx,%eax +c0103b1d: 29 c8 sub %ecx,%eax +c0103b1f: 89 45 f0 mov %eax,-0x10(%ebp) +c0103b22: 8b 45 ec mov -0x14(%ebp),%eax +c0103b25: 89 45 88 mov %eax,-0x78(%ebp) + return listelm->next; +c0103b28: 8b 45 88 mov -0x78(%ebp),%eax +c0103b2b: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { +c0103b2e: 89 45 ec mov %eax,-0x14(%ebp) +c0103b31: 81 7d ec e0 ce 11 c0 cmpl $0xc011cee0,-0x14(%ebp) +c0103b38: 75 8e jne c0103ac8 + } + assert(count == 0);// 确保所有页面都已处理 +c0103b3a: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0103b3e: 74 24 je c0103b64 +c0103b40: c7 44 24 0c 0d 6b 10 movl $0xc0106b0d,0xc(%esp) +c0103b47: c0 +c0103b48: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103b4f: c0 +c0103b50: c7 44 24 04 63 01 00 movl $0x163,0x4(%esp) +c0103b57: 00 +c0103b58: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103b5f: e8 cf d0 ff ff call c0100c33 <__panic> + assert(total == 0);// 确保总属性值为 0 +c0103b64: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0103b68: 74 24 je c0103b8e +c0103b6a: c7 44 24 0c 18 6b 10 movl $0xc0106b18,0xc(%esp) +c0103b71: c0 +c0103b72: c7 44 24 08 96 67 10 movl $0xc0106796,0x8(%esp) +c0103b79: c0 +c0103b7a: c7 44 24 04 64 01 00 movl $0x164,0x4(%esp) +c0103b81: 00 +c0103b82: c7 04 24 ab 67 10 c0 movl $0xc01067ab,(%esp) +c0103b89: e8 a5 d0 ff ff call c0100c33 <__panic> +} +c0103b8e: 90 nop +c0103b8f: 89 ec mov %ebp,%esp +c0103b91: 5d pop %ebp +c0103b92: c3 ret + +c0103b93 : +page2ppn(struct Page *page) { +c0103b93: 55 push %ebp +c0103b94: 89 e5 mov %esp,%ebp + return page - pages; +c0103b96: 8b 15 00 cf 11 c0 mov 0xc011cf00,%edx +c0103b9c: 8b 45 08 mov 0x8(%ebp),%eax +c0103b9f: 29 d0 sub %edx,%eax +c0103ba1: c1 f8 02 sar $0x2,%eax +c0103ba4: 69 c0 cd cc cc cc imul $0xcccccccd,%eax,%eax +} +c0103baa: 5d pop %ebp +c0103bab: c3 ret + +c0103bac : +page2pa(struct Page *page) { +c0103bac: 55 push %ebp +c0103bad: 89 e5 mov %esp,%ebp +c0103baf: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; +c0103bb2: 8b 45 08 mov 0x8(%ebp),%eax +c0103bb5: 89 04 24 mov %eax,(%esp) +c0103bb8: e8 d6 ff ff ff call c0103b93 +c0103bbd: c1 e0 0c shl $0xc,%eax +} +c0103bc0: 89 ec mov %ebp,%esp +c0103bc2: 5d pop %ebp +c0103bc3: c3 ret + +c0103bc4 : +pa2page(uintptr_t pa) { +c0103bc4: 55 push %ebp +c0103bc5: 89 e5 mov %esp,%ebp +c0103bc7: 83 ec 18 sub $0x18,%esp + if (PPN(pa) >= npage) { +c0103bca: 8b 45 08 mov 0x8(%ebp),%eax +c0103bcd: c1 e8 0c shr $0xc,%eax +c0103bd0: 89 c2 mov %eax,%edx +c0103bd2: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c0103bd7: 39 c2 cmp %eax,%edx +c0103bd9: 72 1c jb c0103bf7 + panic("pa2page called with invalid pa"); +c0103bdb: c7 44 24 08 54 6b 10 movl $0xc0106b54,0x8(%esp) +c0103be2: c0 +c0103be3: c7 44 24 04 5a 00 00 movl $0x5a,0x4(%esp) +c0103bea: 00 +c0103beb: c7 04 24 73 6b 10 c0 movl $0xc0106b73,(%esp) +c0103bf2: e8 3c d0 ff ff call c0100c33 <__panic> + return &pages[PPN(pa)]; +c0103bf7: 8b 0d 00 cf 11 c0 mov 0xc011cf00,%ecx +c0103bfd: 8b 45 08 mov 0x8(%ebp),%eax +c0103c00: c1 e8 0c shr $0xc,%eax +c0103c03: 89 c2 mov %eax,%edx +c0103c05: 89 d0 mov %edx,%eax +c0103c07: c1 e0 02 shl $0x2,%eax +c0103c0a: 01 d0 add %edx,%eax +c0103c0c: c1 e0 02 shl $0x2,%eax +c0103c0f: 01 c8 add %ecx,%eax +} +c0103c11: 89 ec mov %ebp,%esp +c0103c13: 5d pop %ebp +c0103c14: c3 ret + +c0103c15 : +page2kva(struct Page *page) { +c0103c15: 55 push %ebp +c0103c16: 89 e5 mov %esp,%ebp +c0103c18: 83 ec 28 sub $0x28,%esp + return KADDR(page2pa(page)); +c0103c1b: 8b 45 08 mov 0x8(%ebp),%eax +c0103c1e: 89 04 24 mov %eax,(%esp) +c0103c21: e8 86 ff ff ff call c0103bac +c0103c26: 89 45 f4 mov %eax,-0xc(%ebp) +c0103c29: 8b 45 f4 mov -0xc(%ebp),%eax +c0103c2c: c1 e8 0c shr $0xc,%eax +c0103c2f: 89 45 f0 mov %eax,-0x10(%ebp) +c0103c32: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c0103c37: 39 45 f0 cmp %eax,-0x10(%ebp) +c0103c3a: 72 23 jb c0103c5f +c0103c3c: 8b 45 f4 mov -0xc(%ebp),%eax +c0103c3f: 89 44 24 0c mov %eax,0xc(%esp) +c0103c43: c7 44 24 08 84 6b 10 movl $0xc0106b84,0x8(%esp) +c0103c4a: c0 +c0103c4b: c7 44 24 04 61 00 00 movl $0x61,0x4(%esp) +c0103c52: 00 +c0103c53: c7 04 24 73 6b 10 c0 movl $0xc0106b73,(%esp) +c0103c5a: e8 d4 cf ff ff call c0100c33 <__panic> +c0103c5f: 8b 45 f4 mov -0xc(%ebp),%eax +c0103c62: 2d 00 00 00 40 sub $0x40000000,%eax +} +c0103c67: 89 ec mov %ebp,%esp +c0103c69: 5d pop %ebp +c0103c6a: c3 ret + +c0103c6b : +pte2page(pte_t pte) { +c0103c6b: 55 push %ebp +c0103c6c: 89 e5 mov %esp,%ebp +c0103c6e: 83 ec 18 sub $0x18,%esp + if (!(pte & PTE_P)) { +c0103c71: 8b 45 08 mov 0x8(%ebp),%eax +c0103c74: 83 e0 01 and $0x1,%eax +c0103c77: 85 c0 test %eax,%eax +c0103c79: 75 1c jne c0103c97 + panic("pte2page called with invalid pte"); +c0103c7b: c7 44 24 08 a8 6b 10 movl $0xc0106ba8,0x8(%esp) +c0103c82: c0 +c0103c83: c7 44 24 04 6c 00 00 movl $0x6c,0x4(%esp) +c0103c8a: 00 +c0103c8b: c7 04 24 73 6b 10 c0 movl $0xc0106b73,(%esp) +c0103c92: e8 9c cf ff ff call c0100c33 <__panic> + return pa2page(PTE_ADDR(pte)); +c0103c97: 8b 45 08 mov 0x8(%ebp),%eax +c0103c9a: 25 00 f0 ff ff and $0xfffff000,%eax +c0103c9f: 89 04 24 mov %eax,(%esp) +c0103ca2: e8 1d ff ff ff call c0103bc4 +} +c0103ca7: 89 ec mov %ebp,%esp +c0103ca9: 5d pop %ebp +c0103caa: c3 ret + +c0103cab : +pde2page(pde_t pde) { +c0103cab: 55 push %ebp +c0103cac: 89 e5 mov %esp,%ebp +c0103cae: 83 ec 18 sub $0x18,%esp + return pa2page(PDE_ADDR(pde)); +c0103cb1: 8b 45 08 mov 0x8(%ebp),%eax +c0103cb4: 25 00 f0 ff ff and $0xfffff000,%eax +c0103cb9: 89 04 24 mov %eax,(%esp) +c0103cbc: e8 03 ff ff ff call c0103bc4 +} +c0103cc1: 89 ec mov %ebp,%esp +c0103cc3: 5d pop %ebp +c0103cc4: c3 ret + +c0103cc5 : +page_ref(struct Page *page) { +c0103cc5: 55 push %ebp +c0103cc6: 89 e5 mov %esp,%ebp + return page->ref; +c0103cc8: 8b 45 08 mov 0x8(%ebp),%eax +c0103ccb: 8b 00 mov (%eax),%eax +} +c0103ccd: 5d pop %ebp +c0103cce: c3 ret + +c0103ccf : +set_page_ref(struct Page *page, int val) { +c0103ccf: 55 push %ebp +c0103cd0: 89 e5 mov %esp,%ebp + page->ref = val; +c0103cd2: 8b 45 08 mov 0x8(%ebp),%eax +c0103cd5: 8b 55 0c mov 0xc(%ebp),%edx +c0103cd8: 89 10 mov %edx,(%eax) +} +c0103cda: 90 nop +c0103cdb: 5d pop %ebp +c0103cdc: c3 ret + +c0103cdd : + +static inline int +page_ref_inc(struct Page *page) { +c0103cdd: 55 push %ebp +c0103cde: 89 e5 mov %esp,%ebp + page->ref += 1; +c0103ce0: 8b 45 08 mov 0x8(%ebp),%eax +c0103ce3: 8b 00 mov (%eax),%eax +c0103ce5: 8d 50 01 lea 0x1(%eax),%edx +c0103ce8: 8b 45 08 mov 0x8(%ebp),%eax +c0103ceb: 89 10 mov %edx,(%eax) + return page->ref; +c0103ced: 8b 45 08 mov 0x8(%ebp),%eax +c0103cf0: 8b 00 mov (%eax),%eax +} +c0103cf2: 5d pop %ebp +c0103cf3: c3 ret + +c0103cf4 : + +static inline int +page_ref_dec(struct Page *page) { +c0103cf4: 55 push %ebp +c0103cf5: 89 e5 mov %esp,%ebp + page->ref -= 1; +c0103cf7: 8b 45 08 mov 0x8(%ebp),%eax +c0103cfa: 8b 00 mov (%eax),%eax +c0103cfc: 8d 50 ff lea -0x1(%eax),%edx +c0103cff: 8b 45 08 mov 0x8(%ebp),%eax +c0103d02: 89 10 mov %edx,(%eax) + return page->ref; +c0103d04: 8b 45 08 mov 0x8(%ebp),%eax +c0103d07: 8b 00 mov (%eax),%eax +} +c0103d09: 5d pop %ebp +c0103d0a: c3 ret + +c0103d0b <__intr_save>: +__intr_save(void) { +c0103d0b: 55 push %ebp +c0103d0c: 89 e5 mov %esp,%ebp +c0103d0e: 83 ec 18 sub $0x18,%esp + asm volatile ("pushfl; popl %0" : "=r" (eflags)); +c0103d11: 9c pushf +c0103d12: 58 pop %eax +c0103d13: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; +c0103d16: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { +c0103d19: 25 00 02 00 00 and $0x200,%eax +c0103d1e: 85 c0 test %eax,%eax +c0103d20: 74 0c je c0103d2e <__intr_save+0x23> + intr_disable(); +c0103d22: e8 65 d9 ff ff call c010168c + return 1; +c0103d27: b8 01 00 00 00 mov $0x1,%eax +c0103d2c: eb 05 jmp c0103d33 <__intr_save+0x28> + return 0; +c0103d2e: b8 00 00 00 00 mov $0x0,%eax +} +c0103d33: 89 ec mov %ebp,%esp +c0103d35: 5d pop %ebp +c0103d36: c3 ret + +c0103d37 <__intr_restore>: +__intr_restore(bool flag) { +c0103d37: 55 push %ebp +c0103d38: 89 e5 mov %esp,%ebp +c0103d3a: 83 ec 08 sub $0x8,%esp + if (flag) { +c0103d3d: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0103d41: 74 05 je c0103d48 <__intr_restore+0x11> + intr_enable(); +c0103d43: e8 3c d9 ff ff call c0101684 +} +c0103d48: 90 nop +c0103d49: 89 ec mov %ebp,%esp +c0103d4b: 5d pop %ebp +c0103d4c: c3 ret + +c0103d4d : + * data/code segement registers for kernel. + * lgdt - 加载全局描述符表寄存器并重置内核的数据/代码段寄存器。 + * */ +//定义了一个静态内联函数 lgdt,接收一个指向伪描述符(struct pseudodesc)的指针 pd +static inline void +lgdt(struct pseudodesc *pd) { +c0103d4d: 55 push %ebp +c0103d4e: 89 e5 mov %esp,%ebp + asm volatile ("lgdt (%0)" :: "r" (pd));//这行汇编代码使用 lgdt 指令加载 GDT。%0 被替换为指向 pd 的指针,告诉处理器 GDT 的地址。 +c0103d50: 8b 45 08 mov 0x8(%ebp),%eax +c0103d53: 0f 01 10 lgdtl (%eax) + asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS));//将 USER_DS(用户数据段)的值移动到 gs 段寄存器。 +c0103d56: b8 23 00 00 00 mov $0x23,%eax +c0103d5b: 8e e8 mov %eax,%gs + asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS));//将 USER_DS 的值移动到 fs 段寄存器。 +c0103d5d: b8 23 00 00 00 mov $0x23,%eax +c0103d62: 8e e0 mov %eax,%fs + asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS));//将 KERNEL_DS(内核数据段)的值移动到 es 段寄存器。 +c0103d64: b8 10 00 00 00 mov $0x10,%eax +c0103d69: 8e c0 mov %eax,%es + asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ds 段寄存器 +c0103d6b: b8 10 00 00 00 mov $0x10,%eax +c0103d70: 8e d8 mov %eax,%ds + asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ss 段寄存器 +c0103d72: b8 10 00 00 00 mov $0x10,%eax +c0103d77: 8e d0 mov %eax,%ss + // reload cs + //通过 ljmp 指令重新加载代码段寄存器 cs,并跳转到标签 1。 + asm volatile ("ljmp %0, $1f\n 1:\n" :: "i" (KERNEL_CS)); +c0103d79: ea 80 3d 10 c0 08 00 ljmp $0x8,$0xc0103d80 +} +c0103d80: 90 nop +c0103d81: 5d pop %ebp +c0103d82: c3 ret + +c0103d83 : + * load_esp0 - 修改默认任务状态段中的 ESP0,以便在从用户态陷入内核态时能够使用不同的内核栈。 + * */ +//uintptr_t esp0:这是新的堆栈指针,通常指向内核栈的顶部。 +//修改当前任务状态段(TSS)中的 ESP0 值。ESP0 是在从用户态切换到内核态时,CPU 使用的内核栈指针。 +void +load_esp0(uintptr_t esp0) { +c0103d83: 55 push %ebp +c0103d84: 89 e5 mov %esp,%ebp + ts.ts_esp0 = esp0; +c0103d86: 8b 45 08 mov 0x8(%ebp),%eax +c0103d89: a3 24 cf 11 c0 mov %eax,0xc011cf24 +} +c0103d8e: 90 nop +c0103d8f: 5d pop %ebp +c0103d90: c3 ret + +c0103d91 : + +/* gdt_init - initialize the default GDT and TSS */ +/* gdt_init - 初始化默认的 GDT 和 TSS */ +static void +gdt_init(void) { +c0103d91: 55 push %ebp +c0103d92: 89 e5 mov %esp,%ebp +c0103d94: 83 ec 14 sub $0x14,%esp + // 设置启动内核栈和默认的 SS0 + // set boot kernel stack and default SS0 + load_esp0((uintptr_t)bootstacktop); +c0103d97: b8 00 90 11 c0 mov $0xc0119000,%eax +c0103d9c: 89 04 24 mov %eax,(%esp) +c0103d9f: e8 df ff ff ff call c0103d83 + ts.ts_ss0 = KERNEL_DS; +c0103da4: 66 c7 05 28 cf 11 c0 movw $0x10,0xc011cf28 +c0103dab: 10 00 + // 初始化 GDT 中的 TSS 字段 + // initialize the TSS filed of the gdt + gdt[SEG_TSS] = SEGTSS(STS_T32A, (uintptr_t)&ts, sizeof(ts), DPL_KERNEL); +c0103dad: 66 c7 05 28 9a 11 c0 movw $0x68,0xc0119a28 +c0103db4: 68 00 +c0103db6: b8 20 cf 11 c0 mov $0xc011cf20,%eax +c0103dbb: 0f b7 c0 movzwl %ax,%eax +c0103dbe: 66 a3 2a 9a 11 c0 mov %ax,0xc0119a2a +c0103dc4: b8 20 cf 11 c0 mov $0xc011cf20,%eax +c0103dc9: c1 e8 10 shr $0x10,%eax +c0103dcc: a2 2c 9a 11 c0 mov %al,0xc0119a2c +c0103dd1: 0f b6 05 2d 9a 11 c0 movzbl 0xc0119a2d,%eax +c0103dd8: 24 f0 and $0xf0,%al +c0103dda: 0c 09 or $0x9,%al +c0103ddc: a2 2d 9a 11 c0 mov %al,0xc0119a2d +c0103de1: 0f b6 05 2d 9a 11 c0 movzbl 0xc0119a2d,%eax +c0103de8: 24 ef and $0xef,%al +c0103dea: a2 2d 9a 11 c0 mov %al,0xc0119a2d +c0103def: 0f b6 05 2d 9a 11 c0 movzbl 0xc0119a2d,%eax +c0103df6: 24 9f and $0x9f,%al +c0103df8: a2 2d 9a 11 c0 mov %al,0xc0119a2d +c0103dfd: 0f b6 05 2d 9a 11 c0 movzbl 0xc0119a2d,%eax +c0103e04: 0c 80 or $0x80,%al +c0103e06: a2 2d 9a 11 c0 mov %al,0xc0119a2d +c0103e0b: 0f b6 05 2e 9a 11 c0 movzbl 0xc0119a2e,%eax +c0103e12: 24 f0 and $0xf0,%al +c0103e14: a2 2e 9a 11 c0 mov %al,0xc0119a2e +c0103e19: 0f b6 05 2e 9a 11 c0 movzbl 0xc0119a2e,%eax +c0103e20: 24 ef and $0xef,%al +c0103e22: a2 2e 9a 11 c0 mov %al,0xc0119a2e +c0103e27: 0f b6 05 2e 9a 11 c0 movzbl 0xc0119a2e,%eax +c0103e2e: 24 df and $0xdf,%al +c0103e30: a2 2e 9a 11 c0 mov %al,0xc0119a2e +c0103e35: 0f b6 05 2e 9a 11 c0 movzbl 0xc0119a2e,%eax +c0103e3c: 0c 40 or $0x40,%al +c0103e3e: a2 2e 9a 11 c0 mov %al,0xc0119a2e +c0103e43: 0f b6 05 2e 9a 11 c0 movzbl 0xc0119a2e,%eax +c0103e4a: 24 7f and $0x7f,%al +c0103e4c: a2 2e 9a 11 c0 mov %al,0xc0119a2e +c0103e51: b8 20 cf 11 c0 mov $0xc011cf20,%eax +c0103e56: c1 e8 18 shr $0x18,%eax +c0103e59: a2 2f 9a 11 c0 mov %al,0xc0119a2f + // 使用lgdt加载全局描述符表,更新所有段寄存器 + // reload all segment registers + lgdt(&gdt_pd); +c0103e5e: c7 04 24 30 9a 11 c0 movl $0xc0119a30,(%esp) +c0103e65: e8 e3 fe ff ff call c0103d4d +c0103e6a: 66 c7 45 fe 28 00 movw $0x28,-0x2(%ebp) + asm volatile ("ltr %0" :: "r" (sel) : "memory"); +c0103e70: 0f b7 45 fe movzwl -0x2(%ebp),%eax +c0103e74: 0f 00 d8 ltr %ax +} +c0103e77: 90 nop + // 加载 TSS,使 CPU 在进行特权级切换时能够正确使用 TSS。 + // load the TSS + ltr(GD_TSS); +} +c0103e78: 90 nop +c0103e79: 89 ec mov %ebp,%esp +c0103e7b: 5d pop %ebp +c0103e7c: c3 ret + +c0103e7d : + +//init_pmm_manager - initialize a pmm_manager instance +//初始化一个 pmm_manager 实例 +static void +init_pmm_manager(void) { +c0103e7d: 55 push %ebp +c0103e7e: 89 e5 mov %esp,%ebp +c0103e80: 83 ec 18 sub $0x18,%esp + //将 pmm_manager 指向默认的 PMM 管理器实例。 + pmm_manager = &default_pmm_manager; +c0103e83: c7 05 0c cf 11 c0 38 movl $0xc0106b38,0xc011cf0c +c0103e8a: 6b 10 c0 + //使用 cprintf 打印当前内存管理器的名称。 + cprintf("memory management: %s\n", pmm_manager->name); +c0103e8d: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c0103e92: 8b 00 mov (%eax),%eax +c0103e94: 89 44 24 04 mov %eax,0x4(%esp) +c0103e98: c7 04 24 d4 6b 10 c0 movl $0xc0106bd4,(%esp) +c0103e9f: e8 c2 c4 ff ff call c0100366 + //调用 PMM 管理器的初始化函数,以设置和准备内存管理的相关数据结构。 + pmm_manager->init(); +c0103ea4: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c0103ea9: 8b 40 04 mov 0x4(%eax),%eax +c0103eac: ff d0 call *%eax +} +c0103eae: 90 nop +c0103eaf: 89 ec mov %ebp,%esp +c0103eb1: 5d pop %ebp +c0103eb2: c3 ret + +c0103eb3 : + +//init_memmap - call pmm->init_memmap to build Page struct for free memory +// init_memmap - 调用 pmm->init_memmap 构建空闲内存的 Page 结构 +//struct Page *base:指向内存页的基础地址。 size_t n:要初始化的页数。 +static void +init_memmap(struct Page *base, size_t n) { +c0103eb3: 55 push %ebp +c0103eb4: 89 e5 mov %esp,%ebp +c0103eb6: 83 ec 18 sub $0x18,%esp + pmm_manager->init_memmap(base, n); +c0103eb9: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c0103ebe: 8b 40 08 mov 0x8(%eax),%eax +c0103ec1: 8b 55 0c mov 0xc(%ebp),%edx +c0103ec4: 89 54 24 04 mov %edx,0x4(%esp) +c0103ec8: 8b 55 08 mov 0x8(%ebp),%edx +c0103ecb: 89 14 24 mov %edx,(%esp) +c0103ece: ff d0 call *%eax +} +c0103ed0: 90 nop +c0103ed1: 89 ec mov %ebp,%esp +c0103ed3: 5d pop %ebp +c0103ed4: c3 ret + +c0103ed5 : + +//alloc_pages - call pmm->alloc_pages to allocate a continuous n*PAGESIZE memory +// alloc_pages - 调用 pmm->alloc_pages 分配连续的 n*PAGESIZE 内存 +struct Page * +alloc_pages(size_t n) { +c0103ed5: 55 push %ebp +c0103ed6: 89 e5 mov %esp,%ebp +c0103ed8: 83 ec 28 sub $0x28,%esp + struct Page *page=NULL; +c0103edb: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在分配内存时发生中断。 + local_intr_save(intr_flag); +c0103ee2: e8 24 fe ff ff call c0103d0b <__intr_save> +c0103ee7: 89 45 f0 mov %eax,-0x10(%ebp) + { + //调用物理内存管理器的 alloc_pages 函数分配 n 页的内存。 + page = pmm_manager->alloc_pages(n); +c0103eea: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c0103eef: 8b 40 0c mov 0xc(%eax),%eax +c0103ef2: 8b 55 08 mov 0x8(%ebp),%edx +c0103ef5: 89 14 24 mov %edx,(%esp) +c0103ef8: ff d0 call *%eax +c0103efa: 89 45 f4 mov %eax,-0xc(%ebp) + } + //恢复之前保存的中断状态。 + local_intr_restore(intr_flag); +c0103efd: 8b 45 f0 mov -0x10(%ebp),%eax +c0103f00: 89 04 24 mov %eax,(%esp) +c0103f03: e8 2f fe ff ff call c0103d37 <__intr_restore> + return page; +c0103f08: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0103f0b: 89 ec mov %ebp,%esp +c0103f0d: 5d pop %ebp +c0103f0e: c3 ret + +c0103f0f : + +//free_pages - call pmm->free_pages to free a continuous n*PAGESIZE memory +// free_pages - 调用 pmm->free_pages 释放连续的 n*PAGESIZE 内存 +//struct Page *base:指向要释放的内存页的基础地址。size_t n:要释放的页数。 +void +free_pages(struct Page *base, size_t n) { +c0103f0f: 55 push %ebp +c0103f10: 89 e5 mov %esp,%ebp +c0103f12: 83 ec 28 sub $0x28,%esp + bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在释放内存时发生中断。 + local_intr_save(intr_flag); +c0103f15: e8 f1 fd ff ff call c0103d0b <__intr_save> +c0103f1a: 89 45 f4 mov %eax,-0xc(%ebp) + { + //调用物理内存管理器的 free_pages 函数释放 n 页的内存。 + pmm_manager->free_pages(base, n); +c0103f1d: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c0103f22: 8b 40 10 mov 0x10(%eax),%eax +c0103f25: 8b 55 0c mov 0xc(%ebp),%edx +c0103f28: 89 54 24 04 mov %edx,0x4(%esp) +c0103f2c: 8b 55 08 mov 0x8(%ebp),%edx +c0103f2f: 89 14 24 mov %edx,(%esp) +c0103f32: ff d0 call *%eax + } + local_intr_restore(intr_flag); +c0103f34: 8b 45 f4 mov -0xc(%ebp),%eax +c0103f37: 89 04 24 mov %eax,(%esp) +c0103f3a: e8 f8 fd ff ff call c0103d37 <__intr_restore> +} +c0103f3f: 90 nop +c0103f40: 89 ec mov %ebp,%esp +c0103f42: 5d pop %ebp +c0103f43: c3 ret + +c0103f44 : + +//nr_free_pages - call pmm->nr_free_pages to get the size (nr*PAGESIZE) +//of current free memory +// nr_free_pages - 调用 pmm->nr_free_pages 获取当前空闲内存的大小 (nr * PAGESIZE) +size_t +nr_free_pages(void) { +c0103f44: 55 push %ebp +c0103f45: 89 e5 mov %esp,%ebp +c0103f47: 83 ec 28 sub $0x28,%esp + size_t ret;// 定义变量 ret 用于存储返回的空闲内存大小 + bool intr_flag;// 定义变量 intr_flag 用于保存中断状态 + local_intr_save(intr_flag);// 保存当前中断状态,并禁用中断 +c0103f4a: e8 bc fd ff ff call c0103d0b <__intr_save> +c0103f4f: 89 45 f4 mov %eax,-0xc(%ebp) + { + ret = pmm_manager->nr_free_pages();// 调用物理内存管理器的函数获取空闲内存页数 +c0103f52: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c0103f57: 8b 40 14 mov 0x14(%eax),%eax +c0103f5a: ff d0 call *%eax +c0103f5c: 89 45 f0 mov %eax,-0x10(%ebp) + } + local_intr_restore(intr_flag);// 恢复之前保存的中断状态 +c0103f5f: 8b 45 f4 mov -0xc(%ebp),%eax +c0103f62: 89 04 24 mov %eax,(%esp) +c0103f65: e8 cd fd ff ff call c0103d37 <__intr_restore> + return ret;// 返回空闲内存的大小 +c0103f6a: 8b 45 f0 mov -0x10(%ebp),%eax +} +c0103f6d: 89 ec mov %ebp,%esp +c0103f6f: 5d pop %ebp +c0103f70: c3 ret + +c0103f71 : + +/* pmm_init - initialize the physical memory management */ +/* pmm_init - 初始化物理内存管理 */ +static void +page_init(void) { +c0103f71: 55 push %ebp +c0103f72: 89 e5 mov %esp,%ebp +c0103f74: 57 push %edi +c0103f75: 56 push %esi +c0103f76: 53 push %ebx +c0103f77: 81 ec 9c 00 00 00 sub $0x9c,%esp + // 获取物理内存映射信息,存于特定地址 + struct e820map *memmap = (struct e820map *)(0x8000 + KERNBASE); +c0103f7d: c7 45 c4 00 80 00 c0 movl $0xc0008000,-0x3c(%ebp) + uint64_t maxpa = 0;// 初始化最大物理地址为0 +c0103f84: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%ebp) +c0103f8b: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + + cprintf("e820map:\n");// 打印“e820map”标题 +c0103f92: c7 04 24 eb 6b 10 c0 movl $0xc0106beb,(%esp) +c0103f99: e8 c8 c3 ff ff call c0100366 + int i; + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 +c0103f9e: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c0103fa5: e9 0c 01 00 00 jmp c01040b6 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size; // 获取每个区域的起始和结束地址 +c0103faa: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0103fad: 8b 55 dc mov -0x24(%ebp),%edx +c0103fb0: 89 d0 mov %edx,%eax +c0103fb2: c1 e0 02 shl $0x2,%eax +c0103fb5: 01 d0 add %edx,%eax +c0103fb7: c1 e0 02 shl $0x2,%eax +c0103fba: 01 c8 add %ecx,%eax +c0103fbc: 8b 50 08 mov 0x8(%eax),%edx +c0103fbf: 8b 40 04 mov 0x4(%eax),%eax +c0103fc2: 89 45 a0 mov %eax,-0x60(%ebp) +c0103fc5: 89 55 a4 mov %edx,-0x5c(%ebp) +c0103fc8: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0103fcb: 8b 55 dc mov -0x24(%ebp),%edx +c0103fce: 89 d0 mov %edx,%eax +c0103fd0: c1 e0 02 shl $0x2,%eax +c0103fd3: 01 d0 add %edx,%eax +c0103fd5: c1 e0 02 shl $0x2,%eax +c0103fd8: 01 c8 add %ecx,%eax +c0103fda: 8b 48 0c mov 0xc(%eax),%ecx +c0103fdd: 8b 58 10 mov 0x10(%eax),%ebx +c0103fe0: 8b 45 a0 mov -0x60(%ebp),%eax +c0103fe3: 8b 55 a4 mov -0x5c(%ebp),%edx +c0103fe6: 01 c8 add %ecx,%eax +c0103fe8: 11 da adc %ebx,%edx +c0103fea: 89 45 98 mov %eax,-0x68(%ebp) +c0103fed: 89 55 9c mov %edx,-0x64(%ebp) + cprintf(" memory: %08llx, [%08llx, %08llx], type = %d.\n",// 打印内存区域的信息 +c0103ff0: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0103ff3: 8b 55 dc mov -0x24(%ebp),%edx +c0103ff6: 89 d0 mov %edx,%eax +c0103ff8: c1 e0 02 shl $0x2,%eax +c0103ffb: 01 d0 add %edx,%eax +c0103ffd: c1 e0 02 shl $0x2,%eax +c0104000: 01 c8 add %ecx,%eax +c0104002: 83 c0 14 add $0x14,%eax +c0104005: 8b 00 mov (%eax),%eax +c0104007: 89 85 7c ff ff ff mov %eax,-0x84(%ebp) +c010400d: 8b 45 98 mov -0x68(%ebp),%eax +c0104010: 8b 55 9c mov -0x64(%ebp),%edx +c0104013: 83 c0 ff add $0xffffffff,%eax +c0104016: 83 d2 ff adc $0xffffffff,%edx +c0104019: 89 c6 mov %eax,%esi +c010401b: 89 d7 mov %edx,%edi +c010401d: 8b 4d c4 mov -0x3c(%ebp),%ecx +c0104020: 8b 55 dc mov -0x24(%ebp),%edx +c0104023: 89 d0 mov %edx,%eax +c0104025: c1 e0 02 shl $0x2,%eax +c0104028: 01 d0 add %edx,%eax +c010402a: c1 e0 02 shl $0x2,%eax +c010402d: 01 c8 add %ecx,%eax +c010402f: 8b 48 0c mov 0xc(%eax),%ecx +c0104032: 8b 58 10 mov 0x10(%eax),%ebx +c0104035: 8b 85 7c ff ff ff mov -0x84(%ebp),%eax +c010403b: 89 44 24 1c mov %eax,0x1c(%esp) +c010403f: 89 74 24 14 mov %esi,0x14(%esp) +c0104043: 89 7c 24 18 mov %edi,0x18(%esp) +c0104047: 8b 45 a0 mov -0x60(%ebp),%eax +c010404a: 8b 55 a4 mov -0x5c(%ebp),%edx +c010404d: 89 44 24 0c mov %eax,0xc(%esp) +c0104051: 89 54 24 10 mov %edx,0x10(%esp) +c0104055: 89 4c 24 04 mov %ecx,0x4(%esp) +c0104059: 89 5c 24 08 mov %ebx,0x8(%esp) +c010405d: c7 04 24 f8 6b 10 c0 movl $0xc0106bf8,(%esp) +c0104064: e8 fd c2 ff ff call c0100366 + memmap->map[i].size, begin, end - 1, memmap->map[i].type); + if (memmap->map[i].type == E820_ARM) { // 检查内存类型是否为可用内存 +c0104069: 8b 4d c4 mov -0x3c(%ebp),%ecx +c010406c: 8b 55 dc mov -0x24(%ebp),%edx +c010406f: 89 d0 mov %edx,%eax +c0104071: c1 e0 02 shl $0x2,%eax +c0104074: 01 d0 add %edx,%eax +c0104076: c1 e0 02 shl $0x2,%eax +c0104079: 01 c8 add %ecx,%eax +c010407b: 83 c0 14 add $0x14,%eax +c010407e: 8b 00 mov (%eax),%eax +c0104080: 83 f8 01 cmp $0x1,%eax +c0104083: 75 2e jne c01040b3 + if (maxpa < end && begin < KMEMSIZE) {// 检查当前区域是否在有效范围内 +c0104085: 8b 45 e0 mov -0x20(%ebp),%eax +c0104088: 8b 55 e4 mov -0x1c(%ebp),%edx +c010408b: 3b 45 98 cmp -0x68(%ebp),%eax +c010408e: 89 d0 mov %edx,%eax +c0104090: 1b 45 9c sbb -0x64(%ebp),%eax +c0104093: 73 1e jae c01040b3 +c0104095: ba ff ff ff 37 mov $0x37ffffff,%edx +c010409a: b8 00 00 00 00 mov $0x0,%eax +c010409f: 3b 55 a0 cmp -0x60(%ebp),%edx +c01040a2: 1b 45 a4 sbb -0x5c(%ebp),%eax +c01040a5: 72 0c jb c01040b3 + maxpa = end;// 更新最大物理地址 +c01040a7: 8b 45 98 mov -0x68(%ebp),%eax +c01040aa: 8b 55 9c mov -0x64(%ebp),%edx +c01040ad: 89 45 e0 mov %eax,-0x20(%ebp) +c01040b0: 89 55 e4 mov %edx,-0x1c(%ebp) + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 +c01040b3: ff 45 dc incl -0x24(%ebp) +c01040b6: 8b 45 c4 mov -0x3c(%ebp),%eax +c01040b9: 8b 00 mov (%eax),%eax +c01040bb: 39 45 dc cmp %eax,-0x24(%ebp) +c01040be: 0f 8c e6 fe ff ff jl c0103faa + } + } + } + if (maxpa > KMEMSIZE) {// 如果最大物理地址超过了预定义的内存上限 +c01040c4: ba 00 00 00 38 mov $0x38000000,%edx +c01040c9: b8 00 00 00 00 mov $0x0,%eax +c01040ce: 3b 55 e0 cmp -0x20(%ebp),%edx +c01040d1: 1b 45 e4 sbb -0x1c(%ebp),%eax +c01040d4: 73 0e jae c01040e4 + maxpa = KMEMSIZE;// 将其限制为内存上限 +c01040d6: c7 45 e0 00 00 00 38 movl $0x38000000,-0x20(%ebp) +c01040dd: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + } + + extern char end[];// 引入全局变量 end,指向内存的结束位置 + + npage = maxpa / PGSIZE; // 计算可用页数 +c01040e4: 8b 45 e0 mov -0x20(%ebp),%eax +c01040e7: 8b 55 e4 mov -0x1c(%ebp),%edx +c01040ea: 0f ac d0 0c shrd $0xc,%edx,%eax +c01040ee: c1 ea 0c shr $0xc,%edx +c01040f1: a3 04 cf 11 c0 mov %eax,0xc011cf04 + pages = (struct Page *)ROUNDUP((void *)end, PGSIZE);// 将 end 对齐到页边界,指向页结构数组的开头 +c01040f6: c7 45 c0 00 10 00 00 movl $0x1000,-0x40(%ebp) +c01040fd: b8 8c cf 11 c0 mov $0xc011cf8c,%eax +c0104102: 8d 50 ff lea -0x1(%eax),%edx +c0104105: 8b 45 c0 mov -0x40(%ebp),%eax +c0104108: 01 d0 add %edx,%eax +c010410a: 89 45 bc mov %eax,-0x44(%ebp) +c010410d: 8b 45 bc mov -0x44(%ebp),%eax +c0104110: ba 00 00 00 00 mov $0x0,%edx +c0104115: f7 75 c0 divl -0x40(%ebp) +c0104118: 8b 45 bc mov -0x44(%ebp),%eax +c010411b: 29 d0 sub %edx,%eax +c010411d: a3 00 cf 11 c0 mov %eax,0xc011cf00 + + for (i = 0; i < npage; i ++) {// 遍历每一页 +c0104122: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c0104129: eb 2f jmp c010415a + SetPageReserved(pages + i);// 将每一页标记为保留状态 +c010412b: 8b 0d 00 cf 11 c0 mov 0xc011cf00,%ecx +c0104131: 8b 55 dc mov -0x24(%ebp),%edx +c0104134: 89 d0 mov %edx,%eax +c0104136: c1 e0 02 shl $0x2,%eax +c0104139: 01 d0 add %edx,%eax +c010413b: c1 e0 02 shl $0x2,%eax +c010413e: 01 c8 add %ecx,%eax +c0104140: 83 c0 04 add $0x4,%eax +c0104143: c7 45 94 00 00 00 00 movl $0x0,-0x6c(%ebp) +c010414a: 89 45 90 mov %eax,-0x70(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); +c010414d: 8b 45 90 mov -0x70(%ebp),%eax +c0104150: 8b 55 94 mov -0x6c(%ebp),%edx +c0104153: 0f ab 10 bts %edx,(%eax) +} +c0104156: 90 nop + for (i = 0; i < npage; i ++) {// 遍历每一页 +c0104157: ff 45 dc incl -0x24(%ebp) +c010415a: 8b 55 dc mov -0x24(%ebp),%edx +c010415d: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c0104162: 39 c2 cmp %eax,%edx +c0104164: 72 c5 jb c010412b + } + + uintptr_t freemem = PADDR((uintptr_t)pages + sizeof(struct Page) * npage);// 计算可用内存的起始地址 +c0104166: 8b 15 04 cf 11 c0 mov 0xc011cf04,%edx +c010416c: 89 d0 mov %edx,%eax +c010416e: c1 e0 02 shl $0x2,%eax +c0104171: 01 d0 add %edx,%eax +c0104173: c1 e0 02 shl $0x2,%eax +c0104176: 89 c2 mov %eax,%edx +c0104178: a1 00 cf 11 c0 mov 0xc011cf00,%eax +c010417d: 01 d0 add %edx,%eax +c010417f: 89 45 b8 mov %eax,-0x48(%ebp) +c0104182: 81 7d b8 ff ff ff bf cmpl $0xbfffffff,-0x48(%ebp) +c0104189: 77 23 ja c01041ae +c010418b: 8b 45 b8 mov -0x48(%ebp),%eax +c010418e: 89 44 24 0c mov %eax,0xc(%esp) +c0104192: c7 44 24 08 28 6c 10 movl $0xc0106c28,0x8(%esp) +c0104199: c0 +c010419a: c7 44 24 04 0c 01 00 movl $0x10c,0x4(%esp) +c01041a1: 00 +c01041a2: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01041a9: e8 85 ca ff ff call c0100c33 <__panic> +c01041ae: 8b 45 b8 mov -0x48(%ebp),%eax +c01041b1: 05 00 00 00 40 add $0x40000000,%eax +c01041b6: 89 45 b4 mov %eax,-0x4c(%ebp) + + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 +c01041b9: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c01041c0: e9 53 01 00 00 jmp c0104318 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址 +c01041c5: 8b 4d c4 mov -0x3c(%ebp),%ecx +c01041c8: 8b 55 dc mov -0x24(%ebp),%edx +c01041cb: 89 d0 mov %edx,%eax +c01041cd: c1 e0 02 shl $0x2,%eax +c01041d0: 01 d0 add %edx,%eax +c01041d2: c1 e0 02 shl $0x2,%eax +c01041d5: 01 c8 add %ecx,%eax +c01041d7: 8b 50 08 mov 0x8(%eax),%edx +c01041da: 8b 40 04 mov 0x4(%eax),%eax +c01041dd: 89 45 d0 mov %eax,-0x30(%ebp) +c01041e0: 89 55 d4 mov %edx,-0x2c(%ebp) +c01041e3: 8b 4d c4 mov -0x3c(%ebp),%ecx +c01041e6: 8b 55 dc mov -0x24(%ebp),%edx +c01041e9: 89 d0 mov %edx,%eax +c01041eb: c1 e0 02 shl $0x2,%eax +c01041ee: 01 d0 add %edx,%eax +c01041f0: c1 e0 02 shl $0x2,%eax +c01041f3: 01 c8 add %ecx,%eax +c01041f5: 8b 48 0c mov 0xc(%eax),%ecx +c01041f8: 8b 58 10 mov 0x10(%eax),%ebx +c01041fb: 8b 45 d0 mov -0x30(%ebp),%eax +c01041fe: 8b 55 d4 mov -0x2c(%ebp),%edx +c0104201: 01 c8 add %ecx,%eax +c0104203: 11 da adc %ebx,%edx +c0104205: 89 45 c8 mov %eax,-0x38(%ebp) +c0104208: 89 55 cc mov %edx,-0x34(%ebp) + if (memmap->map[i].type == E820_ARM) {// 如果区域类型为可用内存 +c010420b: 8b 4d c4 mov -0x3c(%ebp),%ecx +c010420e: 8b 55 dc mov -0x24(%ebp),%edx +c0104211: 89 d0 mov %edx,%eax +c0104213: c1 e0 02 shl $0x2,%eax +c0104216: 01 d0 add %edx,%eax +c0104218: c1 e0 02 shl $0x2,%eax +c010421b: 01 c8 add %ecx,%eax +c010421d: 83 c0 14 add $0x14,%eax +c0104220: 8b 00 mov (%eax),%eax +c0104222: 83 f8 01 cmp $0x1,%eax +c0104225: 0f 85 ea 00 00 00 jne c0104315 + if (begin < freemem) { // 如果起始地址小于可用内存地址 +c010422b: 8b 45 b4 mov -0x4c(%ebp),%eax +c010422e: ba 00 00 00 00 mov $0x0,%edx +c0104233: 8b 4d d4 mov -0x2c(%ebp),%ecx +c0104236: 39 45 d0 cmp %eax,-0x30(%ebp) +c0104239: 19 d1 sbb %edx,%ecx +c010423b: 73 0d jae c010424a + begin = freemem;// 将起始地址设置为可用内存地址 +c010423d: 8b 45 b4 mov -0x4c(%ebp),%eax +c0104240: 89 45 d0 mov %eax,-0x30(%ebp) +c0104243: c7 45 d4 00 00 00 00 movl $0x0,-0x2c(%ebp) + } + if (end > KMEMSIZE) {// 如果结束地址超过内存上限 +c010424a: ba 00 00 00 38 mov $0x38000000,%edx +c010424f: b8 00 00 00 00 mov $0x0,%eax +c0104254: 3b 55 c8 cmp -0x38(%ebp),%edx +c0104257: 1b 45 cc sbb -0x34(%ebp),%eax +c010425a: 73 0e jae c010426a + end = KMEMSIZE;// 将其限制为内存上限 +c010425c: c7 45 c8 00 00 00 38 movl $0x38000000,-0x38(%ebp) +c0104263: c7 45 cc 00 00 00 00 movl $0x0,-0x34(%ebp) + } + if (begin < end) {// 如果起始地址小于结束地址 +c010426a: 8b 45 d0 mov -0x30(%ebp),%eax +c010426d: 8b 55 d4 mov -0x2c(%ebp),%edx +c0104270: 3b 45 c8 cmp -0x38(%ebp),%eax +c0104273: 89 d0 mov %edx,%eax +c0104275: 1b 45 cc sbb -0x34(%ebp),%eax +c0104278: 0f 83 97 00 00 00 jae c0104315 + begin = ROUNDUP(begin, PGSIZE);// 将起始地址对齐到页边界 +c010427e: c7 45 b0 00 10 00 00 movl $0x1000,-0x50(%ebp) +c0104285: 8b 55 d0 mov -0x30(%ebp),%edx +c0104288: 8b 45 b0 mov -0x50(%ebp),%eax +c010428b: 01 d0 add %edx,%eax +c010428d: 48 dec %eax +c010428e: 89 45 ac mov %eax,-0x54(%ebp) +c0104291: 8b 45 ac mov -0x54(%ebp),%eax +c0104294: ba 00 00 00 00 mov $0x0,%edx +c0104299: f7 75 b0 divl -0x50(%ebp) +c010429c: 8b 45 ac mov -0x54(%ebp),%eax +c010429f: 29 d0 sub %edx,%eax +c01042a1: ba 00 00 00 00 mov $0x0,%edx +c01042a6: 89 45 d0 mov %eax,-0x30(%ebp) +c01042a9: 89 55 d4 mov %edx,-0x2c(%ebp) + end = ROUNDDOWN(end, PGSIZE);// 将结束地址对齐到页边界 +c01042ac: 8b 45 c8 mov -0x38(%ebp),%eax +c01042af: 89 45 a8 mov %eax,-0x58(%ebp) +c01042b2: 8b 45 a8 mov -0x58(%ebp),%eax +c01042b5: ba 00 00 00 00 mov $0x0,%edx +c01042ba: 89 c7 mov %eax,%edi +c01042bc: 81 e7 00 f0 ff ff and $0xfffff000,%edi +c01042c2: 89 7d 80 mov %edi,-0x80(%ebp) +c01042c5: 89 d0 mov %edx,%eax +c01042c7: 83 e0 00 and $0x0,%eax +c01042ca: 89 45 84 mov %eax,-0x7c(%ebp) +c01042cd: 8b 45 80 mov -0x80(%ebp),%eax +c01042d0: 8b 55 84 mov -0x7c(%ebp),%edx +c01042d3: 89 45 c8 mov %eax,-0x38(%ebp) +c01042d6: 89 55 cc mov %edx,-0x34(%ebp) + if (begin < end) {// 如果调整后的起始地址仍小于结束地址 +c01042d9: 8b 45 d0 mov -0x30(%ebp),%eax +c01042dc: 8b 55 d4 mov -0x2c(%ebp),%edx +c01042df: 3b 45 c8 cmp -0x38(%ebp),%eax +c01042e2: 89 d0 mov %edx,%eax +c01042e4: 1b 45 cc sbb -0x34(%ebp),%eax +c01042e7: 73 2c jae c0104315 + init_memmap(pa2page(begin), (end - begin) / PGSIZE);// 初始化内存页映射 +c01042e9: 8b 45 c8 mov -0x38(%ebp),%eax +c01042ec: 8b 55 cc mov -0x34(%ebp),%edx +c01042ef: 2b 45 d0 sub -0x30(%ebp),%eax +c01042f2: 1b 55 d4 sbb -0x2c(%ebp),%edx +c01042f5: 0f ac d0 0c shrd $0xc,%edx,%eax +c01042f9: c1 ea 0c shr $0xc,%edx +c01042fc: 89 c3 mov %eax,%ebx +c01042fe: 8b 45 d0 mov -0x30(%ebp),%eax +c0104301: 89 04 24 mov %eax,(%esp) +c0104304: e8 bb f8 ff ff call c0103bc4 +c0104309: 89 5c 24 04 mov %ebx,0x4(%esp) +c010430d: 89 04 24 mov %eax,(%esp) +c0104310: e8 9e fb ff ff call c0103eb3 + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 +c0104315: ff 45 dc incl -0x24(%ebp) +c0104318: 8b 45 c4 mov -0x3c(%ebp),%eax +c010431b: 8b 00 mov (%eax),%eax +c010431d: 39 45 dc cmp %eax,-0x24(%ebp) +c0104320: 0f 8c 9f fe ff ff jl c01041c5 + } + } + } + } +} +c0104326: 90 nop +c0104327: 90 nop +c0104328: 81 c4 9c 00 00 00 add $0x9c,%esp +c010432e: 5b pop %ebx +c010432f: 5e pop %esi +c0104330: 5f pop %edi +c0104331: 5d pop %ebp +c0104332: c3 ret + +c0104333 : +//la: 需要映射的线性地址(经过 x86 段映射后的地址) +// size: memory size size: 内存大小 +// pa: physical address of this memory pa:该内存的物理地址 +// perm: permission of this memory perm: 该内存的权限 +static void +boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, uintptr_t pa, uint32_t perm) { +c0104333: 55 push %ebp +c0104334: 89 e5 mov %esp,%ebp +c0104336: 83 ec 38 sub $0x38,%esp + // 确保线性地址和物理地址的页偏移相同 + assert(PGOFF(la) == PGOFF(pa)); +c0104339: 8b 45 0c mov 0xc(%ebp),%eax +c010433c: 33 45 14 xor 0x14(%ebp),%eax +c010433f: 25 ff 0f 00 00 and $0xfff,%eax +c0104344: 85 c0 test %eax,%eax +c0104346: 74 24 je c010436c +c0104348: c7 44 24 0c 5a 6c 10 movl $0xc0106c5a,0xc(%esp) +c010434f: c0 +c0104350: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104357: c0 +c0104358: c7 44 24 04 2d 01 00 movl $0x12d,0x4(%esp) +c010435f: 00 +c0104360: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104367: e8 c7 c8 ff ff call c0100c33 <__panic> + // 计算需要映射的页数,ROUNDUP 将总大小对齐到下一个页大小的边界 + size_t n = ROUNDUP(size + PGOFF(la), PGSIZE) / PGSIZE; +c010436c: c7 45 f0 00 10 00 00 movl $0x1000,-0x10(%ebp) +c0104373: 8b 45 0c mov 0xc(%ebp),%eax +c0104376: 25 ff 0f 00 00 and $0xfff,%eax +c010437b: 89 c2 mov %eax,%edx +c010437d: 8b 45 10 mov 0x10(%ebp),%eax +c0104380: 01 c2 add %eax,%edx +c0104382: 8b 45 f0 mov -0x10(%ebp),%eax +c0104385: 01 d0 add %edx,%eax +c0104387: 48 dec %eax +c0104388: 89 45 ec mov %eax,-0x14(%ebp) +c010438b: 8b 45 ec mov -0x14(%ebp),%eax +c010438e: ba 00 00 00 00 mov $0x0,%edx +c0104393: f7 75 f0 divl -0x10(%ebp) +c0104396: 8b 45 ec mov -0x14(%ebp),%eax +c0104399: 29 d0 sub %edx,%eax +c010439b: c1 e8 0c shr $0xc,%eax +c010439e: 89 45 f4 mov %eax,-0xc(%ebp) + // 将线性地址向下对齐到页边界 + la = ROUNDDOWN(la, PGSIZE); +c01043a1: 8b 45 0c mov 0xc(%ebp),%eax +c01043a4: 89 45 e8 mov %eax,-0x18(%ebp) +c01043a7: 8b 45 e8 mov -0x18(%ebp),%eax +c01043aa: 25 00 f0 ff ff and $0xfffff000,%eax +c01043af: 89 45 0c mov %eax,0xc(%ebp) + // 将物理地址向下对齐到页边界 + pa = ROUNDDOWN(pa, PGSIZE); +c01043b2: 8b 45 14 mov 0x14(%ebp),%eax +c01043b5: 89 45 e4 mov %eax,-0x1c(%ebp) +c01043b8: 8b 45 e4 mov -0x1c(%ebp),%eax +c01043bb: 25 00 f0 ff ff and $0xfffff000,%eax +c01043c0: 89 45 14 mov %eax,0x14(%ebp) + // 循环遍历每一页,直到映射的页数为零 + for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { +c01043c3: eb 68 jmp c010442d + // 获取当前页的页表项指针,如果不存在则创建新的页表项 + pte_t *ptep = get_pte(pgdir, la, 1); +c01043c5: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) +c01043cc: 00 +c01043cd: 8b 45 0c mov 0xc(%ebp),%eax +c01043d0: 89 44 24 04 mov %eax,0x4(%esp) +c01043d4: 8b 45 08 mov 0x8(%ebp),%eax +c01043d7: 89 04 24 mov %eax,(%esp) +c01043da: e8 88 01 00 00 call c0104567 +c01043df: 89 45 e0 mov %eax,-0x20(%ebp) + // 确保页表项指针不为空 + assert(ptep != NULL); +c01043e2: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) +c01043e6: 75 24 jne c010440c +c01043e8: c7 44 24 0c 86 6c 10 movl $0xc0106c86,0xc(%esp) +c01043ef: c0 +c01043f0: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c01043f7: c0 +c01043f8: c7 44 24 04 39 01 00 movl $0x139,0x4(%esp) +c01043ff: 00 +c0104400: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104407: e8 27 c8 ff ff call c0100c33 <__panic> + // 设置页表项,包含物理地址、存在位和权限 + *ptep = pa | PTE_P | perm; +c010440c: 8b 45 14 mov 0x14(%ebp),%eax +c010440f: 0b 45 18 or 0x18(%ebp),%eax +c0104412: 83 c8 01 or $0x1,%eax +c0104415: 89 c2 mov %eax,%edx +c0104417: 8b 45 e0 mov -0x20(%ebp),%eax +c010441a: 89 10 mov %edx,(%eax) + for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { +c010441c: ff 4d f4 decl -0xc(%ebp) +c010441f: 81 45 0c 00 10 00 00 addl $0x1000,0xc(%ebp) +c0104426: 81 45 14 00 10 00 00 addl $0x1000,0x14(%ebp) +c010442d: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0104431: 75 92 jne c01043c5 + } +} +c0104433: 90 nop +c0104434: 90 nop +c0104435: 89 ec mov %ebp,%esp +c0104437: 5d pop %ebp +c0104438: c3 ret + +c0104439 : +// return value: the kernel virtual address of this allocated page +//note: this function is used to get the memory for PDT(Page Directory Table)&PT(Page Table) +//boot_alloc_page - 使用 pmm->alloc_pages(1) 分配一页内存.返回值: 分配的页面的内核虚拟地址 +//注意: 此函数用于获取页目录表(PDT)和页表(PT)的内存 +static void * +boot_alloc_page(void) { +c0104439: 55 push %ebp +c010443a: 89 e5 mov %esp,%ebp +c010443c: 83 ec 28 sub $0x28,%esp + struct Page *p = alloc_page();// 调用分配页面的函数 +c010443f: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0104446: e8 8a fa ff ff call c0103ed5 +c010444b: 89 45 f4 mov %eax,-0xc(%ebp) + if (p == NULL) {// 检查分配是否成功 +c010444e: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0104452: 75 1c jne c0104470 + panic("boot_alloc_page failed.\n");// 如果分配失败,则触发异常 +c0104454: c7 44 24 08 93 6c 10 movl $0xc0106c93,0x8(%esp) +c010445b: c0 +c010445c: c7 44 24 04 48 01 00 movl $0x148,0x4(%esp) +c0104463: 00 +c0104464: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010446b: e8 c3 c7 ff ff call c0100c33 <__panic> + } + return page2kva(p);// 返回分配页面的内核虚拟地址 +c0104470: 8b 45 f4 mov -0xc(%ebp),%eax +c0104473: 89 04 24 mov %eax,(%esp) +c0104476: e8 9a f7 ff ff call c0103c15 +} +c010447b: 89 ec mov %ebp,%esp +c010447d: 5d pop %ebp +c010447e: c3 ret + +c010447f : +//pmm_init - setup a pmm to manage physical memory, build PDT&PT to setup paging mechanism +// - check the correctness of pmm & paging mechanism, print PDT&PT +//pmm_init - 设置物理内存管理器,构建页目录表(PDT)和页表(PT),以设置分页机制 +// - 检查物理内存管理器和分页机制的正确性,打印页目录表和页表 +void +pmm_init(void) { +c010447f: 55 push %ebp +c0104480: 89 e5 mov %esp,%ebp +c0104482: 83 ec 38 sub $0x38,%esp + // We've already enabled paging + // 我们已经启用了分页 + boot_cr3 = PADDR(boot_pgdir); +c0104485: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c010448a: 89 45 f4 mov %eax,-0xc(%ebp) +c010448d: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) +c0104494: 77 23 ja c01044b9 +c0104496: 8b 45 f4 mov -0xc(%ebp),%eax +c0104499: 89 44 24 0c mov %eax,0xc(%esp) +c010449d: c7 44 24 08 28 6c 10 movl $0xc0106c28,0x8(%esp) +c01044a4: c0 +c01044a5: c7 44 24 04 55 01 00 movl $0x155,0x4(%esp) +c01044ac: 00 +c01044ad: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01044b4: e8 7a c7 ff ff call c0100c33 <__panic> +c01044b9: 8b 45 f4 mov -0xc(%ebp),%eax +c01044bc: 05 00 00 00 40 add $0x40000000,%eax +c01044c1: a3 08 cf 11 c0 mov %eax,0xc011cf08 + // 我们需要分配/释放物理内存(粒度为 4KB 或其他大小)。 + // 因此在 pmm.h 中定义了物理内存管理器的框架(struct pmm_manager)。 + // 首先,我们应该基于该框架初始化一个物理内存管理器(pmm)。 + // 然后 pmm 可以分配/释放物理内存。 + // 现在,first_fit/best_fit/worst_fit/buddy_system 的 pmm 都可用。 + init_pmm_manager();// 初始化物理内存管理器 +c01044c6: e8 b2 f9 ff ff call c0103e7d + + // detect physical memory space, reserve already used memory, + // then use pmm->init_memmap to create free page list + // 检测物理内存空间,保留已经使用的内存, + // 然后使用 pmm->init_memmap 创建空闲页面列表 + page_init();// 初始化页面管理 +c01044cb: e8 a1 fa ff ff call c0103f71 + + //use pmm->check to verify the correctness of the alloc/free function in a pmm + // 使用 pmm->check 验证 pmm 中分配/释放函数的正确性 + check_alloc_page();// 检查页面分配功能 +c01044d0: e8 ed 03 00 00 call c01048c2 + + check_pgdir();// 检查页目录的状态 +c01044d5: e8 09 04 00 00 call c01048e3 + + // recursively insert boot_pgdir in itself + // to form a virtual page table at virtual address VPT + // 递归地将 boot_pgdir 插入到自身中 + // 在虚拟地址 VPT 处形成虚拟页表 + boot_pgdir[PDX(VPT)] = PADDR(boot_pgdir) | PTE_P | PTE_W;// 设置页目录项,映射自身 +c01044da: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01044df: 89 45 f0 mov %eax,-0x10(%ebp) +c01044e2: 81 7d f0 ff ff ff bf cmpl $0xbfffffff,-0x10(%ebp) +c01044e9: 77 23 ja c010450e +c01044eb: 8b 45 f0 mov -0x10(%ebp),%eax +c01044ee: 89 44 24 0c mov %eax,0xc(%esp) +c01044f2: c7 44 24 08 28 6c 10 movl $0xc0106c28,0x8(%esp) +c01044f9: c0 +c01044fa: c7 44 24 04 75 01 00 movl $0x175,0x4(%esp) +c0104501: 00 +c0104502: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104509: e8 25 c7 ff ff call c0100c33 <__panic> +c010450e: 8b 45 f0 mov -0x10(%ebp),%eax +c0104511: 8d 90 00 00 00 40 lea 0x40000000(%eax),%edx +c0104517: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c010451c: 05 ac 0f 00 00 add $0xfac,%eax +c0104521: 83 ca 03 or $0x3,%edx +c0104524: 89 10 mov %edx,(%eax) + + // map all physical memory to linear memory with base linear addr KERNBASE + // linear_addr KERNBASE ~ KERNBASE + KMEMSIZE = phy_addr 0 ~ KMEMSIZE + // 将所有物理内存映射到线性内存,基地址为 KERNBASE + // 线性地址 KERNBASE ~ KERNBASE + KMEMSIZE = 物理地址 0 ~ KMEMSIZE + boot_map_segment(boot_pgdir, KERNBASE, KMEMSIZE, 0, PTE_W);// 映射物理内存 +c0104526: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c010452b: c7 44 24 10 02 00 00 movl $0x2,0x10(%esp) +c0104532: 00 +c0104533: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c010453a: 00 +c010453b: c7 44 24 08 00 00 00 movl $0x38000000,0x8(%esp) +c0104542: 38 +c0104543: c7 44 24 04 00 00 00 movl $0xc0000000,0x4(%esp) +c010454a: c0 +c010454b: 89 04 24 mov %eax,(%esp) +c010454e: e8 e0 fd ff ff call c0104333 + // then set kernel stack (ss:esp) in TSS, setup TSS in gdt, load TSS + // 由于我们正在使用引导加载程序的 GDT, + // 我们应该重新加载 GDT(第二次,也是最后一次),以获取用户段和 TSS + // 映射虚拟地址 0 ~ 4G = 线性地址 0 ~ 4G + // 然后在 TSS 中设置内核栈 (ss:esp),在 gdt 中设置 TSS,加载 TSS + gdt_init();// 初始化全局描述符表 +c0104553: e8 39 f8 ff ff call c0103d91 + + //now the basic virtual memory map(see memalyout.h) is established. + //check the correctness of the basic virtual memory map. + // 现在基本的虚拟内存映射(见 memlayout.h)已建立。 + // 检查基础虚拟内存映射的正确性。 + check_boot_pgdir(); // 检查页目录的正确性 +c0104558: e8 24 0a 00 00 call c0104f81 + + print_pgdir(); // 打印页目录表 +c010455d: e8 a1 0e 00 00 call c0105403 + +} +c0104562: 90 nop +c0104563: 89 ec mov %ebp,%esp +c0104565: 5d pop %ebp +c0104566: c3 ret + +c0104567 : +// pgdir: 页目录的内核虚拟基地址 +// la: 需要映射的线性地址 +// create: 一个逻辑值,决定是否为页表分配一页 +// 返回值:该 PTE 的内核虚拟地址 +pte_t * +get_pte(pde_t *pgdir, uintptr_t la, bool create) { +c0104567: 55 push %ebp +c0104568: 89 e5 mov %esp,%ebp +c010456a: 83 ec 38 sub $0x38,%esp + // (7) set page directory entry's permission + } + return NULL; // (8) return page table entry +#endif + // (1) 找到页目录项 + pde_t *pdep = &pgdir[PDX(la)];// 使用 PDX 宏获取页目录索引 +c010456d: 8b 45 0c mov 0xc(%ebp),%eax +c0104570: c1 e8 16 shr $0x16,%eax +c0104573: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c010457a: 8b 45 08 mov 0x8(%ebp),%eax +c010457d: 01 d0 add %edx,%eax +c010457f: 89 45 f4 mov %eax,-0xc(%ebp) + // (2) 检查页目录项是否存在 + if (!(*pdep & PTE_P)) {// 如果页目录项的存在位 PTE_P 没有被设置 +c0104582: 8b 45 f4 mov -0xc(%ebp),%eax +c0104585: 8b 00 mov (%eax),%eax +c0104587: 83 e0 01 and $0x1,%eax +c010458a: 85 c0 test %eax,%eax +c010458c: 0f 85 af 00 00 00 jne c0104641 + struct Page *page;// 声明一个指针,用于指向新分配的页面 + // 检查是否允许创建新页表,或者分配页表失败 + if (!create || (page = alloc_page()) == NULL) {// 如果不允许创建或分配失败 +c0104592: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0104596: 74 15 je c01045ad +c0104598: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010459f: e8 31 f9 ff ff call c0103ed5 +c01045a4: 89 45 f0 mov %eax,-0x10(%ebp) +c01045a7: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c01045ab: 75 0a jne c01045b7 + return NULL;// 返回 NULL,表示无法获取页表 +c01045ad: b8 00 00 00 00 mov $0x0,%eax +c01045b2: e9 e7 00 00 00 jmp c010469e + } + // 设置新分配页面的引用计数为 1 + set_page_ref(page, 1); +c01045b7: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01045be: 00 +c01045bf: 8b 45 f0 mov -0x10(%ebp),%eax +c01045c2: 89 04 24 mov %eax,(%esp) +c01045c5: e8 05 f7 ff ff call c0103ccf + uintptr_t pa = page2pa(page);// 获取新分配页面的物理地址 +c01045ca: 8b 45 f0 mov -0x10(%ebp),%eax +c01045cd: 89 04 24 mov %eax,(%esp) +c01045d0: e8 d7 f5 ff ff call c0103bac +c01045d5: 89 45 ec mov %eax,-0x14(%ebp) + memset(KADDR(pa), 0, PGSIZE);// 清空新分配的页表内容,初始化为零 +c01045d8: 8b 45 ec mov -0x14(%ebp),%eax +c01045db: 89 45 e8 mov %eax,-0x18(%ebp) +c01045de: 8b 45 e8 mov -0x18(%ebp),%eax +c01045e1: c1 e8 0c shr $0xc,%eax +c01045e4: 89 45 e4 mov %eax,-0x1c(%ebp) +c01045e7: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c01045ec: 39 45 e4 cmp %eax,-0x1c(%ebp) +c01045ef: 72 23 jb c0104614 +c01045f1: 8b 45 e8 mov -0x18(%ebp),%eax +c01045f4: 89 44 24 0c mov %eax,0xc(%esp) +c01045f8: c7 44 24 08 84 6b 10 movl $0xc0106b84,0x8(%esp) +c01045ff: c0 +c0104600: c7 44 24 04 ce 01 00 movl $0x1ce,0x4(%esp) +c0104607: 00 +c0104608: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010460f: e8 1f c6 ff ff call c0100c33 <__panic> +c0104614: 8b 45 e8 mov -0x18(%ebp),%eax +c0104617: 2d 00 00 00 40 sub $0x40000000,%eax +c010461c: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c0104623: 00 +c0104624: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c010462b: 00 +c010462c: 89 04 24 mov %eax,(%esp) +c010462f: e8 d4 18 00 00 call c0105f08 + // 更新页目录项,设置物理地址和权限位 + *pdep = pa | PTE_U | PTE_W | PTE_P;// 将物理地址和权限位(用户可访问、可写、有效)合并设置 +c0104634: 8b 45 ec mov -0x14(%ebp),%eax +c0104637: 83 c8 07 or $0x7,%eax +c010463a: 89 c2 mov %eax,%edx +c010463c: 8b 45 f4 mov -0xc(%ebp),%eax +c010463f: 89 10 mov %edx,(%eax) + } + // 返回指定线性地址 la 对应的页表项的内核虚拟地址 + return &((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)];// 计算并返回页表项的指针 +c0104641: 8b 45 f4 mov -0xc(%ebp),%eax +c0104644: 8b 00 mov (%eax),%eax +c0104646: 25 00 f0 ff ff and $0xfffff000,%eax +c010464b: 89 45 e0 mov %eax,-0x20(%ebp) +c010464e: 8b 45 e0 mov -0x20(%ebp),%eax +c0104651: c1 e8 0c shr $0xc,%eax +c0104654: 89 45 dc mov %eax,-0x24(%ebp) +c0104657: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c010465c: 39 45 dc cmp %eax,-0x24(%ebp) +c010465f: 72 23 jb c0104684 +c0104661: 8b 45 e0 mov -0x20(%ebp),%eax +c0104664: 89 44 24 0c mov %eax,0xc(%esp) +c0104668: c7 44 24 08 84 6b 10 movl $0xc0106b84,0x8(%esp) +c010466f: c0 +c0104670: c7 44 24 04 d3 01 00 movl $0x1d3,0x4(%esp) +c0104677: 00 +c0104678: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010467f: e8 af c5 ff ff call c0100c33 <__panic> +c0104684: 8b 45 e0 mov -0x20(%ebp),%eax +c0104687: 2d 00 00 00 40 sub $0x40000000,%eax +c010468c: 89 c2 mov %eax,%edx +c010468e: 8b 45 0c mov 0xc(%ebp),%eax +c0104691: c1 e8 0c shr $0xc,%eax +c0104694: 25 ff 03 00 00 and $0x3ff,%eax +c0104699: c1 e0 02 shl $0x2,%eax +c010469c: 01 d0 add %edx,%eax +} +c010469e: 89 ec mov %ebp,%esp +c01046a0: 5d pop %ebp +c01046a1: c3 ret + +c01046a2 : + +//get_page - get related Page struct for linear address la using PDT pgdir +// get_page - 获取与线性地址 la 相关的 Page 结构体,使用页目录 pgdir +struct Page * +get_page(pde_t *pgdir, uintptr_t la, pte_t **ptep_store) { +c01046a2: 55 push %ebp +c01046a3: 89 e5 mov %esp,%ebp +c01046a5: 83 ec 28 sub $0x28,%esp + // 调用 get_pte 函数获取对应线性地址 la 的页表项指针 + pte_t *ptep = get_pte(pgdir, la, 0); +c01046a8: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01046af: 00 +c01046b0: 8b 45 0c mov 0xc(%ebp),%eax +c01046b3: 89 44 24 04 mov %eax,0x4(%esp) +c01046b7: 8b 45 08 mov 0x8(%ebp),%eax +c01046ba: 89 04 24 mov %eax,(%esp) +c01046bd: e8 a5 fe ff ff call c0104567 +c01046c2: 89 45 f4 mov %eax,-0xc(%ebp) + // 如果 ptep_store 指针不为 NULL,将 ptep 存储到 ptep_store 指向的位置 + if (ptep_store != NULL) { +c01046c5: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c01046c9: 74 08 je c01046d3 + *ptep_store = ptep; // 存储当前页表项的指针 +c01046cb: 8b 45 10 mov 0x10(%ebp),%eax +c01046ce: 8b 55 f4 mov -0xc(%ebp),%edx +c01046d1: 89 10 mov %edx,(%eax) + } + // 检查 ptep 是否有效以及页表项的存在位 PTE_P 是否被设置 + if (ptep != NULL && *ptep & PTE_P) { +c01046d3: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01046d7: 74 1b je c01046f4 +c01046d9: 8b 45 f4 mov -0xc(%ebp),%eax +c01046dc: 8b 00 mov (%eax),%eax +c01046de: 83 e0 01 and $0x1,%eax +c01046e1: 85 c0 test %eax,%eax +c01046e3: 74 0f je c01046f4 + // 返回与页表项对应的 Page 结构体 + return pte2page(*ptep);// 将页表项转换为对应的 Page 结构 +c01046e5: 8b 45 f4 mov -0xc(%ebp),%eax +c01046e8: 8b 00 mov (%eax),%eax +c01046ea: 89 04 24 mov %eax,(%esp) +c01046ed: e8 79 f5 ff ff call c0103c6b +c01046f2: eb 05 jmp c01046f9 + } + // 如果未找到有效的页,返回 NULL + return NULL; +c01046f4: b8 00 00 00 00 mov $0x0,%eax +} +c01046f9: 89 ec mov %ebp,%esp +c01046fb: 5d pop %ebp +c01046fc: c3 ret + +c01046fd : + +//page_remove_pte - free an Page sturct which is related linear address la +// - and clean(invalidate) pte which is related linear address la +//note: PT is changed, so the TLB need to be invalidate +static inline void +page_remove_pte(pde_t *pgdir, uintptr_t la, pte_t *ptep) { +c01046fd: 55 push %ebp +c01046fe: 89 e5 mov %esp,%ebp +c0104700: 83 ec 28 sub $0x28,%esp + //(4) and free this page when page reference reachs 0 + //(5) clear second page table entry + //(6) flush tlb + } +#endif + if (*ptep & PTE_P) { +c0104703: 8b 45 10 mov 0x10(%ebp),%eax +c0104706: 8b 00 mov (%eax),%eax +c0104708: 83 e0 01 and $0x1,%eax +c010470b: 85 c0 test %eax,%eax +c010470d: 74 4d je c010475c + struct Page *page = pte2page(*ptep);// 找到对应的物理页 +c010470f: 8b 45 10 mov 0x10(%ebp),%eax +c0104712: 8b 00 mov (%eax),%eax +c0104714: 89 04 24 mov %eax,(%esp) +c0104717: e8 4f f5 ff ff call c0103c6b +c010471c: 89 45 f4 mov %eax,-0xc(%ebp) + // 减少物理页的引用计数,如果引用计数为零,释放该物理页 + if (page_ref_dec(page) == 0) { +c010471f: 8b 45 f4 mov -0xc(%ebp),%eax +c0104722: 89 04 24 mov %eax,(%esp) +c0104725: e8 ca f5 ff ff call c0103cf4 +c010472a: 85 c0 test %eax,%eax +c010472c: 75 13 jne c0104741 + free_page(page); +c010472e: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0104735: 00 +c0104736: 8b 45 f4 mov -0xc(%ebp),%eax +c0104739: 89 04 24 mov %eax,(%esp) +c010473c: e8 ce f7 ff ff call c0103f0f + } + *ptep = 0;// 清除页表项 +c0104741: 8b 45 10 mov 0x10(%ebp),%eax +c0104744: c7 00 00 00 00 00 movl $0x0,(%eax) + tlb_invalidate(pgdir, la);// 刷新 TLB +c010474a: 8b 45 0c mov 0xc(%ebp),%eax +c010474d: 89 44 24 04 mov %eax,0x4(%esp) +c0104751: 8b 45 08 mov 0x8(%ebp),%eax +c0104754: 89 04 24 mov %eax,(%esp) +c0104757: e8 07 01 00 00 call c0104863 + } +} +c010475c: 90 nop +c010475d: 89 ec mov %ebp,%esp +c010475f: 5d pop %ebp +c0104760: c3 ret + +c0104761 : + +//page_remove - free an Page which is related linear address la and has an validated pte +//移除一个虚拟地址对应的页面 +void +page_remove(pde_t *pgdir, uintptr_t la) { +c0104761: 55 push %ebp +c0104762: 89 e5 mov %esp,%ebp +c0104764: 83 ec 28 sub $0x28,%esp + //调用 get_pte 函数获取给定虚拟地址 la 对应的页表项指针 ptep。 + pte_t *ptep = get_pte(pgdir, la, 0); +c0104767: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c010476e: 00 +c010476f: 8b 45 0c mov 0xc(%ebp),%eax +c0104772: 89 44 24 04 mov %eax,0x4(%esp) +c0104776: 8b 45 08 mov 0x8(%ebp),%eax +c0104779: 89 04 24 mov %eax,(%esp) +c010477c: e8 e6 fd ff ff call c0104567 +c0104781: 89 45 f4 mov %eax,-0xc(%ebp) + //如果 ptep 不为 NULL,则调用 page_remove_pte 函数移除该页表项。 + if (ptep != NULL) { +c0104784: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c0104788: 74 19 je c01047a3 + page_remove_pte(pgdir, la, ptep); +c010478a: 8b 45 f4 mov -0xc(%ebp),%eax +c010478d: 89 44 24 08 mov %eax,0x8(%esp) +c0104791: 8b 45 0c mov 0xc(%ebp),%eax +c0104794: 89 44 24 04 mov %eax,0x4(%esp) +c0104798: 8b 45 08 mov 0x8(%ebp),%eax +c010479b: 89 04 24 mov %eax,(%esp) +c010479e: e8 5a ff ff ff call c01046fd + } +} +c01047a3: 90 nop +c01047a4: 89 ec mov %ebp,%esp +c01047a6: 5d pop %ebp +c01047a7: c3 ret + +c01047a8 : +// perm: the permission of this Page which is setted in related pte +// return value: always 0 +//note: PT is changed, so the TLB need to be invalidate +//将一个页面插入到页表中。 +int +page_insert(pde_t *pgdir, struct Page *page, uintptr_t la, uint32_t perm) { +c01047a8: 55 push %ebp +c01047a9: 89 e5 mov %esp,%ebp +c01047ab: 83 ec 28 sub $0x28,%esp + //通过 get_pte 函数获取指定虚拟地址 la 对应的页表项指针 ptep。 + pte_t *ptep = get_pte(pgdir, la, 1); +c01047ae: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) +c01047b5: 00 +c01047b6: 8b 45 10 mov 0x10(%ebp),%eax +c01047b9: 89 44 24 04 mov %eax,0x4(%esp) +c01047bd: 8b 45 08 mov 0x8(%ebp),%eax +c01047c0: 89 04 24 mov %eax,(%esp) +c01047c3: e8 9f fd ff ff call c0104567 +c01047c8: 89 45 f4 mov %eax,-0xc(%ebp) + //如果 ptep 为 NULL,表示内存分配失败,返回 -E_NO_MEM。 + if (ptep == NULL) { +c01047cb: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) +c01047cf: 75 0a jne c01047db + return -E_NO_MEM; +c01047d1: b8 fc ff ff ff mov $0xfffffffc,%eax +c01047d6: e9 84 00 00 00 jmp c010485f + } + //调用 page_ref_inc 增加页面的引用计数。 + page_ref_inc(page); +c01047db: 8b 45 0c mov 0xc(%ebp),%eax +c01047de: 89 04 24 mov %eax,(%esp) +c01047e1: e8 f7 f4 ff ff call c0103cdd + //如果页表项已存在且指向当前页面,则减少页面引用计数。 + if (*ptep & PTE_P) { +c01047e6: 8b 45 f4 mov -0xc(%ebp),%eax +c01047e9: 8b 00 mov (%eax),%eax +c01047eb: 83 e0 01 and $0x1,%eax +c01047ee: 85 c0 test %eax,%eax +c01047f0: 74 3e je c0104830 + struct Page *p = pte2page(*ptep); +c01047f2: 8b 45 f4 mov -0xc(%ebp),%eax +c01047f5: 8b 00 mov (%eax),%eax +c01047f7: 89 04 24 mov %eax,(%esp) +c01047fa: e8 6c f4 ff ff call c0103c6b +c01047ff: 89 45 f0 mov %eax,-0x10(%ebp) + if (p == page) { +c0104802: 8b 45 f0 mov -0x10(%ebp),%eax +c0104805: 3b 45 0c cmp 0xc(%ebp),%eax +c0104808: 75 0d jne c0104817 + page_ref_dec(page); +c010480a: 8b 45 0c mov 0xc(%ebp),%eax +c010480d: 89 04 24 mov %eax,(%esp) +c0104810: e8 df f4 ff ff call c0103cf4 +c0104815: eb 19 jmp c0104830 + } + //如果页表项已存在但指向其他页面,则调用 page_remove_pte 移除旧的页表项。 + else { + page_remove_pte(pgdir, la, ptep); +c0104817: 8b 45 f4 mov -0xc(%ebp),%eax +c010481a: 89 44 24 08 mov %eax,0x8(%esp) +c010481e: 8b 45 10 mov 0x10(%ebp),%eax +c0104821: 89 44 24 04 mov %eax,0x4(%esp) +c0104825: 8b 45 08 mov 0x8(%ebp),%eax +c0104828: 89 04 24 mov %eax,(%esp) +c010482b: e8 cd fe ff ff call c01046fd + } + } + *ptep = page2pa(page) | PTE_P | perm; +c0104830: 8b 45 0c mov 0xc(%ebp),%eax +c0104833: 89 04 24 mov %eax,(%esp) +c0104836: e8 71 f3 ff ff call c0103bac +c010483b: 0b 45 14 or 0x14(%ebp),%eax +c010483e: 83 c8 01 or $0x1,%eax +c0104841: 89 c2 mov %eax,%edx +c0104843: 8b 45 f4 mov -0xc(%ebp),%eax +c0104846: 89 10 mov %edx,(%eax) + tlb_invalidate(pgdir, la);//刷新 TLB +c0104848: 8b 45 10 mov 0x10(%ebp),%eax +c010484b: 89 44 24 04 mov %eax,0x4(%esp) +c010484f: 8b 45 08 mov 0x8(%ebp),%eax +c0104852: 89 04 24 mov %eax,(%esp) +c0104855: e8 09 00 00 00 call c0104863 + return 0; +c010485a: b8 00 00 00 00 mov $0x0,%eax +} +c010485f: 89 ec mov %ebp,%esp +c0104861: 5d pop %ebp +c0104862: c3 ret + +c0104863 : + +// invalidate a TLB entry, but only if the page tables being +// edited are the ones currently in use by the processor. +//无效化指定地址的TLB条目 +void +tlb_invalidate(pde_t *pgdir, uintptr_t la) { +c0104863: 55 push %ebp +c0104864: 89 e5 mov %esp,%ebp +c0104866: 83 ec 28 sub $0x28,%esp +} + +static inline uintptr_t +rcr3(void) { + uintptr_t cr3; + asm volatile ("mov %%cr3, %0" : "=r" (cr3) :: "memory"); +c0104869: 0f 20 d8 mov %cr3,%eax +c010486c: 89 45 f0 mov %eax,-0x10(%ebp) + return cr3; +c010486f: 8b 55 f0 mov -0x10(%ebp),%edx + //检查当前页目录地址是否与传入的页目录地址相同。 + if (rcr3() == PADDR(pgdir)) { +c0104872: 8b 45 08 mov 0x8(%ebp),%eax +c0104875: 89 45 f4 mov %eax,-0xc(%ebp) +c0104878: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) +c010487f: 77 23 ja c01048a4 +c0104881: 8b 45 f4 mov -0xc(%ebp),%eax +c0104884: 89 44 24 0c mov %eax,0xc(%esp) +c0104888: c7 44 24 08 28 6c 10 movl $0xc0106c28,0x8(%esp) +c010488f: c0 +c0104890: c7 44 24 04 47 02 00 movl $0x247,0x4(%esp) +c0104897: 00 +c0104898: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010489f: e8 8f c3 ff ff call c0100c33 <__panic> +c01048a4: 8b 45 f4 mov -0xc(%ebp),%eax +c01048a7: 05 00 00 00 40 add $0x40000000,%eax +c01048ac: 39 d0 cmp %edx,%eax +c01048ae: 75 0d jne c01048bd + //如果相同,则调用 invlpg 函数无效化指定线性地址的TLB条目。 + invlpg((void *)la); +c01048b0: 8b 45 0c mov 0xc(%ebp),%eax +c01048b3: 89 45 ec mov %eax,-0x14(%ebp) +} + +static inline void +invlpg(void *addr) { + asm volatile ("invlpg (%0)" :: "r" (addr) : "memory"); +c01048b6: 8b 45 ec mov -0x14(%ebp),%eax +c01048b9: 0f 01 38 invlpg (%eax) +} +c01048bc: 90 nop + } +} +c01048bd: 90 nop +c01048be: 89 ec mov %ebp,%esp +c01048c0: 5d pop %ebp +c01048c1: c3 ret + +c01048c2 : + +static void +check_alloc_page(void) { +c01048c2: 55 push %ebp +c01048c3: 89 e5 mov %esp,%ebp +c01048c5: 83 ec 18 sub $0x18,%esp + //调用内存管理器的 check 方法,用于检查内存分配是否正常。 + pmm_manager->check(); +c01048c8: a1 0c cf 11 c0 mov 0xc011cf0c,%eax +c01048cd: 8b 40 18 mov 0x18(%eax),%eax +c01048d0: ff d0 call *%eax + cprintf("check_alloc_page() succeeded!\n"); +c01048d2: c7 04 24 ac 6c 10 c0 movl $0xc0106cac,(%esp) +c01048d9: e8 88 ba ff ff call c0100366 +} +c01048de: 90 nop +c01048df: 89 ec mov %ebp,%esp +c01048e1: 5d pop %ebp +c01048e2: c3 ret + +c01048e3 : +//用于验证页目录和页表的正确性。 +static void +check_pgdir(void) { +c01048e3: 55 push %ebp +c01048e4: 89 e5 mov %esp,%ebp +c01048e6: 83 ec 38 sub $0x38,%esp + //确保内存页面数量在合理范围内 + assert(npage <= KMEMSIZE / PGSIZE); +c01048e9: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c01048ee: 3d 00 80 03 00 cmp $0x38000,%eax +c01048f3: 76 24 jbe c0104919 +c01048f5: c7 44 24 0c cb 6c 10 movl $0xc0106ccb,0xc(%esp) +c01048fc: c0 +c01048fd: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104904: c0 +c0104905: c7 44 24 04 57 02 00 movl $0x257,0x4(%esp) +c010490c: 00 +c010490d: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104914: e8 1a c3 ff ff call c0100c33 <__panic> + //确保页目录不为空且对齐, + assert(boot_pgdir != NULL && (uint32_t)PGOFF(boot_pgdir) == 0); +c0104919: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c010491e: 85 c0 test %eax,%eax +c0104920: 74 0e je c0104930 +c0104922: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104927: 25 ff 0f 00 00 and $0xfff,%eax +c010492c: 85 c0 test %eax,%eax +c010492e: 74 24 je c0104954 +c0104930: c7 44 24 0c e8 6c 10 movl $0xc0106ce8,0xc(%esp) +c0104937: c0 +c0104938: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c010493f: c0 +c0104940: c7 44 24 04 59 02 00 movl $0x259,0x4(%esp) +c0104947: 00 +c0104948: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010494f: e8 df c2 ff ff call c0100c33 <__panic> + //确保虚拟地址 0x0 没有映射任何页面 + assert(get_page(boot_pgdir, 0x0, NULL) == NULL); +c0104954: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104959: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104960: 00 +c0104961: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0104968: 00 +c0104969: 89 04 24 mov %eax,(%esp) +c010496c: e8 31 fd ff ff call c01046a2 +c0104971: 85 c0 test %eax,%eax +c0104973: 74 24 je c0104999 +c0104975: c7 44 24 0c 20 6d 10 movl $0xc0106d20,0xc(%esp) +c010497c: c0 +c010497d: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104984: c0 +c0104985: c7 44 24 04 5b 02 00 movl $0x25b,0x4(%esp) +c010498c: 00 +c010498d: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104994: e8 9a c2 ff ff call c0100c33 <__panic> + + //定义两个页面指针 p1 和 p2 + struct Page *p1, *p2; + //分配一个页面 p1 + p1 = alloc_page(); +c0104999: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c01049a0: e8 30 f5 ff ff call c0103ed5 +c01049a5: 89 45 f4 mov %eax,-0xc(%ebp) + //将 p1 插入到虚拟地址 0x0 + assert(page_insert(boot_pgdir, p1, 0x0, 0) == 0); +c01049a8: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01049ad: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c01049b4: 00 +c01049b5: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c01049bc: 00 +c01049bd: 8b 55 f4 mov -0xc(%ebp),%edx +c01049c0: 89 54 24 04 mov %edx,0x4(%esp) +c01049c4: 89 04 24 mov %eax,(%esp) +c01049c7: e8 dc fd ff ff call c01047a8 +c01049cc: 85 c0 test %eax,%eax +c01049ce: 74 24 je c01049f4 +c01049d0: c7 44 24 0c 48 6d 10 movl $0xc0106d48,0xc(%esp) +c01049d7: c0 +c01049d8: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c01049df: c0 +c01049e0: c7 44 24 04 62 02 00 movl $0x262,0x4(%esp) +c01049e7: 00 +c01049e8: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01049ef: e8 3f c2 ff ff call c0100c33 <__panic> + + // 获取虚拟地址 0x0 对应的页表项指针 + pte_t *ptep; + assert((ptep = get_pte(boot_pgdir, 0x0, 0)) != NULL); +c01049f4: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01049f9: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104a00: 00 +c0104a01: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0104a08: 00 +c0104a09: 89 04 24 mov %eax,(%esp) +c0104a0c: e8 56 fb ff ff call c0104567 +c0104a11: 89 45 f0 mov %eax,-0x10(%ebp) +c0104a14: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0104a18: 75 24 jne c0104a3e +c0104a1a: c7 44 24 0c 74 6d 10 movl $0xc0106d74,0xc(%esp) +c0104a21: c0 +c0104a22: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104a29: c0 +c0104a2a: c7 44 24 04 66 02 00 movl $0x266,0x4(%esp) +c0104a31: 00 +c0104a32: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104a39: e8 f5 c1 ff ff call c0100c33 <__panic> + // 验证页表项对应的页面是 p1 + assert(pte2page(*ptep) == p1); +c0104a3e: 8b 45 f0 mov -0x10(%ebp),%eax +c0104a41: 8b 00 mov (%eax),%eax +c0104a43: 89 04 24 mov %eax,(%esp) +c0104a46: e8 20 f2 ff ff call c0103c6b +c0104a4b: 39 45 f4 cmp %eax,-0xc(%ebp) +c0104a4e: 74 24 je c0104a74 +c0104a50: c7 44 24 0c a1 6d 10 movl $0xc0106da1,0xc(%esp) +c0104a57: c0 +c0104a58: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104a5f: c0 +c0104a60: c7 44 24 04 68 02 00 movl $0x268,0x4(%esp) +c0104a67: 00 +c0104a68: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104a6f: e8 bf c1 ff ff call c0100c33 <__panic> + // 验证 p1 的引用计数为 1 + assert(page_ref(p1) == 1); +c0104a74: 8b 45 f4 mov -0xc(%ebp),%eax +c0104a77: 89 04 24 mov %eax,(%esp) +c0104a7a: e8 46 f2 ff ff call c0103cc5 +c0104a7f: 83 f8 01 cmp $0x1,%eax +c0104a82: 74 24 je c0104aa8 +c0104a84: c7 44 24 0c b7 6d 10 movl $0xc0106db7,0xc(%esp) +c0104a8b: c0 +c0104a8c: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104a93: c0 +c0104a94: c7 44 24 04 6a 02 00 movl $0x26a,0x4(%esp) +c0104a9b: 00 +c0104a9c: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104aa3: e8 8b c1 ff ff call c0100c33 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + ptep = &((pte_t *)KADDR(PDE_ADDR(boot_pgdir[0])))[1]; +c0104aa8: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104aad: 8b 00 mov (%eax),%eax +c0104aaf: 25 00 f0 ff ff and $0xfffff000,%eax +c0104ab4: 89 45 ec mov %eax,-0x14(%ebp) +c0104ab7: 8b 45 ec mov -0x14(%ebp),%eax +c0104aba: c1 e8 0c shr $0xc,%eax +c0104abd: 89 45 e8 mov %eax,-0x18(%ebp) +c0104ac0: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c0104ac5: 39 45 e8 cmp %eax,-0x18(%ebp) +c0104ac8: 72 23 jb c0104aed +c0104aca: 8b 45 ec mov -0x14(%ebp),%eax +c0104acd: 89 44 24 0c mov %eax,0xc(%esp) +c0104ad1: c7 44 24 08 84 6b 10 movl $0xc0106b84,0x8(%esp) +c0104ad8: c0 +c0104ad9: c7 44 24 04 6c 02 00 movl $0x26c,0x4(%esp) +c0104ae0: 00 +c0104ae1: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104ae8: e8 46 c1 ff ff call c0100c33 <__panic> +c0104aed: 8b 45 ec mov -0x14(%ebp),%eax +c0104af0: 2d 00 00 00 40 sub $0x40000000,%eax +c0104af5: 83 c0 04 add $0x4,%eax +c0104af8: 89 45 f0 mov %eax,-0x10(%ebp) + assert(get_pte(boot_pgdir, PGSIZE, 0) == ptep); +c0104afb: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104b00: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104b07: 00 +c0104b08: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0104b0f: 00 +c0104b10: 89 04 24 mov %eax,(%esp) +c0104b13: e8 4f fa ff ff call c0104567 +c0104b18: 39 45 f0 cmp %eax,-0x10(%ebp) +c0104b1b: 74 24 je c0104b41 +c0104b1d: c7 44 24 0c cc 6d 10 movl $0xc0106dcc,0xc(%esp) +c0104b24: c0 +c0104b25: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104b2c: c0 +c0104b2d: c7 44 24 04 6d 02 00 movl $0x26d,0x4(%esp) +c0104b34: 00 +c0104b35: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104b3c: e8 f2 c0 ff ff call c0100c33 <__panic> + // 分配一个页面 p2 + p2 = alloc_page(); +c0104b41: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c0104b48: e8 88 f3 ff ff call c0103ed5 +c0104b4d: 89 45 e4 mov %eax,-0x1c(%ebp) + // 将 p2 插入到虚拟地址 PGSIZE,并设置用户和写权限 + assert(page_insert(boot_pgdir, p2, PGSIZE, PTE_U | PTE_W) == 0); +c0104b50: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104b55: c7 44 24 0c 06 00 00 movl $0x6,0xc(%esp) +c0104b5c: 00 +c0104b5d: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c0104b64: 00 +c0104b65: 8b 55 e4 mov -0x1c(%ebp),%edx +c0104b68: 89 54 24 04 mov %edx,0x4(%esp) +c0104b6c: 89 04 24 mov %eax,(%esp) +c0104b6f: e8 34 fc ff ff call c01047a8 +c0104b74: 85 c0 test %eax,%eax +c0104b76: 74 24 je c0104b9c +c0104b78: c7 44 24 0c f4 6d 10 movl $0xc0106df4,0xc(%esp) +c0104b7f: c0 +c0104b80: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104b87: c0 +c0104b88: c7 44 24 04 71 02 00 movl $0x271,0x4(%esp) +c0104b8f: 00 +c0104b90: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104b97: e8 97 c0 ff ff call c0100c33 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); +c0104b9c: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104ba1: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104ba8: 00 +c0104ba9: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0104bb0: 00 +c0104bb1: 89 04 24 mov %eax,(%esp) +c0104bb4: e8 ae f9 ff ff call c0104567 +c0104bb9: 89 45 f0 mov %eax,-0x10(%ebp) +c0104bbc: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0104bc0: 75 24 jne c0104be6 +c0104bc2: c7 44 24 0c 2c 6e 10 movl $0xc0106e2c,0xc(%esp) +c0104bc9: c0 +c0104bca: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104bd1: c0 +c0104bd2: c7 44 24 04 73 02 00 movl $0x273,0x4(%esp) +c0104bd9: 00 +c0104bda: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104be1: e8 4d c0 ff ff call c0100c33 <__panic> + // 验证页表项设置了用户权限 + assert(*ptep & PTE_U); +c0104be6: 8b 45 f0 mov -0x10(%ebp),%eax +c0104be9: 8b 00 mov (%eax),%eax +c0104beb: 83 e0 04 and $0x4,%eax +c0104bee: 85 c0 test %eax,%eax +c0104bf0: 75 24 jne c0104c16 +c0104bf2: c7 44 24 0c 5c 6e 10 movl $0xc0106e5c,0xc(%esp) +c0104bf9: c0 +c0104bfa: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104c01: c0 +c0104c02: c7 44 24 04 75 02 00 movl $0x275,0x4(%esp) +c0104c09: 00 +c0104c0a: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104c11: e8 1d c0 ff ff call c0100c33 <__panic> + // 验证页表项设置了写权限 + assert(*ptep & PTE_W); +c0104c16: 8b 45 f0 mov -0x10(%ebp),%eax +c0104c19: 8b 00 mov (%eax),%eax +c0104c1b: 83 e0 02 and $0x2,%eax +c0104c1e: 85 c0 test %eax,%eax +c0104c20: 75 24 jne c0104c46 +c0104c22: c7 44 24 0c 6a 6e 10 movl $0xc0106e6a,0xc(%esp) +c0104c29: c0 +c0104c2a: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104c31: c0 +c0104c32: c7 44 24 04 77 02 00 movl $0x277,0x4(%esp) +c0104c39: 00 +c0104c3a: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104c41: e8 ed bf ff ff call c0100c33 <__panic> + // 验证页目录项设置了用户权限 + assert(boot_pgdir[0] & PTE_U); +c0104c46: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104c4b: 8b 00 mov (%eax),%eax +c0104c4d: 83 e0 04 and $0x4,%eax +c0104c50: 85 c0 test %eax,%eax +c0104c52: 75 24 jne c0104c78 +c0104c54: c7 44 24 0c 78 6e 10 movl $0xc0106e78,0xc(%esp) +c0104c5b: c0 +c0104c5c: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104c63: c0 +c0104c64: c7 44 24 04 79 02 00 movl $0x279,0x4(%esp) +c0104c6b: 00 +c0104c6c: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104c73: e8 bb bf ff ff call c0100c33 <__panic> + // 验证 p2 的引用计数为 1 + assert(page_ref(p2) == 1); +c0104c78: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104c7b: 89 04 24 mov %eax,(%esp) +c0104c7e: e8 42 f0 ff ff call c0103cc5 +c0104c83: 83 f8 01 cmp $0x1,%eax +c0104c86: 74 24 je c0104cac +c0104c88: c7 44 24 0c 8e 6e 10 movl $0xc0106e8e,0xc(%esp) +c0104c8f: c0 +c0104c90: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104c97: c0 +c0104c98: c7 44 24 04 7b 02 00 movl $0x27b,0x4(%esp) +c0104c9f: 00 +c0104ca0: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104ca7: e8 87 bf ff ff call c0100c33 <__panic> + + // 将 p1 插入到虚拟地址 PGSIZE,替换掉 p2 + assert(page_insert(boot_pgdir, p1, PGSIZE, 0) == 0); +c0104cac: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104cb1: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) +c0104cb8: 00 +c0104cb9: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) +c0104cc0: 00 +c0104cc1: 8b 55 f4 mov -0xc(%ebp),%edx +c0104cc4: 89 54 24 04 mov %edx,0x4(%esp) +c0104cc8: 89 04 24 mov %eax,(%esp) +c0104ccb: e8 d8 fa ff ff call c01047a8 +c0104cd0: 85 c0 test %eax,%eax +c0104cd2: 74 24 je c0104cf8 +c0104cd4: c7 44 24 0c a0 6e 10 movl $0xc0106ea0,0xc(%esp) +c0104cdb: c0 +c0104cdc: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104ce3: c0 +c0104ce4: c7 44 24 04 7e 02 00 movl $0x27e,0x4(%esp) +c0104ceb: 00 +c0104cec: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104cf3: e8 3b bf ff ff call c0100c33 <__panic> + // 验证 p1 的引用计数增加到 2 + assert(page_ref(p1) == 2); +c0104cf8: 8b 45 f4 mov -0xc(%ebp),%eax +c0104cfb: 89 04 24 mov %eax,(%esp) +c0104cfe: e8 c2 ef ff ff call c0103cc5 +c0104d03: 83 f8 02 cmp $0x2,%eax +c0104d06: 74 24 je c0104d2c +c0104d08: c7 44 24 0c cc 6e 10 movl $0xc0106ecc,0xc(%esp) +c0104d0f: c0 +c0104d10: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104d17: c0 +c0104d18: c7 44 24 04 80 02 00 movl $0x280,0x4(%esp) +c0104d1f: 00 +c0104d20: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104d27: e8 07 bf ff ff call c0100c33 <__panic> + // 验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); +c0104d2c: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104d2f: 89 04 24 mov %eax,(%esp) +c0104d32: e8 8e ef ff ff call c0103cc5 +c0104d37: 85 c0 test %eax,%eax +c0104d39: 74 24 je c0104d5f +c0104d3b: c7 44 24 0c de 6e 10 movl $0xc0106ede,0xc(%esp) +c0104d42: c0 +c0104d43: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104d4a: c0 +c0104d4b: c7 44 24 04 82 02 00 movl $0x282,0x4(%esp) +c0104d52: 00 +c0104d53: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104d5a: e8 d4 be ff ff call c0100c33 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); +c0104d5f: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104d64: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104d6b: 00 +c0104d6c: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0104d73: 00 +c0104d74: 89 04 24 mov %eax,(%esp) +c0104d77: e8 eb f7 ff ff call c0104567 +c0104d7c: 89 45 f0 mov %eax,-0x10(%ebp) +c0104d7f: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c0104d83: 75 24 jne c0104da9 +c0104d85: c7 44 24 0c 2c 6e 10 movl $0xc0106e2c,0xc(%esp) +c0104d8c: c0 +c0104d8d: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104d94: c0 +c0104d95: c7 44 24 04 84 02 00 movl $0x284,0x4(%esp) +c0104d9c: 00 +c0104d9d: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104da4: e8 8a be ff ff call c0100c33 <__panic> + // 验证页表项对应的页面是 p1 + assert(pte2page(*ptep) == p1); +c0104da9: 8b 45 f0 mov -0x10(%ebp),%eax +c0104dac: 8b 00 mov (%eax),%eax +c0104dae: 89 04 24 mov %eax,(%esp) +c0104db1: e8 b5 ee ff ff call c0103c6b +c0104db6: 39 45 f4 cmp %eax,-0xc(%ebp) +c0104db9: 74 24 je c0104ddf +c0104dbb: c7 44 24 0c a1 6d 10 movl $0xc0106da1,0xc(%esp) +c0104dc2: c0 +c0104dc3: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104dca: c0 +c0104dcb: c7 44 24 04 86 02 00 movl $0x286,0x4(%esp) +c0104dd2: 00 +c0104dd3: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104dda: e8 54 be ff ff call c0100c33 <__panic> + // 验证页表项没有设置用户权限 + assert((*ptep & PTE_U) == 0); +c0104ddf: 8b 45 f0 mov -0x10(%ebp),%eax +c0104de2: 8b 00 mov (%eax),%eax +c0104de4: 83 e0 04 and $0x4,%eax +c0104de7: 85 c0 test %eax,%eax +c0104de9: 74 24 je c0104e0f +c0104deb: c7 44 24 0c f0 6e 10 movl $0xc0106ef0,0xc(%esp) +c0104df2: c0 +c0104df3: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104dfa: c0 +c0104dfb: c7 44 24 04 88 02 00 movl $0x288,0x4(%esp) +c0104e02: 00 +c0104e03: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104e0a: e8 24 be ff ff call c0100c33 <__panic> + + //移除虚拟地址 0x0 的映射, + page_remove(boot_pgdir, 0x0); +c0104e0f: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104e14: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) +c0104e1b: 00 +c0104e1c: 89 04 24 mov %eax,(%esp) +c0104e1f: e8 3d f9 ff ff call c0104761 + //验证 p1 的引用计数减少到 1。 + assert(page_ref(p1) == 1); +c0104e24: 8b 45 f4 mov -0xc(%ebp),%eax +c0104e27: 89 04 24 mov %eax,(%esp) +c0104e2a: e8 96 ee ff ff call c0103cc5 +c0104e2f: 83 f8 01 cmp $0x1,%eax +c0104e32: 74 24 je c0104e58 +c0104e34: c7 44 24 0c b7 6d 10 movl $0xc0106db7,0xc(%esp) +c0104e3b: c0 +c0104e3c: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104e43: c0 +c0104e44: c7 44 24 04 8d 02 00 movl $0x28d,0x4(%esp) +c0104e4b: 00 +c0104e4c: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104e53: e8 db bd ff ff call c0100c33 <__panic> + //验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); +c0104e58: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104e5b: 89 04 24 mov %eax,(%esp) +c0104e5e: e8 62 ee ff ff call c0103cc5 +c0104e63: 85 c0 test %eax,%eax +c0104e65: 74 24 je c0104e8b +c0104e67: c7 44 24 0c de 6e 10 movl $0xc0106ede,0xc(%esp) +c0104e6e: c0 +c0104e6f: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104e76: c0 +c0104e77: c7 44 24 04 8f 02 00 movl $0x28f,0x4(%esp) +c0104e7e: 00 +c0104e7f: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104e86: e8 a8 bd ff ff call c0100c33 <__panic> + + //移除虚拟地址 PGSIZE 的映射, + page_remove(boot_pgdir, PGSIZE); +c0104e8b: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104e90: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) +c0104e97: 00 +c0104e98: 89 04 24 mov %eax,(%esp) +c0104e9b: e8 c1 f8 ff ff call c0104761 + //验证 p1 的引用计数减少到 0 + assert(page_ref(p1) == 0); +c0104ea0: 8b 45 f4 mov -0xc(%ebp),%eax +c0104ea3: 89 04 24 mov %eax,(%esp) +c0104ea6: e8 1a ee ff ff call c0103cc5 +c0104eab: 85 c0 test %eax,%eax +c0104ead: 74 24 je c0104ed3 +c0104eaf: c7 44 24 0c 05 6f 10 movl $0xc0106f05,0xc(%esp) +c0104eb6: c0 +c0104eb7: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104ebe: c0 +c0104ebf: c7 44 24 04 94 02 00 movl $0x294,0x4(%esp) +c0104ec6: 00 +c0104ec7: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104ece: e8 60 bd ff ff call c0100c33 <__panic> + //验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); +c0104ed3: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104ed6: 89 04 24 mov %eax,(%esp) +c0104ed9: e8 e7 ed ff ff call c0103cc5 +c0104ede: 85 c0 test %eax,%eax +c0104ee0: 74 24 je c0104f06 +c0104ee2: c7 44 24 0c de 6e 10 movl $0xc0106ede,0xc(%esp) +c0104ee9: c0 +c0104eea: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104ef1: c0 +c0104ef2: c7 44 24 04 96 02 00 movl $0x296,0x4(%esp) +c0104ef9: 00 +c0104efa: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104f01: e8 2d bd ff ff call c0100c33 <__panic> + + //验证页目录的第一页表的引用计数为 1。 + assert(page_ref(pde2page(boot_pgdir[0])) == 1); +c0104f06: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104f0b: 8b 00 mov (%eax),%eax +c0104f0d: 89 04 24 mov %eax,(%esp) +c0104f10: e8 96 ed ff ff call c0103cab +c0104f15: 89 04 24 mov %eax,(%esp) +c0104f18: e8 a8 ed ff ff call c0103cc5 +c0104f1d: 83 f8 01 cmp $0x1,%eax +c0104f20: 74 24 je c0104f46 +c0104f22: c7 44 24 0c 18 6f 10 movl $0xc0106f18,0xc(%esp) +c0104f29: c0 +c0104f2a: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0104f31: c0 +c0104f32: c7 44 24 04 99 02 00 movl $0x299,0x4(%esp) +c0104f39: 00 +c0104f3a: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104f41: e8 ed bc ff ff call c0100c33 <__panic> + //释放页目录的第一页表 + free_page(pde2page(boot_pgdir[0])); +c0104f46: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104f4b: 8b 00 mov (%eax),%eax +c0104f4d: 89 04 24 mov %eax,(%esp) +c0104f50: e8 56 ed ff ff call c0103cab +c0104f55: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c0104f5c: 00 +c0104f5d: 89 04 24 mov %eax,(%esp) +c0104f60: e8 aa ef ff ff call c0103f0f + //清空页目录的第一页表 + boot_pgdir[0] = 0; +c0104f65: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104f6a: c7 00 00 00 00 00 movl $0x0,(%eax) + + cprintf("check_pgdir() succeeded!\n"); +c0104f70: c7 04 24 3f 6f 10 c0 movl $0xc0106f3f,(%esp) +c0104f77: e8 ea b3 ff ff call c0100366 +} +c0104f7c: 90 nop +c0104f7d: 89 ec mov %ebp,%esp +c0104f7f: 5d pop %ebp +c0104f80: c3 ret + +c0104f81 : + +//检查内核页表 boot_pgdir 的正确性 +static void +check_boot_pgdir(void) { +c0104f81: 55 push %ebp +c0104f82: 89 e5 mov %esp,%ebp +c0104f84: 83 ec 38 sub $0x38,%esp + pte_t *ptep;// 定义一个指向页表项的指针 + int i; + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 +c0104f87: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) +c0104f8e: e9 ca 00 00 00 jmp c010505d + // 获取第 i 个页面的页表项,并确保其不为空 + assert((ptep = get_pte(boot_pgdir, (uintptr_t)KADDR(i), 0)) != NULL); +c0104f93: 8b 45 f4 mov -0xc(%ebp),%eax +c0104f96: 89 45 e4 mov %eax,-0x1c(%ebp) +c0104f99: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104f9c: c1 e8 0c shr $0xc,%eax +c0104f9f: 89 45 e0 mov %eax,-0x20(%ebp) +c0104fa2: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c0104fa7: 39 45 e0 cmp %eax,-0x20(%ebp) +c0104faa: 72 23 jb c0104fcf +c0104fac: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104faf: 89 44 24 0c mov %eax,0xc(%esp) +c0104fb3: c7 44 24 08 84 6b 10 movl $0xc0106b84,0x8(%esp) +c0104fba: c0 +c0104fbb: c7 44 24 04 a9 02 00 movl $0x2a9,0x4(%esp) +c0104fc2: 00 +c0104fc3: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0104fca: e8 64 bc ff ff call c0100c33 <__panic> +c0104fcf: 8b 45 e4 mov -0x1c(%ebp),%eax +c0104fd2: 2d 00 00 00 40 sub $0x40000000,%eax +c0104fd7: 89 c2 mov %eax,%edx +c0104fd9: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0104fde: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) +c0104fe5: 00 +c0104fe6: 89 54 24 04 mov %edx,0x4(%esp) +c0104fea: 89 04 24 mov %eax,(%esp) +c0104fed: e8 75 f5 ff ff call c0104567 +c0104ff2: 89 45 dc mov %eax,-0x24(%ebp) +c0104ff5: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c0104ff9: 75 24 jne c010501f +c0104ffb: c7 44 24 0c 5c 6f 10 movl $0xc0106f5c,0xc(%esp) +c0105002: c0 +c0105003: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c010500a: c0 +c010500b: c7 44 24 04 a9 02 00 movl $0x2a9,0x4(%esp) +c0105012: 00 +c0105013: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010501a: e8 14 bc ff ff call c0100c33 <__panic> + // 验证页表项的物理地址是否正确 + assert(PTE_ADDR(*ptep) == i); +c010501f: 8b 45 dc mov -0x24(%ebp),%eax +c0105022: 8b 00 mov (%eax),%eax +c0105024: 25 00 f0 ff ff and $0xfffff000,%eax +c0105029: 89 c2 mov %eax,%edx +c010502b: 8b 45 f4 mov -0xc(%ebp),%eax +c010502e: 39 c2 cmp %eax,%edx +c0105030: 74 24 je c0105056 +c0105032: c7 44 24 0c 99 6f 10 movl $0xc0106f99,0xc(%esp) +c0105039: c0 +c010503a: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0105041: c0 +c0105042: c7 44 24 04 ab 02 00 movl $0x2ab,0x4(%esp) +c0105049: 00 +c010504a: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0105051: e8 dd bb ff ff call c0100c33 <__panic> + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 +c0105056: 81 45 f4 00 10 00 00 addl $0x1000,-0xc(%ebp) +c010505d: 8b 55 f4 mov -0xc(%ebp),%edx +c0105060: a1 04 cf 11 c0 mov 0xc011cf04,%eax +c0105065: 39 c2 cmp %eax,%edx +c0105067: 0f 82 26 ff ff ff jb c0104f93 + } + // 验证页目录项的物理地址是否正确 + assert(PDE_ADDR(boot_pgdir[PDX(VPT)]) == PADDR(boot_pgdir)); +c010506d: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0105072: 05 ac 0f 00 00 add $0xfac,%eax +c0105077: 8b 00 mov (%eax),%eax +c0105079: 25 00 f0 ff ff and $0xfffff000,%eax +c010507e: 89 c2 mov %eax,%edx +c0105080: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0105085: 89 45 f0 mov %eax,-0x10(%ebp) +c0105088: 81 7d f0 ff ff ff bf cmpl $0xbfffffff,-0x10(%ebp) +c010508f: 77 23 ja c01050b4 +c0105091: 8b 45 f0 mov -0x10(%ebp),%eax +c0105094: 89 44 24 0c mov %eax,0xc(%esp) +c0105098: c7 44 24 08 28 6c 10 movl $0xc0106c28,0x8(%esp) +c010509f: c0 +c01050a0: c7 44 24 04 ae 02 00 movl $0x2ae,0x4(%esp) +c01050a7: 00 +c01050a8: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01050af: e8 7f bb ff ff call c0100c33 <__panic> +c01050b4: 8b 45 f0 mov -0x10(%ebp),%eax +c01050b7: 05 00 00 00 40 add $0x40000000,%eax +c01050bc: 39 d0 cmp %edx,%eax +c01050be: 74 24 je c01050e4 +c01050c0: c7 44 24 0c b0 6f 10 movl $0xc0106fb0,0xc(%esp) +c01050c7: c0 +c01050c8: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c01050cf: c0 +c01050d0: c7 44 24 04 ae 02 00 movl $0x2ae,0x4(%esp) +c01050d7: 00 +c01050d8: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01050df: e8 4f bb ff ff call c0100c33 <__panic> + + assert(boot_pgdir[0] == 0);// 确保页目录的第一个项为0 +c01050e4: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01050e9: 8b 00 mov (%eax),%eax +c01050eb: 85 c0 test %eax,%eax +c01050ed: 74 24 je c0105113 +c01050ef: c7 44 24 0c e4 6f 10 movl $0xc0106fe4,0xc(%esp) +c01050f6: c0 +c01050f7: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c01050fe: c0 +c01050ff: c7 44 24 04 b0 02 00 movl $0x2b0,0x4(%esp) +c0105106: 00 +c0105107: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010510e: e8 20 bb ff ff call c0100c33 <__panic> + + struct Page *p;// 定义一个指向页面的指针 + p = alloc_page();// 分配一个页面 +c0105113: c7 04 24 01 00 00 00 movl $0x1,(%esp) +c010511a: e8 b6 ed ff ff call c0103ed5 +c010511f: 89 45 ec mov %eax,-0x14(%ebp) + // 将页面插入到虚拟地址 0x100,并确保操作成功 + assert(page_insert(boot_pgdir, p, 0x100, PTE_W) == 0); +c0105122: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c0105127: c7 44 24 0c 02 00 00 movl $0x2,0xc(%esp) +c010512e: 00 +c010512f: c7 44 24 08 00 01 00 movl $0x100,0x8(%esp) +c0105136: 00 +c0105137: 8b 55 ec mov -0x14(%ebp),%edx +c010513a: 89 54 24 04 mov %edx,0x4(%esp) +c010513e: 89 04 24 mov %eax,(%esp) +c0105141: e8 62 f6 ff ff call c01047a8 +c0105146: 85 c0 test %eax,%eax +c0105148: 74 24 je c010516e +c010514a: c7 44 24 0c f8 6f 10 movl $0xc0106ff8,0xc(%esp) +c0105151: c0 +c0105152: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0105159: c0 +c010515a: c7 44 24 04 b5 02 00 movl $0x2b5,0x4(%esp) +c0105161: 00 +c0105162: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0105169: e8 c5 ba ff ff call c0100c33 <__panic> + assert(page_ref(p) == 1);// 验证页面的引用计数为1 +c010516e: 8b 45 ec mov -0x14(%ebp),%eax +c0105171: 89 04 24 mov %eax,(%esp) +c0105174: e8 4c eb ff ff call c0103cc5 +c0105179: 83 f8 01 cmp $0x1,%eax +c010517c: 74 24 je c01051a2 +c010517e: c7 44 24 0c 26 70 10 movl $0xc0107026,0xc(%esp) +c0105185: c0 +c0105186: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c010518d: c0 +c010518e: c7 44 24 04 b6 02 00 movl $0x2b6,0x4(%esp) +c0105195: 00 +c0105196: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010519d: e8 91 ba ff ff call c0100c33 <__panic> + // 将页面插入到虚拟地址 0x100 + PGSIZE,并确保操作成功 + assert(page_insert(boot_pgdir, p, 0x100 + PGSIZE, PTE_W) == 0); +c01051a2: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01051a7: c7 44 24 0c 02 00 00 movl $0x2,0xc(%esp) +c01051ae: 00 +c01051af: c7 44 24 08 00 11 00 movl $0x1100,0x8(%esp) +c01051b6: 00 +c01051b7: 8b 55 ec mov -0x14(%ebp),%edx +c01051ba: 89 54 24 04 mov %edx,0x4(%esp) +c01051be: 89 04 24 mov %eax,(%esp) +c01051c1: e8 e2 f5 ff ff call c01047a8 +c01051c6: 85 c0 test %eax,%eax +c01051c8: 74 24 je c01051ee +c01051ca: c7 44 24 0c 38 70 10 movl $0xc0107038,0xc(%esp) +c01051d1: c0 +c01051d2: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c01051d9: c0 +c01051da: c7 44 24 04 b8 02 00 movl $0x2b8,0x4(%esp) +c01051e1: 00 +c01051e2: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01051e9: e8 45 ba ff ff call c0100c33 <__panic> + assert(page_ref(p) == 2);// 验证页面的引用计数为2 +c01051ee: 8b 45 ec mov -0x14(%ebp),%eax +c01051f1: 89 04 24 mov %eax,(%esp) +c01051f4: e8 cc ea ff ff call c0103cc5 +c01051f9: 83 f8 02 cmp $0x2,%eax +c01051fc: 74 24 je c0105222 +c01051fe: c7 44 24 0c 6f 70 10 movl $0xc010706f,0xc(%esp) +c0105205: c0 +c0105206: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c010520d: c0 +c010520e: c7 44 24 04 b9 02 00 movl $0x2b9,0x4(%esp) +c0105215: 00 +c0105216: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c010521d: e8 11 ba ff ff call c0100c33 <__panic> + + const char *str = "ucore: Hello world!!";// 定义一个字符串 +c0105222: c7 45 e8 80 70 10 c0 movl $0xc0107080,-0x18(%ebp) + strcpy((void *)0x100, str);// 将字符串复制到虚拟地址 0x100 +c0105229: 8b 45 e8 mov -0x18(%ebp),%eax +c010522c: 89 44 24 04 mov %eax,0x4(%esp) +c0105230: c7 04 24 00 01 00 00 movl $0x100,(%esp) +c0105237: e8 fc 09 00 00 call c0105c38 + // 验证两个映射地址的数据是否一致 + assert(strcmp((void *)0x100, (void *)(0x100 + PGSIZE)) == 0); +c010523c: c7 44 24 04 00 11 00 movl $0x1100,0x4(%esp) +c0105243: 00 +c0105244: c7 04 24 00 01 00 00 movl $0x100,(%esp) +c010524b: e8 60 0a 00 00 call c0105cb0 +c0105250: 85 c0 test %eax,%eax +c0105252: 74 24 je c0105278 +c0105254: c7 44 24 0c 98 70 10 movl $0xc0107098,0xc(%esp) +c010525b: c0 +c010525c: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c0105263: c0 +c0105264: c7 44 24 04 be 02 00 movl $0x2be,0x4(%esp) +c010526b: 00 +c010526c: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c0105273: e8 bb b9 ff ff call c0100c33 <__panic> + // 在页面的 0x100 偏移处设置字符串结束符 + *(char *)(page2kva(p) + 0x100) = '\0'; +c0105278: 8b 45 ec mov -0x14(%ebp),%eax +c010527b: 89 04 24 mov %eax,(%esp) +c010527e: e8 92 e9 ff ff call c0103c15 +c0105283: 05 00 01 00 00 add $0x100,%eax +c0105288: c6 00 00 movb $0x0,(%eax) + assert(strlen((const char *)0x100) == 0);// 验证字符串长度为0 +c010528b: c7 04 24 00 01 00 00 movl $0x100,(%esp) +c0105292: e8 47 09 00 00 call c0105bde +c0105297: 85 c0 test %eax,%eax +c0105299: 74 24 je c01052bf +c010529b: c7 44 24 0c d0 70 10 movl $0xc01070d0,0xc(%esp) +c01052a2: c0 +c01052a3: c7 44 24 08 71 6c 10 movl $0xc0106c71,0x8(%esp) +c01052aa: c0 +c01052ab: c7 44 24 04 c1 02 00 movl $0x2c1,0x4(%esp) +c01052b2: 00 +c01052b3: c7 04 24 4c 6c 10 c0 movl $0xc0106c4c,(%esp) +c01052ba: e8 74 b9 ff ff call c0100c33 <__panic> + + free_page(p);// 释放页面 p +c01052bf: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01052c6: 00 +c01052c7: 8b 45 ec mov -0x14(%ebp),%eax +c01052ca: 89 04 24 mov %eax,(%esp) +c01052cd: e8 3d ec ff ff call c0103f0f + free_page(pde2page(boot_pgdir[0]));// 释放页目录项对应的页面 +c01052d2: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01052d7: 8b 00 mov (%eax),%eax +c01052d9: 89 04 24 mov %eax,(%esp) +c01052dc: e8 ca e9 ff ff call c0103cab +c01052e1: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) +c01052e8: 00 +c01052e9: 89 04 24 mov %eax,(%esp) +c01052ec: e8 1e ec ff ff call c0103f0f + boot_pgdir[0] = 0;// 将页目录的第一个项设为0 +c01052f1: a1 e0 99 11 c0 mov 0xc01199e0,%eax +c01052f6: c7 00 00 00 00 00 movl $0x0,(%eax) + + cprintf("check_boot_pgdir() succeeded!\n");// 输出成功信息 +c01052fc: c7 04 24 f4 70 10 c0 movl $0xc01070f4,(%esp) +c0105303: e8 5e b0 ff ff call c0100366 +} +c0105308: 90 nop +c0105309: 89 ec mov %ebp,%esp +c010530b: 5d pop %ebp +c010530c: c3 ret + +c010530d : + +//perm2str - use string 'u,r,w,-' to present the permission +static const char * +perm2str(int perm) { +c010530d: 55 push %ebp +c010530e: 89 e5 mov %esp,%ebp + //定义一个静态字符数组 str,长度为4 + static char str[4]; + //如果 perm 与 PTE_U 按位与的结果不为0,则 str[0] 设置为 'u',否则设置为 '-' + str[0] = (perm & PTE_U) ? 'u' : '-'; +c0105310: 8b 45 08 mov 0x8(%ebp),%eax +c0105313: 83 e0 04 and $0x4,%eax +c0105316: 85 c0 test %eax,%eax +c0105318: 74 04 je c010531e +c010531a: b0 75 mov $0x75,%al +c010531c: eb 02 jmp c0105320 +c010531e: b0 2d mov $0x2d,%al +c0105320: a2 88 cf 11 c0 mov %al,0xc011cf88 + //str[1] 始终设置为 'r' + str[1] = 'r'; +c0105325: c6 05 89 cf 11 c0 72 movb $0x72,0xc011cf89 + //如果 perm 与 PTE_W 按位与的结果不为0,则 str[2] 设置为 'w',否则设置为 '-' + str[2] = (perm & PTE_W) ? 'w' : '-'; +c010532c: 8b 45 08 mov 0x8(%ebp),%eax +c010532f: 83 e0 02 and $0x2,%eax +c0105332: 85 c0 test %eax,%eax +c0105334: 74 04 je c010533a +c0105336: b0 77 mov $0x77,%al +c0105338: eb 02 jmp c010533c +c010533a: b0 2d mov $0x2d,%al +c010533c: a2 8a cf 11 c0 mov %al,0xc011cf8a + //str[3] 设置为字符串结束符 \0 + str[3] = '\0'; +c0105341: c6 05 8b cf 11 c0 00 movb $0x0,0xc011cf8b + return str; +c0105348: b8 88 cf 11 c0 mov $0xc011cf88,%eax +} +c010534d: 5d pop %ebp +c010534e: c3 ret + +c010534f : +// left_store: the pointer of the high side of table's next range +// right_store: the pointer of the low side of table's next range +// return value: 0 - not a invalid item range, perm - a valid item range with perm permission +//从页表中获取指定范围内的有效项,并根据权限进行处理。 +static int +get_pgtable_items(size_t left, size_t right, size_t start, uintptr_t *table, size_t *left_store, size_t *right_store) { +c010534f: 55 push %ebp +c0105350: 89 e5 mov %esp,%ebp +c0105352: 83 ec 10 sub $0x10,%esp + if (start >= right) {// 检查起始索引是否超出右边界 +c0105355: 8b 45 10 mov 0x10(%ebp),%eax +c0105358: 3b 45 0c cmp 0xc(%ebp),%eax +c010535b: 72 0d jb c010536a + return 0;// 如果超出右边界,返回0 +c010535d: b8 00 00 00 00 mov $0x0,%eax +c0105362: e9 98 00 00 00 jmp c01053ff + } + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) + start ++;// 索引递增 +c0105367: ff 45 10 incl 0x10(%ebp) + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) +c010536a: 8b 45 10 mov 0x10(%ebp),%eax +c010536d: 3b 45 0c cmp 0xc(%ebp),%eax +c0105370: 73 18 jae c010538a +c0105372: 8b 45 10 mov 0x10(%ebp),%eax +c0105375: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c010537c: 8b 45 14 mov 0x14(%ebp),%eax +c010537f: 01 d0 add %edx,%eax +c0105381: 8b 00 mov (%eax),%eax +c0105383: 83 e0 01 and $0x1,%eax +c0105386: 85 c0 test %eax,%eax +c0105388: 74 dd je c0105367 + } + if (start < right) {// 检查是否找到有效项 +c010538a: 8b 45 10 mov 0x10(%ebp),%eax +c010538d: 3b 45 0c cmp 0xc(%ebp),%eax +c0105390: 73 68 jae c01053fa + if (left_store != NULL) {// 如果left_store不为NULL +c0105392: 83 7d 18 00 cmpl $0x0,0x18(%ebp) +c0105396: 74 08 je c01053a0 + *left_store = start;// 记录左边界索引 +c0105398: 8b 45 18 mov 0x18(%ebp),%eax +c010539b: 8b 55 10 mov 0x10(%ebp),%edx +c010539e: 89 10 mov %edx,(%eax) + } + int perm = (table[start ++] & PTE_USER);// 获取当前项的用户权限位并递增索引 +c01053a0: 8b 45 10 mov 0x10(%ebp),%eax +c01053a3: 8d 50 01 lea 0x1(%eax),%edx +c01053a6: 89 55 10 mov %edx,0x10(%ebp) +c01053a9: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c01053b0: 8b 45 14 mov 0x14(%ebp),%eax +c01053b3: 01 d0 add %edx,%eax +c01053b5: 8b 00 mov (%eax),%eax +c01053b7: 83 e0 07 and $0x7,%eax +c01053ba: 89 45 fc mov %eax,-0x4(%ebp) + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 +c01053bd: eb 03 jmp c01053c2 + start ++;// 索引递增 +c01053bf: ff 45 10 incl 0x10(%ebp) + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 +c01053c2: 8b 45 10 mov 0x10(%ebp),%eax +c01053c5: 3b 45 0c cmp 0xc(%ebp),%eax +c01053c8: 73 1d jae c01053e7 +c01053ca: 8b 45 10 mov 0x10(%ebp),%eax +c01053cd: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx +c01053d4: 8b 45 14 mov 0x14(%ebp),%eax +c01053d7: 01 d0 add %edx,%eax +c01053d9: 8b 00 mov (%eax),%eax +c01053db: 83 e0 07 and $0x7,%eax +c01053de: 89 c2 mov %eax,%edx +c01053e0: 8b 45 fc mov -0x4(%ebp),%eax +c01053e3: 39 c2 cmp %eax,%edx +c01053e5: 74 d8 je c01053bf + } + if (right_store != NULL) {// 如果right_store不为NULL +c01053e7: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) +c01053eb: 74 08 je c01053f5 + *right_store = start;// 记录右边界索引 +c01053ed: 8b 45 1c mov 0x1c(%ebp),%eax +c01053f0: 8b 55 10 mov 0x10(%ebp),%edx +c01053f3: 89 10 mov %edx,(%eax) + } + return perm;// 返回用户权限位 +c01053f5: 8b 45 fc mov -0x4(%ebp),%eax +c01053f8: eb 05 jmp c01053ff + } + return 0;// 如果未找到有效项,返回0 +c01053fa: b8 00 00 00 00 mov $0x0,%eax +} +c01053ff: 89 ec mov %ebp,%esp +c0105401: 5d pop %ebp +c0105402: c3 ret + +c0105403 : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { +c0105403: 55 push %ebp +c0105404: 89 e5 mov %esp,%ebp +c0105406: 57 push %edi +c0105407: 56 push %esi +c0105408: 53 push %ebx +c0105409: 83 ec 4c sub $0x4c,%esp + cprintf("-------------------- BEGIN --------------------\n"); +c010540c: c7 04 24 14 71 10 c0 movl $0xc0107114,(%esp) +c0105413: e8 4e af ff ff call c0100366 + // 定义变量 left, right 和 perm + size_t left, right = 0, perm; +c0105418: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + // 遍历页目录项 + while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { +c010541f: e9 f2 00 00 00 jmp c0105516 + // 打印页目录项的信息 + cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, +c0105424: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105427: 89 04 24 mov %eax,(%esp) +c010542a: e8 de fe ff ff call c010530d + left * PTSIZE, right * PTSIZE, (right - left) * PTSIZE, perm2str(perm)); +c010542f: 8b 55 dc mov -0x24(%ebp),%edx +c0105432: 8b 4d e0 mov -0x20(%ebp),%ecx +c0105435: 29 ca sub %ecx,%edx + cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, +c0105437: 89 d6 mov %edx,%esi +c0105439: c1 e6 16 shl $0x16,%esi +c010543c: 8b 55 dc mov -0x24(%ebp),%edx +c010543f: 89 d3 mov %edx,%ebx +c0105441: c1 e3 16 shl $0x16,%ebx +c0105444: 8b 55 e0 mov -0x20(%ebp),%edx +c0105447: 89 d1 mov %edx,%ecx +c0105449: c1 e1 16 shl $0x16,%ecx +c010544c: 8b 55 dc mov -0x24(%ebp),%edx +c010544f: 8b 7d e0 mov -0x20(%ebp),%edi +c0105452: 29 fa sub %edi,%edx +c0105454: 89 44 24 14 mov %eax,0x14(%esp) +c0105458: 89 74 24 10 mov %esi,0x10(%esp) +c010545c: 89 5c 24 0c mov %ebx,0xc(%esp) +c0105460: 89 4c 24 08 mov %ecx,0x8(%esp) +c0105464: 89 54 24 04 mov %edx,0x4(%esp) +c0105468: c7 04 24 45 71 10 c0 movl $0xc0107145,(%esp) +c010546f: e8 f2 ae ff ff call c0100366 + // 计算页表项的起始和结束索引 + size_t l, r = left * NPTEENTRY; +c0105474: 8b 45 e0 mov -0x20(%ebp),%eax +c0105477: c1 e0 0a shl $0xa,%eax +c010547a: 89 45 d4 mov %eax,-0x2c(%ebp) + // 遍历页表项 + while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { +c010547d: eb 50 jmp c01054cf + // 打印页表项的信息 + cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, +c010547f: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105482: 89 04 24 mov %eax,(%esp) +c0105485: e8 83 fe ff ff call c010530d + l * PGSIZE, r * PGSIZE, (r - l) * PGSIZE, perm2str(perm)); +c010548a: 8b 55 d4 mov -0x2c(%ebp),%edx +c010548d: 8b 4d d8 mov -0x28(%ebp),%ecx +c0105490: 29 ca sub %ecx,%edx + cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, +c0105492: 89 d6 mov %edx,%esi +c0105494: c1 e6 0c shl $0xc,%esi +c0105497: 8b 55 d4 mov -0x2c(%ebp),%edx +c010549a: 89 d3 mov %edx,%ebx +c010549c: c1 e3 0c shl $0xc,%ebx +c010549f: 8b 55 d8 mov -0x28(%ebp),%edx +c01054a2: 89 d1 mov %edx,%ecx +c01054a4: c1 e1 0c shl $0xc,%ecx +c01054a7: 8b 55 d4 mov -0x2c(%ebp),%edx +c01054aa: 8b 7d d8 mov -0x28(%ebp),%edi +c01054ad: 29 fa sub %edi,%edx +c01054af: 89 44 24 14 mov %eax,0x14(%esp) +c01054b3: 89 74 24 10 mov %esi,0x10(%esp) +c01054b7: 89 5c 24 0c mov %ebx,0xc(%esp) +c01054bb: 89 4c 24 08 mov %ecx,0x8(%esp) +c01054bf: 89 54 24 04 mov %edx,0x4(%esp) +c01054c3: c7 04 24 64 71 10 c0 movl $0xc0107164,(%esp) +c01054ca: e8 97 ae ff ff call c0100366 + while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { +c01054cf: be 00 00 c0 fa mov $0xfac00000,%esi +c01054d4: 8b 45 d4 mov -0x2c(%ebp),%eax +c01054d7: 8b 55 dc mov -0x24(%ebp),%edx +c01054da: 89 d3 mov %edx,%ebx +c01054dc: c1 e3 0a shl $0xa,%ebx +c01054df: 8b 55 e0 mov -0x20(%ebp),%edx +c01054e2: 89 d1 mov %edx,%ecx +c01054e4: c1 e1 0a shl $0xa,%ecx +c01054e7: 8d 55 d4 lea -0x2c(%ebp),%edx +c01054ea: 89 54 24 14 mov %edx,0x14(%esp) +c01054ee: 8d 55 d8 lea -0x28(%ebp),%edx +c01054f1: 89 54 24 10 mov %edx,0x10(%esp) +c01054f5: 89 74 24 0c mov %esi,0xc(%esp) +c01054f9: 89 44 24 08 mov %eax,0x8(%esp) +c01054fd: 89 5c 24 04 mov %ebx,0x4(%esp) +c0105501: 89 0c 24 mov %ecx,(%esp) +c0105504: e8 46 fe ff ff call c010534f +c0105509: 89 45 e4 mov %eax,-0x1c(%ebp) +c010550c: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0105510: 0f 85 69 ff ff ff jne c010547f + while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { +c0105516: b9 00 b0 fe fa mov $0xfafeb000,%ecx +c010551b: 8b 45 dc mov -0x24(%ebp),%eax +c010551e: 8d 55 dc lea -0x24(%ebp),%edx +c0105521: 89 54 24 14 mov %edx,0x14(%esp) +c0105525: 8d 55 e0 lea -0x20(%ebp),%edx +c0105528: 89 54 24 10 mov %edx,0x10(%esp) +c010552c: 89 4c 24 0c mov %ecx,0xc(%esp) +c0105530: 89 44 24 08 mov %eax,0x8(%esp) +c0105534: c7 44 24 04 00 04 00 movl $0x400,0x4(%esp) +c010553b: 00 +c010553c: c7 04 24 00 00 00 00 movl $0x0,(%esp) +c0105543: e8 07 fe ff ff call c010534f +c0105548: 89 45 e4 mov %eax,-0x1c(%ebp) +c010554b: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c010554f: 0f 85 cf fe ff ff jne c0105424 + } + } + cprintf("--------------------- END ---------------------\n"); +c0105555: c7 04 24 88 71 10 c0 movl $0xc0107188,(%esp) +c010555c: e8 05 ae ff ff call c0100366 +} +c0105561: 90 nop +c0105562: 83 c4 4c add $0x4c,%esp +c0105565: 5b pop %ebx +c0105566: 5e pop %esi +c0105567: 5f pop %edi +c0105568: 5d pop %ebp +c0105569: c3 ret + +c010556a : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { +c010556a: 55 push %ebp +c010556b: 89 e5 mov %esp,%ebp +c010556d: 83 ec 58 sub $0x58,%esp +c0105570: 8b 45 10 mov 0x10(%ebp),%eax +c0105573: 89 45 d0 mov %eax,-0x30(%ebp) +c0105576: 8b 45 14 mov 0x14(%ebp),%eax +c0105579: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; +c010557c: 8b 45 d0 mov -0x30(%ebp),%eax +c010557f: 8b 55 d4 mov -0x2c(%ebp),%edx +c0105582: 89 45 e8 mov %eax,-0x18(%ebp) +c0105585: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); +c0105588: 8b 45 18 mov 0x18(%ebp),%eax +c010558b: 89 45 e4 mov %eax,-0x1c(%ebp) +c010558e: 8b 45 e8 mov -0x18(%ebp),%eax +c0105591: 8b 55 ec mov -0x14(%ebp),%edx +c0105594: 89 45 e0 mov %eax,-0x20(%ebp) +c0105597: 89 55 f0 mov %edx,-0x10(%ebp) +c010559a: 8b 45 f0 mov -0x10(%ebp),%eax +c010559d: 89 45 f4 mov %eax,-0xc(%ebp) +c01055a0: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) +c01055a4: 74 1c je c01055c2 +c01055a6: 8b 45 f0 mov -0x10(%ebp),%eax +c01055a9: ba 00 00 00 00 mov $0x0,%edx +c01055ae: f7 75 e4 divl -0x1c(%ebp) +c01055b1: 89 55 f4 mov %edx,-0xc(%ebp) +c01055b4: 8b 45 f0 mov -0x10(%ebp),%eax +c01055b7: ba 00 00 00 00 mov $0x0,%edx +c01055bc: f7 75 e4 divl -0x1c(%ebp) +c01055bf: 89 45 f0 mov %eax,-0x10(%ebp) +c01055c2: 8b 45 e0 mov -0x20(%ebp),%eax +c01055c5: 8b 55 f4 mov -0xc(%ebp),%edx +c01055c8: f7 75 e4 divl -0x1c(%ebp) +c01055cb: 89 45 e0 mov %eax,-0x20(%ebp) +c01055ce: 89 55 dc mov %edx,-0x24(%ebp) +c01055d1: 8b 45 e0 mov -0x20(%ebp),%eax +c01055d4: 8b 55 f0 mov -0x10(%ebp),%edx +c01055d7: 89 45 e8 mov %eax,-0x18(%ebp) +c01055da: 89 55 ec mov %edx,-0x14(%ebp) +c01055dd: 8b 45 dc mov -0x24(%ebp),%eax +c01055e0: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { +c01055e3: 8b 45 18 mov 0x18(%ebp),%eax +c01055e6: ba 00 00 00 00 mov $0x0,%edx +c01055eb: 8b 4d d4 mov -0x2c(%ebp),%ecx +c01055ee: 39 45 d0 cmp %eax,-0x30(%ebp) +c01055f1: 19 d1 sbb %edx,%ecx +c01055f3: 72 4c jb c0105641 + printnum(putch, putdat, result, base, width - 1, padc); +c01055f5: 8b 45 1c mov 0x1c(%ebp),%eax +c01055f8: 8d 50 ff lea -0x1(%eax),%edx +c01055fb: 8b 45 20 mov 0x20(%ebp),%eax +c01055fe: 89 44 24 18 mov %eax,0x18(%esp) +c0105602: 89 54 24 14 mov %edx,0x14(%esp) +c0105606: 8b 45 18 mov 0x18(%ebp),%eax +c0105609: 89 44 24 10 mov %eax,0x10(%esp) +c010560d: 8b 45 e8 mov -0x18(%ebp),%eax +c0105610: 8b 55 ec mov -0x14(%ebp),%edx +c0105613: 89 44 24 08 mov %eax,0x8(%esp) +c0105617: 89 54 24 0c mov %edx,0xc(%esp) +c010561b: 8b 45 0c mov 0xc(%ebp),%eax +c010561e: 89 44 24 04 mov %eax,0x4(%esp) +c0105622: 8b 45 08 mov 0x8(%ebp),%eax +c0105625: 89 04 24 mov %eax,(%esp) +c0105628: e8 3d ff ff ff call c010556a +c010562d: eb 1b jmp c010564a + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); +c010562f: 8b 45 0c mov 0xc(%ebp),%eax +c0105632: 89 44 24 04 mov %eax,0x4(%esp) +c0105636: 8b 45 20 mov 0x20(%ebp),%eax +c0105639: 89 04 24 mov %eax,(%esp) +c010563c: 8b 45 08 mov 0x8(%ebp),%eax +c010563f: ff d0 call *%eax + while (-- width > 0) +c0105641: ff 4d 1c decl 0x1c(%ebp) +c0105644: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) +c0105648: 7f e5 jg c010562f + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); +c010564a: 8b 45 d8 mov -0x28(%ebp),%eax +c010564d: 05 3c 72 10 c0 add $0xc010723c,%eax +c0105652: 0f b6 00 movzbl (%eax),%eax +c0105655: 0f be c0 movsbl %al,%eax +c0105658: 8b 55 0c mov 0xc(%ebp),%edx +c010565b: 89 54 24 04 mov %edx,0x4(%esp) +c010565f: 89 04 24 mov %eax,(%esp) +c0105662: 8b 45 08 mov 0x8(%ebp),%eax +c0105665: ff d0 call *%eax +} +c0105667: 90 nop +c0105668: 89 ec mov %ebp,%esp +c010566a: 5d pop %ebp +c010566b: c3 ret + +c010566c : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { +c010566c: 55 push %ebp +c010566d: 89 e5 mov %esp,%ebp + if (lflag >= 2) { +c010566f: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) +c0105673: 7e 14 jle c0105689 + return va_arg(*ap, unsigned long long); +c0105675: 8b 45 08 mov 0x8(%ebp),%eax +c0105678: 8b 00 mov (%eax),%eax +c010567a: 8d 48 08 lea 0x8(%eax),%ecx +c010567d: 8b 55 08 mov 0x8(%ebp),%edx +c0105680: 89 0a mov %ecx,(%edx) +c0105682: 8b 50 04 mov 0x4(%eax),%edx +c0105685: 8b 00 mov (%eax),%eax +c0105687: eb 30 jmp c01056b9 + } + else if (lflag) { +c0105689: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c010568d: 74 16 je c01056a5 + return va_arg(*ap, unsigned long); +c010568f: 8b 45 08 mov 0x8(%ebp),%eax +c0105692: 8b 00 mov (%eax),%eax +c0105694: 8d 48 04 lea 0x4(%eax),%ecx +c0105697: 8b 55 08 mov 0x8(%ebp),%edx +c010569a: 89 0a mov %ecx,(%edx) +c010569c: 8b 00 mov (%eax),%eax +c010569e: ba 00 00 00 00 mov $0x0,%edx +c01056a3: eb 14 jmp c01056b9 + } + else { + return va_arg(*ap, unsigned int); +c01056a5: 8b 45 08 mov 0x8(%ebp),%eax +c01056a8: 8b 00 mov (%eax),%eax +c01056aa: 8d 48 04 lea 0x4(%eax),%ecx +c01056ad: 8b 55 08 mov 0x8(%ebp),%edx +c01056b0: 89 0a mov %ecx,(%edx) +c01056b2: 8b 00 mov (%eax),%eax +c01056b4: ba 00 00 00 00 mov $0x0,%edx + } +} +c01056b9: 5d pop %ebp +c01056ba: c3 ret + +c01056bb : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { +c01056bb: 55 push %ebp +c01056bc: 89 e5 mov %esp,%ebp + if (lflag >= 2) { +c01056be: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) +c01056c2: 7e 14 jle c01056d8 + return va_arg(*ap, long long); +c01056c4: 8b 45 08 mov 0x8(%ebp),%eax +c01056c7: 8b 00 mov (%eax),%eax +c01056c9: 8d 48 08 lea 0x8(%eax),%ecx +c01056cc: 8b 55 08 mov 0x8(%ebp),%edx +c01056cf: 89 0a mov %ecx,(%edx) +c01056d1: 8b 50 04 mov 0x4(%eax),%edx +c01056d4: 8b 00 mov (%eax),%eax +c01056d6: eb 28 jmp c0105700 + } + else if (lflag) { +c01056d8: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c01056dc: 74 12 je c01056f0 + return va_arg(*ap, long); +c01056de: 8b 45 08 mov 0x8(%ebp),%eax +c01056e1: 8b 00 mov (%eax),%eax +c01056e3: 8d 48 04 lea 0x4(%eax),%ecx +c01056e6: 8b 55 08 mov 0x8(%ebp),%edx +c01056e9: 89 0a mov %ecx,(%edx) +c01056eb: 8b 00 mov (%eax),%eax +c01056ed: 99 cltd +c01056ee: eb 10 jmp c0105700 + } + else { + return va_arg(*ap, int); +c01056f0: 8b 45 08 mov 0x8(%ebp),%eax +c01056f3: 8b 00 mov (%eax),%eax +c01056f5: 8d 48 04 lea 0x4(%eax),%ecx +c01056f8: 8b 55 08 mov 0x8(%ebp),%edx +c01056fb: 89 0a mov %ecx,(%edx) +c01056fd: 8b 00 mov (%eax),%eax +c01056ff: 99 cltd + } +} +c0105700: 5d pop %ebp +c0105701: c3 ret + +c0105702 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { +c0105702: 55 push %ebp +c0105703: 89 e5 mov %esp,%ebp +c0105705: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); +c0105708: 8d 45 14 lea 0x14(%ebp),%eax +c010570b: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); +c010570e: 8b 45 f4 mov -0xc(%ebp),%eax +c0105711: 89 44 24 0c mov %eax,0xc(%esp) +c0105715: 8b 45 10 mov 0x10(%ebp),%eax +c0105718: 89 44 24 08 mov %eax,0x8(%esp) +c010571c: 8b 45 0c mov 0xc(%ebp),%eax +c010571f: 89 44 24 04 mov %eax,0x4(%esp) +c0105723: 8b 45 08 mov 0x8(%ebp),%eax +c0105726: 89 04 24 mov %eax,(%esp) +c0105729: e8 05 00 00 00 call c0105733 + va_end(ap); +} +c010572e: 90 nop +c010572f: 89 ec mov %ebp,%esp +c0105731: 5d pop %ebp +c0105732: c3 ret + +c0105733 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { +c0105733: 55 push %ebp +c0105734: 89 e5 mov %esp,%ebp +c0105736: 56 push %esi +c0105737: 53 push %ebx +c0105738: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { +c010573b: eb 17 jmp c0105754 + if (ch == '\0') { +c010573d: 85 db test %ebx,%ebx +c010573f: 0f 84 bf 03 00 00 je c0105b04 + return; + } + putch(ch, putdat); +c0105745: 8b 45 0c mov 0xc(%ebp),%eax +c0105748: 89 44 24 04 mov %eax,0x4(%esp) +c010574c: 89 1c 24 mov %ebx,(%esp) +c010574f: 8b 45 08 mov 0x8(%ebp),%eax +c0105752: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { +c0105754: 8b 45 10 mov 0x10(%ebp),%eax +c0105757: 8d 50 01 lea 0x1(%eax),%edx +c010575a: 89 55 10 mov %edx,0x10(%ebp) +c010575d: 0f b6 00 movzbl (%eax),%eax +c0105760: 0f b6 d8 movzbl %al,%ebx +c0105763: 83 fb 25 cmp $0x25,%ebx +c0105766: 75 d5 jne c010573d + } + + // Process a %-escape sequence + char padc = ' '; +c0105768: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; +c010576c: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) +c0105773: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105776: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; +c0105779: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) +c0105780: 8b 45 dc mov -0x24(%ebp),%eax +c0105783: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { +c0105786: 8b 45 10 mov 0x10(%ebp),%eax +c0105789: 8d 50 01 lea 0x1(%eax),%edx +c010578c: 89 55 10 mov %edx,0x10(%ebp) +c010578f: 0f b6 00 movzbl (%eax),%eax +c0105792: 0f b6 d8 movzbl %al,%ebx +c0105795: 8d 43 dd lea -0x23(%ebx),%eax +c0105798: 83 f8 55 cmp $0x55,%eax +c010579b: 0f 87 37 03 00 00 ja c0105ad8 +c01057a1: 8b 04 85 60 72 10 c0 mov -0x3fef8da0(,%eax,4),%eax +c01057a8: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; +c01057aa: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; +c01057ae: eb d6 jmp c0105786 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; +c01057b0: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; +c01057b4: eb d0 jmp c0105786 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { +c01057b6: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; +c01057bd: 8b 55 e4 mov -0x1c(%ebp),%edx +c01057c0: 89 d0 mov %edx,%eax +c01057c2: c1 e0 02 shl $0x2,%eax +c01057c5: 01 d0 add %edx,%eax +c01057c7: 01 c0 add %eax,%eax +c01057c9: 01 d8 add %ebx,%eax +c01057cb: 83 e8 30 sub $0x30,%eax +c01057ce: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; +c01057d1: 8b 45 10 mov 0x10(%ebp),%eax +c01057d4: 0f b6 00 movzbl (%eax),%eax +c01057d7: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { +c01057da: 83 fb 2f cmp $0x2f,%ebx +c01057dd: 7e 38 jle c0105817 +c01057df: 83 fb 39 cmp $0x39,%ebx +c01057e2: 7f 33 jg c0105817 + for (precision = 0; ; ++ fmt) { +c01057e4: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; +c01057e7: eb d4 jmp c01057bd + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); +c01057e9: 8b 45 14 mov 0x14(%ebp),%eax +c01057ec: 8d 50 04 lea 0x4(%eax),%edx +c01057ef: 89 55 14 mov %edx,0x14(%ebp) +c01057f2: 8b 00 mov (%eax),%eax +c01057f4: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; +c01057f7: eb 1f jmp c0105818 + + case '.': + if (width < 0) +c01057f9: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c01057fd: 79 87 jns c0105786 + width = 0; +c01057ff: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; +c0105806: e9 7b ff ff ff jmp c0105786 + + case '#': + altflag = 1; +c010580b: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; +c0105812: e9 6f ff ff ff jmp c0105786 + goto process_precision; +c0105817: 90 nop + + process_precision: + if (width < 0) +c0105818: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010581c: 0f 89 64 ff ff ff jns c0105786 + width = precision, precision = -1; +c0105822: 8b 45 e4 mov -0x1c(%ebp),%eax +c0105825: 89 45 e8 mov %eax,-0x18(%ebp) +c0105828: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; +c010582f: e9 52 ff ff ff jmp c0105786 + + // long flag (doubled for long long) + case 'l': + lflag ++; +c0105834: ff 45 e0 incl -0x20(%ebp) + goto reswitch; +c0105837: e9 4a ff ff ff jmp c0105786 + + // character + case 'c': + putch(va_arg(ap, int), putdat); +c010583c: 8b 45 14 mov 0x14(%ebp),%eax +c010583f: 8d 50 04 lea 0x4(%eax),%edx +c0105842: 89 55 14 mov %edx,0x14(%ebp) +c0105845: 8b 00 mov (%eax),%eax +c0105847: 8b 55 0c mov 0xc(%ebp),%edx +c010584a: 89 54 24 04 mov %edx,0x4(%esp) +c010584e: 89 04 24 mov %eax,(%esp) +c0105851: 8b 45 08 mov 0x8(%ebp),%eax +c0105854: ff d0 call *%eax + break; +c0105856: e9 a4 02 00 00 jmp c0105aff + + // error message + case 'e': + err = va_arg(ap, int); +c010585b: 8b 45 14 mov 0x14(%ebp),%eax +c010585e: 8d 50 04 lea 0x4(%eax),%edx +c0105861: 89 55 14 mov %edx,0x14(%ebp) +c0105864: 8b 18 mov (%eax),%ebx + if (err < 0) { +c0105866: 85 db test %ebx,%ebx +c0105868: 79 02 jns c010586c + err = -err; +c010586a: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { +c010586c: 83 fb 06 cmp $0x6,%ebx +c010586f: 7f 0b jg c010587c +c0105871: 8b 34 9d 20 72 10 c0 mov -0x3fef8de0(,%ebx,4),%esi +c0105878: 85 f6 test %esi,%esi +c010587a: 75 23 jne c010589f + printfmt(putch, putdat, "error %d", err); +c010587c: 89 5c 24 0c mov %ebx,0xc(%esp) +c0105880: c7 44 24 08 4d 72 10 movl $0xc010724d,0x8(%esp) +c0105887: c0 +c0105888: 8b 45 0c mov 0xc(%ebp),%eax +c010588b: 89 44 24 04 mov %eax,0x4(%esp) +c010588f: 8b 45 08 mov 0x8(%ebp),%eax +c0105892: 89 04 24 mov %eax,(%esp) +c0105895: e8 68 fe ff ff call c0105702 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; +c010589a: e9 60 02 00 00 jmp c0105aff + printfmt(putch, putdat, "%s", p); +c010589f: 89 74 24 0c mov %esi,0xc(%esp) +c01058a3: c7 44 24 08 56 72 10 movl $0xc0107256,0x8(%esp) +c01058aa: c0 +c01058ab: 8b 45 0c mov 0xc(%ebp),%eax +c01058ae: 89 44 24 04 mov %eax,0x4(%esp) +c01058b2: 8b 45 08 mov 0x8(%ebp),%eax +c01058b5: 89 04 24 mov %eax,(%esp) +c01058b8: e8 45 fe ff ff call c0105702 + break; +c01058bd: e9 3d 02 00 00 jmp c0105aff + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { +c01058c2: 8b 45 14 mov 0x14(%ebp),%eax +c01058c5: 8d 50 04 lea 0x4(%eax),%edx +c01058c8: 89 55 14 mov %edx,0x14(%ebp) +c01058cb: 8b 30 mov (%eax),%esi +c01058cd: 85 f6 test %esi,%esi +c01058cf: 75 05 jne c01058d6 + p = "(null)"; +c01058d1: be 59 72 10 c0 mov $0xc0107259,%esi + } + if (width > 0 && padc != '-') { +c01058d6: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c01058da: 7e 76 jle c0105952 +c01058dc: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) +c01058e0: 74 70 je c0105952 + for (width -= strnlen(p, precision); width > 0; width --) { +c01058e2: 8b 45 e4 mov -0x1c(%ebp),%eax +c01058e5: 89 44 24 04 mov %eax,0x4(%esp) +c01058e9: 89 34 24 mov %esi,(%esp) +c01058ec: e8 16 03 00 00 call c0105c07 +c01058f1: 89 c2 mov %eax,%edx +c01058f3: 8b 45 e8 mov -0x18(%ebp),%eax +c01058f6: 29 d0 sub %edx,%eax +c01058f8: 89 45 e8 mov %eax,-0x18(%ebp) +c01058fb: eb 16 jmp c0105913 + putch(padc, putdat); +c01058fd: 0f be 45 db movsbl -0x25(%ebp),%eax +c0105901: 8b 55 0c mov 0xc(%ebp),%edx +c0105904: 89 54 24 04 mov %edx,0x4(%esp) +c0105908: 89 04 24 mov %eax,(%esp) +c010590b: 8b 45 08 mov 0x8(%ebp),%eax +c010590e: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { +c0105910: ff 4d e8 decl -0x18(%ebp) +c0105913: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c0105917: 7f e4 jg c01058fd + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { +c0105919: eb 37 jmp c0105952 + if (altflag && (ch < ' ' || ch > '~')) { +c010591b: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) +c010591f: 74 1f je c0105940 +c0105921: 83 fb 1f cmp $0x1f,%ebx +c0105924: 7e 05 jle c010592b +c0105926: 83 fb 7e cmp $0x7e,%ebx +c0105929: 7e 15 jle c0105940 + putch('?', putdat); +c010592b: 8b 45 0c mov 0xc(%ebp),%eax +c010592e: 89 44 24 04 mov %eax,0x4(%esp) +c0105932: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) +c0105939: 8b 45 08 mov 0x8(%ebp),%eax +c010593c: ff d0 call *%eax +c010593e: eb 0f jmp c010594f + } + else { + putch(ch, putdat); +c0105940: 8b 45 0c mov 0xc(%ebp),%eax +c0105943: 89 44 24 04 mov %eax,0x4(%esp) +c0105947: 89 1c 24 mov %ebx,(%esp) +c010594a: 8b 45 08 mov 0x8(%ebp),%eax +c010594d: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { +c010594f: ff 4d e8 decl -0x18(%ebp) +c0105952: 89 f0 mov %esi,%eax +c0105954: 8d 70 01 lea 0x1(%eax),%esi +c0105957: 0f b6 00 movzbl (%eax),%eax +c010595a: 0f be d8 movsbl %al,%ebx +c010595d: 85 db test %ebx,%ebx +c010595f: 74 27 je c0105988 +c0105961: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c0105965: 78 b4 js c010591b +c0105967: ff 4d e4 decl -0x1c(%ebp) +c010596a: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) +c010596e: 79 ab jns c010591b + } + } + for (; width > 0; width --) { +c0105970: eb 16 jmp c0105988 + putch(' ', putdat); +c0105972: 8b 45 0c mov 0xc(%ebp),%eax +c0105975: 89 44 24 04 mov %eax,0x4(%esp) +c0105979: c7 04 24 20 00 00 00 movl $0x20,(%esp) +c0105980: 8b 45 08 mov 0x8(%ebp),%eax +c0105983: ff d0 call *%eax + for (; width > 0; width --) { +c0105985: ff 4d e8 decl -0x18(%ebp) +c0105988: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) +c010598c: 7f e4 jg c0105972 + } + break; +c010598e: e9 6c 01 00 00 jmp c0105aff + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); +c0105993: 8b 45 e0 mov -0x20(%ebp),%eax +c0105996: 89 44 24 04 mov %eax,0x4(%esp) +c010599a: 8d 45 14 lea 0x14(%ebp),%eax +c010599d: 89 04 24 mov %eax,(%esp) +c01059a0: e8 16 fd ff ff call c01056bb +c01059a5: 89 45 f0 mov %eax,-0x10(%ebp) +c01059a8: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { +c01059ab: 8b 45 f0 mov -0x10(%ebp),%eax +c01059ae: 8b 55 f4 mov -0xc(%ebp),%edx +c01059b1: 85 d2 test %edx,%edx +c01059b3: 79 26 jns c01059db + putch('-', putdat); +c01059b5: 8b 45 0c mov 0xc(%ebp),%eax +c01059b8: 89 44 24 04 mov %eax,0x4(%esp) +c01059bc: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) +c01059c3: 8b 45 08 mov 0x8(%ebp),%eax +c01059c6: ff d0 call *%eax + num = -(long long)num; +c01059c8: 8b 45 f0 mov -0x10(%ebp),%eax +c01059cb: 8b 55 f4 mov -0xc(%ebp),%edx +c01059ce: f7 d8 neg %eax +c01059d0: 83 d2 00 adc $0x0,%edx +c01059d3: f7 da neg %edx +c01059d5: 89 45 f0 mov %eax,-0x10(%ebp) +c01059d8: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; +c01059db: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; +c01059e2: e9 a8 00 00 00 jmp c0105a8f + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); +c01059e7: 8b 45 e0 mov -0x20(%ebp),%eax +c01059ea: 89 44 24 04 mov %eax,0x4(%esp) +c01059ee: 8d 45 14 lea 0x14(%ebp),%eax +c01059f1: 89 04 24 mov %eax,(%esp) +c01059f4: e8 73 fc ff ff call c010566c +c01059f9: 89 45 f0 mov %eax,-0x10(%ebp) +c01059fc: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; +c01059ff: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; +c0105a06: e9 84 00 00 00 jmp c0105a8f + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); +c0105a0b: 8b 45 e0 mov -0x20(%ebp),%eax +c0105a0e: 89 44 24 04 mov %eax,0x4(%esp) +c0105a12: 8d 45 14 lea 0x14(%ebp),%eax +c0105a15: 89 04 24 mov %eax,(%esp) +c0105a18: e8 4f fc ff ff call c010566c +c0105a1d: 89 45 f0 mov %eax,-0x10(%ebp) +c0105a20: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; +c0105a23: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; +c0105a2a: eb 63 jmp c0105a8f + + // pointer + case 'p': + putch('0', putdat); +c0105a2c: 8b 45 0c mov 0xc(%ebp),%eax +c0105a2f: 89 44 24 04 mov %eax,0x4(%esp) +c0105a33: c7 04 24 30 00 00 00 movl $0x30,(%esp) +c0105a3a: 8b 45 08 mov 0x8(%ebp),%eax +c0105a3d: ff d0 call *%eax + putch('x', putdat); +c0105a3f: 8b 45 0c mov 0xc(%ebp),%eax +c0105a42: 89 44 24 04 mov %eax,0x4(%esp) +c0105a46: c7 04 24 78 00 00 00 movl $0x78,(%esp) +c0105a4d: 8b 45 08 mov 0x8(%ebp),%eax +c0105a50: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); +c0105a52: 8b 45 14 mov 0x14(%ebp),%eax +c0105a55: 8d 50 04 lea 0x4(%eax),%edx +c0105a58: 89 55 14 mov %edx,0x14(%ebp) +c0105a5b: 8b 00 mov (%eax),%eax +c0105a5d: 89 45 f0 mov %eax,-0x10(%ebp) +c0105a60: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; +c0105a67: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; +c0105a6e: eb 1f jmp c0105a8f + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); +c0105a70: 8b 45 e0 mov -0x20(%ebp),%eax +c0105a73: 89 44 24 04 mov %eax,0x4(%esp) +c0105a77: 8d 45 14 lea 0x14(%ebp),%eax +c0105a7a: 89 04 24 mov %eax,(%esp) +c0105a7d: e8 ea fb ff ff call c010566c +c0105a82: 89 45 f0 mov %eax,-0x10(%ebp) +c0105a85: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; +c0105a88: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); +c0105a8f: 0f be 55 db movsbl -0x25(%ebp),%edx +c0105a93: 8b 45 ec mov -0x14(%ebp),%eax +c0105a96: 89 54 24 18 mov %edx,0x18(%esp) +c0105a9a: 8b 55 e8 mov -0x18(%ebp),%edx +c0105a9d: 89 54 24 14 mov %edx,0x14(%esp) +c0105aa1: 89 44 24 10 mov %eax,0x10(%esp) +c0105aa5: 8b 45 f0 mov -0x10(%ebp),%eax +c0105aa8: 8b 55 f4 mov -0xc(%ebp),%edx +c0105aab: 89 44 24 08 mov %eax,0x8(%esp) +c0105aaf: 89 54 24 0c mov %edx,0xc(%esp) +c0105ab3: 8b 45 0c mov 0xc(%ebp),%eax +c0105ab6: 89 44 24 04 mov %eax,0x4(%esp) +c0105aba: 8b 45 08 mov 0x8(%ebp),%eax +c0105abd: 89 04 24 mov %eax,(%esp) +c0105ac0: e8 a5 fa ff ff call c010556a + break; +c0105ac5: eb 38 jmp c0105aff + + // escaped '%' character + case '%': + putch(ch, putdat); +c0105ac7: 8b 45 0c mov 0xc(%ebp),%eax +c0105aca: 89 44 24 04 mov %eax,0x4(%esp) +c0105ace: 89 1c 24 mov %ebx,(%esp) +c0105ad1: 8b 45 08 mov 0x8(%ebp),%eax +c0105ad4: ff d0 call *%eax + break; +c0105ad6: eb 27 jmp c0105aff + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); +c0105ad8: 8b 45 0c mov 0xc(%ebp),%eax +c0105adb: 89 44 24 04 mov %eax,0x4(%esp) +c0105adf: c7 04 24 25 00 00 00 movl $0x25,(%esp) +c0105ae6: 8b 45 08 mov 0x8(%ebp),%eax +c0105ae9: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) +c0105aeb: ff 4d 10 decl 0x10(%ebp) +c0105aee: eb 03 jmp c0105af3 +c0105af0: ff 4d 10 decl 0x10(%ebp) +c0105af3: 8b 45 10 mov 0x10(%ebp),%eax +c0105af6: 48 dec %eax +c0105af7: 0f b6 00 movzbl (%eax),%eax +c0105afa: 3c 25 cmp $0x25,%al +c0105afc: 75 f2 jne c0105af0 + /* do nothing */; + break; +c0105afe: 90 nop + while (1) { +c0105aff: e9 37 fc ff ff jmp c010573b + return; +c0105b04: 90 nop + } + } +} +c0105b05: 83 c4 40 add $0x40,%esp +c0105b08: 5b pop %ebx +c0105b09: 5e pop %esi +c0105b0a: 5d pop %ebp +c0105b0b: c3 ret + +c0105b0c : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { +c0105b0c: 55 push %ebp +c0105b0d: 89 e5 mov %esp,%ebp + b->cnt ++; +c0105b0f: 8b 45 0c mov 0xc(%ebp),%eax +c0105b12: 8b 40 08 mov 0x8(%eax),%eax +c0105b15: 8d 50 01 lea 0x1(%eax),%edx +c0105b18: 8b 45 0c mov 0xc(%ebp),%eax +c0105b1b: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { +c0105b1e: 8b 45 0c mov 0xc(%ebp),%eax +c0105b21: 8b 10 mov (%eax),%edx +c0105b23: 8b 45 0c mov 0xc(%ebp),%eax +c0105b26: 8b 40 04 mov 0x4(%eax),%eax +c0105b29: 39 c2 cmp %eax,%edx +c0105b2b: 73 12 jae c0105b3f + *b->buf ++ = ch; +c0105b2d: 8b 45 0c mov 0xc(%ebp),%eax +c0105b30: 8b 00 mov (%eax),%eax +c0105b32: 8d 48 01 lea 0x1(%eax),%ecx +c0105b35: 8b 55 0c mov 0xc(%ebp),%edx +c0105b38: 89 0a mov %ecx,(%edx) +c0105b3a: 8b 55 08 mov 0x8(%ebp),%edx +c0105b3d: 88 10 mov %dl,(%eax) + } +} +c0105b3f: 90 nop +c0105b40: 5d pop %ebp +c0105b41: c3 ret + +c0105b42 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { +c0105b42: 55 push %ebp +c0105b43: 89 e5 mov %esp,%ebp +c0105b45: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); +c0105b48: 8d 45 14 lea 0x14(%ebp),%eax +c0105b4b: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); +c0105b4e: 8b 45 f0 mov -0x10(%ebp),%eax +c0105b51: 89 44 24 0c mov %eax,0xc(%esp) +c0105b55: 8b 45 10 mov 0x10(%ebp),%eax +c0105b58: 89 44 24 08 mov %eax,0x8(%esp) +c0105b5c: 8b 45 0c mov 0xc(%ebp),%eax +c0105b5f: 89 44 24 04 mov %eax,0x4(%esp) +c0105b63: 8b 45 08 mov 0x8(%ebp),%eax +c0105b66: 89 04 24 mov %eax,(%esp) +c0105b69: e8 0a 00 00 00 call c0105b78 +c0105b6e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; +c0105b71: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0105b74: 89 ec mov %ebp,%esp +c0105b76: 5d pop %ebp +c0105b77: c3 ret + +c0105b78 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { +c0105b78: 55 push %ebp +c0105b79: 89 e5 mov %esp,%ebp +c0105b7b: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; +c0105b7e: 8b 45 08 mov 0x8(%ebp),%eax +c0105b81: 89 45 ec mov %eax,-0x14(%ebp) +c0105b84: 8b 45 0c mov 0xc(%ebp),%eax +c0105b87: 8d 50 ff lea -0x1(%eax),%edx +c0105b8a: 8b 45 08 mov 0x8(%ebp),%eax +c0105b8d: 01 d0 add %edx,%eax +c0105b8f: 89 45 f0 mov %eax,-0x10(%ebp) +c0105b92: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { +c0105b99: 83 7d 08 00 cmpl $0x0,0x8(%ebp) +c0105b9d: 74 0a je c0105ba9 +c0105b9f: 8b 55 ec mov -0x14(%ebp),%edx +c0105ba2: 8b 45 f0 mov -0x10(%ebp),%eax +c0105ba5: 39 c2 cmp %eax,%edx +c0105ba7: 76 07 jbe c0105bb0 + return -E_INVAL; +c0105ba9: b8 fd ff ff ff mov $0xfffffffd,%eax +c0105bae: eb 2a jmp c0105bda + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); +c0105bb0: 8b 45 14 mov 0x14(%ebp),%eax +c0105bb3: 89 44 24 0c mov %eax,0xc(%esp) +c0105bb7: 8b 45 10 mov 0x10(%ebp),%eax +c0105bba: 89 44 24 08 mov %eax,0x8(%esp) +c0105bbe: 8d 45 ec lea -0x14(%ebp),%eax +c0105bc1: 89 44 24 04 mov %eax,0x4(%esp) +c0105bc5: c7 04 24 0c 5b 10 c0 movl $0xc0105b0c,(%esp) +c0105bcc: e8 62 fb ff ff call c0105733 + // null terminate the buffer + *b.buf = '\0'; +c0105bd1: 8b 45 ec mov -0x14(%ebp),%eax +c0105bd4: c6 00 00 movb $0x0,(%eax) + return b.cnt; +c0105bd7: 8b 45 f4 mov -0xc(%ebp),%eax +} +c0105bda: 89 ec mov %ebp,%esp +c0105bdc: 5d pop %ebp +c0105bdd: c3 ret + +c0105bde : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { +c0105bde: 55 push %ebp +c0105bdf: 89 e5 mov %esp,%ebp +c0105be1: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; +c0105be4: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { +c0105beb: eb 03 jmp c0105bf0 + cnt ++; +c0105bed: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { +c0105bf0: 8b 45 08 mov 0x8(%ebp),%eax +c0105bf3: 8d 50 01 lea 0x1(%eax),%edx +c0105bf6: 89 55 08 mov %edx,0x8(%ebp) +c0105bf9: 0f b6 00 movzbl (%eax),%eax +c0105bfc: 84 c0 test %al,%al +c0105bfe: 75 ed jne c0105bed + } + return cnt; +c0105c00: 8b 45 fc mov -0x4(%ebp),%eax +} +c0105c03: 89 ec mov %ebp,%esp +c0105c05: 5d pop %ebp +c0105c06: c3 ret + +c0105c07 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { +c0105c07: 55 push %ebp +c0105c08: 89 e5 mov %esp,%ebp +c0105c0a: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; +c0105c0d: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { +c0105c14: eb 03 jmp c0105c19 + cnt ++; +c0105c16: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { +c0105c19: 8b 45 fc mov -0x4(%ebp),%eax +c0105c1c: 3b 45 0c cmp 0xc(%ebp),%eax +c0105c1f: 73 10 jae c0105c31 +c0105c21: 8b 45 08 mov 0x8(%ebp),%eax +c0105c24: 8d 50 01 lea 0x1(%eax),%edx +c0105c27: 89 55 08 mov %edx,0x8(%ebp) +c0105c2a: 0f b6 00 movzbl (%eax),%eax +c0105c2d: 84 c0 test %al,%al +c0105c2f: 75 e5 jne c0105c16 + } + return cnt; +c0105c31: 8b 45 fc mov -0x4(%ebp),%eax +} +c0105c34: 89 ec mov %ebp,%esp +c0105c36: 5d pop %ebp +c0105c37: c3 ret + +c0105c38 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { +c0105c38: 55 push %ebp +c0105c39: 89 e5 mov %esp,%ebp +c0105c3b: 57 push %edi +c0105c3c: 56 push %esi +c0105c3d: 83 ec 20 sub $0x20,%esp +c0105c40: 8b 45 08 mov 0x8(%ebp),%eax +c0105c43: 89 45 f4 mov %eax,-0xc(%ebp) +c0105c46: 8b 45 0c mov 0xc(%ebp),%eax +c0105c49: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( +c0105c4c: 8b 55 f0 mov -0x10(%ebp),%edx +c0105c4f: 8b 45 f4 mov -0xc(%ebp),%eax +c0105c52: 89 d1 mov %edx,%ecx +c0105c54: 89 c2 mov %eax,%edx +c0105c56: 89 ce mov %ecx,%esi +c0105c58: 89 d7 mov %edx,%edi +c0105c5a: ac lods %ds:(%esi),%al +c0105c5b: aa stos %al,%es:(%edi) +c0105c5c: 84 c0 test %al,%al +c0105c5e: 75 fa jne c0105c5a +c0105c60: 89 fa mov %edi,%edx +c0105c62: 89 f1 mov %esi,%ecx +c0105c64: 89 4d ec mov %ecx,-0x14(%ebp) +c0105c67: 89 55 e8 mov %edx,-0x18(%ebp) +c0105c6a: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; +c0105c6d: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} +c0105c70: 83 c4 20 add $0x20,%esp +c0105c73: 5e pop %esi +c0105c74: 5f pop %edi +c0105c75: 5d pop %ebp +c0105c76: c3 ret + +c0105c77 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { +c0105c77: 55 push %ebp +c0105c78: 89 e5 mov %esp,%ebp +c0105c7a: 83 ec 10 sub $0x10,%esp + char *p = dst; +c0105c7d: 8b 45 08 mov 0x8(%ebp),%eax +c0105c80: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { +c0105c83: eb 1e jmp c0105ca3 + if ((*p = *src) != '\0') { +c0105c85: 8b 45 0c mov 0xc(%ebp),%eax +c0105c88: 0f b6 10 movzbl (%eax),%edx +c0105c8b: 8b 45 fc mov -0x4(%ebp),%eax +c0105c8e: 88 10 mov %dl,(%eax) +c0105c90: 8b 45 fc mov -0x4(%ebp),%eax +c0105c93: 0f b6 00 movzbl (%eax),%eax +c0105c96: 84 c0 test %al,%al +c0105c98: 74 03 je c0105c9d + src ++; +c0105c9a: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; +c0105c9d: ff 45 fc incl -0x4(%ebp) +c0105ca0: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { +c0105ca3: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0105ca7: 75 dc jne c0105c85 + } + return dst; +c0105ca9: 8b 45 08 mov 0x8(%ebp),%eax +} +c0105cac: 89 ec mov %ebp,%esp +c0105cae: 5d pop %ebp +c0105caf: c3 ret + +c0105cb0 : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { +c0105cb0: 55 push %ebp +c0105cb1: 89 e5 mov %esp,%ebp +c0105cb3: 57 push %edi +c0105cb4: 56 push %esi +c0105cb5: 83 ec 20 sub $0x20,%esp +c0105cb8: 8b 45 08 mov 0x8(%ebp),%eax +c0105cbb: 89 45 f4 mov %eax,-0xc(%ebp) +c0105cbe: 8b 45 0c mov 0xc(%ebp),%eax +c0105cc1: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( +c0105cc4: 8b 55 f4 mov -0xc(%ebp),%edx +c0105cc7: 8b 45 f0 mov -0x10(%ebp),%eax +c0105cca: 89 d1 mov %edx,%ecx +c0105ccc: 89 c2 mov %eax,%edx +c0105cce: 89 ce mov %ecx,%esi +c0105cd0: 89 d7 mov %edx,%edi +c0105cd2: ac lods %ds:(%esi),%al +c0105cd3: ae scas %es:(%edi),%al +c0105cd4: 75 08 jne c0105cde +c0105cd6: 84 c0 test %al,%al +c0105cd8: 75 f8 jne c0105cd2 +c0105cda: 31 c0 xor %eax,%eax +c0105cdc: eb 04 jmp c0105ce2 +c0105cde: 19 c0 sbb %eax,%eax +c0105ce0: 0c 01 or $0x1,%al +c0105ce2: 89 fa mov %edi,%edx +c0105ce4: 89 f1 mov %esi,%ecx +c0105ce6: 89 45 ec mov %eax,-0x14(%ebp) +c0105ce9: 89 4d e8 mov %ecx,-0x18(%ebp) +c0105cec: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; +c0105cef: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} +c0105cf2: 83 c4 20 add $0x20,%esp +c0105cf5: 5e pop %esi +c0105cf6: 5f pop %edi +c0105cf7: 5d pop %ebp +c0105cf8: c3 ret + +c0105cf9 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { +c0105cf9: 55 push %ebp +c0105cfa: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { +c0105cfc: eb 09 jmp c0105d07 + n --, s1 ++, s2 ++; +c0105cfe: ff 4d 10 decl 0x10(%ebp) +c0105d01: ff 45 08 incl 0x8(%ebp) +c0105d04: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { +c0105d07: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0105d0b: 74 1a je c0105d27 +c0105d0d: 8b 45 08 mov 0x8(%ebp),%eax +c0105d10: 0f b6 00 movzbl (%eax),%eax +c0105d13: 84 c0 test %al,%al +c0105d15: 74 10 je c0105d27 +c0105d17: 8b 45 08 mov 0x8(%ebp),%eax +c0105d1a: 0f b6 10 movzbl (%eax),%edx +c0105d1d: 8b 45 0c mov 0xc(%ebp),%eax +c0105d20: 0f b6 00 movzbl (%eax),%eax +c0105d23: 38 c2 cmp %al,%dl +c0105d25: 74 d7 je c0105cfe + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); +c0105d27: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0105d2b: 74 18 je c0105d45 +c0105d2d: 8b 45 08 mov 0x8(%ebp),%eax +c0105d30: 0f b6 00 movzbl (%eax),%eax +c0105d33: 0f b6 d0 movzbl %al,%edx +c0105d36: 8b 45 0c mov 0xc(%ebp),%eax +c0105d39: 0f b6 00 movzbl (%eax),%eax +c0105d3c: 0f b6 c8 movzbl %al,%ecx +c0105d3f: 89 d0 mov %edx,%eax +c0105d41: 29 c8 sub %ecx,%eax +c0105d43: eb 05 jmp c0105d4a +c0105d45: b8 00 00 00 00 mov $0x0,%eax +} +c0105d4a: 5d pop %ebp +c0105d4b: c3 ret + +c0105d4c : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { +c0105d4c: 55 push %ebp +c0105d4d: 89 e5 mov %esp,%ebp +c0105d4f: 83 ec 04 sub $0x4,%esp +c0105d52: 8b 45 0c mov 0xc(%ebp),%eax +c0105d55: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { +c0105d58: eb 13 jmp c0105d6d + if (*s == c) { +c0105d5a: 8b 45 08 mov 0x8(%ebp),%eax +c0105d5d: 0f b6 00 movzbl (%eax),%eax +c0105d60: 38 45 fc cmp %al,-0x4(%ebp) +c0105d63: 75 05 jne c0105d6a + return (char *)s; +c0105d65: 8b 45 08 mov 0x8(%ebp),%eax +c0105d68: eb 12 jmp c0105d7c + } + s ++; +c0105d6a: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { +c0105d6d: 8b 45 08 mov 0x8(%ebp),%eax +c0105d70: 0f b6 00 movzbl (%eax),%eax +c0105d73: 84 c0 test %al,%al +c0105d75: 75 e3 jne c0105d5a + } + return NULL; +c0105d77: b8 00 00 00 00 mov $0x0,%eax +} +c0105d7c: 89 ec mov %ebp,%esp +c0105d7e: 5d pop %ebp +c0105d7f: c3 ret + +c0105d80 : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { +c0105d80: 55 push %ebp +c0105d81: 89 e5 mov %esp,%ebp +c0105d83: 83 ec 04 sub $0x4,%esp +c0105d86: 8b 45 0c mov 0xc(%ebp),%eax +c0105d89: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { +c0105d8c: eb 0e jmp c0105d9c + if (*s == c) { +c0105d8e: 8b 45 08 mov 0x8(%ebp),%eax +c0105d91: 0f b6 00 movzbl (%eax),%eax +c0105d94: 38 45 fc cmp %al,-0x4(%ebp) +c0105d97: 74 0f je c0105da8 + break; + } + s ++; +c0105d99: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { +c0105d9c: 8b 45 08 mov 0x8(%ebp),%eax +c0105d9f: 0f b6 00 movzbl (%eax),%eax +c0105da2: 84 c0 test %al,%al +c0105da4: 75 e8 jne c0105d8e +c0105da6: eb 01 jmp c0105da9 + break; +c0105da8: 90 nop + } + return (char *)s; +c0105da9: 8b 45 08 mov 0x8(%ebp),%eax +} +c0105dac: 89 ec mov %ebp,%esp +c0105dae: 5d pop %ebp +c0105daf: c3 ret + +c0105db0 : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { +c0105db0: 55 push %ebp +c0105db1: 89 e5 mov %esp,%ebp +c0105db3: 83 ec 10 sub $0x10,%esp + int neg = 0; +c0105db6: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; +c0105dbd: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { +c0105dc4: eb 03 jmp c0105dc9 + s ++; +c0105dc6: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { +c0105dc9: 8b 45 08 mov 0x8(%ebp),%eax +c0105dcc: 0f b6 00 movzbl (%eax),%eax +c0105dcf: 3c 20 cmp $0x20,%al +c0105dd1: 74 f3 je c0105dc6 +c0105dd3: 8b 45 08 mov 0x8(%ebp),%eax +c0105dd6: 0f b6 00 movzbl (%eax),%eax +c0105dd9: 3c 09 cmp $0x9,%al +c0105ddb: 74 e9 je c0105dc6 + } + + // plus/minus sign + if (*s == '+') { +c0105ddd: 8b 45 08 mov 0x8(%ebp),%eax +c0105de0: 0f b6 00 movzbl (%eax),%eax +c0105de3: 3c 2b cmp $0x2b,%al +c0105de5: 75 05 jne c0105dec + s ++; +c0105de7: ff 45 08 incl 0x8(%ebp) +c0105dea: eb 14 jmp c0105e00 + } + else if (*s == '-') { +c0105dec: 8b 45 08 mov 0x8(%ebp),%eax +c0105def: 0f b6 00 movzbl (%eax),%eax +c0105df2: 3c 2d cmp $0x2d,%al +c0105df4: 75 0a jne c0105e00 + s ++, neg = 1; +c0105df6: ff 45 08 incl 0x8(%ebp) +c0105df9: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { +c0105e00: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0105e04: 74 06 je c0105e0c +c0105e06: 83 7d 10 10 cmpl $0x10,0x10(%ebp) +c0105e0a: 75 22 jne c0105e2e +c0105e0c: 8b 45 08 mov 0x8(%ebp),%eax +c0105e0f: 0f b6 00 movzbl (%eax),%eax +c0105e12: 3c 30 cmp $0x30,%al +c0105e14: 75 18 jne c0105e2e +c0105e16: 8b 45 08 mov 0x8(%ebp),%eax +c0105e19: 40 inc %eax +c0105e1a: 0f b6 00 movzbl (%eax),%eax +c0105e1d: 3c 78 cmp $0x78,%al +c0105e1f: 75 0d jne c0105e2e + s += 2, base = 16; +c0105e21: 83 45 08 02 addl $0x2,0x8(%ebp) +c0105e25: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) +c0105e2c: eb 29 jmp c0105e57 + } + else if (base == 0 && s[0] == '0') { +c0105e2e: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0105e32: 75 16 jne c0105e4a +c0105e34: 8b 45 08 mov 0x8(%ebp),%eax +c0105e37: 0f b6 00 movzbl (%eax),%eax +c0105e3a: 3c 30 cmp $0x30,%al +c0105e3c: 75 0c jne c0105e4a + s ++, base = 8; +c0105e3e: ff 45 08 incl 0x8(%ebp) +c0105e41: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) +c0105e48: eb 0d jmp c0105e57 + } + else if (base == 0) { +c0105e4a: 83 7d 10 00 cmpl $0x0,0x10(%ebp) +c0105e4e: 75 07 jne c0105e57 + base = 10; +c0105e50: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { +c0105e57: 8b 45 08 mov 0x8(%ebp),%eax +c0105e5a: 0f b6 00 movzbl (%eax),%eax +c0105e5d: 3c 2f cmp $0x2f,%al +c0105e5f: 7e 1b jle c0105e7c +c0105e61: 8b 45 08 mov 0x8(%ebp),%eax +c0105e64: 0f b6 00 movzbl (%eax),%eax +c0105e67: 3c 39 cmp $0x39,%al +c0105e69: 7f 11 jg c0105e7c + dig = *s - '0'; +c0105e6b: 8b 45 08 mov 0x8(%ebp),%eax +c0105e6e: 0f b6 00 movzbl (%eax),%eax +c0105e71: 0f be c0 movsbl %al,%eax +c0105e74: 83 e8 30 sub $0x30,%eax +c0105e77: 89 45 f4 mov %eax,-0xc(%ebp) +c0105e7a: eb 48 jmp c0105ec4 + } + else if (*s >= 'a' && *s <= 'z') { +c0105e7c: 8b 45 08 mov 0x8(%ebp),%eax +c0105e7f: 0f b6 00 movzbl (%eax),%eax +c0105e82: 3c 60 cmp $0x60,%al +c0105e84: 7e 1b jle c0105ea1 +c0105e86: 8b 45 08 mov 0x8(%ebp),%eax +c0105e89: 0f b6 00 movzbl (%eax),%eax +c0105e8c: 3c 7a cmp $0x7a,%al +c0105e8e: 7f 11 jg c0105ea1 + dig = *s - 'a' + 10; +c0105e90: 8b 45 08 mov 0x8(%ebp),%eax +c0105e93: 0f b6 00 movzbl (%eax),%eax +c0105e96: 0f be c0 movsbl %al,%eax +c0105e99: 83 e8 57 sub $0x57,%eax +c0105e9c: 89 45 f4 mov %eax,-0xc(%ebp) +c0105e9f: eb 23 jmp c0105ec4 + } + else if (*s >= 'A' && *s <= 'Z') { +c0105ea1: 8b 45 08 mov 0x8(%ebp),%eax +c0105ea4: 0f b6 00 movzbl (%eax),%eax +c0105ea7: 3c 40 cmp $0x40,%al +c0105ea9: 7e 3b jle c0105ee6 +c0105eab: 8b 45 08 mov 0x8(%ebp),%eax +c0105eae: 0f b6 00 movzbl (%eax),%eax +c0105eb1: 3c 5a cmp $0x5a,%al +c0105eb3: 7f 31 jg c0105ee6 + dig = *s - 'A' + 10; +c0105eb5: 8b 45 08 mov 0x8(%ebp),%eax +c0105eb8: 0f b6 00 movzbl (%eax),%eax +c0105ebb: 0f be c0 movsbl %al,%eax +c0105ebe: 83 e8 37 sub $0x37,%eax +c0105ec1: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { +c0105ec4: 8b 45 f4 mov -0xc(%ebp),%eax +c0105ec7: 3b 45 10 cmp 0x10(%ebp),%eax +c0105eca: 7d 19 jge c0105ee5 + break; + } + s ++, val = (val * base) + dig; +c0105ecc: ff 45 08 incl 0x8(%ebp) +c0105ecf: 8b 45 f8 mov -0x8(%ebp),%eax +c0105ed2: 0f af 45 10 imul 0x10(%ebp),%eax +c0105ed6: 89 c2 mov %eax,%edx +c0105ed8: 8b 45 f4 mov -0xc(%ebp),%eax +c0105edb: 01 d0 add %edx,%eax +c0105edd: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { +c0105ee0: e9 72 ff ff ff jmp c0105e57 + break; +c0105ee5: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { +c0105ee6: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) +c0105eea: 74 08 je c0105ef4 + *endptr = (char *) s; +c0105eec: 8b 45 0c mov 0xc(%ebp),%eax +c0105eef: 8b 55 08 mov 0x8(%ebp),%edx +c0105ef2: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); +c0105ef4: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) +c0105ef8: 74 07 je c0105f01 +c0105efa: 8b 45 f8 mov -0x8(%ebp),%eax +c0105efd: f7 d8 neg %eax +c0105eff: eb 03 jmp c0105f04 +c0105f01: 8b 45 f8 mov -0x8(%ebp),%eax +} +c0105f04: 89 ec mov %ebp,%esp +c0105f06: 5d pop %ebp +c0105f07: c3 ret + +c0105f08 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { +c0105f08: 55 push %ebp +c0105f09: 89 e5 mov %esp,%ebp +c0105f0b: 83 ec 28 sub $0x28,%esp +c0105f0e: 89 7d fc mov %edi,-0x4(%ebp) +c0105f11: 8b 45 0c mov 0xc(%ebp),%eax +c0105f14: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); +c0105f17: 0f be 55 d8 movsbl -0x28(%ebp),%edx +c0105f1b: 8b 45 08 mov 0x8(%ebp),%eax +c0105f1e: 89 45 f8 mov %eax,-0x8(%ebp) +c0105f21: 88 55 f7 mov %dl,-0x9(%ebp) +c0105f24: 8b 45 10 mov 0x10(%ebp),%eax +c0105f27: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( +c0105f2a: 8b 4d f0 mov -0x10(%ebp),%ecx +c0105f2d: 0f b6 45 f7 movzbl -0x9(%ebp),%eax +c0105f31: 8b 55 f8 mov -0x8(%ebp),%edx +c0105f34: 89 d7 mov %edx,%edi +c0105f36: f3 aa rep stos %al,%es:(%edi) +c0105f38: 89 fa mov %edi,%edx +c0105f3a: 89 4d ec mov %ecx,-0x14(%ebp) +c0105f3d: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; +c0105f40: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} +c0105f43: 8b 7d fc mov -0x4(%ebp),%edi +c0105f46: 89 ec mov %ebp,%esp +c0105f48: 5d pop %ebp +c0105f49: c3 ret + +c0105f4a : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { +c0105f4a: 55 push %ebp +c0105f4b: 89 e5 mov %esp,%ebp +c0105f4d: 57 push %edi +c0105f4e: 56 push %esi +c0105f4f: 53 push %ebx +c0105f50: 83 ec 30 sub $0x30,%esp +c0105f53: 8b 45 08 mov 0x8(%ebp),%eax +c0105f56: 89 45 f0 mov %eax,-0x10(%ebp) +c0105f59: 8b 45 0c mov 0xc(%ebp),%eax +c0105f5c: 89 45 ec mov %eax,-0x14(%ebp) +c0105f5f: 8b 45 10 mov 0x10(%ebp),%eax +c0105f62: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { +c0105f65: 8b 45 f0 mov -0x10(%ebp),%eax +c0105f68: 3b 45 ec cmp -0x14(%ebp),%eax +c0105f6b: 73 42 jae c0105faf +c0105f6d: 8b 45 f0 mov -0x10(%ebp),%eax +c0105f70: 89 45 e4 mov %eax,-0x1c(%ebp) +c0105f73: 8b 45 ec mov -0x14(%ebp),%eax +c0105f76: 89 45 e0 mov %eax,-0x20(%ebp) +c0105f79: 8b 45 e8 mov -0x18(%ebp),%eax +c0105f7c: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) +c0105f7f: 8b 45 dc mov -0x24(%ebp),%eax +c0105f82: c1 e8 02 shr $0x2,%eax +c0105f85: 89 c1 mov %eax,%ecx + asm volatile ( +c0105f87: 8b 55 e4 mov -0x1c(%ebp),%edx +c0105f8a: 8b 45 e0 mov -0x20(%ebp),%eax +c0105f8d: 89 d7 mov %edx,%edi +c0105f8f: 89 c6 mov %eax,%esi +c0105f91: f3 a5 rep movsl %ds:(%esi),%es:(%edi) +c0105f93: 8b 4d dc mov -0x24(%ebp),%ecx +c0105f96: 83 e1 03 and $0x3,%ecx +c0105f99: 74 02 je c0105f9d +c0105f9b: f3 a4 rep movsb %ds:(%esi),%es:(%edi) +c0105f9d: 89 f0 mov %esi,%eax +c0105f9f: 89 fa mov %edi,%edx +c0105fa1: 89 4d d8 mov %ecx,-0x28(%ebp) +c0105fa4: 89 55 d4 mov %edx,-0x2c(%ebp) +c0105fa7: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; +c0105faa: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); +c0105fad: eb 36 jmp c0105fe5 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) +c0105faf: 8b 45 e8 mov -0x18(%ebp),%eax +c0105fb2: 8d 50 ff lea -0x1(%eax),%edx +c0105fb5: 8b 45 ec mov -0x14(%ebp),%eax +c0105fb8: 01 c2 add %eax,%edx +c0105fba: 8b 45 e8 mov -0x18(%ebp),%eax +c0105fbd: 8d 48 ff lea -0x1(%eax),%ecx +c0105fc0: 8b 45 f0 mov -0x10(%ebp),%eax +c0105fc3: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( +c0105fc6: 8b 45 e8 mov -0x18(%ebp),%eax +c0105fc9: 89 c1 mov %eax,%ecx +c0105fcb: 89 d8 mov %ebx,%eax +c0105fcd: 89 d6 mov %edx,%esi +c0105fcf: 89 c7 mov %eax,%edi +c0105fd1: fd std +c0105fd2: f3 a4 rep movsb %ds:(%esi),%es:(%edi) +c0105fd4: fc cld +c0105fd5: 89 f8 mov %edi,%eax +c0105fd7: 89 f2 mov %esi,%edx +c0105fd9: 89 4d cc mov %ecx,-0x34(%ebp) +c0105fdc: 89 55 c8 mov %edx,-0x38(%ebp) +c0105fdf: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; +c0105fe2: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} +c0105fe5: 83 c4 30 add $0x30,%esp +c0105fe8: 5b pop %ebx +c0105fe9: 5e pop %esi +c0105fea: 5f pop %edi +c0105feb: 5d pop %ebp +c0105fec: c3 ret + +c0105fed : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { +c0105fed: 55 push %ebp +c0105fee: 89 e5 mov %esp,%ebp +c0105ff0: 57 push %edi +c0105ff1: 56 push %esi +c0105ff2: 83 ec 20 sub $0x20,%esp +c0105ff5: 8b 45 08 mov 0x8(%ebp),%eax +c0105ff8: 89 45 f4 mov %eax,-0xc(%ebp) +c0105ffb: 8b 45 0c mov 0xc(%ebp),%eax +c0105ffe: 89 45 f0 mov %eax,-0x10(%ebp) +c0106001: 8b 45 10 mov 0x10(%ebp),%eax +c0106004: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) +c0106007: 8b 45 ec mov -0x14(%ebp),%eax +c010600a: c1 e8 02 shr $0x2,%eax +c010600d: 89 c1 mov %eax,%ecx + asm volatile ( +c010600f: 8b 55 f4 mov -0xc(%ebp),%edx +c0106012: 8b 45 f0 mov -0x10(%ebp),%eax +c0106015: 89 d7 mov %edx,%edi +c0106017: 89 c6 mov %eax,%esi +c0106019: f3 a5 rep movsl %ds:(%esi),%es:(%edi) +c010601b: 8b 4d ec mov -0x14(%ebp),%ecx +c010601e: 83 e1 03 and $0x3,%ecx +c0106021: 74 02 je c0106025 +c0106023: f3 a4 rep movsb %ds:(%esi),%es:(%edi) +c0106025: 89 f0 mov %esi,%eax +c0106027: 89 fa mov %edi,%edx +c0106029: 89 4d e8 mov %ecx,-0x18(%ebp) +c010602c: 89 55 e4 mov %edx,-0x1c(%ebp) +c010602f: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; +c0106032: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} +c0106035: 83 c4 20 add $0x20,%esp +c0106038: 5e pop %esi +c0106039: 5f pop %edi +c010603a: 5d pop %ebp +c010603b: c3 ret + +c010603c : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { +c010603c: 55 push %ebp +c010603d: 89 e5 mov %esp,%ebp +c010603f: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; +c0106042: 8b 45 08 mov 0x8(%ebp),%eax +c0106045: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; +c0106048: 8b 45 0c mov 0xc(%ebp),%eax +c010604b: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { +c010604e: eb 2e jmp c010607e + if (*s1 != *s2) { +c0106050: 8b 45 fc mov -0x4(%ebp),%eax +c0106053: 0f b6 10 movzbl (%eax),%edx +c0106056: 8b 45 f8 mov -0x8(%ebp),%eax +c0106059: 0f b6 00 movzbl (%eax),%eax +c010605c: 38 c2 cmp %al,%dl +c010605e: 74 18 je c0106078 + return (int)((unsigned char)*s1 - (unsigned char)*s2); +c0106060: 8b 45 fc mov -0x4(%ebp),%eax +c0106063: 0f b6 00 movzbl (%eax),%eax +c0106066: 0f b6 d0 movzbl %al,%edx +c0106069: 8b 45 f8 mov -0x8(%ebp),%eax +c010606c: 0f b6 00 movzbl (%eax),%eax +c010606f: 0f b6 c8 movzbl %al,%ecx +c0106072: 89 d0 mov %edx,%eax +c0106074: 29 c8 sub %ecx,%eax +c0106076: eb 18 jmp c0106090 + } + s1 ++, s2 ++; +c0106078: ff 45 fc incl -0x4(%ebp) +c010607b: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { +c010607e: 8b 45 10 mov 0x10(%ebp),%eax +c0106081: 8d 50 ff lea -0x1(%eax),%edx +c0106084: 89 55 10 mov %edx,0x10(%ebp) +c0106087: 85 c0 test %eax,%eax +c0106089: 75 c5 jne c0106050 + } + return 0; +c010608b: b8 00 00 00 00 mov $0x0,%eax +} +c0106090: 89 ec mov %ebp,%esp +c0106092: 5d pop %ebp +c0106093: c3 ret diff --git a/labcodes/lab2/obj/kernel.sym b/labcodes/lab2/obj/kernel.sym new file mode 100644 index 00000000..92622bfe --- /dev/null +++ b/labcodes/lab2/obj/kernel.sym @@ -0,0 +1,461 @@ +00000000 entry.o +c010001e next +c0100034 spin +c011b000 __boot_pt1 +00000400 i +00000000 init.c +c010021b lab1_switch_test +c0100144 lab1_print_cur_status +c011c000 round.0 +c0100204 lab1_switch_to_user +c0100211 lab1_switch_to_kernel +00000000 readline.c +c011c020 buf +00000000 stdio.c +c010030e cputch +00000000 kdebug.c +c0100411 stab_binsearch +c01009c2 read_eip +00000000 kmonitor.c +c0119000 commands +c01009db parse +c0100a94 runcmd +00000000 panic.c +c011c420 is_panic +00000000 clock.c +00000000 console.c +c0100d6d __intr_save +c0100d99 __intr_restore +c0100daf delay +c011c440 crt_buf +c011c444 crt_pos +c011c446 addr_6845 +c0100dfa cga_init +c011c448 serial_exists +c0100ee2 serial_init +c0100fcf lpt_putc_sub +c010104d lpt_putc +c010108f cga_putc +c0101285 serial_putc_sub +c01012e1 serial_putc +c011c460 cons +c0101323 cons_intr +c0101372 serial_proc_data +c0119040 shiftcode +c0119140 togglecode +c0119240 normalmap +c0119340 shiftmap +c0119440 ctlmap +c0119540 charcode +c01013eb kbd_proc_data +c011c668 shift.0 +c0101572 kbd_intr +c0101589 kbd_init +00000000 intr.c +00000000 picirq.c +c0119550 irq_mask +c011c66c did_init +c0101694 pic_setmask +00000000 trap.c +c0101870 print_ticks +c011c6e0 idt +c0119560 idt_pd +c0101a04 trapname +c0106740 excnames.0 +c0119580 IA32flags +c0101cb7 trap_dispatch +00000000 default_pmm.c +c01029a9 page2ppn +c01029c2 page2pa +c01029da page_ref +c01029e4 set_page_ref +c01029f2 default_init +c0102a23 default_init_memmap +c0102b85 default_alloc_pages +c0102d01 default_free_pages +c0102fb9 default_nr_free_pages +c0102fc3 basic_check +c0103503 default_check +00000000 pmm.c +c0103b93 page2ppn +c0103bac page2pa +c0103bc4 pa2page +c0103c15 page2kva +c0103c6b pte2page +c0103cab pde2page +c0103cc5 page_ref +c0103ccf set_page_ref +c0103cdd page_ref_inc +c0103cf4 page_ref_dec +c0103d0b __intr_save +c0103d37 __intr_restore +c011cf20 ts +c0119a00 gdt +c0119a30 gdt_pd +c0103d4d lgdt +c0103d91 gdt_init +c0103e7d init_pmm_manager +c0103eb3 init_memmap +c0103f71 page_init +c0104333 boot_map_segment +c0104439 boot_alloc_page +c01048c2 check_alloc_page +c01048e3 check_pgdir +c0104f81 check_boot_pgdir +c01046fd page_remove_pte +c010530d perm2str +c011cf88 str.0 +c010534f get_pgtable_items +00000000 printfmt.c +c0107220 error_string +c010556a printnum +c010566c getuint +c01056bb getint +c0105b0c sprintputch +00000000 string.c +c0102901 vector242 +c0102358 vector119 +c0100889 print_kerninfo +c0102238 vector87 +c010222f vector86 +c010296d vector251 +c0105c38 strcpy +c010225c vector91 +c0102052 vector33 +c0102541 vector162 +c01027a5 vector213 +c01022f5 vector108 +c01020ac vector43 +c0100000 kern_entry +c0100c1f mon_backtrace +c0102565 vector165 +c0102655 vector185 +c0102334 vector115 +c0102373 vector122 +c01047a8 page_insert +c01024f9 vector156 +c0102925 vector245 +c0102685 vector189 +c0101f76 vector7 +c010214e vector61 +c0102001 vector24 +c0102310 vector111 +c0102709 vector200 +c0102184 vector67 +c0102421 vector138 +c01021c3 vector74 +c0105f4a memmove +c010212a vector57 +c0105b42 snprintf +c0101a4a print_trapframe +c01027b1 vector214 +c0105733 vprintfmt +c01022a4 vector99 +c01046a2 get_page +c0101f15 __alltraps +c0101613 cons_getc +c0102445 vector141 +c0100cfa is_kernel_panic +c01025b9 vector172 +c01009d5 print_stackframe +c01028f5 vector241 +c0102985 vector253 +c0101f52 vector3 +c0101f49 vector2 +c010284d vector227 +c0102781 vector210 +c0102829 vector224 +c010209a vector41 +c0100366 cprintf +c0101fe6 vector21 +c01025f5 vector177 +c010234f vector118 +c010219f vector70 +c0102196 vector69 +c01028c5 vector237 +c0102169 vector64 +c010201c vector27 +c01023d9 vector132 +c0102661 vector186 +c01027d5 vector217 +c0105fed memcpy +c0101f40 vector1 +c0102601 vector178 +c010207f vector38 +c01028d1 vector238 +c0100257 readline +c01023e5 vector133 +c01021ba vector73 +c0102469 vector144 +c0106bd0 vpd +c0100036 kern_init +c0102991 vector254 +c01022b6 vector101 +c010278d vector211 +c01025d1 vector174 +c010290d vector243 +c01023a9 vector128 +c0102202 vector81 +c0103f0f free_pages +c0101fa4 vector13 +c0105b78 vsnprintf +c01020f4 vector51 +c0101fbb vector16 +c011c000 edata +c01015a5 cons_init +c011cf0c pmm_manager +c01028e9 vector240 +c010210f vector54 +c0101fd4 vector19 +c0112aac __STAB_END__ +c0102265 vector92 +c0102919 vector244 +c0103d83 load_esp0 +c0102439 vector140 +c01020be vector45 +c01021f0 vector79 +c0102865 vector229 +c0102511 vector158 +c01016f1 pic_enable +c0102088 vector39 +c0102589 vector168 +c0102064 vector35 +c0102322 vector113 +c0112aad __STABSTR_BEGIN__ +c010238e vector125 +c0100c33 __panic +c01027c9 vector216 +c0102160 vector63 +c0102013 vector26 +c01013cb serial_intr +c01026b5 vector193 +c01026d9 vector196 +c01000ff grade_backtrace0 +c0102775 vector209 +c0101f5b vector4 +c01025a1 vector170 +c0102409 vector136 +c0101f8f vector10 +c0102751 vector206 +c010299d vector255 +c0102625 vector181 +c010213c vector59 +c010011c grade_backtrace +c0102226 vector85 +c010221d vector84 +c010263d vector183 +c010251d vector159 +c0102799 vector212 +c01020d0 vector47 +c0105db0 strtol +c0102859 vector228 +c01020a3 vector42 +c010232b vector114 +c0105c07 strnlen +c01025dd vector175 +c010245d vector143 +c01023c1 vector130 +c0106b38 default_pmm_manager +c0102931 vector246 +c0101f86 vector9 +c0102451 vector142 +c01022ad vector100 +c0102715 vector201 +c010188f idt_init +c010091d print_debuginfo +c0102145 vector60 +c0101ff8 vector23 +c01028b9 vector236 +c011cf04 npage +c010287d vector231 +c010217b vector66 +c010202e vector29 +c0105403 print_pgdir +c01023fd vector135 +c0100b4c kmonitor +c01021de vector77 +c0102619 vector180 +c0100d04 clock_init +c0102769 vector208 +c010229b vector98 +c0102292 vector97 +c0103f44 nr_free_pages +c01025e9 vector176 +c01026c1 vector194 +c0102049 vector32 +c011cf08 boot_cr3 +c011cf8c end +c01026fd vector199 +c01023cd vector131 +c0102979 vector252 +c0101f37 vector0 +c0105d80 strfind +c01015d4 cons_putc +c0106094 etext +c0102475 vector145 +c01022ec vector107 +c01199e0 boot_pgdir +c0102091 vector40 +c0101684 intr_enable +c01022bf vector102 +c0102121 vector56 +c010218d vector68 +c0101f6d vector6 +c01023b5 vector129 +c01026e5 vector197 +c01024c9 vector152 +c01195e0 __vectors +c0102871 vector230 +c0105cf9 strncmp +c0104567 get_pte +c0102076 vector37 +c0102745 vector205 +c0102535 vector161 +c0105c77 strncpy +c01021a8 vector71 +c0102529 vector160 +c01027bd vector215 +c0102505 vector157 +c010168c intr_disable +c0101bfd print_regs +c0102319 vector112 +c01000a7 grade_backtrace2 +c0102631 vector182 +c0101f9d vector12 +c010603c memcmp +c01022fe vector109 +c0101fdd vector20 +c0102106 vector53 +c0101fcb vector18 +c0102280 vector95 +c0102841 vector226 +c01020e2 vector49 +c01020b5 vector44 +c01021e7 vector78 +c01025c5 vector173 +c0102346 vector117 +c0101a35 trap_in_kernel +c010220b vector82 +c0102811 vector222 +c0101f7f vector8 +c01024a5 vector149 +c010038e cputchar +c0105f08 memset +c0102889 vector232 +c01022e3 vector106 +c01027f9 vector220 +c0102253 vector90 +c010254d vector163 +c01028a1 vector234 +c0102157 vector62 +c010200a vector25 +c01026f1 vector198 +c0102361 vector120 +c01003f5 getchar +c0104761 page_remove +c01020eb vector50 +c0101fb2 vector15 +c0105702 printfmt +c01024bd vector151 +c0102214 vector83 +c010224a vector89 +c0102241 vector88 +c0101eff trap +c010260d vector179 +c010205b vector34 +c0116044 __STABSTR_END__ +c01020c7 vector46 +c0105cb0 strcmp +c01023f1 vector134 +c010281d vector223 +c01027e1 vector218 +c0100561 debuginfo_eip +c0101726 pic_init +c0102835 vector225 +c010266d vector187 +c010447f pmm_init +c0102037 vector30 +c01023a0 vector127 +c011c424 ticks +c01026a9 vector192 +c0102571 vector166 +c01021d5 vector76 +c01021cc vector75 +c01026cd vector195 +c01024b1 vector150 +c0102133 vector58 +c0102949 vector248 +c010237c vector123 +c0102289 vector96 +c0102040 vector31 +c010272d vector203 +c0103ed5 alloc_pages +c010242d vector139 +c01024d5 vector153 +c0102559 vector164 +c010236a vector121 +c011c680 switchk2u +c0101f64 vector5 +c010257d vector167 +c01024ed vector155 +c0102955 vector249 +c0106bcc vpt +c0102961 vector250 +c0102385 vector124 +c0102307 vector110 +c0102739 vector204 +c0101f2c __trapret +c0100331 vcprintf +c0102415 vector137 +c0100cb1 __warn +c010293d vector247 +c0101fef vector22 +c0102721 vector202 +c01021b1 vector72 +c0102118 vector55 +c01003a4 cputs +c0119000 bootstacktop +c0102397 vector126 +c0102172 vector65 +c0102025 vector28 +c0102595 vector169 +c0102895 vector233 +c010248d vector147 +c0117000 bootstack +c011a000 __boot_pgdir +c01022d1 vector104 +c011cee0 free_area +c010233d vector116 +c01073b8 __STAB_BEGIN__ +c01020fd vector52 +c0101fc4 vector17 +c0102649 vector184 +c0105bde strlen +c010275d vector207 +c0102691 vector190 +c01028dd vector239 +c0102277 vector94 +c010226e vector93 +c0102679 vector188 +c0105d4c strchr +c01020d9 vector48 +c01000ce grade_backtrace1 +c01027ed vector219 +c0102499 vector148 +c0102805 vector221 +c01021f9 vector80 +c01025ad vector171 +c01024e1 vector154 +c010206d vector36 +c011c6cc switchu2k +c01028ad vector235 +c01022da vector105 +c0100c0b mon_kerninfo +c011cf00 pages +c0102481 vector146 +c010269d vector191 +c01022c8 vector103 +c0100bae mon_help +c0101f96 vector11 +c0104863 tlb_invalidate +c0101fab vector14 diff --git a/labcodes/lab2/obj/kernel_nopage.asm b/labcodes/lab2/obj/kernel_nopage.asm new file mode 100644 index 00000000..adeed7de --- /dev/null +++ b/labcodes/lab2/obj/kernel_nopage.asm @@ -0,0 +1,12382 @@ + +bin/kernel_nopage: file format elf32-i386 + + +Disassembly of section .text: + +00100000 : + +.text +.globl kern_entry +kern_entry: + # load pa of boot pgdir + movl $REALLOC(__boot_pgdir), %eax + 100000: b8 00 a0 11 40 mov $0x4011a000,%eax + movl %eax, %cr3 + 100005: 0f 22 d8 mov %eax,%cr3 + + # enable paging + movl %cr0, %eax + 100008: 0f 20 c0 mov %cr0,%eax + orl $(CR0_PE | CR0_PG | CR0_AM | CR0_WP | CR0_NE | CR0_TS | CR0_EM | CR0_MP), %eax + 10000b: 0d 2f 00 05 80 or $0x8005002f,%eax + andl $~(CR0_TS | CR0_EM), %eax + 100010: 83 e0 f3 and $0xfffffff3,%eax + movl %eax, %cr0 + 100013: 0f 22 c0 mov %eax,%cr0 + + # update eip + # now, eip = 0x1..... + leal next, %eax + 100016: 8d 05 1e 00 10 00 lea 0x10001e,%eax + # set eip = KERNBASE + 0x1..... + jmp *%eax + 10001c: ff e0 jmp *%eax + +0010001e : +next: + + # unmap va 0 ~ 4M, it's temporary mapping + xorl %eax, %eax + 10001e: 31 c0 xor %eax,%eax + movl %eax, __boot_pgdir + 100020: a3 00 a0 11 00 mov %eax,0x11a000 + + # set ebp, esp + movl $0x0, %ebp + 100025: bd 00 00 00 00 mov $0x0,%ebp + # the kernel stack region is from bootstack -- bootstacktop, + # the kernel stack size is KSTACKSIZE (8KB)defined in memlayout.h + movl $bootstacktop, %esp + 10002a: bc 00 90 11 00 mov $0x119000,%esp + # now kernel stack is ready , call the first C function + call kern_init + 10002f: e8 02 00 00 00 call 100036 + +00100034 : + +# should never get here +spin: + jmp spin + 100034: eb fe jmp 100034 + +00100036 : +int kern_init(void) __attribute__((noreturn)); +void grade_backtrace(void); +static void lab1_switch_test(void); + +int +kern_init(void) { + 100036: 55 push %ebp + 100037: 89 e5 mov %esp,%ebp + 100039: 83 ec 28 sub $0x28,%esp + extern char edata[], end[]; + memset(edata, 0, end - edata); + 10003c: b8 8c cf 11 00 mov $0x11cf8c,%eax + 100041: 2d 36 9a 11 00 sub $0x119a36,%eax + 100046: 89 44 24 08 mov %eax,0x8(%esp) + 10004a: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 100051: 00 + 100052: c7 04 24 36 9a 11 00 movl $0x119a36,(%esp) + 100059: e8 aa 5e 00 00 call 105f08 + + cons_init(); // init the console + 10005e: e8 42 15 00 00 call 1015a5 + + const char *message = "(THU.CST) os is loading ..."; + 100063: c7 45 f4 a0 60 10 00 movl $0x1060a0,-0xc(%ebp) + cprintf("%s\n\n", message); + 10006a: 8b 45 f4 mov -0xc(%ebp),%eax + 10006d: 89 44 24 04 mov %eax,0x4(%esp) + 100071: c7 04 24 bc 60 10 00 movl $0x1060bc,(%esp) + 100078: e8 e9 02 00 00 call 100366 + + print_kerninfo(); + 10007d: e8 07 08 00 00 call 100889 + + grade_backtrace(); + 100082: e8 95 00 00 00 call 10011c + + pmm_init(); // init physical memory management + 100087: e8 f3 43 00 00 call 10447f + + pic_init(); // init interrupt controller + 10008c: e8 95 16 00 00 call 101726 + idt_init(); // init interrupt descriptor table + 100091: e8 f9 17 00 00 call 10188f + + clock_init(); // init clock interrupt + 100096: e8 69 0c 00 00 call 100d04 + intr_enable(); // enable irq interrupt + 10009b: e8 e4 15 00 00 call 101684 + + //LAB1: CAHLLENGE 1 If you try to do it, uncomment lab1_switch_test() + // user/kernel mode switch test + lab1_switch_test(); + 1000a0: e8 76 01 00 00 call 10021b + + /* do nothing */ + while (1); + 1000a5: eb fe jmp 1000a5 + +001000a7 : +} + +void __attribute__((noinline)) +grade_backtrace2(int arg0, int arg1, int arg2, int arg3) { + 1000a7: 55 push %ebp + 1000a8: 89 e5 mov %esp,%ebp + 1000aa: 83 ec 18 sub $0x18,%esp + mon_backtrace(0, NULL, NULL); + 1000ad: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 1000b4: 00 + 1000b5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 1000bc: 00 + 1000bd: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 1000c4: e8 56 0b 00 00 call 100c1f +} + 1000c9: 90 nop + 1000ca: 89 ec mov %ebp,%esp + 1000cc: 5d pop %ebp + 1000cd: c3 ret + +001000ce : + +void __attribute__((noinline)) +grade_backtrace1(int arg0, int arg1) { + 1000ce: 55 push %ebp + 1000cf: 89 e5 mov %esp,%ebp + 1000d1: 83 ec 18 sub $0x18,%esp + 1000d4: 89 5d fc mov %ebx,-0x4(%ebp) + grade_backtrace2(arg0, (int)&arg0, arg1, (int)&arg1); + 1000d7: 8d 4d 0c lea 0xc(%ebp),%ecx + 1000da: 8b 55 0c mov 0xc(%ebp),%edx + 1000dd: 8d 5d 08 lea 0x8(%ebp),%ebx + 1000e0: 8b 45 08 mov 0x8(%ebp),%eax + 1000e3: 89 4c 24 0c mov %ecx,0xc(%esp) + 1000e7: 89 54 24 08 mov %edx,0x8(%esp) + 1000eb: 89 5c 24 04 mov %ebx,0x4(%esp) + 1000ef: 89 04 24 mov %eax,(%esp) + 1000f2: e8 b0 ff ff ff call 1000a7 +} + 1000f7: 90 nop + 1000f8: 8b 5d fc mov -0x4(%ebp),%ebx + 1000fb: 89 ec mov %ebp,%esp + 1000fd: 5d pop %ebp + 1000fe: c3 ret + +001000ff : + +void __attribute__((noinline)) +grade_backtrace0(int arg0, int arg1, int arg2) { + 1000ff: 55 push %ebp + 100100: 89 e5 mov %esp,%ebp + 100102: 83 ec 18 sub $0x18,%esp + grade_backtrace1(arg0, arg2); + 100105: 8b 45 10 mov 0x10(%ebp),%eax + 100108: 89 44 24 04 mov %eax,0x4(%esp) + 10010c: 8b 45 08 mov 0x8(%ebp),%eax + 10010f: 89 04 24 mov %eax,(%esp) + 100112: e8 b7 ff ff ff call 1000ce +} + 100117: 90 nop + 100118: 89 ec mov %ebp,%esp + 10011a: 5d pop %ebp + 10011b: c3 ret + +0010011c : + +void +grade_backtrace(void) { + 10011c: 55 push %ebp + 10011d: 89 e5 mov %esp,%ebp + 10011f: 83 ec 18 sub $0x18,%esp + grade_backtrace0(0, (int)kern_init, 0xffff0000); + 100122: b8 36 00 10 00 mov $0x100036,%eax + 100127: c7 44 24 08 00 00 ff movl $0xffff0000,0x8(%esp) + 10012e: ff + 10012f: 89 44 24 04 mov %eax,0x4(%esp) + 100133: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 10013a: e8 c0 ff ff ff call 1000ff +} + 10013f: 90 nop + 100140: 89 ec mov %ebp,%esp + 100142: 5d pop %ebp + 100143: c3 ret + +00100144 : + +static void +lab1_print_cur_status(void) { + 100144: 55 push %ebp + 100145: 89 e5 mov %esp,%ebp + 100147: 83 ec 28 sub $0x28,%esp + static int round = 0; + uint16_t reg1, reg2, reg3, reg4; + asm volatile ( + 10014a: 8c 4d f6 mov %cs,-0xa(%ebp) + 10014d: 8c 5d f4 mov %ds,-0xc(%ebp) + 100150: 8c 45 f2 mov %es,-0xe(%ebp) + 100153: 8c 55 f0 mov %ss,-0x10(%ebp) + "mov %%cs, %0;" + "mov %%ds, %1;" + "mov %%es, %2;" + "mov %%ss, %3;" + : "=m"(reg1), "=m"(reg2), "=m"(reg3), "=m"(reg4)); + cprintf("%d: @ring %d\n", round, reg1 & 3); + 100156: 0f b7 45 f6 movzwl -0xa(%ebp),%eax + 10015a: 83 e0 03 and $0x3,%eax + 10015d: 89 c2 mov %eax,%edx + 10015f: a1 00 c0 11 00 mov 0x11c000,%eax + 100164: 89 54 24 08 mov %edx,0x8(%esp) + 100168: 89 44 24 04 mov %eax,0x4(%esp) + 10016c: c7 04 24 c1 60 10 00 movl $0x1060c1,(%esp) + 100173: e8 ee 01 00 00 call 100366 + cprintf("%d: cs = %x\n", round, reg1); + 100178: 0f b7 45 f6 movzwl -0xa(%ebp),%eax + 10017c: 89 c2 mov %eax,%edx + 10017e: a1 00 c0 11 00 mov 0x11c000,%eax + 100183: 89 54 24 08 mov %edx,0x8(%esp) + 100187: 89 44 24 04 mov %eax,0x4(%esp) + 10018b: c7 04 24 cf 60 10 00 movl $0x1060cf,(%esp) + 100192: e8 cf 01 00 00 call 100366 + cprintf("%d: ds = %x\n", round, reg2); + 100197: 0f b7 45 f4 movzwl -0xc(%ebp),%eax + 10019b: 89 c2 mov %eax,%edx + 10019d: a1 00 c0 11 00 mov 0x11c000,%eax + 1001a2: 89 54 24 08 mov %edx,0x8(%esp) + 1001a6: 89 44 24 04 mov %eax,0x4(%esp) + 1001aa: c7 04 24 dd 60 10 00 movl $0x1060dd,(%esp) + 1001b1: e8 b0 01 00 00 call 100366 + cprintf("%d: es = %x\n", round, reg3); + 1001b6: 0f b7 45 f2 movzwl -0xe(%ebp),%eax + 1001ba: 89 c2 mov %eax,%edx + 1001bc: a1 00 c0 11 00 mov 0x11c000,%eax + 1001c1: 89 54 24 08 mov %edx,0x8(%esp) + 1001c5: 89 44 24 04 mov %eax,0x4(%esp) + 1001c9: c7 04 24 eb 60 10 00 movl $0x1060eb,(%esp) + 1001d0: e8 91 01 00 00 call 100366 + cprintf("%d: ss = %x\n", round, reg4); + 1001d5: 0f b7 45 f0 movzwl -0x10(%ebp),%eax + 1001d9: 89 c2 mov %eax,%edx + 1001db: a1 00 c0 11 00 mov 0x11c000,%eax + 1001e0: 89 54 24 08 mov %edx,0x8(%esp) + 1001e4: 89 44 24 04 mov %eax,0x4(%esp) + 1001e8: c7 04 24 f9 60 10 00 movl $0x1060f9,(%esp) + 1001ef: e8 72 01 00 00 call 100366 + round ++; + 1001f4: a1 00 c0 11 00 mov 0x11c000,%eax + 1001f9: 40 inc %eax + 1001fa: a3 00 c0 11 00 mov %eax,0x11c000 +} + 1001ff: 90 nop + 100200: 89 ec mov %ebp,%esp + 100202: 5d pop %ebp + 100203: c3 ret + +00100204 : + +static void +lab1_switch_to_user(void) { + 100204: 55 push %ebp + 100205: 89 e5 mov %esp,%ebp + //LAB1 CHALLENGE 1 : TODO + asm volatile ( + 100207: 83 ec 08 sub $0x8,%esp + 10020a: cd 78 int $0x78 + 10020c: 89 ec mov %ebp,%esp + "int %0 \n" + "movl %%ebp, %%esp" + : + : "i"(T_SWITCH_TOU) + ); +} + 10020e: 90 nop + 10020f: 5d pop %ebp + 100210: c3 ret + +00100211 : + +static void +lab1_switch_to_kernel(void) { + 100211: 55 push %ebp + 100212: 89 e5 mov %esp,%ebp + //LAB1 CHALLENGE 1 : TODO + asm volatile ( + 100214: cd 79 int $0x79 + 100216: 89 ec mov %ebp,%esp + "int %0 \n" + "movl %%ebp, %%esp \n" + : + : "i"(T_SWITCH_TOK) + ); +} + 100218: 90 nop + 100219: 5d pop %ebp + 10021a: c3 ret + +0010021b : + +static void +lab1_switch_test(void) { + 10021b: 55 push %ebp + 10021c: 89 e5 mov %esp,%ebp + 10021e: 83 ec 18 sub $0x18,%esp + lab1_print_cur_status(); + 100221: e8 1e ff ff ff call 100144 + cprintf("+++ switch to user mode +++\n"); + 100226: c7 04 24 08 61 10 00 movl $0x106108,(%esp) + 10022d: e8 34 01 00 00 call 100366 + lab1_switch_to_user(); + 100232: e8 cd ff ff ff call 100204 + lab1_print_cur_status(); + 100237: e8 08 ff ff ff call 100144 + cprintf("+++ switch to kernel mode +++\n"); + 10023c: c7 04 24 28 61 10 00 movl $0x106128,(%esp) + 100243: e8 1e 01 00 00 call 100366 + lab1_switch_to_kernel(); + 100248: e8 c4 ff ff ff call 100211 + lab1_print_cur_status(); + 10024d: e8 f2 fe ff ff call 100144 +} + 100252: 90 nop + 100253: 89 ec mov %ebp,%esp + 100255: 5d pop %ebp + 100256: c3 ret + +00100257 : + * The readline() function returns the text of the line read. If some errors + * are happened, NULL is returned. The return value is a global variable, + * thus it should be copied before it is used. + * */ +char * +readline(const char *prompt) { + 100257: 55 push %ebp + 100258: 89 e5 mov %esp,%ebp + 10025a: 83 ec 28 sub $0x28,%esp + if (prompt != NULL) { + 10025d: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 100261: 74 13 je 100276 + cprintf("%s", prompt); + 100263: 8b 45 08 mov 0x8(%ebp),%eax + 100266: 89 44 24 04 mov %eax,0x4(%esp) + 10026a: c7 04 24 47 61 10 00 movl $0x106147,(%esp) + 100271: e8 f0 00 00 00 call 100366 + } + int i = 0, c; + 100276: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + while (1) { + c = getchar(); + 10027d: e8 73 01 00 00 call 1003f5 + 100282: 89 45 f0 mov %eax,-0x10(%ebp) + if (c < 0) { + 100285: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 100289: 79 07 jns 100292 + return NULL; + 10028b: b8 00 00 00 00 mov $0x0,%eax + 100290: eb 78 jmp 10030a + } + else if (c >= ' ' && i < BUFSIZE - 1) { + 100292: 83 7d f0 1f cmpl $0x1f,-0x10(%ebp) + 100296: 7e 28 jle 1002c0 + 100298: 81 7d f4 fe 03 00 00 cmpl $0x3fe,-0xc(%ebp) + 10029f: 7f 1f jg 1002c0 + cputchar(c); + 1002a1: 8b 45 f0 mov -0x10(%ebp),%eax + 1002a4: 89 04 24 mov %eax,(%esp) + 1002a7: e8 e2 00 00 00 call 10038e + buf[i ++] = c; + 1002ac: 8b 45 f4 mov -0xc(%ebp),%eax + 1002af: 8d 50 01 lea 0x1(%eax),%edx + 1002b2: 89 55 f4 mov %edx,-0xc(%ebp) + 1002b5: 8b 55 f0 mov -0x10(%ebp),%edx + 1002b8: 88 90 20 c0 11 00 mov %dl,0x11c020(%eax) + 1002be: eb 45 jmp 100305 + } + else if (c == '\b' && i > 0) { + 1002c0: 83 7d f0 08 cmpl $0x8,-0x10(%ebp) + 1002c4: 75 16 jne 1002dc + 1002c6: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 1002ca: 7e 10 jle 1002dc + cputchar(c); + 1002cc: 8b 45 f0 mov -0x10(%ebp),%eax + 1002cf: 89 04 24 mov %eax,(%esp) + 1002d2: e8 b7 00 00 00 call 10038e + i --; + 1002d7: ff 4d f4 decl -0xc(%ebp) + 1002da: eb 29 jmp 100305 + } + else if (c == '\n' || c == '\r') { + 1002dc: 83 7d f0 0a cmpl $0xa,-0x10(%ebp) + 1002e0: 74 06 je 1002e8 + 1002e2: 83 7d f0 0d cmpl $0xd,-0x10(%ebp) + 1002e6: 75 95 jne 10027d + cputchar(c); + 1002e8: 8b 45 f0 mov -0x10(%ebp),%eax + 1002eb: 89 04 24 mov %eax,(%esp) + 1002ee: e8 9b 00 00 00 call 10038e + buf[i] = '\0'; + 1002f3: 8b 45 f4 mov -0xc(%ebp),%eax + 1002f6: 05 20 c0 11 00 add $0x11c020,%eax + 1002fb: c6 00 00 movb $0x0,(%eax) + return buf; + 1002fe: b8 20 c0 11 00 mov $0x11c020,%eax + 100303: eb 05 jmp 10030a + c = getchar(); + 100305: e9 73 ff ff ff jmp 10027d + } + } +} + 10030a: 89 ec mov %ebp,%esp + 10030c: 5d pop %ebp + 10030d: c3 ret + +0010030e : +/* * + * cputch - writes a single character @c to stdout, and it will + * increace the value of counter pointed by @cnt. + * */ +static void +cputch(int c, int *cnt) { + 10030e: 55 push %ebp + 10030f: 89 e5 mov %esp,%ebp + 100311: 83 ec 18 sub $0x18,%esp + cons_putc(c); + 100314: 8b 45 08 mov 0x8(%ebp),%eax + 100317: 89 04 24 mov %eax,(%esp) + 10031a: e8 b5 12 00 00 call 1015d4 + (*cnt) ++; + 10031f: 8b 45 0c mov 0xc(%ebp),%eax + 100322: 8b 00 mov (%eax),%eax + 100324: 8d 50 01 lea 0x1(%eax),%edx + 100327: 8b 45 0c mov 0xc(%ebp),%eax + 10032a: 89 10 mov %edx,(%eax) +} + 10032c: 90 nop + 10032d: 89 ec mov %ebp,%esp + 10032f: 5d pop %ebp + 100330: c3 ret + +00100331 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want cprintf() instead. + * */ +int +vcprintf(const char *fmt, va_list ap) { + 100331: 55 push %ebp + 100332: 89 e5 mov %esp,%ebp + 100334: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 100337: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + vprintfmt((void*)cputch, &cnt, fmt, ap); + 10033e: 8b 45 0c mov 0xc(%ebp),%eax + 100341: 89 44 24 0c mov %eax,0xc(%esp) + 100345: 8b 45 08 mov 0x8(%ebp),%eax + 100348: 89 44 24 08 mov %eax,0x8(%esp) + 10034c: 8d 45 f4 lea -0xc(%ebp),%eax + 10034f: 89 44 24 04 mov %eax,0x4(%esp) + 100353: c7 04 24 0e 03 10 00 movl $0x10030e,(%esp) + 10035a: e8 d4 53 00 00 call 105733 + return cnt; + 10035f: 8b 45 f4 mov -0xc(%ebp),%eax +} + 100362: 89 ec mov %ebp,%esp + 100364: 5d pop %ebp + 100365: c3 ret + +00100366 : + * + * The return value is the number of characters which would be + * written to stdout. + * */ +int +cprintf(const char *fmt, ...) { + 100366: 55 push %ebp + 100367: 89 e5 mov %esp,%ebp + 100369: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 10036c: 8d 45 0c lea 0xc(%ebp),%eax + 10036f: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vcprintf(fmt, ap); + 100372: 8b 45 f0 mov -0x10(%ebp),%eax + 100375: 89 44 24 04 mov %eax,0x4(%esp) + 100379: 8b 45 08 mov 0x8(%ebp),%eax + 10037c: 89 04 24 mov %eax,(%esp) + 10037f: e8 ad ff ff ff call 100331 + 100384: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 100387: 8b 45 f4 mov -0xc(%ebp),%eax +} + 10038a: 89 ec mov %ebp,%esp + 10038c: 5d pop %ebp + 10038d: c3 ret + +0010038e : + +/* cputchar - writes a single character to stdout */ +void +cputchar(int c) { + 10038e: 55 push %ebp + 10038f: 89 e5 mov %esp,%ebp + 100391: 83 ec 18 sub $0x18,%esp + cons_putc(c); + 100394: 8b 45 08 mov 0x8(%ebp),%eax + 100397: 89 04 24 mov %eax,(%esp) + 10039a: e8 35 12 00 00 call 1015d4 +} + 10039f: 90 nop + 1003a0: 89 ec mov %ebp,%esp + 1003a2: 5d pop %ebp + 1003a3: c3 ret + +001003a4 : +/* * + * cputs- writes the string pointed by @str to stdout and + * appends a newline character. + * */ +int +cputs(const char *str) { + 1003a4: 55 push %ebp + 1003a5: 89 e5 mov %esp,%ebp + 1003a7: 83 ec 28 sub $0x28,%esp + int cnt = 0; + 1003aa: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + char c; + while ((c = *str ++) != '\0') { + 1003b1: eb 13 jmp 1003c6 + cputch(c, &cnt); + 1003b3: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 1003b7: 8d 55 f0 lea -0x10(%ebp),%edx + 1003ba: 89 54 24 04 mov %edx,0x4(%esp) + 1003be: 89 04 24 mov %eax,(%esp) + 1003c1: e8 48 ff ff ff call 10030e + while ((c = *str ++) != '\0') { + 1003c6: 8b 45 08 mov 0x8(%ebp),%eax + 1003c9: 8d 50 01 lea 0x1(%eax),%edx + 1003cc: 89 55 08 mov %edx,0x8(%ebp) + 1003cf: 0f b6 00 movzbl (%eax),%eax + 1003d2: 88 45 f7 mov %al,-0x9(%ebp) + 1003d5: 80 7d f7 00 cmpb $0x0,-0x9(%ebp) + 1003d9: 75 d8 jne 1003b3 + } + cputch('\n', &cnt); + 1003db: 8d 45 f0 lea -0x10(%ebp),%eax + 1003de: 89 44 24 04 mov %eax,0x4(%esp) + 1003e2: c7 04 24 0a 00 00 00 movl $0xa,(%esp) + 1003e9: e8 20 ff ff ff call 10030e + return cnt; + 1003ee: 8b 45 f0 mov -0x10(%ebp),%eax +} + 1003f1: 89 ec mov %ebp,%esp + 1003f3: 5d pop %ebp + 1003f4: c3 ret + +001003f5 : + +/* getchar - reads a single non-zero character from stdin */ +int +getchar(void) { + 1003f5: 55 push %ebp + 1003f6: 89 e5 mov %esp,%ebp + 1003f8: 83 ec 18 sub $0x18,%esp + int c; + while ((c = cons_getc()) == 0) + 1003fb: 90 nop + 1003fc: e8 12 12 00 00 call 101613 + 100401: 89 45 f4 mov %eax,-0xc(%ebp) + 100404: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 100408: 74 f2 je 1003fc + /* do nothing */; + return c; + 10040a: 8b 45 f4 mov -0xc(%ebp),%eax +} + 10040d: 89 ec mov %ebp,%esp + 10040f: 5d pop %ebp + 100410: c3 ret + +00100411 : + * stab_binsearch(stabs, &left, &right, N_SO, 0xf0100184); + * will exit setting left = 118, right = 554. + * */ +static void +stab_binsearch(const struct stab *stabs, int *region_left, int *region_right, + int type, uintptr_t addr) { + 100411: 55 push %ebp + 100412: 89 e5 mov %esp,%ebp + 100414: 83 ec 20 sub $0x20,%esp + int l = *region_left, r = *region_right, any_matches = 0; + 100417: 8b 45 0c mov 0xc(%ebp),%eax + 10041a: 8b 00 mov (%eax),%eax + 10041c: 89 45 fc mov %eax,-0x4(%ebp) + 10041f: 8b 45 10 mov 0x10(%ebp),%eax + 100422: 8b 00 mov (%eax),%eax + 100424: 89 45 f8 mov %eax,-0x8(%ebp) + 100427: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + + while (l <= r) { + 10042e: e9 ca 00 00 00 jmp 1004fd + int true_m = (l + r) / 2, m = true_m; + 100433: 8b 55 fc mov -0x4(%ebp),%edx + 100436: 8b 45 f8 mov -0x8(%ebp),%eax + 100439: 01 d0 add %edx,%eax + 10043b: 89 c2 mov %eax,%edx + 10043d: c1 ea 1f shr $0x1f,%edx + 100440: 01 d0 add %edx,%eax + 100442: d1 f8 sar %eax + 100444: 89 45 ec mov %eax,-0x14(%ebp) + 100447: 8b 45 ec mov -0x14(%ebp),%eax + 10044a: 89 45 f0 mov %eax,-0x10(%ebp) + + // search for earliest stab with right type + while (m >= l && stabs[m].n_type != type) { + 10044d: eb 03 jmp 100452 + m --; + 10044f: ff 4d f0 decl -0x10(%ebp) + while (m >= l && stabs[m].n_type != type) { + 100452: 8b 45 f0 mov -0x10(%ebp),%eax + 100455: 3b 45 fc cmp -0x4(%ebp),%eax + 100458: 7c 1f jl 100479 + 10045a: 8b 55 f0 mov -0x10(%ebp),%edx + 10045d: 89 d0 mov %edx,%eax + 10045f: 01 c0 add %eax,%eax + 100461: 01 d0 add %edx,%eax + 100463: c1 e0 02 shl $0x2,%eax + 100466: 89 c2 mov %eax,%edx + 100468: 8b 45 08 mov 0x8(%ebp),%eax + 10046b: 01 d0 add %edx,%eax + 10046d: 0f b6 40 04 movzbl 0x4(%eax),%eax + 100471: 0f b6 c0 movzbl %al,%eax + 100474: 39 45 14 cmp %eax,0x14(%ebp) + 100477: 75 d6 jne 10044f + } + if (m < l) { // no match in [l, m] + 100479: 8b 45 f0 mov -0x10(%ebp),%eax + 10047c: 3b 45 fc cmp -0x4(%ebp),%eax + 10047f: 7d 09 jge 10048a + l = true_m + 1; + 100481: 8b 45 ec mov -0x14(%ebp),%eax + 100484: 40 inc %eax + 100485: 89 45 fc mov %eax,-0x4(%ebp) + continue; + 100488: eb 73 jmp 1004fd + } + + // actual binary search + any_matches = 1; + 10048a: c7 45 f4 01 00 00 00 movl $0x1,-0xc(%ebp) + if (stabs[m].n_value < addr) { + 100491: 8b 55 f0 mov -0x10(%ebp),%edx + 100494: 89 d0 mov %edx,%eax + 100496: 01 c0 add %eax,%eax + 100498: 01 d0 add %edx,%eax + 10049a: c1 e0 02 shl $0x2,%eax + 10049d: 89 c2 mov %eax,%edx + 10049f: 8b 45 08 mov 0x8(%ebp),%eax + 1004a2: 01 d0 add %edx,%eax + 1004a4: 8b 40 08 mov 0x8(%eax),%eax + 1004a7: 39 45 18 cmp %eax,0x18(%ebp) + 1004aa: 76 11 jbe 1004bd + *region_left = m; + 1004ac: 8b 45 0c mov 0xc(%ebp),%eax + 1004af: 8b 55 f0 mov -0x10(%ebp),%edx + 1004b2: 89 10 mov %edx,(%eax) + l = true_m + 1; + 1004b4: 8b 45 ec mov -0x14(%ebp),%eax + 1004b7: 40 inc %eax + 1004b8: 89 45 fc mov %eax,-0x4(%ebp) + 1004bb: eb 40 jmp 1004fd + } else if (stabs[m].n_value > addr) { + 1004bd: 8b 55 f0 mov -0x10(%ebp),%edx + 1004c0: 89 d0 mov %edx,%eax + 1004c2: 01 c0 add %eax,%eax + 1004c4: 01 d0 add %edx,%eax + 1004c6: c1 e0 02 shl $0x2,%eax + 1004c9: 89 c2 mov %eax,%edx + 1004cb: 8b 45 08 mov 0x8(%ebp),%eax + 1004ce: 01 d0 add %edx,%eax + 1004d0: 8b 40 08 mov 0x8(%eax),%eax + 1004d3: 39 45 18 cmp %eax,0x18(%ebp) + 1004d6: 73 14 jae 1004ec + *region_right = m - 1; + 1004d8: 8b 45 f0 mov -0x10(%ebp),%eax + 1004db: 8d 50 ff lea -0x1(%eax),%edx + 1004de: 8b 45 10 mov 0x10(%ebp),%eax + 1004e1: 89 10 mov %edx,(%eax) + r = m - 1; + 1004e3: 8b 45 f0 mov -0x10(%ebp),%eax + 1004e6: 48 dec %eax + 1004e7: 89 45 f8 mov %eax,-0x8(%ebp) + 1004ea: eb 11 jmp 1004fd + } else { + // exact match for 'addr', but continue loop to find + // *region_right + *region_left = m; + 1004ec: 8b 45 0c mov 0xc(%ebp),%eax + 1004ef: 8b 55 f0 mov -0x10(%ebp),%edx + 1004f2: 89 10 mov %edx,(%eax) + l = m; + 1004f4: 8b 45 f0 mov -0x10(%ebp),%eax + 1004f7: 89 45 fc mov %eax,-0x4(%ebp) + addr ++; + 1004fa: ff 45 18 incl 0x18(%ebp) + while (l <= r) { + 1004fd: 8b 45 fc mov -0x4(%ebp),%eax + 100500: 3b 45 f8 cmp -0x8(%ebp),%eax + 100503: 0f 8e 2a ff ff ff jle 100433 + } + } + + if (!any_matches) { + 100509: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 10050d: 75 0f jne 10051e + *region_right = *region_left - 1; + 10050f: 8b 45 0c mov 0xc(%ebp),%eax + 100512: 8b 00 mov (%eax),%eax + 100514: 8d 50 ff lea -0x1(%eax),%edx + 100517: 8b 45 10 mov 0x10(%ebp),%eax + 10051a: 89 10 mov %edx,(%eax) + l = *region_right; + for (; l > *region_left && stabs[l].n_type != type; l --) + /* do nothing */; + *region_left = l; + } +} + 10051c: eb 3e jmp 10055c + l = *region_right; + 10051e: 8b 45 10 mov 0x10(%ebp),%eax + 100521: 8b 00 mov (%eax),%eax + 100523: 89 45 fc mov %eax,-0x4(%ebp) + for (; l > *region_left && stabs[l].n_type != type; l --) + 100526: eb 03 jmp 10052b + 100528: ff 4d fc decl -0x4(%ebp) + 10052b: 8b 45 0c mov 0xc(%ebp),%eax + 10052e: 8b 00 mov (%eax),%eax + 100530: 39 45 fc cmp %eax,-0x4(%ebp) + 100533: 7e 1f jle 100554 + 100535: 8b 55 fc mov -0x4(%ebp),%edx + 100538: 89 d0 mov %edx,%eax + 10053a: 01 c0 add %eax,%eax + 10053c: 01 d0 add %edx,%eax + 10053e: c1 e0 02 shl $0x2,%eax + 100541: 89 c2 mov %eax,%edx + 100543: 8b 45 08 mov 0x8(%ebp),%eax + 100546: 01 d0 add %edx,%eax + 100548: 0f b6 40 04 movzbl 0x4(%eax),%eax + 10054c: 0f b6 c0 movzbl %al,%eax + 10054f: 39 45 14 cmp %eax,0x14(%ebp) + 100552: 75 d4 jne 100528 + *region_left = l; + 100554: 8b 45 0c mov 0xc(%ebp),%eax + 100557: 8b 55 fc mov -0x4(%ebp),%edx + 10055a: 89 10 mov %edx,(%eax) +} + 10055c: 90 nop + 10055d: 89 ec mov %ebp,%esp + 10055f: 5d pop %ebp + 100560: c3 ret + +00100561 : + * the specified instruction address, @addr. Returns 0 if information + * was found, and negative if not. But even if it returns negative it + * has stored some information into '*info'. + * */ +int +debuginfo_eip(uintptr_t addr, struct eipdebuginfo *info) { + 100561: 55 push %ebp + 100562: 89 e5 mov %esp,%ebp + 100564: 83 ec 58 sub $0x58,%esp + const struct stab *stabs, *stab_end; + const char *stabstr, *stabstr_end; + + info->eip_file = ""; + 100567: 8b 45 0c mov 0xc(%ebp),%eax + 10056a: c7 00 4c 61 10 00 movl $0x10614c,(%eax) + info->eip_line = 0; + 100570: 8b 45 0c mov 0xc(%ebp),%eax + 100573: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) + info->eip_fn_name = ""; + 10057a: 8b 45 0c mov 0xc(%ebp),%eax + 10057d: c7 40 08 4c 61 10 00 movl $0x10614c,0x8(%eax) + info->eip_fn_namelen = 9; + 100584: 8b 45 0c mov 0xc(%ebp),%eax + 100587: c7 40 0c 09 00 00 00 movl $0x9,0xc(%eax) + info->eip_fn_addr = addr; + 10058e: 8b 45 0c mov 0xc(%ebp),%eax + 100591: 8b 55 08 mov 0x8(%ebp),%edx + 100594: 89 50 10 mov %edx,0x10(%eax) + info->eip_fn_narg = 0; + 100597: 8b 45 0c mov 0xc(%ebp),%eax + 10059a: c7 40 14 00 00 00 00 movl $0x0,0x14(%eax) + + stabs = __STAB_BEGIN__; + 1005a1: c7 45 f4 b8 73 10 00 movl $0x1073b8,-0xc(%ebp) + stab_end = __STAB_END__; + 1005a8: c7 45 f0 ac 2a 11 00 movl $0x112aac,-0x10(%ebp) + stabstr = __STABSTR_BEGIN__; + 1005af: c7 45 ec ad 2a 11 00 movl $0x112aad,-0x14(%ebp) + stabstr_end = __STABSTR_END__; + 1005b6: c7 45 e8 44 60 11 00 movl $0x116044,-0x18(%ebp) + + // String table validity checks + if (stabstr_end <= stabstr || stabstr_end[-1] != 0) { + 1005bd: 8b 45 e8 mov -0x18(%ebp),%eax + 1005c0: 3b 45 ec cmp -0x14(%ebp),%eax + 1005c3: 76 0b jbe 1005d0 + 1005c5: 8b 45 e8 mov -0x18(%ebp),%eax + 1005c8: 48 dec %eax + 1005c9: 0f b6 00 movzbl (%eax),%eax + 1005cc: 84 c0 test %al,%al + 1005ce: 74 0a je 1005da + return -1; + 1005d0: b8 ff ff ff ff mov $0xffffffff,%eax + 1005d5: e9 ab 02 00 00 jmp 100885 + // 'eip'. First, we find the basic source file containing 'eip'. + // Then, we look in that source file for the function. Then we look + // for the line number. + + // Search the entire set of stabs for the source file (type N_SO). + int lfile = 0, rfile = (stab_end - stabs) - 1; + 1005da: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + 1005e1: 8b 45 f0 mov -0x10(%ebp),%eax + 1005e4: 2b 45 f4 sub -0xc(%ebp),%eax + 1005e7: c1 f8 02 sar $0x2,%eax + 1005ea: 69 c0 ab aa aa aa imul $0xaaaaaaab,%eax,%eax + 1005f0: 48 dec %eax + 1005f1: 89 45 e0 mov %eax,-0x20(%ebp) + stab_binsearch(stabs, &lfile, &rfile, N_SO, addr); + 1005f4: 8b 45 08 mov 0x8(%ebp),%eax + 1005f7: 89 44 24 10 mov %eax,0x10(%esp) + 1005fb: c7 44 24 0c 64 00 00 movl $0x64,0xc(%esp) + 100602: 00 + 100603: 8d 45 e0 lea -0x20(%ebp),%eax + 100606: 89 44 24 08 mov %eax,0x8(%esp) + 10060a: 8d 45 e4 lea -0x1c(%ebp),%eax + 10060d: 89 44 24 04 mov %eax,0x4(%esp) + 100611: 8b 45 f4 mov -0xc(%ebp),%eax + 100614: 89 04 24 mov %eax,(%esp) + 100617: e8 f5 fd ff ff call 100411 + if (lfile == 0) + 10061c: 8b 45 e4 mov -0x1c(%ebp),%eax + 10061f: 85 c0 test %eax,%eax + 100621: 75 0a jne 10062d + return -1; + 100623: b8 ff ff ff ff mov $0xffffffff,%eax + 100628: e9 58 02 00 00 jmp 100885 + + // Search within that file's stabs for the function definition + // (N_FUN). + int lfun = lfile, rfun = rfile; + 10062d: 8b 45 e4 mov -0x1c(%ebp),%eax + 100630: 89 45 dc mov %eax,-0x24(%ebp) + 100633: 8b 45 e0 mov -0x20(%ebp),%eax + 100636: 89 45 d8 mov %eax,-0x28(%ebp) + int lline, rline; + stab_binsearch(stabs, &lfun, &rfun, N_FUN, addr); + 100639: 8b 45 08 mov 0x8(%ebp),%eax + 10063c: 89 44 24 10 mov %eax,0x10(%esp) + 100640: c7 44 24 0c 24 00 00 movl $0x24,0xc(%esp) + 100647: 00 + 100648: 8d 45 d8 lea -0x28(%ebp),%eax + 10064b: 89 44 24 08 mov %eax,0x8(%esp) + 10064f: 8d 45 dc lea -0x24(%ebp),%eax + 100652: 89 44 24 04 mov %eax,0x4(%esp) + 100656: 8b 45 f4 mov -0xc(%ebp),%eax + 100659: 89 04 24 mov %eax,(%esp) + 10065c: e8 b0 fd ff ff call 100411 + + if (lfun <= rfun) { + 100661: 8b 55 dc mov -0x24(%ebp),%edx + 100664: 8b 45 d8 mov -0x28(%ebp),%eax + 100667: 39 c2 cmp %eax,%edx + 100669: 7f 78 jg 1006e3 + // stabs[lfun] points to the function name + // in the string table, but check bounds just in case. + if (stabs[lfun].n_strx < stabstr_end - stabstr) { + 10066b: 8b 45 dc mov -0x24(%ebp),%eax + 10066e: 89 c2 mov %eax,%edx + 100670: 89 d0 mov %edx,%eax + 100672: 01 c0 add %eax,%eax + 100674: 01 d0 add %edx,%eax + 100676: c1 e0 02 shl $0x2,%eax + 100679: 89 c2 mov %eax,%edx + 10067b: 8b 45 f4 mov -0xc(%ebp),%eax + 10067e: 01 d0 add %edx,%eax + 100680: 8b 10 mov (%eax),%edx + 100682: 8b 45 e8 mov -0x18(%ebp),%eax + 100685: 2b 45 ec sub -0x14(%ebp),%eax + 100688: 39 c2 cmp %eax,%edx + 10068a: 73 22 jae 1006ae + info->eip_fn_name = stabstr + stabs[lfun].n_strx; + 10068c: 8b 45 dc mov -0x24(%ebp),%eax + 10068f: 89 c2 mov %eax,%edx + 100691: 89 d0 mov %edx,%eax + 100693: 01 c0 add %eax,%eax + 100695: 01 d0 add %edx,%eax + 100697: c1 e0 02 shl $0x2,%eax + 10069a: 89 c2 mov %eax,%edx + 10069c: 8b 45 f4 mov -0xc(%ebp),%eax + 10069f: 01 d0 add %edx,%eax + 1006a1: 8b 10 mov (%eax),%edx + 1006a3: 8b 45 ec mov -0x14(%ebp),%eax + 1006a6: 01 c2 add %eax,%edx + 1006a8: 8b 45 0c mov 0xc(%ebp),%eax + 1006ab: 89 50 08 mov %edx,0x8(%eax) + } + info->eip_fn_addr = stabs[lfun].n_value; + 1006ae: 8b 45 dc mov -0x24(%ebp),%eax + 1006b1: 89 c2 mov %eax,%edx + 1006b3: 89 d0 mov %edx,%eax + 1006b5: 01 c0 add %eax,%eax + 1006b7: 01 d0 add %edx,%eax + 1006b9: c1 e0 02 shl $0x2,%eax + 1006bc: 89 c2 mov %eax,%edx + 1006be: 8b 45 f4 mov -0xc(%ebp),%eax + 1006c1: 01 d0 add %edx,%eax + 1006c3: 8b 50 08 mov 0x8(%eax),%edx + 1006c6: 8b 45 0c mov 0xc(%ebp),%eax + 1006c9: 89 50 10 mov %edx,0x10(%eax) + addr -= info->eip_fn_addr; + 1006cc: 8b 45 0c mov 0xc(%ebp),%eax + 1006cf: 8b 40 10 mov 0x10(%eax),%eax + 1006d2: 29 45 08 sub %eax,0x8(%ebp) + // Search within the function definition for the line number. + lline = lfun; + 1006d5: 8b 45 dc mov -0x24(%ebp),%eax + 1006d8: 89 45 d4 mov %eax,-0x2c(%ebp) + rline = rfun; + 1006db: 8b 45 d8 mov -0x28(%ebp),%eax + 1006de: 89 45 d0 mov %eax,-0x30(%ebp) + 1006e1: eb 15 jmp 1006f8 + } else { + // Couldn't find function stab! Maybe we're in an assembly + // file. Search the whole file for the line number. + info->eip_fn_addr = addr; + 1006e3: 8b 45 0c mov 0xc(%ebp),%eax + 1006e6: 8b 55 08 mov 0x8(%ebp),%edx + 1006e9: 89 50 10 mov %edx,0x10(%eax) + lline = lfile; + 1006ec: 8b 45 e4 mov -0x1c(%ebp),%eax + 1006ef: 89 45 d4 mov %eax,-0x2c(%ebp) + rline = rfile; + 1006f2: 8b 45 e0 mov -0x20(%ebp),%eax + 1006f5: 89 45 d0 mov %eax,-0x30(%ebp) + } + info->eip_fn_namelen = strfind(info->eip_fn_name, ':') - info->eip_fn_name; + 1006f8: 8b 45 0c mov 0xc(%ebp),%eax + 1006fb: 8b 40 08 mov 0x8(%eax),%eax + 1006fe: c7 44 24 04 3a 00 00 movl $0x3a,0x4(%esp) + 100705: 00 + 100706: 89 04 24 mov %eax,(%esp) + 100709: e8 72 56 00 00 call 105d80 + 10070e: 8b 55 0c mov 0xc(%ebp),%edx + 100711: 8b 4a 08 mov 0x8(%edx),%ecx + 100714: 29 c8 sub %ecx,%eax + 100716: 89 c2 mov %eax,%edx + 100718: 8b 45 0c mov 0xc(%ebp),%eax + 10071b: 89 50 0c mov %edx,0xc(%eax) + + // Search within [lline, rline] for the line number stab. + // If found, set info->eip_line to the right line number. + // If not found, return -1. + stab_binsearch(stabs, &lline, &rline, N_SLINE, addr); + 10071e: 8b 45 08 mov 0x8(%ebp),%eax + 100721: 89 44 24 10 mov %eax,0x10(%esp) + 100725: c7 44 24 0c 44 00 00 movl $0x44,0xc(%esp) + 10072c: 00 + 10072d: 8d 45 d0 lea -0x30(%ebp),%eax + 100730: 89 44 24 08 mov %eax,0x8(%esp) + 100734: 8d 45 d4 lea -0x2c(%ebp),%eax + 100737: 89 44 24 04 mov %eax,0x4(%esp) + 10073b: 8b 45 f4 mov -0xc(%ebp),%eax + 10073e: 89 04 24 mov %eax,(%esp) + 100741: e8 cb fc ff ff call 100411 + if (lline <= rline) { + 100746: 8b 55 d4 mov -0x2c(%ebp),%edx + 100749: 8b 45 d0 mov -0x30(%ebp),%eax + 10074c: 39 c2 cmp %eax,%edx + 10074e: 7f 23 jg 100773 + info->eip_line = stabs[rline].n_desc; + 100750: 8b 45 d0 mov -0x30(%ebp),%eax + 100753: 89 c2 mov %eax,%edx + 100755: 89 d0 mov %edx,%eax + 100757: 01 c0 add %eax,%eax + 100759: 01 d0 add %edx,%eax + 10075b: c1 e0 02 shl $0x2,%eax + 10075e: 89 c2 mov %eax,%edx + 100760: 8b 45 f4 mov -0xc(%ebp),%eax + 100763: 01 d0 add %edx,%eax + 100765: 0f b7 40 06 movzwl 0x6(%eax),%eax + 100769: 89 c2 mov %eax,%edx + 10076b: 8b 45 0c mov 0xc(%ebp),%eax + 10076e: 89 50 04 mov %edx,0x4(%eax) + + // Search backwards from the line number for the relevant filename stab. + // We can't just use the "lfile" stab because inlined functions + // can interpolate code from a different file! + // Such included source files use the N_SOL stab type. + while (lline >= lfile + 100771: eb 11 jmp 100784 + return -1; + 100773: b8 ff ff ff ff mov $0xffffffff,%eax + 100778: e9 08 01 00 00 jmp 100885 + && stabs[lline].n_type != N_SOL + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { + lline --; + 10077d: 8b 45 d4 mov -0x2c(%ebp),%eax + 100780: 48 dec %eax + 100781: 89 45 d4 mov %eax,-0x2c(%ebp) + while (lline >= lfile + 100784: 8b 55 d4 mov -0x2c(%ebp),%edx + 100787: 8b 45 e4 mov -0x1c(%ebp),%eax + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { + 10078a: 39 c2 cmp %eax,%edx + 10078c: 7c 56 jl 1007e4 + && stabs[lline].n_type != N_SOL + 10078e: 8b 45 d4 mov -0x2c(%ebp),%eax + 100791: 89 c2 mov %eax,%edx + 100793: 89 d0 mov %edx,%eax + 100795: 01 c0 add %eax,%eax + 100797: 01 d0 add %edx,%eax + 100799: c1 e0 02 shl $0x2,%eax + 10079c: 89 c2 mov %eax,%edx + 10079e: 8b 45 f4 mov -0xc(%ebp),%eax + 1007a1: 01 d0 add %edx,%eax + 1007a3: 0f b6 40 04 movzbl 0x4(%eax),%eax + 1007a7: 3c 84 cmp $0x84,%al + 1007a9: 74 39 je 1007e4 + && (stabs[lline].n_type != N_SO || !stabs[lline].n_value)) { + 1007ab: 8b 45 d4 mov -0x2c(%ebp),%eax + 1007ae: 89 c2 mov %eax,%edx + 1007b0: 89 d0 mov %edx,%eax + 1007b2: 01 c0 add %eax,%eax + 1007b4: 01 d0 add %edx,%eax + 1007b6: c1 e0 02 shl $0x2,%eax + 1007b9: 89 c2 mov %eax,%edx + 1007bb: 8b 45 f4 mov -0xc(%ebp),%eax + 1007be: 01 d0 add %edx,%eax + 1007c0: 0f b6 40 04 movzbl 0x4(%eax),%eax + 1007c4: 3c 64 cmp $0x64,%al + 1007c6: 75 b5 jne 10077d + 1007c8: 8b 45 d4 mov -0x2c(%ebp),%eax + 1007cb: 89 c2 mov %eax,%edx + 1007cd: 89 d0 mov %edx,%eax + 1007cf: 01 c0 add %eax,%eax + 1007d1: 01 d0 add %edx,%eax + 1007d3: c1 e0 02 shl $0x2,%eax + 1007d6: 89 c2 mov %eax,%edx + 1007d8: 8b 45 f4 mov -0xc(%ebp),%eax + 1007db: 01 d0 add %edx,%eax + 1007dd: 8b 40 08 mov 0x8(%eax),%eax + 1007e0: 85 c0 test %eax,%eax + 1007e2: 74 99 je 10077d + } + if (lline >= lfile && stabs[lline].n_strx < stabstr_end - stabstr) { + 1007e4: 8b 55 d4 mov -0x2c(%ebp),%edx + 1007e7: 8b 45 e4 mov -0x1c(%ebp),%eax + 1007ea: 39 c2 cmp %eax,%edx + 1007ec: 7c 42 jl 100830 + 1007ee: 8b 45 d4 mov -0x2c(%ebp),%eax + 1007f1: 89 c2 mov %eax,%edx + 1007f3: 89 d0 mov %edx,%eax + 1007f5: 01 c0 add %eax,%eax + 1007f7: 01 d0 add %edx,%eax + 1007f9: c1 e0 02 shl $0x2,%eax + 1007fc: 89 c2 mov %eax,%edx + 1007fe: 8b 45 f4 mov -0xc(%ebp),%eax + 100801: 01 d0 add %edx,%eax + 100803: 8b 10 mov (%eax),%edx + 100805: 8b 45 e8 mov -0x18(%ebp),%eax + 100808: 2b 45 ec sub -0x14(%ebp),%eax + 10080b: 39 c2 cmp %eax,%edx + 10080d: 73 21 jae 100830 + info->eip_file = stabstr + stabs[lline].n_strx; + 10080f: 8b 45 d4 mov -0x2c(%ebp),%eax + 100812: 89 c2 mov %eax,%edx + 100814: 89 d0 mov %edx,%eax + 100816: 01 c0 add %eax,%eax + 100818: 01 d0 add %edx,%eax + 10081a: c1 e0 02 shl $0x2,%eax + 10081d: 89 c2 mov %eax,%edx + 10081f: 8b 45 f4 mov -0xc(%ebp),%eax + 100822: 01 d0 add %edx,%eax + 100824: 8b 10 mov (%eax),%edx + 100826: 8b 45 ec mov -0x14(%ebp),%eax + 100829: 01 c2 add %eax,%edx + 10082b: 8b 45 0c mov 0xc(%ebp),%eax + 10082e: 89 10 mov %edx,(%eax) + } + + // Set eip_fn_narg to the number of arguments taken by the function, + // or 0 if there was no containing function. + if (lfun < rfun) { + 100830: 8b 55 dc mov -0x24(%ebp),%edx + 100833: 8b 45 d8 mov -0x28(%ebp),%eax + 100836: 39 c2 cmp %eax,%edx + 100838: 7d 46 jge 100880 + for (lline = lfun + 1; + 10083a: 8b 45 dc mov -0x24(%ebp),%eax + 10083d: 40 inc %eax + 10083e: 89 45 d4 mov %eax,-0x2c(%ebp) + 100841: eb 16 jmp 100859 + lline < rfun && stabs[lline].n_type == N_PSYM; + lline ++) { + info->eip_fn_narg ++; + 100843: 8b 45 0c mov 0xc(%ebp),%eax + 100846: 8b 40 14 mov 0x14(%eax),%eax + 100849: 8d 50 01 lea 0x1(%eax),%edx + 10084c: 8b 45 0c mov 0xc(%ebp),%eax + 10084f: 89 50 14 mov %edx,0x14(%eax) + lline ++) { + 100852: 8b 45 d4 mov -0x2c(%ebp),%eax + 100855: 40 inc %eax + 100856: 89 45 d4 mov %eax,-0x2c(%ebp) + lline < rfun && stabs[lline].n_type == N_PSYM; + 100859: 8b 55 d4 mov -0x2c(%ebp),%edx + 10085c: 8b 45 d8 mov -0x28(%ebp),%eax + 10085f: 39 c2 cmp %eax,%edx + 100861: 7d 1d jge 100880 + 100863: 8b 45 d4 mov -0x2c(%ebp),%eax + 100866: 89 c2 mov %eax,%edx + 100868: 89 d0 mov %edx,%eax + 10086a: 01 c0 add %eax,%eax + 10086c: 01 d0 add %edx,%eax + 10086e: c1 e0 02 shl $0x2,%eax + 100871: 89 c2 mov %eax,%edx + 100873: 8b 45 f4 mov -0xc(%ebp),%eax + 100876: 01 d0 add %edx,%eax + 100878: 0f b6 40 04 movzbl 0x4(%eax),%eax + 10087c: 3c a0 cmp $0xa0,%al + 10087e: 74 c3 je 100843 + } + } + return 0; + 100880: b8 00 00 00 00 mov $0x0,%eax +} + 100885: 89 ec mov %ebp,%esp + 100887: 5d pop %ebp + 100888: c3 ret + +00100889 : + * print_kerninfo - print the information about kernel, including the location + * of kernel entry, the start addresses of data and text segements, the start + * address of free memory and how many memory that kernel has used. + * */ +void +print_kerninfo(void) { + 100889: 55 push %ebp + 10088a: 89 e5 mov %esp,%ebp + 10088c: 83 ec 18 sub $0x18,%esp + extern char etext[], edata[], end[], kern_init[]; + cprintf("Special kernel symbols:\n"); + 10088f: c7 04 24 56 61 10 00 movl $0x106156,(%esp) + 100896: e8 cb fa ff ff call 100366 + cprintf(" entry 0x%08x (phys)\n", kern_init); + 10089b: c7 44 24 04 36 00 10 movl $0x100036,0x4(%esp) + 1008a2: 00 + 1008a3: c7 04 24 6f 61 10 00 movl $0x10616f,(%esp) + 1008aa: e8 b7 fa ff ff call 100366 + cprintf(" etext 0x%08x (phys)\n", etext); + 1008af: c7 44 24 04 94 60 10 movl $0x106094,0x4(%esp) + 1008b6: 00 + 1008b7: c7 04 24 87 61 10 00 movl $0x106187,(%esp) + 1008be: e8 a3 fa ff ff call 100366 + cprintf(" edata 0x%08x (phys)\n", edata); + 1008c3: c7 44 24 04 36 9a 11 movl $0x119a36,0x4(%esp) + 1008ca: 00 + 1008cb: c7 04 24 9f 61 10 00 movl $0x10619f,(%esp) + 1008d2: e8 8f fa ff ff call 100366 + cprintf(" end 0x%08x (phys)\n", end); + 1008d7: c7 44 24 04 8c cf 11 movl $0x11cf8c,0x4(%esp) + 1008de: 00 + 1008df: c7 04 24 b7 61 10 00 movl $0x1061b7,(%esp) + 1008e6: e8 7b fa ff ff call 100366 + cprintf("Kernel executable memory footprint: %dKB\n", (end - kern_init + 1023)/1024); + 1008eb: b8 8c cf 11 00 mov $0x11cf8c,%eax + 1008f0: 2d 36 00 10 00 sub $0x100036,%eax + 1008f5: 05 ff 03 00 00 add $0x3ff,%eax + 1008fa: 8d 90 ff 03 00 00 lea 0x3ff(%eax),%edx + 100900: 85 c0 test %eax,%eax + 100902: 0f 48 c2 cmovs %edx,%eax + 100905: c1 f8 0a sar $0xa,%eax + 100908: 89 44 24 04 mov %eax,0x4(%esp) + 10090c: c7 04 24 d0 61 10 00 movl $0x1061d0,(%esp) + 100913: e8 4e fa ff ff call 100366 +} + 100918: 90 nop + 100919: 89 ec mov %ebp,%esp + 10091b: 5d pop %ebp + 10091c: c3 ret + +0010091d : +/* * + * print_debuginfo - read and print the stat information for the address @eip, + * and info.eip_fn_addr should be the first address of the related function. + * */ +void +print_debuginfo(uintptr_t eip) { + 10091d: 55 push %ebp + 10091e: 89 e5 mov %esp,%ebp + 100920: 81 ec 48 01 00 00 sub $0x148,%esp + struct eipdebuginfo info; + if (debuginfo_eip(eip, &info) != 0) { + 100926: 8d 45 dc lea -0x24(%ebp),%eax + 100929: 89 44 24 04 mov %eax,0x4(%esp) + 10092d: 8b 45 08 mov 0x8(%ebp),%eax + 100930: 89 04 24 mov %eax,(%esp) + 100933: e8 29 fc ff ff call 100561 + 100938: 85 c0 test %eax,%eax + 10093a: 74 15 je 100951 + cprintf(" : -- 0x%08x --\n", eip); + 10093c: 8b 45 08 mov 0x8(%ebp),%eax + 10093f: 89 44 24 04 mov %eax,0x4(%esp) + 100943: c7 04 24 fa 61 10 00 movl $0x1061fa,(%esp) + 10094a: e8 17 fa ff ff call 100366 + } + fnname[j] = '\0'; + cprintf(" %s:%d: %s+%d\n", info.eip_file, info.eip_line, + fnname, eip - info.eip_fn_addr); + } +} + 10094f: eb 6c jmp 1009bd + for (j = 0; j < info.eip_fn_namelen; j ++) { + 100951: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 100958: eb 1b jmp 100975 + fnname[j] = info.eip_fn_name[j]; + 10095a: 8b 55 e4 mov -0x1c(%ebp),%edx + 10095d: 8b 45 f4 mov -0xc(%ebp),%eax + 100960: 01 d0 add %edx,%eax + 100962: 0f b6 10 movzbl (%eax),%edx + 100965: 8d 8d dc fe ff ff lea -0x124(%ebp),%ecx + 10096b: 8b 45 f4 mov -0xc(%ebp),%eax + 10096e: 01 c8 add %ecx,%eax + 100970: 88 10 mov %dl,(%eax) + for (j = 0; j < info.eip_fn_namelen; j ++) { + 100972: ff 45 f4 incl -0xc(%ebp) + 100975: 8b 45 e8 mov -0x18(%ebp),%eax + 100978: 39 45 f4 cmp %eax,-0xc(%ebp) + 10097b: 7c dd jl 10095a + fnname[j] = '\0'; + 10097d: 8d 95 dc fe ff ff lea -0x124(%ebp),%edx + 100983: 8b 45 f4 mov -0xc(%ebp),%eax + 100986: 01 d0 add %edx,%eax + 100988: c6 00 00 movb $0x0,(%eax) + fnname, eip - info.eip_fn_addr); + 10098b: 8b 55 ec mov -0x14(%ebp),%edx + cprintf(" %s:%d: %s+%d\n", info.eip_file, info.eip_line, + 10098e: 8b 45 08 mov 0x8(%ebp),%eax + 100991: 29 d0 sub %edx,%eax + 100993: 89 c1 mov %eax,%ecx + 100995: 8b 55 e0 mov -0x20(%ebp),%edx + 100998: 8b 45 dc mov -0x24(%ebp),%eax + 10099b: 89 4c 24 10 mov %ecx,0x10(%esp) + 10099f: 8d 8d dc fe ff ff lea -0x124(%ebp),%ecx + 1009a5: 89 4c 24 0c mov %ecx,0xc(%esp) + 1009a9: 89 54 24 08 mov %edx,0x8(%esp) + 1009ad: 89 44 24 04 mov %eax,0x4(%esp) + 1009b1: c7 04 24 16 62 10 00 movl $0x106216,(%esp) + 1009b8: e8 a9 f9 ff ff call 100366 +} + 1009bd: 90 nop + 1009be: 89 ec mov %ebp,%esp + 1009c0: 5d pop %ebp + 1009c1: c3 ret + +001009c2 : + +static __noinline uint32_t +read_eip(void) { + 1009c2: 55 push %ebp + 1009c3: 89 e5 mov %esp,%ebp + 1009c5: 83 ec 10 sub $0x10,%esp + uint32_t eip; + asm volatile("movl 4(%%ebp), %0" : "=r" (eip)); + 1009c8: 8b 45 04 mov 0x4(%ebp),%eax + 1009cb: 89 45 fc mov %eax,-0x4(%ebp) + return eip; + 1009ce: 8b 45 fc mov -0x4(%ebp),%eax +} + 1009d1: 89 ec mov %ebp,%esp + 1009d3: 5d pop %ebp + 1009d4: c3 ret + +001009d5 : + * + * Note that, the length of ebp-chain is limited. In boot/bootasm.S, before jumping + * to the kernel entry, the value of ebp has been set to zero, that's the boundary. + * */ +void +print_stackframe(void) { + 1009d5: 55 push %ebp + 1009d6: 89 e5 mov %esp,%ebp + * (3.4) call print_debuginfo(eip-1) to print the C calling function name and line number, etc. + * (3.5) popup a calling stackframe + * NOTICE: the calling funciton's return addr eip = ss:[ebp+4] + * the calling funciton's ebp = ss:[ebp] + */ +} + 1009d8: 90 nop + 1009d9: 5d pop %ebp + 1009da: c3 ret + +001009db : +#define MAXARGS 16 +#define WHITESPACE " \t\n\r" + +/* parse - parse the command buffer into whitespace-separated arguments */ +static int +parse(char *buf, char **argv) { + 1009db: 55 push %ebp + 1009dc: 89 e5 mov %esp,%ebp + 1009de: 83 ec 28 sub $0x28,%esp + int argc = 0; + 1009e1: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + while (1) { + // find global whitespace + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { + 1009e8: eb 0c jmp 1009f6 + *buf ++ = '\0'; + 1009ea: 8b 45 08 mov 0x8(%ebp),%eax + 1009ed: 8d 50 01 lea 0x1(%eax),%edx + 1009f0: 89 55 08 mov %edx,0x8(%ebp) + 1009f3: c6 00 00 movb $0x0,(%eax) + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { + 1009f6: 8b 45 08 mov 0x8(%ebp),%eax + 1009f9: 0f b6 00 movzbl (%eax),%eax + 1009fc: 84 c0 test %al,%al + 1009fe: 74 1d je 100a1d + 100a00: 8b 45 08 mov 0x8(%ebp),%eax + 100a03: 0f b6 00 movzbl (%eax),%eax + 100a06: 0f be c0 movsbl %al,%eax + 100a09: 89 44 24 04 mov %eax,0x4(%esp) + 100a0d: c7 04 24 a8 62 10 00 movl $0x1062a8,(%esp) + 100a14: e8 33 53 00 00 call 105d4c + 100a19: 85 c0 test %eax,%eax + 100a1b: 75 cd jne 1009ea + } + if (*buf == '\0') { + 100a1d: 8b 45 08 mov 0x8(%ebp),%eax + 100a20: 0f b6 00 movzbl (%eax),%eax + 100a23: 84 c0 test %al,%al + 100a25: 74 65 je 100a8c + break; + } + + // save and scan past next arg + if (argc == MAXARGS - 1) { + 100a27: 83 7d f4 0f cmpl $0xf,-0xc(%ebp) + 100a2b: 75 14 jne 100a41 + cprintf("Too many arguments (max %d).\n", MAXARGS); + 100a2d: c7 44 24 04 10 00 00 movl $0x10,0x4(%esp) + 100a34: 00 + 100a35: c7 04 24 ad 62 10 00 movl $0x1062ad,(%esp) + 100a3c: e8 25 f9 ff ff call 100366 + } + argv[argc ++] = buf; + 100a41: 8b 45 f4 mov -0xc(%ebp),%eax + 100a44: 8d 50 01 lea 0x1(%eax),%edx + 100a47: 89 55 f4 mov %edx,-0xc(%ebp) + 100a4a: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx + 100a51: 8b 45 0c mov 0xc(%ebp),%eax + 100a54: 01 c2 add %eax,%edx + 100a56: 8b 45 08 mov 0x8(%ebp),%eax + 100a59: 89 02 mov %eax,(%edx) + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { + 100a5b: eb 03 jmp 100a60 + buf ++; + 100a5d: ff 45 08 incl 0x8(%ebp) + while (*buf != '\0' && strchr(WHITESPACE, *buf) == NULL) { + 100a60: 8b 45 08 mov 0x8(%ebp),%eax + 100a63: 0f b6 00 movzbl (%eax),%eax + 100a66: 84 c0 test %al,%al + 100a68: 74 8c je 1009f6 + 100a6a: 8b 45 08 mov 0x8(%ebp),%eax + 100a6d: 0f b6 00 movzbl (%eax),%eax + 100a70: 0f be c0 movsbl %al,%eax + 100a73: 89 44 24 04 mov %eax,0x4(%esp) + 100a77: c7 04 24 a8 62 10 00 movl $0x1062a8,(%esp) + 100a7e: e8 c9 52 00 00 call 105d4c + 100a83: 85 c0 test %eax,%eax + 100a85: 74 d6 je 100a5d + while (*buf != '\0' && strchr(WHITESPACE, *buf) != NULL) { + 100a87: e9 6a ff ff ff jmp 1009f6 + break; + 100a8c: 90 nop + } + } + return argc; + 100a8d: 8b 45 f4 mov -0xc(%ebp),%eax +} + 100a90: 89 ec mov %ebp,%esp + 100a92: 5d pop %ebp + 100a93: c3 ret + +00100a94 : +/* * + * runcmd - parse the input string, split it into separated arguments + * and then lookup and invoke some related commands/ + * */ +static int +runcmd(char *buf, struct trapframe *tf) { + 100a94: 55 push %ebp + 100a95: 89 e5 mov %esp,%ebp + 100a97: 83 ec 68 sub $0x68,%esp + 100a9a: 89 5d fc mov %ebx,-0x4(%ebp) + char *argv[MAXARGS]; + int argc = parse(buf, argv); + 100a9d: 8d 45 b0 lea -0x50(%ebp),%eax + 100aa0: 89 44 24 04 mov %eax,0x4(%esp) + 100aa4: 8b 45 08 mov 0x8(%ebp),%eax + 100aa7: 89 04 24 mov %eax,(%esp) + 100aaa: e8 2c ff ff ff call 1009db + 100aaf: 89 45 f0 mov %eax,-0x10(%ebp) + if (argc == 0) { + 100ab2: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 100ab6: 75 0a jne 100ac2 + return 0; + 100ab8: b8 00 00 00 00 mov $0x0,%eax + 100abd: e9 83 00 00 00 jmp 100b45 + } + int i; + for (i = 0; i < NCOMMANDS; i ++) { + 100ac2: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 100ac9: eb 5a jmp 100b25 + if (strcmp(commands[i].name, argv[0]) == 0) { + 100acb: 8b 55 b0 mov -0x50(%ebp),%edx + 100ace: 8b 4d f4 mov -0xc(%ebp),%ecx + 100ad1: 89 c8 mov %ecx,%eax + 100ad3: 01 c0 add %eax,%eax + 100ad5: 01 c8 add %ecx,%eax + 100ad7: c1 e0 02 shl $0x2,%eax + 100ada: 05 00 90 11 00 add $0x119000,%eax + 100adf: 8b 00 mov (%eax),%eax + 100ae1: 89 54 24 04 mov %edx,0x4(%esp) + 100ae5: 89 04 24 mov %eax,(%esp) + 100ae8: e8 c3 51 00 00 call 105cb0 + 100aed: 85 c0 test %eax,%eax + 100aef: 75 31 jne 100b22 + return commands[i].func(argc - 1, argv + 1, tf); + 100af1: 8b 55 f4 mov -0xc(%ebp),%edx + 100af4: 89 d0 mov %edx,%eax + 100af6: 01 c0 add %eax,%eax + 100af8: 01 d0 add %edx,%eax + 100afa: c1 e0 02 shl $0x2,%eax + 100afd: 05 08 90 11 00 add $0x119008,%eax + 100b02: 8b 10 mov (%eax),%edx + 100b04: 8d 45 b0 lea -0x50(%ebp),%eax + 100b07: 83 c0 04 add $0x4,%eax + 100b0a: 8b 4d f0 mov -0x10(%ebp),%ecx + 100b0d: 8d 59 ff lea -0x1(%ecx),%ebx + 100b10: 8b 4d 0c mov 0xc(%ebp),%ecx + 100b13: 89 4c 24 08 mov %ecx,0x8(%esp) + 100b17: 89 44 24 04 mov %eax,0x4(%esp) + 100b1b: 89 1c 24 mov %ebx,(%esp) + 100b1e: ff d2 call *%edx + 100b20: eb 23 jmp 100b45 + for (i = 0; i < NCOMMANDS; i ++) { + 100b22: ff 45 f4 incl -0xc(%ebp) + 100b25: 8b 45 f4 mov -0xc(%ebp),%eax + 100b28: 83 f8 02 cmp $0x2,%eax + 100b2b: 76 9e jbe 100acb + } + } + cprintf("Unknown command '%s'\n", argv[0]); + 100b2d: 8b 45 b0 mov -0x50(%ebp),%eax + 100b30: 89 44 24 04 mov %eax,0x4(%esp) + 100b34: c7 04 24 cb 62 10 00 movl $0x1062cb,(%esp) + 100b3b: e8 26 f8 ff ff call 100366 + return 0; + 100b40: b8 00 00 00 00 mov $0x0,%eax +} + 100b45: 8b 5d fc mov -0x4(%ebp),%ebx + 100b48: 89 ec mov %ebp,%esp + 100b4a: 5d pop %ebp + 100b4b: c3 ret + +00100b4c : + +/***** Implementations of basic kernel monitor commands *****/ + +void +kmonitor(struct trapframe *tf) { + 100b4c: 55 push %ebp + 100b4d: 89 e5 mov %esp,%ebp + 100b4f: 83 ec 28 sub $0x28,%esp + cprintf("Welcome to the kernel debug monitor!!\n"); + 100b52: c7 04 24 e4 62 10 00 movl $0x1062e4,(%esp) + 100b59: e8 08 f8 ff ff call 100366 + cprintf("Type 'help' for a list of commands.\n"); + 100b5e: c7 04 24 0c 63 10 00 movl $0x10630c,(%esp) + 100b65: e8 fc f7 ff ff call 100366 + + if (tf != NULL) { + 100b6a: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 100b6e: 74 0b je 100b7b + print_trapframe(tf); + 100b70: 8b 45 08 mov 0x8(%ebp),%eax + 100b73: 89 04 24 mov %eax,(%esp) + 100b76: e8 cf 0e 00 00 call 101a4a + } + + char *buf; + while (1) { + if ((buf = readline("K> ")) != NULL) { + 100b7b: c7 04 24 31 63 10 00 movl $0x106331,(%esp) + 100b82: e8 d0 f6 ff ff call 100257 + 100b87: 89 45 f4 mov %eax,-0xc(%ebp) + 100b8a: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 100b8e: 74 eb je 100b7b + if (runcmd(buf, tf) < 0) { + 100b90: 8b 45 08 mov 0x8(%ebp),%eax + 100b93: 89 44 24 04 mov %eax,0x4(%esp) + 100b97: 8b 45 f4 mov -0xc(%ebp),%eax + 100b9a: 89 04 24 mov %eax,(%esp) + 100b9d: e8 f2 fe ff ff call 100a94 + 100ba2: 85 c0 test %eax,%eax + 100ba4: 78 02 js 100ba8 + if ((buf = readline("K> ")) != NULL) { + 100ba6: eb d3 jmp 100b7b + break; + 100ba8: 90 nop + } + } + } +} + 100ba9: 90 nop + 100baa: 89 ec mov %ebp,%esp + 100bac: 5d pop %ebp + 100bad: c3 ret + +00100bae : + +/* mon_help - print the information about mon_* functions */ +int +mon_help(int argc, char **argv, struct trapframe *tf) { + 100bae: 55 push %ebp + 100baf: 89 e5 mov %esp,%ebp + 100bb1: 83 ec 28 sub $0x28,%esp + int i; + for (i = 0; i < NCOMMANDS; i ++) { + 100bb4: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 100bbb: eb 3d jmp 100bfa + cprintf("%s - %s\n", commands[i].name, commands[i].desc); + 100bbd: 8b 55 f4 mov -0xc(%ebp),%edx + 100bc0: 89 d0 mov %edx,%eax + 100bc2: 01 c0 add %eax,%eax + 100bc4: 01 d0 add %edx,%eax + 100bc6: c1 e0 02 shl $0x2,%eax + 100bc9: 05 04 90 11 00 add $0x119004,%eax + 100bce: 8b 10 mov (%eax),%edx + 100bd0: 8b 4d f4 mov -0xc(%ebp),%ecx + 100bd3: 89 c8 mov %ecx,%eax + 100bd5: 01 c0 add %eax,%eax + 100bd7: 01 c8 add %ecx,%eax + 100bd9: c1 e0 02 shl $0x2,%eax + 100bdc: 05 00 90 11 00 add $0x119000,%eax + 100be1: 8b 00 mov (%eax),%eax + 100be3: 89 54 24 08 mov %edx,0x8(%esp) + 100be7: 89 44 24 04 mov %eax,0x4(%esp) + 100beb: c7 04 24 35 63 10 00 movl $0x106335,(%esp) + 100bf2: e8 6f f7 ff ff call 100366 + for (i = 0; i < NCOMMANDS; i ++) { + 100bf7: ff 45 f4 incl -0xc(%ebp) + 100bfa: 8b 45 f4 mov -0xc(%ebp),%eax + 100bfd: 83 f8 02 cmp $0x2,%eax + 100c00: 76 bb jbe 100bbd + } + return 0; + 100c02: b8 00 00 00 00 mov $0x0,%eax +} + 100c07: 89 ec mov %ebp,%esp + 100c09: 5d pop %ebp + 100c0a: c3 ret + +00100c0b : +/* * + * mon_kerninfo - call print_kerninfo in kern/debug/kdebug.c to + * print the memory occupancy in kernel. + * */ +int +mon_kerninfo(int argc, char **argv, struct trapframe *tf) { + 100c0b: 55 push %ebp + 100c0c: 89 e5 mov %esp,%ebp + 100c0e: 83 ec 08 sub $0x8,%esp + print_kerninfo(); + 100c11: e8 73 fc ff ff call 100889 + return 0; + 100c16: b8 00 00 00 00 mov $0x0,%eax +} + 100c1b: 89 ec mov %ebp,%esp + 100c1d: 5d pop %ebp + 100c1e: c3 ret + +00100c1f : +/* * + * mon_backtrace - call print_stackframe in kern/debug/kdebug.c to + * print a backtrace of the stack. + * */ +int +mon_backtrace(int argc, char **argv, struct trapframe *tf) { + 100c1f: 55 push %ebp + 100c20: 89 e5 mov %esp,%ebp + 100c22: 83 ec 08 sub $0x8,%esp + print_stackframe(); + 100c25: e8 ab fd ff ff call 1009d5 + return 0; + 100c2a: b8 00 00 00 00 mov $0x0,%eax +} + 100c2f: 89 ec mov %ebp,%esp + 100c31: 5d pop %ebp + 100c32: c3 ret + +00100c33 <__panic>: +/* * + * __panic - __panic is called on unresolvable fatal errors. it prints + * "panic: 'message'", and then enters the kernel monitor. + * */ +void +__panic(const char *file, int line, const char *fmt, ...) { + 100c33: 55 push %ebp + 100c34: 89 e5 mov %esp,%ebp + 100c36: 83 ec 28 sub $0x28,%esp + if (is_panic) { + 100c39: a1 20 c4 11 00 mov 0x11c420,%eax + 100c3e: 85 c0 test %eax,%eax + 100c40: 75 5b jne 100c9d <__panic+0x6a> + goto panic_dead; + } + is_panic = 1; + 100c42: c7 05 20 c4 11 00 01 movl $0x1,0x11c420 + 100c49: 00 00 00 + + // print the 'message' + va_list ap; + va_start(ap, fmt); + 100c4c: 8d 45 14 lea 0x14(%ebp),%eax + 100c4f: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("kernel panic at %s:%d:\n ", file, line); + 100c52: 8b 45 0c mov 0xc(%ebp),%eax + 100c55: 89 44 24 08 mov %eax,0x8(%esp) + 100c59: 8b 45 08 mov 0x8(%ebp),%eax + 100c5c: 89 44 24 04 mov %eax,0x4(%esp) + 100c60: c7 04 24 3e 63 10 00 movl $0x10633e,(%esp) + 100c67: e8 fa f6 ff ff call 100366 + vcprintf(fmt, ap); + 100c6c: 8b 45 f4 mov -0xc(%ebp),%eax + 100c6f: 89 44 24 04 mov %eax,0x4(%esp) + 100c73: 8b 45 10 mov 0x10(%ebp),%eax + 100c76: 89 04 24 mov %eax,(%esp) + 100c79: e8 b3 f6 ff ff call 100331 + cprintf("\n"); + 100c7e: c7 04 24 5a 63 10 00 movl $0x10635a,(%esp) + 100c85: e8 dc f6 ff ff call 100366 + + cprintf("stack trackback:\n"); + 100c8a: c7 04 24 5c 63 10 00 movl $0x10635c,(%esp) + 100c91: e8 d0 f6 ff ff call 100366 + print_stackframe(); + 100c96: e8 3a fd ff ff call 1009d5 + 100c9b: eb 01 jmp 100c9e <__panic+0x6b> + goto panic_dead; + 100c9d: 90 nop + + va_end(ap); + +panic_dead: + intr_disable(); + 100c9e: e8 e9 09 00 00 call 10168c + while (1) { + kmonitor(NULL); + 100ca3: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 100caa: e8 9d fe ff ff call 100b4c + 100caf: eb f2 jmp 100ca3 <__panic+0x70> + +00100cb1 <__warn>: + } +} + +/* __warn - like panic, but don't */ +void +__warn(const char *file, int line, const char *fmt, ...) { + 100cb1: 55 push %ebp + 100cb2: 89 e5 mov %esp,%ebp + 100cb4: 83 ec 28 sub $0x28,%esp + va_list ap; + va_start(ap, fmt); + 100cb7: 8d 45 14 lea 0x14(%ebp),%eax + 100cba: 89 45 f4 mov %eax,-0xc(%ebp) + cprintf("kernel warning at %s:%d:\n ", file, line); + 100cbd: 8b 45 0c mov 0xc(%ebp),%eax + 100cc0: 89 44 24 08 mov %eax,0x8(%esp) + 100cc4: 8b 45 08 mov 0x8(%ebp),%eax + 100cc7: 89 44 24 04 mov %eax,0x4(%esp) + 100ccb: c7 04 24 6e 63 10 00 movl $0x10636e,(%esp) + 100cd2: e8 8f f6 ff ff call 100366 + vcprintf(fmt, ap); + 100cd7: 8b 45 f4 mov -0xc(%ebp),%eax + 100cda: 89 44 24 04 mov %eax,0x4(%esp) + 100cde: 8b 45 10 mov 0x10(%ebp),%eax + 100ce1: 89 04 24 mov %eax,(%esp) + 100ce4: e8 48 f6 ff ff call 100331 + cprintf("\n"); + 100ce9: c7 04 24 5a 63 10 00 movl $0x10635a,(%esp) + 100cf0: e8 71 f6 ff ff call 100366 + va_end(ap); +} + 100cf5: 90 nop + 100cf6: 89 ec mov %ebp,%esp + 100cf8: 5d pop %ebp + 100cf9: c3 ret + +00100cfa : + +bool +is_kernel_panic(void) { + 100cfa: 55 push %ebp + 100cfb: 89 e5 mov %esp,%ebp + return is_panic; + 100cfd: a1 20 c4 11 00 mov 0x11c420,%eax +} + 100d02: 5d pop %ebp + 100d03: c3 ret + +00100d04 : +/* * + * clock_init - initialize 8253 clock to interrupt 100 times per second, + * and then enable IRQ_TIMER. + * */ +void +clock_init(void) { + 100d04: 55 push %ebp + 100d05: 89 e5 mov %esp,%ebp + 100d07: 83 ec 28 sub $0x28,%esp + 100d0a: 66 c7 45 ee 43 00 movw $0x43,-0x12(%ebp) + 100d10: c6 45 ed 34 movb $0x34,-0x13(%ebp) + : "memory", "cc"); +} + +static inline void +outb(uint16_t port, uint8_t data) { + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100d14: 0f b6 45 ed movzbl -0x13(%ebp),%eax + 100d18: 0f b7 55 ee movzwl -0x12(%ebp),%edx + 100d1c: ee out %al,(%dx) +} + 100d1d: 90 nop + 100d1e: 66 c7 45 f2 40 00 movw $0x40,-0xe(%ebp) + 100d24: c6 45 f1 9c movb $0x9c,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100d28: 0f b6 45 f1 movzbl -0xf(%ebp),%eax + 100d2c: 0f b7 55 f2 movzwl -0xe(%ebp),%edx + 100d30: ee out %al,(%dx) +} + 100d31: 90 nop + 100d32: 66 c7 45 f6 40 00 movw $0x40,-0xa(%ebp) + 100d38: c6 45 f5 2e movb $0x2e,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100d3c: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + 100d40: 0f b7 55 f6 movzwl -0xa(%ebp),%edx + 100d44: ee out %al,(%dx) +} + 100d45: 90 nop + outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT); + outb(IO_TIMER1, TIMER_DIV(100) % 256); + outb(IO_TIMER1, TIMER_DIV(100) / 256); + + // initialize time counter 'ticks' to zero + ticks = 0; + 100d46: c7 05 24 c4 11 00 00 movl $0x0,0x11c424 + 100d4d: 00 00 00 + + cprintf("++ setup timer interrupts\n"); + 100d50: c7 04 24 8c 63 10 00 movl $0x10638c,(%esp) + 100d57: e8 0a f6 ff ff call 100366 + pic_enable(IRQ_TIMER); + 100d5c: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 100d63: e8 89 09 00 00 call 1016f1 +} + 100d68: 90 nop + 100d69: 89 ec mov %ebp,%esp + 100d6b: 5d pop %ebp + 100d6c: c3 ret + +00100d6d <__intr_save>: +#include +#include +#include + +static inline bool +__intr_save(void) { + 100d6d: 55 push %ebp + 100d6e: 89 e5 mov %esp,%ebp + 100d70: 83 ec 18 sub $0x18,%esp +} + +static inline uint32_t +read_eflags(void) { + uint32_t eflags; + asm volatile ("pushfl; popl %0" : "=r" (eflags)); + 100d73: 9c pushf + 100d74: 58 pop %eax + 100d75: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; + 100d78: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { + 100d7b: 25 00 02 00 00 and $0x200,%eax + 100d80: 85 c0 test %eax,%eax + 100d82: 74 0c je 100d90 <__intr_save+0x23> + intr_disable(); + 100d84: e8 03 09 00 00 call 10168c + return 1; + 100d89: b8 01 00 00 00 mov $0x1,%eax + 100d8e: eb 05 jmp 100d95 <__intr_save+0x28> + } + return 0; + 100d90: b8 00 00 00 00 mov $0x0,%eax +} + 100d95: 89 ec mov %ebp,%esp + 100d97: 5d pop %ebp + 100d98: c3 ret + +00100d99 <__intr_restore>: + +static inline void +__intr_restore(bool flag) { + 100d99: 55 push %ebp + 100d9a: 89 e5 mov %esp,%ebp + 100d9c: 83 ec 08 sub $0x8,%esp + if (flag) { + 100d9f: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 100da3: 74 05 je 100daa <__intr_restore+0x11> + intr_enable(); + 100da5: e8 da 08 00 00 call 101684 + } +} + 100daa: 90 nop + 100dab: 89 ec mov %ebp,%esp + 100dad: 5d pop %ebp + 100dae: c3 ret + +00100daf : +#include +#include + +/* stupid I/O delay routine necessitated by historical PC design flaws */ +static void +delay(void) { + 100daf: 55 push %ebp + 100db0: 89 e5 mov %esp,%ebp + 100db2: 83 ec 10 sub $0x10,%esp + 100db5: 66 c7 45 f2 84 00 movw $0x84,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 100dbb: 0f b7 45 f2 movzwl -0xe(%ebp),%eax + 100dbf: 89 c2 mov %eax,%edx + 100dc1: ec in (%dx),%al + 100dc2: 88 45 f1 mov %al,-0xf(%ebp) + 100dc5: 66 c7 45 f6 84 00 movw $0x84,-0xa(%ebp) + 100dcb: 0f b7 45 f6 movzwl -0xa(%ebp),%eax + 100dcf: 89 c2 mov %eax,%edx + 100dd1: ec in (%dx),%al + 100dd2: 88 45 f5 mov %al,-0xb(%ebp) + 100dd5: 66 c7 45 fa 84 00 movw $0x84,-0x6(%ebp) + 100ddb: 0f b7 45 fa movzwl -0x6(%ebp),%eax + 100ddf: 89 c2 mov %eax,%edx + 100de1: ec in (%dx),%al + 100de2: 88 45 f9 mov %al,-0x7(%ebp) + 100de5: 66 c7 45 fe 84 00 movw $0x84,-0x2(%ebp) + 100deb: 0f b7 45 fe movzwl -0x2(%ebp),%eax + 100def: 89 c2 mov %eax,%edx + 100df1: ec in (%dx),%al + 100df2: 88 45 fd mov %al,-0x3(%ebp) + inb(0x84); + inb(0x84); + inb(0x84); + inb(0x84); +} + 100df5: 90 nop + 100df6: 89 ec mov %ebp,%esp + 100df8: 5d pop %ebp + 100df9: c3 ret + +00100dfa : +static uint16_t addr_6845; + +/* TEXT-mode CGA/VGA display output */ + +static void +cga_init(void) { + 100dfa: 55 push %ebp + 100dfb: 89 e5 mov %esp,%ebp + 100dfd: 83 ec 20 sub $0x20,%esp + volatile uint16_t *cp = (uint16_t *)(CGA_BUF + KERNBASE); + 100e00: c7 45 fc 00 80 0b c0 movl $0xc00b8000,-0x4(%ebp) + uint16_t was = *cp; + 100e07: 8b 45 fc mov -0x4(%ebp),%eax + 100e0a: 0f b7 00 movzwl (%eax),%eax + 100e0d: 66 89 45 fa mov %ax,-0x6(%ebp) + *cp = (uint16_t) 0xA55A; + 100e11: 8b 45 fc mov -0x4(%ebp),%eax + 100e14: 66 c7 00 5a a5 movw $0xa55a,(%eax) + if (*cp != 0xA55A) { + 100e19: 8b 45 fc mov -0x4(%ebp),%eax + 100e1c: 0f b7 00 movzwl (%eax),%eax + 100e1f: 0f b7 c0 movzwl %ax,%eax + 100e22: 3d 5a a5 00 00 cmp $0xa55a,%eax + 100e27: 74 12 je 100e3b + cp = (uint16_t*)(MONO_BUF + KERNBASE); + 100e29: c7 45 fc 00 00 0b c0 movl $0xc00b0000,-0x4(%ebp) + addr_6845 = MONO_BASE; + 100e30: 66 c7 05 46 c4 11 00 movw $0x3b4,0x11c446 + 100e37: b4 03 + 100e39: eb 13 jmp 100e4e + } else { + *cp = was; + 100e3b: 8b 45 fc mov -0x4(%ebp),%eax + 100e3e: 0f b7 55 fa movzwl -0x6(%ebp),%edx + 100e42: 66 89 10 mov %dx,(%eax) + addr_6845 = CGA_BASE; + 100e45: 66 c7 05 46 c4 11 00 movw $0x3d4,0x11c446 + 100e4c: d4 03 + } + + // Extract cursor location + uint32_t pos; + outb(addr_6845, 14); + 100e4e: 0f b7 05 46 c4 11 00 movzwl 0x11c446,%eax + 100e55: 66 89 45 e6 mov %ax,-0x1a(%ebp) + 100e59: c6 45 e5 0e movb $0xe,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100e5d: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax + 100e61: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx + 100e65: ee out %al,(%dx) +} + 100e66: 90 nop + pos = inb(addr_6845 + 1) << 8; + 100e67: 0f b7 05 46 c4 11 00 movzwl 0x11c446,%eax + 100e6e: 40 inc %eax + 100e6f: 0f b7 c0 movzwl %ax,%eax + 100e72: 66 89 45 ea mov %ax,-0x16(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 100e76: 0f b7 45 ea movzwl -0x16(%ebp),%eax + 100e7a: 89 c2 mov %eax,%edx + 100e7c: ec in (%dx),%al + 100e7d: 88 45 e9 mov %al,-0x17(%ebp) + return data; + 100e80: 0f b6 45 e9 movzbl -0x17(%ebp),%eax + 100e84: 0f b6 c0 movzbl %al,%eax + 100e87: c1 e0 08 shl $0x8,%eax + 100e8a: 89 45 f4 mov %eax,-0xc(%ebp) + outb(addr_6845, 15); + 100e8d: 0f b7 05 46 c4 11 00 movzwl 0x11c446,%eax + 100e94: 66 89 45 ee mov %ax,-0x12(%ebp) + 100e98: c6 45 ed 0f movb $0xf,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100e9c: 0f b6 45 ed movzbl -0x13(%ebp),%eax + 100ea0: 0f b7 55 ee movzwl -0x12(%ebp),%edx + 100ea4: ee out %al,(%dx) +} + 100ea5: 90 nop + pos |= inb(addr_6845 + 1); + 100ea6: 0f b7 05 46 c4 11 00 movzwl 0x11c446,%eax + 100ead: 40 inc %eax + 100eae: 0f b7 c0 movzwl %ax,%eax + 100eb1: 66 89 45 f2 mov %ax,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 100eb5: 0f b7 45 f2 movzwl -0xe(%ebp),%eax + 100eb9: 89 c2 mov %eax,%edx + 100ebb: ec in (%dx),%al + 100ebc: 88 45 f1 mov %al,-0xf(%ebp) + return data; + 100ebf: 0f b6 45 f1 movzbl -0xf(%ebp),%eax + 100ec3: 0f b6 c0 movzbl %al,%eax + 100ec6: 09 45 f4 or %eax,-0xc(%ebp) + + crt_buf = (uint16_t*) cp; + 100ec9: 8b 45 fc mov -0x4(%ebp),%eax + 100ecc: a3 40 c4 11 00 mov %eax,0x11c440 + crt_pos = pos; + 100ed1: 8b 45 f4 mov -0xc(%ebp),%eax + 100ed4: 0f b7 c0 movzwl %ax,%eax + 100ed7: 66 a3 44 c4 11 00 mov %ax,0x11c444 +} + 100edd: 90 nop + 100ede: 89 ec mov %ebp,%esp + 100ee0: 5d pop %ebp + 100ee1: c3 ret + +00100ee2 : + +static bool serial_exists = 0; + +static void +serial_init(void) { + 100ee2: 55 push %ebp + 100ee3: 89 e5 mov %esp,%ebp + 100ee5: 83 ec 48 sub $0x48,%esp + 100ee8: 66 c7 45 d2 fa 03 movw $0x3fa,-0x2e(%ebp) + 100eee: c6 45 d1 00 movb $0x0,-0x2f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100ef2: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax + 100ef6: 0f b7 55 d2 movzwl -0x2e(%ebp),%edx + 100efa: ee out %al,(%dx) +} + 100efb: 90 nop + 100efc: 66 c7 45 d6 fb 03 movw $0x3fb,-0x2a(%ebp) + 100f02: c6 45 d5 80 movb $0x80,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100f06: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax + 100f0a: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx + 100f0e: ee out %al,(%dx) +} + 100f0f: 90 nop + 100f10: 66 c7 45 da f8 03 movw $0x3f8,-0x26(%ebp) + 100f16: c6 45 d9 0c movb $0xc,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100f1a: 0f b6 45 d9 movzbl -0x27(%ebp),%eax + 100f1e: 0f b7 55 da movzwl -0x26(%ebp),%edx + 100f22: ee out %al,(%dx) +} + 100f23: 90 nop + 100f24: 66 c7 45 de f9 03 movw $0x3f9,-0x22(%ebp) + 100f2a: c6 45 dd 00 movb $0x0,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100f2e: 0f b6 45 dd movzbl -0x23(%ebp),%eax + 100f32: 0f b7 55 de movzwl -0x22(%ebp),%edx + 100f36: ee out %al,(%dx) +} + 100f37: 90 nop + 100f38: 66 c7 45 e2 fb 03 movw $0x3fb,-0x1e(%ebp) + 100f3e: c6 45 e1 03 movb $0x3,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100f42: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax + 100f46: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx + 100f4a: ee out %al,(%dx) +} + 100f4b: 90 nop + 100f4c: 66 c7 45 e6 fc 03 movw $0x3fc,-0x1a(%ebp) + 100f52: c6 45 e5 00 movb $0x0,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100f56: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax + 100f5a: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx + 100f5e: ee out %al,(%dx) +} + 100f5f: 90 nop + 100f60: 66 c7 45 ea f9 03 movw $0x3f9,-0x16(%ebp) + 100f66: c6 45 e9 01 movb $0x1,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 100f6a: 0f b6 45 e9 movzbl -0x17(%ebp),%eax + 100f6e: 0f b7 55 ea movzwl -0x16(%ebp),%edx + 100f72: ee out %al,(%dx) +} + 100f73: 90 nop + 100f74: 66 c7 45 ee fd 03 movw $0x3fd,-0x12(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 100f7a: 0f b7 45 ee movzwl -0x12(%ebp),%eax + 100f7e: 89 c2 mov %eax,%edx + 100f80: ec in (%dx),%al + 100f81: 88 45 ed mov %al,-0x13(%ebp) + return data; + 100f84: 0f b6 45 ed movzbl -0x13(%ebp),%eax + // Enable rcv interrupts + outb(COM1 + COM_IER, COM_IER_RDI); + + // Clear any preexisting overrun indications and interrupts + // Serial port doesn't exist if COM_LSR returns 0xFF + serial_exists = (inb(COM1 + COM_LSR) != 0xFF); + 100f88: 3c ff cmp $0xff,%al + 100f8a: 0f 95 c0 setne %al + 100f8d: 0f b6 c0 movzbl %al,%eax + 100f90: a3 48 c4 11 00 mov %eax,0x11c448 + 100f95: 66 c7 45 f2 fa 03 movw $0x3fa,-0xe(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 100f9b: 0f b7 45 f2 movzwl -0xe(%ebp),%eax + 100f9f: 89 c2 mov %eax,%edx + 100fa1: ec in (%dx),%al + 100fa2: 88 45 f1 mov %al,-0xf(%ebp) + 100fa5: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) + 100fab: 0f b7 45 f6 movzwl -0xa(%ebp),%eax + 100faf: 89 c2 mov %eax,%edx + 100fb1: ec in (%dx),%al + 100fb2: 88 45 f5 mov %al,-0xb(%ebp) + (void) inb(COM1+COM_IIR); + (void) inb(COM1+COM_RX); + + if (serial_exists) { + 100fb5: a1 48 c4 11 00 mov 0x11c448,%eax + 100fba: 85 c0 test %eax,%eax + 100fbc: 74 0c je 100fca + pic_enable(IRQ_COM1); + 100fbe: c7 04 24 04 00 00 00 movl $0x4,(%esp) + 100fc5: e8 27 07 00 00 call 1016f1 + } +} + 100fca: 90 nop + 100fcb: 89 ec mov %ebp,%esp + 100fcd: 5d pop %ebp + 100fce: c3 ret + +00100fcf : + +static void +lpt_putc_sub(int c) { + 100fcf: 55 push %ebp + 100fd0: 89 e5 mov %esp,%ebp + 100fd2: 83 ec 20 sub $0x20,%esp + int i; + for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) { + 100fd5: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + 100fdc: eb 08 jmp 100fe6 + delay(); + 100fde: e8 cc fd ff ff call 100daf + for (i = 0; !(inb(LPTPORT + 1) & 0x80) && i < 12800; i ++) { + 100fe3: ff 45 fc incl -0x4(%ebp) + 100fe6: 66 c7 45 fa 79 03 movw $0x379,-0x6(%ebp) + 100fec: 0f b7 45 fa movzwl -0x6(%ebp),%eax + 100ff0: 89 c2 mov %eax,%edx + 100ff2: ec in (%dx),%al + 100ff3: 88 45 f9 mov %al,-0x7(%ebp) + return data; + 100ff6: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + 100ffa: 84 c0 test %al,%al + 100ffc: 78 09 js 101007 + 100ffe: 81 7d fc ff 31 00 00 cmpl $0x31ff,-0x4(%ebp) + 101005: 7e d7 jle 100fde + } + outb(LPTPORT + 0, c); + 101007: 8b 45 08 mov 0x8(%ebp),%eax + 10100a: 0f b6 c0 movzbl %al,%eax + 10100d: 66 c7 45 ee 78 03 movw $0x378,-0x12(%ebp) + 101013: 88 45 ed mov %al,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101016: 0f b6 45 ed movzbl -0x13(%ebp),%eax + 10101a: 0f b7 55 ee movzwl -0x12(%ebp),%edx + 10101e: ee out %al,(%dx) +} + 10101f: 90 nop + 101020: 66 c7 45 f2 7a 03 movw $0x37a,-0xe(%ebp) + 101026: c6 45 f1 0d movb $0xd,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 10102a: 0f b6 45 f1 movzbl -0xf(%ebp),%eax + 10102e: 0f b7 55 f2 movzwl -0xe(%ebp),%edx + 101032: ee out %al,(%dx) +} + 101033: 90 nop + 101034: 66 c7 45 f6 7a 03 movw $0x37a,-0xa(%ebp) + 10103a: c6 45 f5 08 movb $0x8,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 10103e: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + 101042: 0f b7 55 f6 movzwl -0xa(%ebp),%edx + 101046: ee out %al,(%dx) +} + 101047: 90 nop + outb(LPTPORT + 2, 0x08 | 0x04 | 0x01); + outb(LPTPORT + 2, 0x08); +} + 101048: 90 nop + 101049: 89 ec mov %ebp,%esp + 10104b: 5d pop %ebp + 10104c: c3 ret + +0010104d : + +/* lpt_putc - copy console output to parallel port */ +static void +lpt_putc(int c) { + 10104d: 55 push %ebp + 10104e: 89 e5 mov %esp,%ebp + 101050: 83 ec 04 sub $0x4,%esp + if (c != '\b') { + 101053: 83 7d 08 08 cmpl $0x8,0x8(%ebp) + 101057: 74 0d je 101066 + lpt_putc_sub(c); + 101059: 8b 45 08 mov 0x8(%ebp),%eax + 10105c: 89 04 24 mov %eax,(%esp) + 10105f: e8 6b ff ff ff call 100fcf + else { + lpt_putc_sub('\b'); + lpt_putc_sub(' '); + lpt_putc_sub('\b'); + } +} + 101064: eb 24 jmp 10108a + lpt_putc_sub('\b'); + 101066: c7 04 24 08 00 00 00 movl $0x8,(%esp) + 10106d: e8 5d ff ff ff call 100fcf + lpt_putc_sub(' '); + 101072: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 101079: e8 51 ff ff ff call 100fcf + lpt_putc_sub('\b'); + 10107e: c7 04 24 08 00 00 00 movl $0x8,(%esp) + 101085: e8 45 ff ff ff call 100fcf +} + 10108a: 90 nop + 10108b: 89 ec mov %ebp,%esp + 10108d: 5d pop %ebp + 10108e: c3 ret + +0010108f : + +/* cga_putc - print character to console */ +static void +cga_putc(int c) { + 10108f: 55 push %ebp + 101090: 89 e5 mov %esp,%ebp + 101092: 83 ec 38 sub $0x38,%esp + 101095: 89 5d fc mov %ebx,-0x4(%ebp) + // set black on white + if (!(c & ~0xFF)) { + 101098: 8b 45 08 mov 0x8(%ebp),%eax + 10109b: 25 00 ff ff ff and $0xffffff00,%eax + 1010a0: 85 c0 test %eax,%eax + 1010a2: 75 07 jne 1010ab + c |= 0x0700; + 1010a4: 81 4d 08 00 07 00 00 orl $0x700,0x8(%ebp) + } + + switch (c & 0xff) { + 1010ab: 8b 45 08 mov 0x8(%ebp),%eax + 1010ae: 0f b6 c0 movzbl %al,%eax + 1010b1: 83 f8 0d cmp $0xd,%eax + 1010b4: 74 72 je 101128 + 1010b6: 83 f8 0d cmp $0xd,%eax + 1010b9: 0f 8f a3 00 00 00 jg 101162 + 1010bf: 83 f8 08 cmp $0x8,%eax + 1010c2: 74 0a je 1010ce + 1010c4: 83 f8 0a cmp $0xa,%eax + 1010c7: 74 4c je 101115 + 1010c9: e9 94 00 00 00 jmp 101162 + case '\b': + if (crt_pos > 0) { + 1010ce: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 1010d5: 85 c0 test %eax,%eax + 1010d7: 0f 84 af 00 00 00 je 10118c + crt_pos --; + 1010dd: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 1010e4: 48 dec %eax + 1010e5: 0f b7 c0 movzwl %ax,%eax + 1010e8: 66 a3 44 c4 11 00 mov %ax,0x11c444 + crt_buf[crt_pos] = (c & ~0xff) | ' '; + 1010ee: 8b 45 08 mov 0x8(%ebp),%eax + 1010f1: 98 cwtl + 1010f2: 25 00 ff ff ff and $0xffffff00,%eax + 1010f7: 98 cwtl + 1010f8: 83 c8 20 or $0x20,%eax + 1010fb: 98 cwtl + 1010fc: 8b 0d 40 c4 11 00 mov 0x11c440,%ecx + 101102: 0f b7 15 44 c4 11 00 movzwl 0x11c444,%edx + 101109: 01 d2 add %edx,%edx + 10110b: 01 ca add %ecx,%edx + 10110d: 0f b7 c0 movzwl %ax,%eax + 101110: 66 89 02 mov %ax,(%edx) + } + break; + 101113: eb 77 jmp 10118c + case '\n': + crt_pos += CRT_COLS; + 101115: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 10111c: 83 c0 50 add $0x50,%eax + 10111f: 0f b7 c0 movzwl %ax,%eax + 101122: 66 a3 44 c4 11 00 mov %ax,0x11c444 + case '\r': + crt_pos -= (crt_pos % CRT_COLS); + 101128: 0f b7 1d 44 c4 11 00 movzwl 0x11c444,%ebx + 10112f: 0f b7 0d 44 c4 11 00 movzwl 0x11c444,%ecx + 101136: ba cd cc cc cc mov $0xcccccccd,%edx + 10113b: 89 c8 mov %ecx,%eax + 10113d: f7 e2 mul %edx + 10113f: c1 ea 06 shr $0x6,%edx + 101142: 89 d0 mov %edx,%eax + 101144: c1 e0 02 shl $0x2,%eax + 101147: 01 d0 add %edx,%eax + 101149: c1 e0 04 shl $0x4,%eax + 10114c: 29 c1 sub %eax,%ecx + 10114e: 89 ca mov %ecx,%edx + 101150: 0f b7 d2 movzwl %dx,%edx + 101153: 89 d8 mov %ebx,%eax + 101155: 29 d0 sub %edx,%eax + 101157: 0f b7 c0 movzwl %ax,%eax + 10115a: 66 a3 44 c4 11 00 mov %ax,0x11c444 + break; + 101160: eb 2b jmp 10118d + default: + crt_buf[crt_pos ++] = c; // write the character + 101162: 8b 0d 40 c4 11 00 mov 0x11c440,%ecx + 101168: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 10116f: 8d 50 01 lea 0x1(%eax),%edx + 101172: 0f b7 d2 movzwl %dx,%edx + 101175: 66 89 15 44 c4 11 00 mov %dx,0x11c444 + 10117c: 01 c0 add %eax,%eax + 10117e: 8d 14 01 lea (%ecx,%eax,1),%edx + 101181: 8b 45 08 mov 0x8(%ebp),%eax + 101184: 0f b7 c0 movzwl %ax,%eax + 101187: 66 89 02 mov %ax,(%edx) + break; + 10118a: eb 01 jmp 10118d + break; + 10118c: 90 nop + } + + // What is the purpose of this? + if (crt_pos >= CRT_SIZE) { + 10118d: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 101194: 3d cf 07 00 00 cmp $0x7cf,%eax + 101199: 76 5e jbe 1011f9 + int i; + memmove(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t)); + 10119b: a1 40 c4 11 00 mov 0x11c440,%eax + 1011a0: 8d 90 a0 00 00 00 lea 0xa0(%eax),%edx + 1011a6: a1 40 c4 11 00 mov 0x11c440,%eax + 1011ab: c7 44 24 08 00 0f 00 movl $0xf00,0x8(%esp) + 1011b2: 00 + 1011b3: 89 54 24 04 mov %edx,0x4(%esp) + 1011b7: 89 04 24 mov %eax,(%esp) + 1011ba: e8 8b 4d 00 00 call 105f4a + for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) { + 1011bf: c7 45 f4 80 07 00 00 movl $0x780,-0xc(%ebp) + 1011c6: eb 15 jmp 1011dd + crt_buf[i] = 0x0700 | ' '; + 1011c8: 8b 15 40 c4 11 00 mov 0x11c440,%edx + 1011ce: 8b 45 f4 mov -0xc(%ebp),%eax + 1011d1: 01 c0 add %eax,%eax + 1011d3: 01 d0 add %edx,%eax + 1011d5: 66 c7 00 20 07 movw $0x720,(%eax) + for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i ++) { + 1011da: ff 45 f4 incl -0xc(%ebp) + 1011dd: 81 7d f4 cf 07 00 00 cmpl $0x7cf,-0xc(%ebp) + 1011e4: 7e e2 jle 1011c8 + } + crt_pos -= CRT_COLS; + 1011e6: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 1011ed: 83 e8 50 sub $0x50,%eax + 1011f0: 0f b7 c0 movzwl %ax,%eax + 1011f3: 66 a3 44 c4 11 00 mov %ax,0x11c444 + } + + // move that little blinky thing + outb(addr_6845, 14); + 1011f9: 0f b7 05 46 c4 11 00 movzwl 0x11c446,%eax + 101200: 66 89 45 e6 mov %ax,-0x1a(%ebp) + 101204: c6 45 e5 0e movb $0xe,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101208: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax + 10120c: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx + 101210: ee out %al,(%dx) +} + 101211: 90 nop + outb(addr_6845 + 1, crt_pos >> 8); + 101212: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 101219: c1 e8 08 shr $0x8,%eax + 10121c: 0f b7 c0 movzwl %ax,%eax + 10121f: 0f b6 c0 movzbl %al,%eax + 101222: 0f b7 15 46 c4 11 00 movzwl 0x11c446,%edx + 101229: 42 inc %edx + 10122a: 0f b7 d2 movzwl %dx,%edx + 10122d: 66 89 55 ea mov %dx,-0x16(%ebp) + 101231: 88 45 e9 mov %al,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101234: 0f b6 45 e9 movzbl -0x17(%ebp),%eax + 101238: 0f b7 55 ea movzwl -0x16(%ebp),%edx + 10123c: ee out %al,(%dx) +} + 10123d: 90 nop + outb(addr_6845, 15); + 10123e: 0f b7 05 46 c4 11 00 movzwl 0x11c446,%eax + 101245: 66 89 45 ee mov %ax,-0x12(%ebp) + 101249: c6 45 ed 0f movb $0xf,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 10124d: 0f b6 45 ed movzbl -0x13(%ebp),%eax + 101251: 0f b7 55 ee movzwl -0x12(%ebp),%edx + 101255: ee out %al,(%dx) +} + 101256: 90 nop + outb(addr_6845 + 1, crt_pos); + 101257: 0f b7 05 44 c4 11 00 movzwl 0x11c444,%eax + 10125e: 0f b6 c0 movzbl %al,%eax + 101261: 0f b7 15 46 c4 11 00 movzwl 0x11c446,%edx + 101268: 42 inc %edx + 101269: 0f b7 d2 movzwl %dx,%edx + 10126c: 66 89 55 f2 mov %dx,-0xe(%ebp) + 101270: 88 45 f1 mov %al,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101273: 0f b6 45 f1 movzbl -0xf(%ebp),%eax + 101277: 0f b7 55 f2 movzwl -0xe(%ebp),%edx + 10127b: ee out %al,(%dx) +} + 10127c: 90 nop +} + 10127d: 90 nop + 10127e: 8b 5d fc mov -0x4(%ebp),%ebx + 101281: 89 ec mov %ebp,%esp + 101283: 5d pop %ebp + 101284: c3 ret + +00101285 : + +static void +serial_putc_sub(int c) { + 101285: 55 push %ebp + 101286: 89 e5 mov %esp,%ebp + 101288: 83 ec 10 sub $0x10,%esp + int i; + for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) { + 10128b: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + 101292: eb 08 jmp 10129c + delay(); + 101294: e8 16 fb ff ff call 100daf + for (i = 0; !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800; i ++) { + 101299: ff 45 fc incl -0x4(%ebp) + 10129c: 66 c7 45 fa fd 03 movw $0x3fd,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 1012a2: 0f b7 45 fa movzwl -0x6(%ebp),%eax + 1012a6: 89 c2 mov %eax,%edx + 1012a8: ec in (%dx),%al + 1012a9: 88 45 f9 mov %al,-0x7(%ebp) + return data; + 1012ac: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + 1012b0: 0f b6 c0 movzbl %al,%eax + 1012b3: 83 e0 20 and $0x20,%eax + 1012b6: 85 c0 test %eax,%eax + 1012b8: 75 09 jne 1012c3 + 1012ba: 81 7d fc ff 31 00 00 cmpl $0x31ff,-0x4(%ebp) + 1012c1: 7e d1 jle 101294 + } + outb(COM1 + COM_TX, c); + 1012c3: 8b 45 08 mov 0x8(%ebp),%eax + 1012c6: 0f b6 c0 movzbl %al,%eax + 1012c9: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) + 1012cf: 88 45 f5 mov %al,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1012d2: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + 1012d6: 0f b7 55 f6 movzwl -0xa(%ebp),%edx + 1012da: ee out %al,(%dx) +} + 1012db: 90 nop +} + 1012dc: 90 nop + 1012dd: 89 ec mov %ebp,%esp + 1012df: 5d pop %ebp + 1012e0: c3 ret + +001012e1 : + +/* serial_putc - print character to serial port */ +static void +serial_putc(int c) { + 1012e1: 55 push %ebp + 1012e2: 89 e5 mov %esp,%ebp + 1012e4: 83 ec 04 sub $0x4,%esp + if (c != '\b') { + 1012e7: 83 7d 08 08 cmpl $0x8,0x8(%ebp) + 1012eb: 74 0d je 1012fa + serial_putc_sub(c); + 1012ed: 8b 45 08 mov 0x8(%ebp),%eax + 1012f0: 89 04 24 mov %eax,(%esp) + 1012f3: e8 8d ff ff ff call 101285 + else { + serial_putc_sub('\b'); + serial_putc_sub(' '); + serial_putc_sub('\b'); + } +} + 1012f8: eb 24 jmp 10131e + serial_putc_sub('\b'); + 1012fa: c7 04 24 08 00 00 00 movl $0x8,(%esp) + 101301: e8 7f ff ff ff call 101285 + serial_putc_sub(' '); + 101306: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 10130d: e8 73 ff ff ff call 101285 + serial_putc_sub('\b'); + 101312: c7 04 24 08 00 00 00 movl $0x8,(%esp) + 101319: e8 67 ff ff ff call 101285 +} + 10131e: 90 nop + 10131f: 89 ec mov %ebp,%esp + 101321: 5d pop %ebp + 101322: c3 ret + +00101323 : +/* * + * cons_intr - called by device interrupt routines to feed input + * characters into the circular console input buffer. + * */ +static void +cons_intr(int (*proc)(void)) { + 101323: 55 push %ebp + 101324: 89 e5 mov %esp,%ebp + 101326: 83 ec 18 sub $0x18,%esp + int c; + while ((c = (*proc)()) != -1) { + 101329: eb 33 jmp 10135e + if (c != 0) { + 10132b: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 10132f: 74 2d je 10135e + cons.buf[cons.wpos ++] = c; + 101331: a1 64 c6 11 00 mov 0x11c664,%eax + 101336: 8d 50 01 lea 0x1(%eax),%edx + 101339: 89 15 64 c6 11 00 mov %edx,0x11c664 + 10133f: 8b 55 f4 mov -0xc(%ebp),%edx + 101342: 88 90 60 c4 11 00 mov %dl,0x11c460(%eax) + if (cons.wpos == CONSBUFSIZE) { + 101348: a1 64 c6 11 00 mov 0x11c664,%eax + 10134d: 3d 00 02 00 00 cmp $0x200,%eax + 101352: 75 0a jne 10135e + cons.wpos = 0; + 101354: c7 05 64 c6 11 00 00 movl $0x0,0x11c664 + 10135b: 00 00 00 + while ((c = (*proc)()) != -1) { + 10135e: 8b 45 08 mov 0x8(%ebp),%eax + 101361: ff d0 call *%eax + 101363: 89 45 f4 mov %eax,-0xc(%ebp) + 101366: 83 7d f4 ff cmpl $0xffffffff,-0xc(%ebp) + 10136a: 75 bf jne 10132b + } + } + } +} + 10136c: 90 nop + 10136d: 90 nop + 10136e: 89 ec mov %ebp,%esp + 101370: 5d pop %ebp + 101371: c3 ret + +00101372 : + +/* serial_proc_data - get data from serial port */ +static int +serial_proc_data(void) { + 101372: 55 push %ebp + 101373: 89 e5 mov %esp,%ebp + 101375: 83 ec 10 sub $0x10,%esp + 101378: 66 c7 45 fa fd 03 movw $0x3fd,-0x6(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 10137e: 0f b7 45 fa movzwl -0x6(%ebp),%eax + 101382: 89 c2 mov %eax,%edx + 101384: ec in (%dx),%al + 101385: 88 45 f9 mov %al,-0x7(%ebp) + return data; + 101388: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + if (!(inb(COM1 + COM_LSR) & COM_LSR_DATA)) { + 10138c: 0f b6 c0 movzbl %al,%eax + 10138f: 83 e0 01 and $0x1,%eax + 101392: 85 c0 test %eax,%eax + 101394: 75 07 jne 10139d + return -1; + 101396: b8 ff ff ff ff mov $0xffffffff,%eax + 10139b: eb 2a jmp 1013c7 + 10139d: 66 c7 45 f6 f8 03 movw $0x3f8,-0xa(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 1013a3: 0f b7 45 f6 movzwl -0xa(%ebp),%eax + 1013a7: 89 c2 mov %eax,%edx + 1013a9: ec in (%dx),%al + 1013aa: 88 45 f5 mov %al,-0xb(%ebp) + return data; + 1013ad: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + } + int c = inb(COM1 + COM_RX); + 1013b1: 0f b6 c0 movzbl %al,%eax + 1013b4: 89 45 fc mov %eax,-0x4(%ebp) + if (c == 127) { + 1013b7: 83 7d fc 7f cmpl $0x7f,-0x4(%ebp) + 1013bb: 75 07 jne 1013c4 + c = '\b'; + 1013bd: c7 45 fc 08 00 00 00 movl $0x8,-0x4(%ebp) + } + return c; + 1013c4: 8b 45 fc mov -0x4(%ebp),%eax +} + 1013c7: 89 ec mov %ebp,%esp + 1013c9: 5d pop %ebp + 1013ca: c3 ret + +001013cb : + +/* serial_intr - try to feed input characters from serial port */ +void +serial_intr(void) { + 1013cb: 55 push %ebp + 1013cc: 89 e5 mov %esp,%ebp + 1013ce: 83 ec 18 sub $0x18,%esp + if (serial_exists) { + 1013d1: a1 48 c4 11 00 mov 0x11c448,%eax + 1013d6: 85 c0 test %eax,%eax + 1013d8: 74 0c je 1013e6 + cons_intr(serial_proc_data); + 1013da: c7 04 24 72 13 10 00 movl $0x101372,(%esp) + 1013e1: e8 3d ff ff ff call 101323 + } +} + 1013e6: 90 nop + 1013e7: 89 ec mov %ebp,%esp + 1013e9: 5d pop %ebp + 1013ea: c3 ret + +001013eb : + * + * The kbd_proc_data() function gets data from the keyboard. + * If we finish a character, return it, else 0. And return -1 if no data. + * */ +static int +kbd_proc_data(void) { + 1013eb: 55 push %ebp + 1013ec: 89 e5 mov %esp,%ebp + 1013ee: 83 ec 38 sub $0x38,%esp + 1013f1: 66 c7 45 f0 64 00 movw $0x64,-0x10(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 1013f7: 8b 45 f0 mov -0x10(%ebp),%eax + 1013fa: 89 c2 mov %eax,%edx + 1013fc: ec in (%dx),%al + 1013fd: 88 45 ef mov %al,-0x11(%ebp) + return data; + 101400: 0f b6 45 ef movzbl -0x11(%ebp),%eax + int c; + uint8_t data; + static uint32_t shift; + + if ((inb(KBSTATP) & KBS_DIB) == 0) { + 101404: 0f b6 c0 movzbl %al,%eax + 101407: 83 e0 01 and $0x1,%eax + 10140a: 85 c0 test %eax,%eax + 10140c: 75 0a jne 101418 + return -1; + 10140e: b8 ff ff ff ff mov $0xffffffff,%eax + 101413: e9 56 01 00 00 jmp 10156e + 101418: 66 c7 45 ec 60 00 movw $0x60,-0x14(%ebp) + asm volatile ("inb %1, %0" : "=a" (data) : "d" (port) : "memory"); + 10141e: 8b 45 ec mov -0x14(%ebp),%eax + 101421: 89 c2 mov %eax,%edx + 101423: ec in (%dx),%al + 101424: 88 45 eb mov %al,-0x15(%ebp) + return data; + 101427: 0f b6 45 eb movzbl -0x15(%ebp),%eax + } + + data = inb(KBDATAP); + 10142b: 88 45 f3 mov %al,-0xd(%ebp) + + if (data == 0xE0) { + 10142e: 80 7d f3 e0 cmpb $0xe0,-0xd(%ebp) + 101432: 75 17 jne 10144b + // E0 escape character + shift |= E0ESC; + 101434: a1 68 c6 11 00 mov 0x11c668,%eax + 101439: 83 c8 40 or $0x40,%eax + 10143c: a3 68 c6 11 00 mov %eax,0x11c668 + return 0; + 101441: b8 00 00 00 00 mov $0x0,%eax + 101446: e9 23 01 00 00 jmp 10156e + } else if (data & 0x80) { + 10144b: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 10144f: 84 c0 test %al,%al + 101451: 79 45 jns 101498 + // Key released + data = (shift & E0ESC ? data : data & 0x7F); + 101453: a1 68 c6 11 00 mov 0x11c668,%eax + 101458: 83 e0 40 and $0x40,%eax + 10145b: 85 c0 test %eax,%eax + 10145d: 75 08 jne 101467 + 10145f: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 101463: 24 7f and $0x7f,%al + 101465: eb 04 jmp 10146b + 101467: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 10146b: 88 45 f3 mov %al,-0xd(%ebp) + shift &= ~(shiftcode[data] | E0ESC); + 10146e: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 101472: 0f b6 80 40 90 11 00 movzbl 0x119040(%eax),%eax + 101479: 0c 40 or $0x40,%al + 10147b: 0f b6 c0 movzbl %al,%eax + 10147e: f7 d0 not %eax + 101480: 89 c2 mov %eax,%edx + 101482: a1 68 c6 11 00 mov 0x11c668,%eax + 101487: 21 d0 and %edx,%eax + 101489: a3 68 c6 11 00 mov %eax,0x11c668 + return 0; + 10148e: b8 00 00 00 00 mov $0x0,%eax + 101493: e9 d6 00 00 00 jmp 10156e + } else if (shift & E0ESC) { + 101498: a1 68 c6 11 00 mov 0x11c668,%eax + 10149d: 83 e0 40 and $0x40,%eax + 1014a0: 85 c0 test %eax,%eax + 1014a2: 74 11 je 1014b5 + // Last character was an E0 escape; or with 0x80 + data |= 0x80; + 1014a4: 80 4d f3 80 orb $0x80,-0xd(%ebp) + shift &= ~E0ESC; + 1014a8: a1 68 c6 11 00 mov 0x11c668,%eax + 1014ad: 83 e0 bf and $0xffffffbf,%eax + 1014b0: a3 68 c6 11 00 mov %eax,0x11c668 + } + + shift |= shiftcode[data]; + 1014b5: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 1014b9: 0f b6 80 40 90 11 00 movzbl 0x119040(%eax),%eax + 1014c0: 0f b6 d0 movzbl %al,%edx + 1014c3: a1 68 c6 11 00 mov 0x11c668,%eax + 1014c8: 09 d0 or %edx,%eax + 1014ca: a3 68 c6 11 00 mov %eax,0x11c668 + shift ^= togglecode[data]; + 1014cf: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 1014d3: 0f b6 80 40 91 11 00 movzbl 0x119140(%eax),%eax + 1014da: 0f b6 d0 movzbl %al,%edx + 1014dd: a1 68 c6 11 00 mov 0x11c668,%eax + 1014e2: 31 d0 xor %edx,%eax + 1014e4: a3 68 c6 11 00 mov %eax,0x11c668 + + c = charcode[shift & (CTL | SHIFT)][data]; + 1014e9: a1 68 c6 11 00 mov 0x11c668,%eax + 1014ee: 83 e0 03 and $0x3,%eax + 1014f1: 8b 14 85 40 95 11 00 mov 0x119540(,%eax,4),%edx + 1014f8: 0f b6 45 f3 movzbl -0xd(%ebp),%eax + 1014fc: 01 d0 add %edx,%eax + 1014fe: 0f b6 00 movzbl (%eax),%eax + 101501: 0f b6 c0 movzbl %al,%eax + 101504: 89 45 f4 mov %eax,-0xc(%ebp) + if (shift & CAPSLOCK) { + 101507: a1 68 c6 11 00 mov 0x11c668,%eax + 10150c: 83 e0 08 and $0x8,%eax + 10150f: 85 c0 test %eax,%eax + 101511: 74 22 je 101535 + if ('a' <= c && c <= 'z') + 101513: 83 7d f4 60 cmpl $0x60,-0xc(%ebp) + 101517: 7e 0c jle 101525 + 101519: 83 7d f4 7a cmpl $0x7a,-0xc(%ebp) + 10151d: 7f 06 jg 101525 + c += 'A' - 'a'; + 10151f: 83 6d f4 20 subl $0x20,-0xc(%ebp) + 101523: eb 10 jmp 101535 + else if ('A' <= c && c <= 'Z') + 101525: 83 7d f4 40 cmpl $0x40,-0xc(%ebp) + 101529: 7e 0a jle 101535 + 10152b: 83 7d f4 5a cmpl $0x5a,-0xc(%ebp) + 10152f: 7f 04 jg 101535 + c += 'a' - 'A'; + 101531: 83 45 f4 20 addl $0x20,-0xc(%ebp) + } + + // Process special keys + // Ctrl-Alt-Del: reboot + if (!(~shift & (CTL | ALT)) && c == KEY_DEL) { + 101535: a1 68 c6 11 00 mov 0x11c668,%eax + 10153a: f7 d0 not %eax + 10153c: 83 e0 06 and $0x6,%eax + 10153f: 85 c0 test %eax,%eax + 101541: 75 28 jne 10156b + 101543: 81 7d f4 e9 00 00 00 cmpl $0xe9,-0xc(%ebp) + 10154a: 75 1f jne 10156b + cprintf("Rebooting!\n"); + 10154c: c7 04 24 a7 63 10 00 movl $0x1063a7,(%esp) + 101553: e8 0e ee ff ff call 100366 + 101558: 66 c7 45 e8 92 00 movw $0x92,-0x18(%ebp) + 10155e: c6 45 e7 03 movb $0x3,-0x19(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101562: 0f b6 45 e7 movzbl -0x19(%ebp),%eax + 101566: 8b 55 e8 mov -0x18(%ebp),%edx + 101569: ee out %al,(%dx) +} + 10156a: 90 nop + outb(0x92, 0x3); // courtesy of Chris Frost + } + return c; + 10156b: 8b 45 f4 mov -0xc(%ebp),%eax +} + 10156e: 89 ec mov %ebp,%esp + 101570: 5d pop %ebp + 101571: c3 ret + +00101572 : + +/* kbd_intr - try to feed input characters from keyboard */ +static void +kbd_intr(void) { + 101572: 55 push %ebp + 101573: 89 e5 mov %esp,%ebp + 101575: 83 ec 18 sub $0x18,%esp + cons_intr(kbd_proc_data); + 101578: c7 04 24 eb 13 10 00 movl $0x1013eb,(%esp) + 10157f: e8 9f fd ff ff call 101323 +} + 101584: 90 nop + 101585: 89 ec mov %ebp,%esp + 101587: 5d pop %ebp + 101588: c3 ret + +00101589 : + +static void +kbd_init(void) { + 101589: 55 push %ebp + 10158a: 89 e5 mov %esp,%ebp + 10158c: 83 ec 18 sub $0x18,%esp + // drain the kbd buffer + kbd_intr(); + 10158f: e8 de ff ff ff call 101572 + pic_enable(IRQ_KBD); + 101594: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 10159b: e8 51 01 00 00 call 1016f1 +} + 1015a0: 90 nop + 1015a1: 89 ec mov %ebp,%esp + 1015a3: 5d pop %ebp + 1015a4: c3 ret + +001015a5 : + +/* cons_init - initializes the console devices */ +void +cons_init(void) { + 1015a5: 55 push %ebp + 1015a6: 89 e5 mov %esp,%ebp + 1015a8: 83 ec 18 sub $0x18,%esp + cga_init(); + 1015ab: e8 4a f8 ff ff call 100dfa + serial_init(); + 1015b0: e8 2d f9 ff ff call 100ee2 + kbd_init(); + 1015b5: e8 cf ff ff ff call 101589 + if (!serial_exists) { + 1015ba: a1 48 c4 11 00 mov 0x11c448,%eax + 1015bf: 85 c0 test %eax,%eax + 1015c1: 75 0c jne 1015cf + cprintf("serial port does not exist!!\n"); + 1015c3: c7 04 24 b3 63 10 00 movl $0x1063b3,(%esp) + 1015ca: e8 97 ed ff ff call 100366 + } +} + 1015cf: 90 nop + 1015d0: 89 ec mov %ebp,%esp + 1015d2: 5d pop %ebp + 1015d3: c3 ret + +001015d4 : + +/* cons_putc - print a single character @c to console devices */ +void +cons_putc(int c) { + 1015d4: 55 push %ebp + 1015d5: 89 e5 mov %esp,%ebp + 1015d7: 83 ec 28 sub $0x28,%esp + bool intr_flag; + local_intr_save(intr_flag); + 1015da: e8 8e f7 ff ff call 100d6d <__intr_save> + 1015df: 89 45 f4 mov %eax,-0xc(%ebp) + { + lpt_putc(c); + 1015e2: 8b 45 08 mov 0x8(%ebp),%eax + 1015e5: 89 04 24 mov %eax,(%esp) + 1015e8: e8 60 fa ff ff call 10104d + cga_putc(c); + 1015ed: 8b 45 08 mov 0x8(%ebp),%eax + 1015f0: 89 04 24 mov %eax,(%esp) + 1015f3: e8 97 fa ff ff call 10108f + serial_putc(c); + 1015f8: 8b 45 08 mov 0x8(%ebp),%eax + 1015fb: 89 04 24 mov %eax,(%esp) + 1015fe: e8 de fc ff ff call 1012e1 + } + local_intr_restore(intr_flag); + 101603: 8b 45 f4 mov -0xc(%ebp),%eax + 101606: 89 04 24 mov %eax,(%esp) + 101609: e8 8b f7 ff ff call 100d99 <__intr_restore> +} + 10160e: 90 nop + 10160f: 89 ec mov %ebp,%esp + 101611: 5d pop %ebp + 101612: c3 ret + +00101613 : +/* * + * cons_getc - return the next input character from console, + * or 0 if none waiting. + * */ +int +cons_getc(void) { + 101613: 55 push %ebp + 101614: 89 e5 mov %esp,%ebp + 101616: 83 ec 28 sub $0x28,%esp + int c = 0; + 101619: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + bool intr_flag; + local_intr_save(intr_flag); + 101620: e8 48 f7 ff ff call 100d6d <__intr_save> + 101625: 89 45 f0 mov %eax,-0x10(%ebp) + { + // poll for any pending input characters, + // so that this function works even when interrupts are disabled + // (e.g., when called from the kernel monitor). + serial_intr(); + 101628: e8 9e fd ff ff call 1013cb + kbd_intr(); + 10162d: e8 40 ff ff ff call 101572 + + // grab the next character from the input buffer. + if (cons.rpos != cons.wpos) { + 101632: 8b 15 60 c6 11 00 mov 0x11c660,%edx + 101638: a1 64 c6 11 00 mov 0x11c664,%eax + 10163d: 39 c2 cmp %eax,%edx + 10163f: 74 31 je 101672 + c = cons.buf[cons.rpos ++]; + 101641: a1 60 c6 11 00 mov 0x11c660,%eax + 101646: 8d 50 01 lea 0x1(%eax),%edx + 101649: 89 15 60 c6 11 00 mov %edx,0x11c660 + 10164f: 0f b6 80 60 c4 11 00 movzbl 0x11c460(%eax),%eax + 101656: 0f b6 c0 movzbl %al,%eax + 101659: 89 45 f4 mov %eax,-0xc(%ebp) + if (cons.rpos == CONSBUFSIZE) { + 10165c: a1 60 c6 11 00 mov 0x11c660,%eax + 101661: 3d 00 02 00 00 cmp $0x200,%eax + 101666: 75 0a jne 101672 + cons.rpos = 0; + 101668: c7 05 60 c6 11 00 00 movl $0x0,0x11c660 + 10166f: 00 00 00 + } + } + } + local_intr_restore(intr_flag); + 101672: 8b 45 f0 mov -0x10(%ebp),%eax + 101675: 89 04 24 mov %eax,(%esp) + 101678: e8 1c f7 ff ff call 100d99 <__intr_restore> + return c; + 10167d: 8b 45 f4 mov -0xc(%ebp),%eax +} + 101680: 89 ec mov %ebp,%esp + 101682: 5d pop %ebp + 101683: c3 ret + +00101684 : +#include +#include + +/* intr_enable - enable irq interrupt */ +void +intr_enable(void) { + 101684: 55 push %ebp + 101685: 89 e5 mov %esp,%ebp + asm volatile ("sti"); + 101687: fb sti +} + 101688: 90 nop + sti(); +} + 101689: 90 nop + 10168a: 5d pop %ebp + 10168b: c3 ret + +0010168c : + +/* intr_disable - disable irq interrupt */ +void +intr_disable(void) { + 10168c: 55 push %ebp + 10168d: 89 e5 mov %esp,%ebp + asm volatile ("cli" ::: "memory"); + 10168f: fa cli +} + 101690: 90 nop + cli(); +} + 101691: 90 nop + 101692: 5d pop %ebp + 101693: c3 ret + +00101694 : +// Initial IRQ mask has interrupt 2 enabled (for slave 8259A). +static uint16_t irq_mask = 0xFFFF & ~(1 << IRQ_SLAVE); +static bool did_init = 0; + +static void +pic_setmask(uint16_t mask) { + 101694: 55 push %ebp + 101695: 89 e5 mov %esp,%ebp + 101697: 83 ec 14 sub $0x14,%esp + 10169a: 8b 45 08 mov 0x8(%ebp),%eax + 10169d: 66 89 45 ec mov %ax,-0x14(%ebp) + irq_mask = mask; + 1016a1: 8b 45 ec mov -0x14(%ebp),%eax + 1016a4: 66 a3 50 95 11 00 mov %ax,0x119550 + if (did_init) { + 1016aa: a1 6c c6 11 00 mov 0x11c66c,%eax + 1016af: 85 c0 test %eax,%eax + 1016b1: 74 39 je 1016ec + outb(IO_PIC1 + 1, mask); + 1016b3: 8b 45 ec mov -0x14(%ebp),%eax + 1016b6: 0f b6 c0 movzbl %al,%eax + 1016b9: 66 c7 45 fa 21 00 movw $0x21,-0x6(%ebp) + 1016bf: 88 45 f9 mov %al,-0x7(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1016c2: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + 1016c6: 0f b7 55 fa movzwl -0x6(%ebp),%edx + 1016ca: ee out %al,(%dx) +} + 1016cb: 90 nop + outb(IO_PIC2 + 1, mask >> 8); + 1016cc: 0f b7 45 ec movzwl -0x14(%ebp),%eax + 1016d0: c1 e8 08 shr $0x8,%eax + 1016d3: 0f b7 c0 movzwl %ax,%eax + 1016d6: 0f b6 c0 movzbl %al,%eax + 1016d9: 66 c7 45 fe a1 00 movw $0xa1,-0x2(%ebp) + 1016df: 88 45 fd mov %al,-0x3(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1016e2: 0f b6 45 fd movzbl -0x3(%ebp),%eax + 1016e6: 0f b7 55 fe movzwl -0x2(%ebp),%edx + 1016ea: ee out %al,(%dx) +} + 1016eb: 90 nop + } +} + 1016ec: 90 nop + 1016ed: 89 ec mov %ebp,%esp + 1016ef: 5d pop %ebp + 1016f0: c3 ret + +001016f1 : + +void +pic_enable(unsigned int irq) { + 1016f1: 55 push %ebp + 1016f2: 89 e5 mov %esp,%ebp + 1016f4: 83 ec 04 sub $0x4,%esp + pic_setmask(irq_mask & ~(1 << irq)); + 1016f7: 8b 45 08 mov 0x8(%ebp),%eax + 1016fa: ba 01 00 00 00 mov $0x1,%edx + 1016ff: 88 c1 mov %al,%cl + 101701: d3 e2 shl %cl,%edx + 101703: 89 d0 mov %edx,%eax + 101705: 98 cwtl + 101706: f7 d0 not %eax + 101708: 0f bf d0 movswl %ax,%edx + 10170b: 0f b7 05 50 95 11 00 movzwl 0x119550,%eax + 101712: 98 cwtl + 101713: 21 d0 and %edx,%eax + 101715: 98 cwtl + 101716: 0f b7 c0 movzwl %ax,%eax + 101719: 89 04 24 mov %eax,(%esp) + 10171c: e8 73 ff ff ff call 101694 +} + 101721: 90 nop + 101722: 89 ec mov %ebp,%esp + 101724: 5d pop %ebp + 101725: c3 ret + +00101726 : + +/* pic_init - initialize the 8259A interrupt controllers */ +void +pic_init(void) { + 101726: 55 push %ebp + 101727: 89 e5 mov %esp,%ebp + 101729: 83 ec 44 sub $0x44,%esp + did_init = 1; + 10172c: c7 05 6c c6 11 00 01 movl $0x1,0x11c66c + 101733: 00 00 00 + 101736: 66 c7 45 ca 21 00 movw $0x21,-0x36(%ebp) + 10173c: c6 45 c9 ff movb $0xff,-0x37(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101740: 0f b6 45 c9 movzbl -0x37(%ebp),%eax + 101744: 0f b7 55 ca movzwl -0x36(%ebp),%edx + 101748: ee out %al,(%dx) +} + 101749: 90 nop + 10174a: 66 c7 45 ce a1 00 movw $0xa1,-0x32(%ebp) + 101750: c6 45 cd ff movb $0xff,-0x33(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101754: 0f b6 45 cd movzbl -0x33(%ebp),%eax + 101758: 0f b7 55 ce movzwl -0x32(%ebp),%edx + 10175c: ee out %al,(%dx) +} + 10175d: 90 nop + 10175e: 66 c7 45 d2 20 00 movw $0x20,-0x2e(%ebp) + 101764: c6 45 d1 11 movb $0x11,-0x2f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101768: 0f b6 45 d1 movzbl -0x2f(%ebp),%eax + 10176c: 0f b7 55 d2 movzwl -0x2e(%ebp),%edx + 101770: ee out %al,(%dx) +} + 101771: 90 nop + 101772: 66 c7 45 d6 21 00 movw $0x21,-0x2a(%ebp) + 101778: c6 45 d5 20 movb $0x20,-0x2b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 10177c: 0f b6 45 d5 movzbl -0x2b(%ebp),%eax + 101780: 0f b7 55 d6 movzwl -0x2a(%ebp),%edx + 101784: ee out %al,(%dx) +} + 101785: 90 nop + 101786: 66 c7 45 da 21 00 movw $0x21,-0x26(%ebp) + 10178c: c6 45 d9 04 movb $0x4,-0x27(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101790: 0f b6 45 d9 movzbl -0x27(%ebp),%eax + 101794: 0f b7 55 da movzwl -0x26(%ebp),%edx + 101798: ee out %al,(%dx) +} + 101799: 90 nop + 10179a: 66 c7 45 de 21 00 movw $0x21,-0x22(%ebp) + 1017a0: c6 45 dd 03 movb $0x3,-0x23(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1017a4: 0f b6 45 dd movzbl -0x23(%ebp),%eax + 1017a8: 0f b7 55 de movzwl -0x22(%ebp),%edx + 1017ac: ee out %al,(%dx) +} + 1017ad: 90 nop + 1017ae: 66 c7 45 e2 a0 00 movw $0xa0,-0x1e(%ebp) + 1017b4: c6 45 e1 11 movb $0x11,-0x1f(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1017b8: 0f b6 45 e1 movzbl -0x1f(%ebp),%eax + 1017bc: 0f b7 55 e2 movzwl -0x1e(%ebp),%edx + 1017c0: ee out %al,(%dx) +} + 1017c1: 90 nop + 1017c2: 66 c7 45 e6 a1 00 movw $0xa1,-0x1a(%ebp) + 1017c8: c6 45 e5 28 movb $0x28,-0x1b(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1017cc: 0f b6 45 e5 movzbl -0x1b(%ebp),%eax + 1017d0: 0f b7 55 e6 movzwl -0x1a(%ebp),%edx + 1017d4: ee out %al,(%dx) +} + 1017d5: 90 nop + 1017d6: 66 c7 45 ea a1 00 movw $0xa1,-0x16(%ebp) + 1017dc: c6 45 e9 02 movb $0x2,-0x17(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1017e0: 0f b6 45 e9 movzbl -0x17(%ebp),%eax + 1017e4: 0f b7 55 ea movzwl -0x16(%ebp),%edx + 1017e8: ee out %al,(%dx) +} + 1017e9: 90 nop + 1017ea: 66 c7 45 ee a1 00 movw $0xa1,-0x12(%ebp) + 1017f0: c6 45 ed 03 movb $0x3,-0x13(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 1017f4: 0f b6 45 ed movzbl -0x13(%ebp),%eax + 1017f8: 0f b7 55 ee movzwl -0x12(%ebp),%edx + 1017fc: ee out %al,(%dx) +} + 1017fd: 90 nop + 1017fe: 66 c7 45 f2 20 00 movw $0x20,-0xe(%ebp) + 101804: c6 45 f1 68 movb $0x68,-0xf(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101808: 0f b6 45 f1 movzbl -0xf(%ebp),%eax + 10180c: 0f b7 55 f2 movzwl -0xe(%ebp),%edx + 101810: ee out %al,(%dx) +} + 101811: 90 nop + 101812: 66 c7 45 f6 20 00 movw $0x20,-0xa(%ebp) + 101818: c6 45 f5 0a movb $0xa,-0xb(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 10181c: 0f b6 45 f5 movzbl -0xb(%ebp),%eax + 101820: 0f b7 55 f6 movzwl -0xa(%ebp),%edx + 101824: ee out %al,(%dx) +} + 101825: 90 nop + 101826: 66 c7 45 fa a0 00 movw $0xa0,-0x6(%ebp) + 10182c: c6 45 f9 68 movb $0x68,-0x7(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101830: 0f b6 45 f9 movzbl -0x7(%ebp),%eax + 101834: 0f b7 55 fa movzwl -0x6(%ebp),%edx + 101838: ee out %al,(%dx) +} + 101839: 90 nop + 10183a: 66 c7 45 fe a0 00 movw $0xa0,-0x2(%ebp) + 101840: c6 45 fd 0a movb $0xa,-0x3(%ebp) + asm volatile ("outb %0, %1" :: "a" (data), "d" (port) : "memory"); + 101844: 0f b6 45 fd movzbl -0x3(%ebp),%eax + 101848: 0f b7 55 fe movzwl -0x2(%ebp),%edx + 10184c: ee out %al,(%dx) +} + 10184d: 90 nop + outb(IO_PIC1, 0x0a); // read IRR by default + + outb(IO_PIC2, 0x68); // OCW3 + outb(IO_PIC2, 0x0a); // OCW3 + + if (irq_mask != 0xFFFF) { + 10184e: 0f b7 05 50 95 11 00 movzwl 0x119550,%eax + 101855: 3d ff ff 00 00 cmp $0xffff,%eax + 10185a: 74 0f je 10186b + pic_setmask(irq_mask); + 10185c: 0f b7 05 50 95 11 00 movzwl 0x119550,%eax + 101863: 89 04 24 mov %eax,(%esp) + 101866: e8 29 fe ff ff call 101694 + } +} + 10186b: 90 nop + 10186c: 89 ec mov %ebp,%esp + 10186e: 5d pop %ebp + 10186f: c3 ret + +00101870 : +#include +#include + +#define TICK_NUM 100 + +static void print_ticks() { + 101870: 55 push %ebp + 101871: 89 e5 mov %esp,%ebp + 101873: 83 ec 18 sub $0x18,%esp + cprintf("%d ticks\n",TICK_NUM); + 101876: c7 44 24 04 64 00 00 movl $0x64,0x4(%esp) + 10187d: 00 + 10187e: c7 04 24 e0 63 10 00 movl $0x1063e0,(%esp) + 101885: e8 dc ea ff ff call 100366 +#ifdef DEBUG_GRADE + cprintf("End of Test.\n"); + panic("EOT: kernel seems ok."); +#endif +} + 10188a: 90 nop + 10188b: 89 ec mov %ebp,%esp + 10188d: 5d pop %ebp + 10188e: c3 ret + +0010188f : + sizeof(idt) - 1, (uintptr_t)idt +}; + +/* idt_init - initialize IDT to each of the entry points in kern/trap/vectors.S */ +void +idt_init(void) { + 10188f: 55 push %ebp + 101890: 89 e5 mov %esp,%ebp + 101892: 83 ec 10 sub $0x10,%esp + * You don't know the meaning of this instruction? just google it! and check the libs/x86.h to know more. + * Notice: the argument of lidt is idt_pd. try to find it! + */ + extern uintptr_t __vectors[];//声明了一个外部数组 __vectors,该数组存储中断服务例程(ISR)的地址。 + int i; + for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { + 101895: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + 10189c: e9 c4 00 00 00 jmp 101965 + SETGATE(idt[i], 0, GD_KTEXT, __vectors[i], DPL_KERNEL); + 1018a1: 8b 45 fc mov -0x4(%ebp),%eax + 1018a4: 8b 04 85 e0 95 11 00 mov 0x1195e0(,%eax,4),%eax + 1018ab: 0f b7 d0 movzwl %ax,%edx + 1018ae: 8b 45 fc mov -0x4(%ebp),%eax + 1018b1: 66 89 14 c5 e0 c6 11 mov %dx,0x11c6e0(,%eax,8) + 1018b8: 00 + 1018b9: 8b 45 fc mov -0x4(%ebp),%eax + 1018bc: 66 c7 04 c5 e2 c6 11 movw $0x8,0x11c6e2(,%eax,8) + 1018c3: 00 08 00 + 1018c6: 8b 45 fc mov -0x4(%ebp),%eax + 1018c9: 0f b6 14 c5 e4 c6 11 movzbl 0x11c6e4(,%eax,8),%edx + 1018d0: 00 + 1018d1: 80 e2 e0 and $0xe0,%dl + 1018d4: 88 14 c5 e4 c6 11 00 mov %dl,0x11c6e4(,%eax,8) + 1018db: 8b 45 fc mov -0x4(%ebp),%eax + 1018de: 0f b6 14 c5 e4 c6 11 movzbl 0x11c6e4(,%eax,8),%edx + 1018e5: 00 + 1018e6: 80 e2 1f and $0x1f,%dl + 1018e9: 88 14 c5 e4 c6 11 00 mov %dl,0x11c6e4(,%eax,8) + 1018f0: 8b 45 fc mov -0x4(%ebp),%eax + 1018f3: 0f b6 14 c5 e5 c6 11 movzbl 0x11c6e5(,%eax,8),%edx + 1018fa: 00 + 1018fb: 80 e2 f0 and $0xf0,%dl + 1018fe: 80 ca 0e or $0xe,%dl + 101901: 88 14 c5 e5 c6 11 00 mov %dl,0x11c6e5(,%eax,8) + 101908: 8b 45 fc mov -0x4(%ebp),%eax + 10190b: 0f b6 14 c5 e5 c6 11 movzbl 0x11c6e5(,%eax,8),%edx + 101912: 00 + 101913: 80 e2 ef and $0xef,%dl + 101916: 88 14 c5 e5 c6 11 00 mov %dl,0x11c6e5(,%eax,8) + 10191d: 8b 45 fc mov -0x4(%ebp),%eax + 101920: 0f b6 14 c5 e5 c6 11 movzbl 0x11c6e5(,%eax,8),%edx + 101927: 00 + 101928: 80 e2 9f and $0x9f,%dl + 10192b: 88 14 c5 e5 c6 11 00 mov %dl,0x11c6e5(,%eax,8) + 101932: 8b 45 fc mov -0x4(%ebp),%eax + 101935: 0f b6 14 c5 e5 c6 11 movzbl 0x11c6e5(,%eax,8),%edx + 10193c: 00 + 10193d: 80 ca 80 or $0x80,%dl + 101940: 88 14 c5 e5 c6 11 00 mov %dl,0x11c6e5(,%eax,8) + 101947: 8b 45 fc mov -0x4(%ebp),%eax + 10194a: 8b 04 85 e0 95 11 00 mov 0x1195e0(,%eax,4),%eax + 101951: c1 e8 10 shr $0x10,%eax + 101954: 0f b7 d0 movzwl %ax,%edx + 101957: 8b 45 fc mov -0x4(%ebp),%eax + 10195a: 66 89 14 c5 e6 c6 11 mov %dx,0x11c6e6(,%eax,8) + 101961: 00 + for (i = 0; i < sizeof(idt) / sizeof(struct gatedesc); i ++) { + 101962: ff 45 fc incl -0x4(%ebp) + 101965: 8b 45 fc mov -0x4(%ebp),%eax + 101968: 3d ff 00 00 00 cmp $0xff,%eax + 10196d: 0f 86 2e ff ff ff jbe 1018a1 + //宏用于配置每个 IDT 条目.0 表示最高特权级(内核级)GD_KTEXT: 指向内核代码段的选择子,确保 ISR 在内核代码段中执行。 + //__vectors[i]: 对应中断的 ISR 地址,DPL_KERNEL: 描述符特权级,表示该中断只能由内核级代码触发。 + // set for switch from user to kernel + //SETGATE 这行代码特别设置了 T_SWITCH_TOK(一个特定的中断向量,用于用户态到内核态的切换)的 IDT 条目。 + //DPL_USER 表示该中断可以由用户态代码触发 + SETGATE(idt[T_SWITCH_TOK], 0, GD_KTEXT, __vectors[T_SWITCH_TOK], DPL_USER); + 101973: a1 c4 97 11 00 mov 0x1197c4,%eax + 101978: 0f b7 c0 movzwl %ax,%eax + 10197b: 66 a3 a8 ca 11 00 mov %ax,0x11caa8 + 101981: 66 c7 05 aa ca 11 00 movw $0x8,0x11caaa + 101988: 08 00 + 10198a: 0f b6 05 ac ca 11 00 movzbl 0x11caac,%eax + 101991: 24 e0 and $0xe0,%al + 101993: a2 ac ca 11 00 mov %al,0x11caac + 101998: 0f b6 05 ac ca 11 00 movzbl 0x11caac,%eax + 10199f: 24 1f and $0x1f,%al + 1019a1: a2 ac ca 11 00 mov %al,0x11caac + 1019a6: 0f b6 05 ad ca 11 00 movzbl 0x11caad,%eax + 1019ad: 24 f0 and $0xf0,%al + 1019af: 0c 0e or $0xe,%al + 1019b1: a2 ad ca 11 00 mov %al,0x11caad + 1019b6: 0f b6 05 ad ca 11 00 movzbl 0x11caad,%eax + 1019bd: 24 ef and $0xef,%al + 1019bf: a2 ad ca 11 00 mov %al,0x11caad + 1019c4: 0f b6 05 ad ca 11 00 movzbl 0x11caad,%eax + 1019cb: 0c 60 or $0x60,%al + 1019cd: a2 ad ca 11 00 mov %al,0x11caad + 1019d2: 0f b6 05 ad ca 11 00 movzbl 0x11caad,%eax + 1019d9: 0c 80 or $0x80,%al + 1019db: a2 ad ca 11 00 mov %al,0x11caad + 1019e0: a1 c4 97 11 00 mov 0x1197c4,%eax + 1019e5: c1 e8 10 shr $0x10,%eax + 1019e8: 0f b7 c0 movzwl %ax,%eax + 1019eb: 66 a3 ae ca 11 00 mov %ax,0x11caae + 1019f1: c7 45 f8 60 95 11 00 movl $0x119560,-0x8(%ebp) + asm volatile ("lidt (%0)" :: "r" (pd) : "memory"); + 1019f8: 8b 45 f8 mov -0x8(%ebp),%eax + 1019fb: 0f 01 18 lidtl (%eax) +} + 1019fe: 90 nop + // load the IDT + //使用 lidt 指令将 IDT 描述符加载到 CPU 中 + lidt(&idt_pd); +} + 1019ff: 90 nop + 101a00: 89 ec mov %ebp,%esp + 101a02: 5d pop %ebp + 101a03: c3 ret + +00101a04 : + +static const char * +trapname(int trapno) { + 101a04: 55 push %ebp + 101a05: 89 e5 mov %esp,%ebp + "Alignment Check", + "Machine-Check", + "SIMD Floating-Point Exception" + }; + + if (trapno < sizeof(excnames)/sizeof(const char * const)) { + 101a07: 8b 45 08 mov 0x8(%ebp),%eax + 101a0a: 83 f8 13 cmp $0x13,%eax + 101a0d: 77 0c ja 101a1b + return excnames[trapno]; + 101a0f: 8b 45 08 mov 0x8(%ebp),%eax + 101a12: 8b 04 85 40 67 10 00 mov 0x106740(,%eax,4),%eax + 101a19: eb 18 jmp 101a33 + } + if (trapno >= IRQ_OFFSET && trapno < IRQ_OFFSET + 16) { + 101a1b: 83 7d 08 1f cmpl $0x1f,0x8(%ebp) + 101a1f: 7e 0d jle 101a2e + 101a21: 83 7d 08 2f cmpl $0x2f,0x8(%ebp) + 101a25: 7f 07 jg 101a2e + return "Hardware Interrupt"; + 101a27: b8 ea 63 10 00 mov $0x1063ea,%eax + 101a2c: eb 05 jmp 101a33 + } + return "(unknown trap)"; + 101a2e: b8 fd 63 10 00 mov $0x1063fd,%eax +} + 101a33: 5d pop %ebp + 101a34: c3 ret + +00101a35 : + +/* trap_in_kernel - test if trap happened in kernel */ +bool +trap_in_kernel(struct trapframe *tf) { + 101a35: 55 push %ebp + 101a36: 89 e5 mov %esp,%ebp + return (tf->tf_cs == (uint16_t)KERNEL_CS); + 101a38: 8b 45 08 mov 0x8(%ebp),%eax + 101a3b: 0f b7 40 3c movzwl 0x3c(%eax),%eax + 101a3f: 83 f8 08 cmp $0x8,%eax + 101a42: 0f 94 c0 sete %al + 101a45: 0f b6 c0 movzbl %al,%eax +} + 101a48: 5d pop %ebp + 101a49: c3 ret + +00101a4a : + "TF", "IF", "DF", "OF", NULL, NULL, "NT", NULL, + "RF", "VM", "AC", "VIF", "VIP", "ID", NULL, NULL, +}; + +void +print_trapframe(struct trapframe *tf) { + 101a4a: 55 push %ebp + 101a4b: 89 e5 mov %esp,%ebp + 101a4d: 83 ec 28 sub $0x28,%esp + cprintf("trapframe at %p\n", tf); + 101a50: 8b 45 08 mov 0x8(%ebp),%eax + 101a53: 89 44 24 04 mov %eax,0x4(%esp) + 101a57: c7 04 24 3e 64 10 00 movl $0x10643e,(%esp) + 101a5e: e8 03 e9 ff ff call 100366 + print_regs(&tf->tf_regs); + 101a63: 8b 45 08 mov 0x8(%ebp),%eax + 101a66: 89 04 24 mov %eax,(%esp) + 101a69: e8 8f 01 00 00 call 101bfd + cprintf(" ds 0x----%04x\n", tf->tf_ds); + 101a6e: 8b 45 08 mov 0x8(%ebp),%eax + 101a71: 0f b7 40 2c movzwl 0x2c(%eax),%eax + 101a75: 89 44 24 04 mov %eax,0x4(%esp) + 101a79: c7 04 24 4f 64 10 00 movl $0x10644f,(%esp) + 101a80: e8 e1 e8 ff ff call 100366 + cprintf(" es 0x----%04x\n", tf->tf_es); + 101a85: 8b 45 08 mov 0x8(%ebp),%eax + 101a88: 0f b7 40 28 movzwl 0x28(%eax),%eax + 101a8c: 89 44 24 04 mov %eax,0x4(%esp) + 101a90: c7 04 24 62 64 10 00 movl $0x106462,(%esp) + 101a97: e8 ca e8 ff ff call 100366 + cprintf(" fs 0x----%04x\n", tf->tf_fs); + 101a9c: 8b 45 08 mov 0x8(%ebp),%eax + 101a9f: 0f b7 40 24 movzwl 0x24(%eax),%eax + 101aa3: 89 44 24 04 mov %eax,0x4(%esp) + 101aa7: c7 04 24 75 64 10 00 movl $0x106475,(%esp) + 101aae: e8 b3 e8 ff ff call 100366 + cprintf(" gs 0x----%04x\n", tf->tf_gs); + 101ab3: 8b 45 08 mov 0x8(%ebp),%eax + 101ab6: 0f b7 40 20 movzwl 0x20(%eax),%eax + 101aba: 89 44 24 04 mov %eax,0x4(%esp) + 101abe: c7 04 24 88 64 10 00 movl $0x106488,(%esp) + 101ac5: e8 9c e8 ff ff call 100366 + cprintf(" trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno)); + 101aca: 8b 45 08 mov 0x8(%ebp),%eax + 101acd: 8b 40 30 mov 0x30(%eax),%eax + 101ad0: 89 04 24 mov %eax,(%esp) + 101ad3: e8 2c ff ff ff call 101a04 + 101ad8: 8b 55 08 mov 0x8(%ebp),%edx + 101adb: 8b 52 30 mov 0x30(%edx),%edx + 101ade: 89 44 24 08 mov %eax,0x8(%esp) + 101ae2: 89 54 24 04 mov %edx,0x4(%esp) + 101ae6: c7 04 24 9b 64 10 00 movl $0x10649b,(%esp) + 101aed: e8 74 e8 ff ff call 100366 + cprintf(" err 0x%08x\n", tf->tf_err); + 101af2: 8b 45 08 mov 0x8(%ebp),%eax + 101af5: 8b 40 34 mov 0x34(%eax),%eax + 101af8: 89 44 24 04 mov %eax,0x4(%esp) + 101afc: c7 04 24 ad 64 10 00 movl $0x1064ad,(%esp) + 101b03: e8 5e e8 ff ff call 100366 + cprintf(" eip 0x%08x\n", tf->tf_eip); + 101b08: 8b 45 08 mov 0x8(%ebp),%eax + 101b0b: 8b 40 38 mov 0x38(%eax),%eax + 101b0e: 89 44 24 04 mov %eax,0x4(%esp) + 101b12: c7 04 24 bc 64 10 00 movl $0x1064bc,(%esp) + 101b19: e8 48 e8 ff ff call 100366 + cprintf(" cs 0x----%04x\n", tf->tf_cs); + 101b1e: 8b 45 08 mov 0x8(%ebp),%eax + 101b21: 0f b7 40 3c movzwl 0x3c(%eax),%eax + 101b25: 89 44 24 04 mov %eax,0x4(%esp) + 101b29: c7 04 24 cb 64 10 00 movl $0x1064cb,(%esp) + 101b30: e8 31 e8 ff ff call 100366 + cprintf(" flag 0x%08x ", tf->tf_eflags); + 101b35: 8b 45 08 mov 0x8(%ebp),%eax + 101b38: 8b 40 40 mov 0x40(%eax),%eax + 101b3b: 89 44 24 04 mov %eax,0x4(%esp) + 101b3f: c7 04 24 de 64 10 00 movl $0x1064de,(%esp) + 101b46: e8 1b e8 ff ff call 100366 + + int i, j; + for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) { + 101b4b: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 101b52: c7 45 f0 01 00 00 00 movl $0x1,-0x10(%ebp) + 101b59: eb 3d jmp 101b98 + if ((tf->tf_eflags & j) && IA32flags[i] != NULL) { + 101b5b: 8b 45 08 mov 0x8(%ebp),%eax + 101b5e: 8b 50 40 mov 0x40(%eax),%edx + 101b61: 8b 45 f0 mov -0x10(%ebp),%eax + 101b64: 21 d0 and %edx,%eax + 101b66: 85 c0 test %eax,%eax + 101b68: 74 28 je 101b92 + 101b6a: 8b 45 f4 mov -0xc(%ebp),%eax + 101b6d: 8b 04 85 80 95 11 00 mov 0x119580(,%eax,4),%eax + 101b74: 85 c0 test %eax,%eax + 101b76: 74 1a je 101b92 + cprintf("%s,", IA32flags[i]); + 101b78: 8b 45 f4 mov -0xc(%ebp),%eax + 101b7b: 8b 04 85 80 95 11 00 mov 0x119580(,%eax,4),%eax + 101b82: 89 44 24 04 mov %eax,0x4(%esp) + 101b86: c7 04 24 ed 64 10 00 movl $0x1064ed,(%esp) + 101b8d: e8 d4 e7 ff ff call 100366 + for (i = 0, j = 1; i < sizeof(IA32flags) / sizeof(IA32flags[0]); i ++, j <<= 1) { + 101b92: ff 45 f4 incl -0xc(%ebp) + 101b95: d1 65 f0 shll -0x10(%ebp) + 101b98: 8b 45 f4 mov -0xc(%ebp),%eax + 101b9b: 83 f8 17 cmp $0x17,%eax + 101b9e: 76 bb jbe 101b5b + } + } + cprintf("IOPL=%d\n", (tf->tf_eflags & FL_IOPL_MASK) >> 12); + 101ba0: 8b 45 08 mov 0x8(%ebp),%eax + 101ba3: 8b 40 40 mov 0x40(%eax),%eax + 101ba6: c1 e8 0c shr $0xc,%eax + 101ba9: 83 e0 03 and $0x3,%eax + 101bac: 89 44 24 04 mov %eax,0x4(%esp) + 101bb0: c7 04 24 f1 64 10 00 movl $0x1064f1,(%esp) + 101bb7: e8 aa e7 ff ff call 100366 + + if (!trap_in_kernel(tf)) { + 101bbc: 8b 45 08 mov 0x8(%ebp),%eax + 101bbf: 89 04 24 mov %eax,(%esp) + 101bc2: e8 6e fe ff ff call 101a35 + 101bc7: 85 c0 test %eax,%eax + 101bc9: 75 2d jne 101bf8 + cprintf(" esp 0x%08x\n", tf->tf_esp); + 101bcb: 8b 45 08 mov 0x8(%ebp),%eax + 101bce: 8b 40 44 mov 0x44(%eax),%eax + 101bd1: 89 44 24 04 mov %eax,0x4(%esp) + 101bd5: c7 04 24 fa 64 10 00 movl $0x1064fa,(%esp) + 101bdc: e8 85 e7 ff ff call 100366 + cprintf(" ss 0x----%04x\n", tf->tf_ss); + 101be1: 8b 45 08 mov 0x8(%ebp),%eax + 101be4: 0f b7 40 48 movzwl 0x48(%eax),%eax + 101be8: 89 44 24 04 mov %eax,0x4(%esp) + 101bec: c7 04 24 09 65 10 00 movl $0x106509,(%esp) + 101bf3: e8 6e e7 ff ff call 100366 + } +} + 101bf8: 90 nop + 101bf9: 89 ec mov %ebp,%esp + 101bfb: 5d pop %ebp + 101bfc: c3 ret + +00101bfd : + +void +print_regs(struct pushregs *regs) { + 101bfd: 55 push %ebp + 101bfe: 89 e5 mov %esp,%ebp + 101c00: 83 ec 18 sub $0x18,%esp + cprintf(" edi 0x%08x\n", regs->reg_edi); + 101c03: 8b 45 08 mov 0x8(%ebp),%eax + 101c06: 8b 00 mov (%eax),%eax + 101c08: 89 44 24 04 mov %eax,0x4(%esp) + 101c0c: c7 04 24 1c 65 10 00 movl $0x10651c,(%esp) + 101c13: e8 4e e7 ff ff call 100366 + cprintf(" esi 0x%08x\n", regs->reg_esi); + 101c18: 8b 45 08 mov 0x8(%ebp),%eax + 101c1b: 8b 40 04 mov 0x4(%eax),%eax + 101c1e: 89 44 24 04 mov %eax,0x4(%esp) + 101c22: c7 04 24 2b 65 10 00 movl $0x10652b,(%esp) + 101c29: e8 38 e7 ff ff call 100366 + cprintf(" ebp 0x%08x\n", regs->reg_ebp); + 101c2e: 8b 45 08 mov 0x8(%ebp),%eax + 101c31: 8b 40 08 mov 0x8(%eax),%eax + 101c34: 89 44 24 04 mov %eax,0x4(%esp) + 101c38: c7 04 24 3a 65 10 00 movl $0x10653a,(%esp) + 101c3f: e8 22 e7 ff ff call 100366 + cprintf(" oesp 0x%08x\n", regs->reg_oesp); + 101c44: 8b 45 08 mov 0x8(%ebp),%eax + 101c47: 8b 40 0c mov 0xc(%eax),%eax + 101c4a: 89 44 24 04 mov %eax,0x4(%esp) + 101c4e: c7 04 24 49 65 10 00 movl $0x106549,(%esp) + 101c55: e8 0c e7 ff ff call 100366 + cprintf(" ebx 0x%08x\n", regs->reg_ebx); + 101c5a: 8b 45 08 mov 0x8(%ebp),%eax + 101c5d: 8b 40 10 mov 0x10(%eax),%eax + 101c60: 89 44 24 04 mov %eax,0x4(%esp) + 101c64: c7 04 24 58 65 10 00 movl $0x106558,(%esp) + 101c6b: e8 f6 e6 ff ff call 100366 + cprintf(" edx 0x%08x\n", regs->reg_edx); + 101c70: 8b 45 08 mov 0x8(%ebp),%eax + 101c73: 8b 40 14 mov 0x14(%eax),%eax + 101c76: 89 44 24 04 mov %eax,0x4(%esp) + 101c7a: c7 04 24 67 65 10 00 movl $0x106567,(%esp) + 101c81: e8 e0 e6 ff ff call 100366 + cprintf(" ecx 0x%08x\n", regs->reg_ecx); + 101c86: 8b 45 08 mov 0x8(%ebp),%eax + 101c89: 8b 40 18 mov 0x18(%eax),%eax + 101c8c: 89 44 24 04 mov %eax,0x4(%esp) + 101c90: c7 04 24 76 65 10 00 movl $0x106576,(%esp) + 101c97: e8 ca e6 ff ff call 100366 + cprintf(" eax 0x%08x\n", regs->reg_eax); + 101c9c: 8b 45 08 mov 0x8(%ebp),%eax + 101c9f: 8b 40 1c mov 0x1c(%eax),%eax + 101ca2: 89 44 24 04 mov %eax,0x4(%esp) + 101ca6: c7 04 24 85 65 10 00 movl $0x106585,(%esp) + 101cad: e8 b4 e6 ff ff call 100366 +} + 101cb2: 90 nop + 101cb3: 89 ec mov %ebp,%esp + 101cb5: 5d pop %ebp + 101cb6: c3 ret + +00101cb7 : + +struct trapframe switchk2u, *switchu2k; +/* trap_dispatch - dispatch based on what type of trap occurred */ +static void +trap_dispatch(struct trapframe *tf) { + 101cb7: 55 push %ebp + 101cb8: 89 e5 mov %esp,%ebp + 101cba: 83 ec 28 sub $0x28,%esp + 101cbd: 89 5d fc mov %ebx,-0x4(%ebp) + char c; + + switch (tf->tf_trapno) { + 101cc0: 8b 45 08 mov 0x8(%ebp),%eax + 101cc3: 8b 40 30 mov 0x30(%eax),%eax + 101cc6: 83 f8 79 cmp $0x79,%eax + 101cc9: 0f 84 6c 01 00 00 je 101e3b + 101ccf: 83 f8 79 cmp $0x79,%eax + 101cd2: 0f 87 e0 01 00 00 ja 101eb8 + 101cd8: 83 f8 78 cmp $0x78,%eax + 101cdb: 0f 84 d0 00 00 00 je 101db1 + 101ce1: 83 f8 78 cmp $0x78,%eax + 101ce4: 0f 87 ce 01 00 00 ja 101eb8 + 101cea: 83 f8 2f cmp $0x2f,%eax + 101ced: 0f 87 c5 01 00 00 ja 101eb8 + 101cf3: 83 f8 2e cmp $0x2e,%eax + 101cf6: 0f 83 f1 01 00 00 jae 101eed + 101cfc: 83 f8 24 cmp $0x24,%eax + 101cff: 74 5e je 101d5f + 101d01: 83 f8 24 cmp $0x24,%eax + 101d04: 0f 87 ae 01 00 00 ja 101eb8 + 101d0a: 83 f8 20 cmp $0x20,%eax + 101d0d: 74 0a je 101d19 + 101d0f: 83 f8 21 cmp $0x21,%eax + 101d12: 74 74 je 101d88 + 101d14: e9 9f 01 00 00 jmp 101eb8 + /* handle the timer interrupt */ + /* (1) After a timer interrupt, you should record this event using a global variable (increase it), such as ticks in kern/driver/clock.c + * (2) Every TICK_NUM cycle, you can print some info using a funciton, such as print_ticks(). + * (3) Too Simple? Yes, I think so! + */ + ticks ++; //记录中断事件 + 101d19: a1 24 c4 11 00 mov 0x11c424,%eax + 101d1e: 40 inc %eax + 101d1f: a3 24 c4 11 00 mov %eax,0x11c424 + if (ticks % TICK_NUM == 0) + 101d24: 8b 0d 24 c4 11 00 mov 0x11c424,%ecx + 101d2a: ba 1f 85 eb 51 mov $0x51eb851f,%edx + 101d2f: 89 c8 mov %ecx,%eax + 101d31: f7 e2 mul %edx + 101d33: c1 ea 05 shr $0x5,%edx + 101d36: 89 d0 mov %edx,%eax + 101d38: c1 e0 02 shl $0x2,%eax + 101d3b: 01 d0 add %edx,%eax + 101d3d: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx + 101d44: 01 d0 add %edx,%eax + 101d46: c1 e0 02 shl $0x2,%eax + 101d49: 29 c1 sub %eax,%ecx + 101d4b: 89 ca mov %ecx,%edx + 101d4d: 85 d2 test %edx,%edx + 101d4f: 0f 85 9b 01 00 00 jne 101ef0 + { + print_ticks(); + 101d55: e8 16 fb ff ff call 101870 + }//每经过 TICK_NUM 次周期时,调用 print_ticks() 打印信息。 + break; + 101d5a: e9 91 01 00 00 jmp 101ef0 + case IRQ_OFFSET + IRQ_COM1: + c = cons_getc(); + 101d5f: e8 af f8 ff ff call 101613 + 101d64: 88 45 f7 mov %al,-0x9(%ebp) + cprintf("serial [%03d] %c\n", c, c); + 101d67: 0f be 55 f7 movsbl -0x9(%ebp),%edx + 101d6b: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 101d6f: 89 54 24 08 mov %edx,0x8(%esp) + 101d73: 89 44 24 04 mov %eax,0x4(%esp) + 101d77: c7 04 24 94 65 10 00 movl $0x106594,(%esp) + 101d7e: e8 e3 e5 ff ff call 100366 + break; + 101d83: e9 6f 01 00 00 jmp 101ef7 + case IRQ_OFFSET + IRQ_KBD: + c = cons_getc(); + 101d88: e8 86 f8 ff ff call 101613 + 101d8d: 88 45 f7 mov %al,-0x9(%ebp) + cprintf("kbd [%03d] %c\n", c, c); + 101d90: 0f be 55 f7 movsbl -0x9(%ebp),%edx + 101d94: 0f be 45 f7 movsbl -0x9(%ebp),%eax + 101d98: 89 54 24 08 mov %edx,0x8(%esp) + 101d9c: 89 44 24 04 mov %eax,0x4(%esp) + 101da0: c7 04 24 a6 65 10 00 movl $0x1065a6,(%esp) + 101da7: e8 ba e5 ff ff call 100366 + break; + 101dac: e9 46 01 00 00 jmp 101ef7 + //LAB1 CHALLENGE 1 : YOUR CODE you should modify below codes. + case T_SWITCH_TOU://表示发生了从内核模式切换到用户模式的请求。 + if (tf->tf_cs != USER_CS) {//判断当前是否在内核模式下 + 101db1: 8b 45 08 mov 0x8(%ebp),%eax + 101db4: 0f b7 40 3c movzwl 0x3c(%eax),%eax + 101db8: 83 f8 1b cmp $0x1b,%eax + 101dbb: 0f 84 32 01 00 00 je 101ef3 + switchk2u = *tf; //保存当前陷阱框架 + 101dc1: 8b 4d 08 mov 0x8(%ebp),%ecx + 101dc4: b8 4c 00 00 00 mov $0x4c,%eax + 101dc9: 83 e0 fc and $0xfffffffc,%eax + 101dcc: 89 c3 mov %eax,%ebx + 101dce: b8 00 00 00 00 mov $0x0,%eax + 101dd3: 8b 14 01 mov (%ecx,%eax,1),%edx + 101dd6: 89 90 80 c6 11 00 mov %edx,0x11c680(%eax) + 101ddc: 83 c0 04 add $0x4,%eax + 101ddf: 39 d8 cmp %ebx,%eax + 101de1: 72 f0 jb 101dd3 + switchk2u.tf_cs = USER_CS;//设置用户模式的段寄存器 + 101de3: 66 c7 05 bc c6 11 00 movw $0x1b,0x11c6bc + 101dea: 1b 00 + //将数据段和栈段寄存器 都设置为 USER_DS(用户数据段) + switchk2u.tf_ds = switchk2u.tf_es = switchk2u.tf_ss = USER_DS; + 101dec: 66 c7 05 c8 c6 11 00 movw $0x23,0x11c6c8 + 101df3: 23 00 + 101df5: 0f b7 05 c8 c6 11 00 movzwl 0x11c6c8,%eax + 101dfc: 66 a3 a8 c6 11 00 mov %ax,0x11c6a8 + 101e02: 0f b7 05 a8 c6 11 00 movzwl 0x11c6a8,%eax + 101e09: 66 a3 ac c6 11 00 mov %ax,0x11c6ac + switchk2u.tf_esp = (uint32_t)tf + sizeof(struct trapframe) - 8; + 101e0f: 8b 45 08 mov 0x8(%ebp),%eax + 101e12: 83 c0 44 add $0x44,%eax + 101e15: a3 c4 c6 11 00 mov %eax,0x11c6c4 + + // set eflags, make sure ucore can use io under user mode. + // if CPL > IOPL, then cpu will generate a general protection. + switchk2u.tf_eflags |= FL_IOPL_MASK;//允许用户模式下进行 I/O 操作 + 101e1a: a1 c0 c6 11 00 mov 0x11c6c0,%eax + 101e1f: 0d 00 30 00 00 or $0x3000,%eax + 101e24: a3 c0 c6 11 00 mov %eax,0x11c6c0 + + // set temporary stack + // then iret will jump to the right stack + *((uint32_t *)tf - 1) = (uint32_t)&switchk2u; + 101e29: 8b 45 08 mov 0x8(%ebp),%eax + 101e2c: 83 e8 04 sub $0x4,%eax + 101e2f: ba 80 c6 11 00 mov $0x11c680,%edx + 101e34: 89 10 mov %edx,(%eax) + } + break; + 101e36: e9 b8 00 00 00 jmp 101ef3 + case T_SWITCH_TOK: // T_SWITCH_TOK 表示发生了从用户模式切换到内核模式的请求。 + if (tf->tf_cs != KERNEL_CS) { //判断当前是否在用户模式下 + 101e3b: 8b 45 08 mov 0x8(%ebp),%eax + 101e3e: 0f b7 40 3c movzwl 0x3c(%eax),%eax + 101e42: 83 f8 08 cmp $0x8,%eax + 101e45: 0f 84 ab 00 00 00 je 101ef6 + tf->tf_cs = KERNEL_CS; + 101e4b: 8b 45 08 mov 0x8(%ebp),%eax + 101e4e: 66 c7 40 3c 08 00 movw $0x8,0x3c(%eax) + tf->tf_ds = tf->tf_es = KERNEL_DS; + 101e54: 8b 45 08 mov 0x8(%ebp),%eax + 101e57: 66 c7 40 28 10 00 movw $0x10,0x28(%eax) + 101e5d: 8b 45 08 mov 0x8(%ebp),%eax + 101e60: 0f b7 50 28 movzwl 0x28(%eax),%edx + 101e64: 8b 45 08 mov 0x8(%ebp),%eax + 101e67: 66 89 50 2c mov %dx,0x2c(%eax) + //设置内核模式的段寄存器 + tf->tf_eflags &= ~FL_IOPL_MASK; //清除 I/O 权限标志 + 101e6b: 8b 45 08 mov 0x8(%ebp),%eax + 101e6e: 8b 40 40 mov 0x40(%eax),%eax + 101e71: 25 ff cf ff ff and $0xffffcfff,%eax + 101e76: 89 c2 mov %eax,%edx + 101e78: 8b 45 08 mov 0x8(%ebp),%eax + 101e7b: 89 50 40 mov %edx,0x40(%eax) + switchu2k = (struct trapframe *)(tf->tf_esp - (sizeof(struct trapframe) - 8)); + 101e7e: 8b 45 08 mov 0x8(%ebp),%eax + 101e81: 8b 40 44 mov 0x44(%eax),%eax + 101e84: 83 e8 44 sub $0x44,%eax + 101e87: a3 cc c6 11 00 mov %eax,0x11c6cc + //使用 memmove 将当前的陷阱框架(除了最后8个字节)复制到新的陷阱框架位置 switchu2k + memmove(switchu2k, tf, sizeof(struct trapframe) - 8); + 101e8c: a1 cc c6 11 00 mov 0x11c6cc,%eax + 101e91: c7 44 24 08 44 00 00 movl $0x44,0x8(%esp) + 101e98: 00 + 101e99: 8b 55 08 mov 0x8(%ebp),%edx + 101e9c: 89 54 24 04 mov %edx,0x4(%esp) + 101ea0: 89 04 24 mov %eax,(%esp) + 101ea3: e8 a2 40 00 00 call 105f4a + //将新的陷阱框架地址 switchu2k 存储到当前陷阱框架之前的一个栈位置 + *((uint32_t *)tf - 1) = (uint32_t)switchu2k; + 101ea8: 8b 15 cc c6 11 00 mov 0x11c6cc,%edx + 101eae: 8b 45 08 mov 0x8(%ebp),%eax + 101eb1: 83 e8 04 sub $0x4,%eax + 101eb4: 89 10 mov %edx,(%eax) + } + break; + 101eb6: eb 3e jmp 101ef6 + case IRQ_OFFSET + IRQ_IDE2: + /* do nothing */ + break; + default: + // in kernel, it must be a mistake + if ((tf->tf_cs & 3) == 0) { + 101eb8: 8b 45 08 mov 0x8(%ebp),%eax + 101ebb: 0f b7 40 3c movzwl 0x3c(%eax),%eax + 101ebf: 83 e0 03 and $0x3,%eax + 101ec2: 85 c0 test %eax,%eax + 101ec4: 75 31 jne 101ef7 + print_trapframe(tf); + 101ec6: 8b 45 08 mov 0x8(%ebp),%eax + 101ec9: 89 04 24 mov %eax,(%esp) + 101ecc: e8 79 fb ff ff call 101a4a + panic("unexpected trap in kernel.\n"); + 101ed1: c7 44 24 08 b5 65 10 movl $0x1065b5,0x8(%esp) + 101ed8: 00 + 101ed9: c7 44 24 04 dc 00 00 movl $0xdc,0x4(%esp) + 101ee0: 00 + 101ee1: c7 04 24 d1 65 10 00 movl $0x1065d1,(%esp) + 101ee8: e8 46 ed ff ff call 100c33 <__panic> + break; + 101eed: 90 nop + 101eee: eb 07 jmp 101ef7 + break; + 101ef0: 90 nop + 101ef1: eb 04 jmp 101ef7 + break; + 101ef3: 90 nop + 101ef4: eb 01 jmp 101ef7 + break; + 101ef6: 90 nop + } + } +} + 101ef7: 90 nop + 101ef8: 8b 5d fc mov -0x4(%ebp),%ebx + 101efb: 89 ec mov %ebp,%esp + 101efd: 5d pop %ebp + 101efe: c3 ret + +00101eff : + * trap - handles or dispatches an exception/interrupt. if and when trap() returns, + * the code in kern/trap/trapentry.S restores the old CPU state saved in the + * trapframe and then uses the iret instruction to return from the exception. + * */ +void +trap(struct trapframe *tf) { + 101eff: 55 push %ebp + 101f00: 89 e5 mov %esp,%ebp + 101f02: 83 ec 18 sub $0x18,%esp + // dispatch based on what type of trap occurred + trap_dispatch(tf); + 101f05: 8b 45 08 mov 0x8(%ebp),%eax + 101f08: 89 04 24 mov %eax,(%esp) + 101f0b: e8 a7 fd ff ff call 101cb7 +} + 101f10: 90 nop + 101f11: 89 ec mov %ebp,%esp + 101f13: 5d pop %ebp + 101f14: c3 ret + +00101f15 <__alltraps>: +.text +.globl __alltraps +__alltraps: + # push registers to build a trap frame + # therefore make the stack look like a struct trapframe + pushl %ds + 101f15: 1e push %ds + pushl %es + 101f16: 06 push %es + pushl %fs + 101f17: 0f a0 push %fs + pushl %gs + 101f19: 0f a8 push %gs + pushal + 101f1b: 60 pusha + + # load GD_KDATA into %ds and %es to set up data segments for kernel + movl $GD_KDATA, %eax + 101f1c: b8 10 00 00 00 mov $0x10,%eax + movw %ax, %ds + 101f21: 8e d8 mov %eax,%ds + movw %ax, %es + 101f23: 8e c0 mov %eax,%es + + # push %esp to pass a pointer to the trapframe as an argument to trap() + pushl %esp + 101f25: 54 push %esp + + # call trap(tf), where tf=%esp + call trap + 101f26: e8 d4 ff ff ff call 101eff + + # pop the pushed stack pointer + popl %esp + 101f2b: 5c pop %esp + +00101f2c <__trapret>: + + # return falls through to trapret... +.globl __trapret +__trapret: + # restore registers from stack + popal + 101f2c: 61 popa + + # restore %ds, %es, %fs and %gs + popl %gs + 101f2d: 0f a9 pop %gs + popl %fs + 101f2f: 0f a1 pop %fs + popl %es + 101f31: 07 pop %es + popl %ds + 101f32: 1f pop %ds + + # get rid of the trap number and error code + addl $0x8, %esp + 101f33: 83 c4 08 add $0x8,%esp + iret + 101f36: cf iret + +00101f37 : +# handler +.text +.globl __alltraps +.globl vector0 +vector0: + pushl $0 + 101f37: 6a 00 push $0x0 + pushl $0 + 101f39: 6a 00 push $0x0 + jmp __alltraps + 101f3b: e9 d5 ff ff ff jmp 101f15 <__alltraps> + +00101f40 : +.globl vector1 +vector1: + pushl $0 + 101f40: 6a 00 push $0x0 + pushl $1 + 101f42: 6a 01 push $0x1 + jmp __alltraps + 101f44: e9 cc ff ff ff jmp 101f15 <__alltraps> + +00101f49 : +.globl vector2 +vector2: + pushl $0 + 101f49: 6a 00 push $0x0 + pushl $2 + 101f4b: 6a 02 push $0x2 + jmp __alltraps + 101f4d: e9 c3 ff ff ff jmp 101f15 <__alltraps> + +00101f52 : +.globl vector3 +vector3: + pushl $0 + 101f52: 6a 00 push $0x0 + pushl $3 + 101f54: 6a 03 push $0x3 + jmp __alltraps + 101f56: e9 ba ff ff ff jmp 101f15 <__alltraps> + +00101f5b : +.globl vector4 +vector4: + pushl $0 + 101f5b: 6a 00 push $0x0 + pushl $4 + 101f5d: 6a 04 push $0x4 + jmp __alltraps + 101f5f: e9 b1 ff ff ff jmp 101f15 <__alltraps> + +00101f64 : +.globl vector5 +vector5: + pushl $0 + 101f64: 6a 00 push $0x0 + pushl $5 + 101f66: 6a 05 push $0x5 + jmp __alltraps + 101f68: e9 a8 ff ff ff jmp 101f15 <__alltraps> + +00101f6d : +.globl vector6 +vector6: + pushl $0 + 101f6d: 6a 00 push $0x0 + pushl $6 + 101f6f: 6a 06 push $0x6 + jmp __alltraps + 101f71: e9 9f ff ff ff jmp 101f15 <__alltraps> + +00101f76 : +.globl vector7 +vector7: + pushl $0 + 101f76: 6a 00 push $0x0 + pushl $7 + 101f78: 6a 07 push $0x7 + jmp __alltraps + 101f7a: e9 96 ff ff ff jmp 101f15 <__alltraps> + +00101f7f : +.globl vector8 +vector8: + pushl $8 + 101f7f: 6a 08 push $0x8 + jmp __alltraps + 101f81: e9 8f ff ff ff jmp 101f15 <__alltraps> + +00101f86 : +.globl vector9 +vector9: + pushl $0 + 101f86: 6a 00 push $0x0 + pushl $9 + 101f88: 6a 09 push $0x9 + jmp __alltraps + 101f8a: e9 86 ff ff ff jmp 101f15 <__alltraps> + +00101f8f : +.globl vector10 +vector10: + pushl $10 + 101f8f: 6a 0a push $0xa + jmp __alltraps + 101f91: e9 7f ff ff ff jmp 101f15 <__alltraps> + +00101f96 : +.globl vector11 +vector11: + pushl $11 + 101f96: 6a 0b push $0xb + jmp __alltraps + 101f98: e9 78 ff ff ff jmp 101f15 <__alltraps> + +00101f9d : +.globl vector12 +vector12: + pushl $12 + 101f9d: 6a 0c push $0xc + jmp __alltraps + 101f9f: e9 71 ff ff ff jmp 101f15 <__alltraps> + +00101fa4 : +.globl vector13 +vector13: + pushl $13 + 101fa4: 6a 0d push $0xd + jmp __alltraps + 101fa6: e9 6a ff ff ff jmp 101f15 <__alltraps> + +00101fab : +.globl vector14 +vector14: + pushl $14 + 101fab: 6a 0e push $0xe + jmp __alltraps + 101fad: e9 63 ff ff ff jmp 101f15 <__alltraps> + +00101fb2 : +.globl vector15 +vector15: + pushl $0 + 101fb2: 6a 00 push $0x0 + pushl $15 + 101fb4: 6a 0f push $0xf + jmp __alltraps + 101fb6: e9 5a ff ff ff jmp 101f15 <__alltraps> + +00101fbb : +.globl vector16 +vector16: + pushl $0 + 101fbb: 6a 00 push $0x0 + pushl $16 + 101fbd: 6a 10 push $0x10 + jmp __alltraps + 101fbf: e9 51 ff ff ff jmp 101f15 <__alltraps> + +00101fc4 : +.globl vector17 +vector17: + pushl $17 + 101fc4: 6a 11 push $0x11 + jmp __alltraps + 101fc6: e9 4a ff ff ff jmp 101f15 <__alltraps> + +00101fcb : +.globl vector18 +vector18: + pushl $0 + 101fcb: 6a 00 push $0x0 + pushl $18 + 101fcd: 6a 12 push $0x12 + jmp __alltraps + 101fcf: e9 41 ff ff ff jmp 101f15 <__alltraps> + +00101fd4 : +.globl vector19 +vector19: + pushl $0 + 101fd4: 6a 00 push $0x0 + pushl $19 + 101fd6: 6a 13 push $0x13 + jmp __alltraps + 101fd8: e9 38 ff ff ff jmp 101f15 <__alltraps> + +00101fdd : +.globl vector20 +vector20: + pushl $0 + 101fdd: 6a 00 push $0x0 + pushl $20 + 101fdf: 6a 14 push $0x14 + jmp __alltraps + 101fe1: e9 2f ff ff ff jmp 101f15 <__alltraps> + +00101fe6 : +.globl vector21 +vector21: + pushl $0 + 101fe6: 6a 00 push $0x0 + pushl $21 + 101fe8: 6a 15 push $0x15 + jmp __alltraps + 101fea: e9 26 ff ff ff jmp 101f15 <__alltraps> + +00101fef : +.globl vector22 +vector22: + pushl $0 + 101fef: 6a 00 push $0x0 + pushl $22 + 101ff1: 6a 16 push $0x16 + jmp __alltraps + 101ff3: e9 1d ff ff ff jmp 101f15 <__alltraps> + +00101ff8 : +.globl vector23 +vector23: + pushl $0 + 101ff8: 6a 00 push $0x0 + pushl $23 + 101ffa: 6a 17 push $0x17 + jmp __alltraps + 101ffc: e9 14 ff ff ff jmp 101f15 <__alltraps> + +00102001 : +.globl vector24 +vector24: + pushl $0 + 102001: 6a 00 push $0x0 + pushl $24 + 102003: 6a 18 push $0x18 + jmp __alltraps + 102005: e9 0b ff ff ff jmp 101f15 <__alltraps> + +0010200a : +.globl vector25 +vector25: + pushl $0 + 10200a: 6a 00 push $0x0 + pushl $25 + 10200c: 6a 19 push $0x19 + jmp __alltraps + 10200e: e9 02 ff ff ff jmp 101f15 <__alltraps> + +00102013 : +.globl vector26 +vector26: + pushl $0 + 102013: 6a 00 push $0x0 + pushl $26 + 102015: 6a 1a push $0x1a + jmp __alltraps + 102017: e9 f9 fe ff ff jmp 101f15 <__alltraps> + +0010201c : +.globl vector27 +vector27: + pushl $0 + 10201c: 6a 00 push $0x0 + pushl $27 + 10201e: 6a 1b push $0x1b + jmp __alltraps + 102020: e9 f0 fe ff ff jmp 101f15 <__alltraps> + +00102025 : +.globl vector28 +vector28: + pushl $0 + 102025: 6a 00 push $0x0 + pushl $28 + 102027: 6a 1c push $0x1c + jmp __alltraps + 102029: e9 e7 fe ff ff jmp 101f15 <__alltraps> + +0010202e : +.globl vector29 +vector29: + pushl $0 + 10202e: 6a 00 push $0x0 + pushl $29 + 102030: 6a 1d push $0x1d + jmp __alltraps + 102032: e9 de fe ff ff jmp 101f15 <__alltraps> + +00102037 : +.globl vector30 +vector30: + pushl $0 + 102037: 6a 00 push $0x0 + pushl $30 + 102039: 6a 1e push $0x1e + jmp __alltraps + 10203b: e9 d5 fe ff ff jmp 101f15 <__alltraps> + +00102040 : +.globl vector31 +vector31: + pushl $0 + 102040: 6a 00 push $0x0 + pushl $31 + 102042: 6a 1f push $0x1f + jmp __alltraps + 102044: e9 cc fe ff ff jmp 101f15 <__alltraps> + +00102049 : +.globl vector32 +vector32: + pushl $0 + 102049: 6a 00 push $0x0 + pushl $32 + 10204b: 6a 20 push $0x20 + jmp __alltraps + 10204d: e9 c3 fe ff ff jmp 101f15 <__alltraps> + +00102052 : +.globl vector33 +vector33: + pushl $0 + 102052: 6a 00 push $0x0 + pushl $33 + 102054: 6a 21 push $0x21 + jmp __alltraps + 102056: e9 ba fe ff ff jmp 101f15 <__alltraps> + +0010205b : +.globl vector34 +vector34: + pushl $0 + 10205b: 6a 00 push $0x0 + pushl $34 + 10205d: 6a 22 push $0x22 + jmp __alltraps + 10205f: e9 b1 fe ff ff jmp 101f15 <__alltraps> + +00102064 : +.globl vector35 +vector35: + pushl $0 + 102064: 6a 00 push $0x0 + pushl $35 + 102066: 6a 23 push $0x23 + jmp __alltraps + 102068: e9 a8 fe ff ff jmp 101f15 <__alltraps> + +0010206d : +.globl vector36 +vector36: + pushl $0 + 10206d: 6a 00 push $0x0 + pushl $36 + 10206f: 6a 24 push $0x24 + jmp __alltraps + 102071: e9 9f fe ff ff jmp 101f15 <__alltraps> + +00102076 : +.globl vector37 +vector37: + pushl $0 + 102076: 6a 00 push $0x0 + pushl $37 + 102078: 6a 25 push $0x25 + jmp __alltraps + 10207a: e9 96 fe ff ff jmp 101f15 <__alltraps> + +0010207f : +.globl vector38 +vector38: + pushl $0 + 10207f: 6a 00 push $0x0 + pushl $38 + 102081: 6a 26 push $0x26 + jmp __alltraps + 102083: e9 8d fe ff ff jmp 101f15 <__alltraps> + +00102088 : +.globl vector39 +vector39: + pushl $0 + 102088: 6a 00 push $0x0 + pushl $39 + 10208a: 6a 27 push $0x27 + jmp __alltraps + 10208c: e9 84 fe ff ff jmp 101f15 <__alltraps> + +00102091 : +.globl vector40 +vector40: + pushl $0 + 102091: 6a 00 push $0x0 + pushl $40 + 102093: 6a 28 push $0x28 + jmp __alltraps + 102095: e9 7b fe ff ff jmp 101f15 <__alltraps> + +0010209a : +.globl vector41 +vector41: + pushl $0 + 10209a: 6a 00 push $0x0 + pushl $41 + 10209c: 6a 29 push $0x29 + jmp __alltraps + 10209e: e9 72 fe ff ff jmp 101f15 <__alltraps> + +001020a3 : +.globl vector42 +vector42: + pushl $0 + 1020a3: 6a 00 push $0x0 + pushl $42 + 1020a5: 6a 2a push $0x2a + jmp __alltraps + 1020a7: e9 69 fe ff ff jmp 101f15 <__alltraps> + +001020ac : +.globl vector43 +vector43: + pushl $0 + 1020ac: 6a 00 push $0x0 + pushl $43 + 1020ae: 6a 2b push $0x2b + jmp __alltraps + 1020b0: e9 60 fe ff ff jmp 101f15 <__alltraps> + +001020b5 : +.globl vector44 +vector44: + pushl $0 + 1020b5: 6a 00 push $0x0 + pushl $44 + 1020b7: 6a 2c push $0x2c + jmp __alltraps + 1020b9: e9 57 fe ff ff jmp 101f15 <__alltraps> + +001020be : +.globl vector45 +vector45: + pushl $0 + 1020be: 6a 00 push $0x0 + pushl $45 + 1020c0: 6a 2d push $0x2d + jmp __alltraps + 1020c2: e9 4e fe ff ff jmp 101f15 <__alltraps> + +001020c7 : +.globl vector46 +vector46: + pushl $0 + 1020c7: 6a 00 push $0x0 + pushl $46 + 1020c9: 6a 2e push $0x2e + jmp __alltraps + 1020cb: e9 45 fe ff ff jmp 101f15 <__alltraps> + +001020d0 : +.globl vector47 +vector47: + pushl $0 + 1020d0: 6a 00 push $0x0 + pushl $47 + 1020d2: 6a 2f push $0x2f + jmp __alltraps + 1020d4: e9 3c fe ff ff jmp 101f15 <__alltraps> + +001020d9 : +.globl vector48 +vector48: + pushl $0 + 1020d9: 6a 00 push $0x0 + pushl $48 + 1020db: 6a 30 push $0x30 + jmp __alltraps + 1020dd: e9 33 fe ff ff jmp 101f15 <__alltraps> + +001020e2 : +.globl vector49 +vector49: + pushl $0 + 1020e2: 6a 00 push $0x0 + pushl $49 + 1020e4: 6a 31 push $0x31 + jmp __alltraps + 1020e6: e9 2a fe ff ff jmp 101f15 <__alltraps> + +001020eb : +.globl vector50 +vector50: + pushl $0 + 1020eb: 6a 00 push $0x0 + pushl $50 + 1020ed: 6a 32 push $0x32 + jmp __alltraps + 1020ef: e9 21 fe ff ff jmp 101f15 <__alltraps> + +001020f4 : +.globl vector51 +vector51: + pushl $0 + 1020f4: 6a 00 push $0x0 + pushl $51 + 1020f6: 6a 33 push $0x33 + jmp __alltraps + 1020f8: e9 18 fe ff ff jmp 101f15 <__alltraps> + +001020fd : +.globl vector52 +vector52: + pushl $0 + 1020fd: 6a 00 push $0x0 + pushl $52 + 1020ff: 6a 34 push $0x34 + jmp __alltraps + 102101: e9 0f fe ff ff jmp 101f15 <__alltraps> + +00102106 : +.globl vector53 +vector53: + pushl $0 + 102106: 6a 00 push $0x0 + pushl $53 + 102108: 6a 35 push $0x35 + jmp __alltraps + 10210a: e9 06 fe ff ff jmp 101f15 <__alltraps> + +0010210f : +.globl vector54 +vector54: + pushl $0 + 10210f: 6a 00 push $0x0 + pushl $54 + 102111: 6a 36 push $0x36 + jmp __alltraps + 102113: e9 fd fd ff ff jmp 101f15 <__alltraps> + +00102118 : +.globl vector55 +vector55: + pushl $0 + 102118: 6a 00 push $0x0 + pushl $55 + 10211a: 6a 37 push $0x37 + jmp __alltraps + 10211c: e9 f4 fd ff ff jmp 101f15 <__alltraps> + +00102121 : +.globl vector56 +vector56: + pushl $0 + 102121: 6a 00 push $0x0 + pushl $56 + 102123: 6a 38 push $0x38 + jmp __alltraps + 102125: e9 eb fd ff ff jmp 101f15 <__alltraps> + +0010212a : +.globl vector57 +vector57: + pushl $0 + 10212a: 6a 00 push $0x0 + pushl $57 + 10212c: 6a 39 push $0x39 + jmp __alltraps + 10212e: e9 e2 fd ff ff jmp 101f15 <__alltraps> + +00102133 : +.globl vector58 +vector58: + pushl $0 + 102133: 6a 00 push $0x0 + pushl $58 + 102135: 6a 3a push $0x3a + jmp __alltraps + 102137: e9 d9 fd ff ff jmp 101f15 <__alltraps> + +0010213c : +.globl vector59 +vector59: + pushl $0 + 10213c: 6a 00 push $0x0 + pushl $59 + 10213e: 6a 3b push $0x3b + jmp __alltraps + 102140: e9 d0 fd ff ff jmp 101f15 <__alltraps> + +00102145 : +.globl vector60 +vector60: + pushl $0 + 102145: 6a 00 push $0x0 + pushl $60 + 102147: 6a 3c push $0x3c + jmp __alltraps + 102149: e9 c7 fd ff ff jmp 101f15 <__alltraps> + +0010214e : +.globl vector61 +vector61: + pushl $0 + 10214e: 6a 00 push $0x0 + pushl $61 + 102150: 6a 3d push $0x3d + jmp __alltraps + 102152: e9 be fd ff ff jmp 101f15 <__alltraps> + +00102157 : +.globl vector62 +vector62: + pushl $0 + 102157: 6a 00 push $0x0 + pushl $62 + 102159: 6a 3e push $0x3e + jmp __alltraps + 10215b: e9 b5 fd ff ff jmp 101f15 <__alltraps> + +00102160 : +.globl vector63 +vector63: + pushl $0 + 102160: 6a 00 push $0x0 + pushl $63 + 102162: 6a 3f push $0x3f + jmp __alltraps + 102164: e9 ac fd ff ff jmp 101f15 <__alltraps> + +00102169 : +.globl vector64 +vector64: + pushl $0 + 102169: 6a 00 push $0x0 + pushl $64 + 10216b: 6a 40 push $0x40 + jmp __alltraps + 10216d: e9 a3 fd ff ff jmp 101f15 <__alltraps> + +00102172 : +.globl vector65 +vector65: + pushl $0 + 102172: 6a 00 push $0x0 + pushl $65 + 102174: 6a 41 push $0x41 + jmp __alltraps + 102176: e9 9a fd ff ff jmp 101f15 <__alltraps> + +0010217b : +.globl vector66 +vector66: + pushl $0 + 10217b: 6a 00 push $0x0 + pushl $66 + 10217d: 6a 42 push $0x42 + jmp __alltraps + 10217f: e9 91 fd ff ff jmp 101f15 <__alltraps> + +00102184 : +.globl vector67 +vector67: + pushl $0 + 102184: 6a 00 push $0x0 + pushl $67 + 102186: 6a 43 push $0x43 + jmp __alltraps + 102188: e9 88 fd ff ff jmp 101f15 <__alltraps> + +0010218d : +.globl vector68 +vector68: + pushl $0 + 10218d: 6a 00 push $0x0 + pushl $68 + 10218f: 6a 44 push $0x44 + jmp __alltraps + 102191: e9 7f fd ff ff jmp 101f15 <__alltraps> + +00102196 : +.globl vector69 +vector69: + pushl $0 + 102196: 6a 00 push $0x0 + pushl $69 + 102198: 6a 45 push $0x45 + jmp __alltraps + 10219a: e9 76 fd ff ff jmp 101f15 <__alltraps> + +0010219f : +.globl vector70 +vector70: + pushl $0 + 10219f: 6a 00 push $0x0 + pushl $70 + 1021a1: 6a 46 push $0x46 + jmp __alltraps + 1021a3: e9 6d fd ff ff jmp 101f15 <__alltraps> + +001021a8 : +.globl vector71 +vector71: + pushl $0 + 1021a8: 6a 00 push $0x0 + pushl $71 + 1021aa: 6a 47 push $0x47 + jmp __alltraps + 1021ac: e9 64 fd ff ff jmp 101f15 <__alltraps> + +001021b1 : +.globl vector72 +vector72: + pushl $0 + 1021b1: 6a 00 push $0x0 + pushl $72 + 1021b3: 6a 48 push $0x48 + jmp __alltraps + 1021b5: e9 5b fd ff ff jmp 101f15 <__alltraps> + +001021ba : +.globl vector73 +vector73: + pushl $0 + 1021ba: 6a 00 push $0x0 + pushl $73 + 1021bc: 6a 49 push $0x49 + jmp __alltraps + 1021be: e9 52 fd ff ff jmp 101f15 <__alltraps> + +001021c3 : +.globl vector74 +vector74: + pushl $0 + 1021c3: 6a 00 push $0x0 + pushl $74 + 1021c5: 6a 4a push $0x4a + jmp __alltraps + 1021c7: e9 49 fd ff ff jmp 101f15 <__alltraps> + +001021cc : +.globl vector75 +vector75: + pushl $0 + 1021cc: 6a 00 push $0x0 + pushl $75 + 1021ce: 6a 4b push $0x4b + jmp __alltraps + 1021d0: e9 40 fd ff ff jmp 101f15 <__alltraps> + +001021d5 : +.globl vector76 +vector76: + pushl $0 + 1021d5: 6a 00 push $0x0 + pushl $76 + 1021d7: 6a 4c push $0x4c + jmp __alltraps + 1021d9: e9 37 fd ff ff jmp 101f15 <__alltraps> + +001021de : +.globl vector77 +vector77: + pushl $0 + 1021de: 6a 00 push $0x0 + pushl $77 + 1021e0: 6a 4d push $0x4d + jmp __alltraps + 1021e2: e9 2e fd ff ff jmp 101f15 <__alltraps> + +001021e7 : +.globl vector78 +vector78: + pushl $0 + 1021e7: 6a 00 push $0x0 + pushl $78 + 1021e9: 6a 4e push $0x4e + jmp __alltraps + 1021eb: e9 25 fd ff ff jmp 101f15 <__alltraps> + +001021f0 : +.globl vector79 +vector79: + pushl $0 + 1021f0: 6a 00 push $0x0 + pushl $79 + 1021f2: 6a 4f push $0x4f + jmp __alltraps + 1021f4: e9 1c fd ff ff jmp 101f15 <__alltraps> + +001021f9 : +.globl vector80 +vector80: + pushl $0 + 1021f9: 6a 00 push $0x0 + pushl $80 + 1021fb: 6a 50 push $0x50 + jmp __alltraps + 1021fd: e9 13 fd ff ff jmp 101f15 <__alltraps> + +00102202 : +.globl vector81 +vector81: + pushl $0 + 102202: 6a 00 push $0x0 + pushl $81 + 102204: 6a 51 push $0x51 + jmp __alltraps + 102206: e9 0a fd ff ff jmp 101f15 <__alltraps> + +0010220b : +.globl vector82 +vector82: + pushl $0 + 10220b: 6a 00 push $0x0 + pushl $82 + 10220d: 6a 52 push $0x52 + jmp __alltraps + 10220f: e9 01 fd ff ff jmp 101f15 <__alltraps> + +00102214 : +.globl vector83 +vector83: + pushl $0 + 102214: 6a 00 push $0x0 + pushl $83 + 102216: 6a 53 push $0x53 + jmp __alltraps + 102218: e9 f8 fc ff ff jmp 101f15 <__alltraps> + +0010221d : +.globl vector84 +vector84: + pushl $0 + 10221d: 6a 00 push $0x0 + pushl $84 + 10221f: 6a 54 push $0x54 + jmp __alltraps + 102221: e9 ef fc ff ff jmp 101f15 <__alltraps> + +00102226 : +.globl vector85 +vector85: + pushl $0 + 102226: 6a 00 push $0x0 + pushl $85 + 102228: 6a 55 push $0x55 + jmp __alltraps + 10222a: e9 e6 fc ff ff jmp 101f15 <__alltraps> + +0010222f : +.globl vector86 +vector86: + pushl $0 + 10222f: 6a 00 push $0x0 + pushl $86 + 102231: 6a 56 push $0x56 + jmp __alltraps + 102233: e9 dd fc ff ff jmp 101f15 <__alltraps> + +00102238 : +.globl vector87 +vector87: + pushl $0 + 102238: 6a 00 push $0x0 + pushl $87 + 10223a: 6a 57 push $0x57 + jmp __alltraps + 10223c: e9 d4 fc ff ff jmp 101f15 <__alltraps> + +00102241 : +.globl vector88 +vector88: + pushl $0 + 102241: 6a 00 push $0x0 + pushl $88 + 102243: 6a 58 push $0x58 + jmp __alltraps + 102245: e9 cb fc ff ff jmp 101f15 <__alltraps> + +0010224a : +.globl vector89 +vector89: + pushl $0 + 10224a: 6a 00 push $0x0 + pushl $89 + 10224c: 6a 59 push $0x59 + jmp __alltraps + 10224e: e9 c2 fc ff ff jmp 101f15 <__alltraps> + +00102253 : +.globl vector90 +vector90: + pushl $0 + 102253: 6a 00 push $0x0 + pushl $90 + 102255: 6a 5a push $0x5a + jmp __alltraps + 102257: e9 b9 fc ff ff jmp 101f15 <__alltraps> + +0010225c : +.globl vector91 +vector91: + pushl $0 + 10225c: 6a 00 push $0x0 + pushl $91 + 10225e: 6a 5b push $0x5b + jmp __alltraps + 102260: e9 b0 fc ff ff jmp 101f15 <__alltraps> + +00102265 : +.globl vector92 +vector92: + pushl $0 + 102265: 6a 00 push $0x0 + pushl $92 + 102267: 6a 5c push $0x5c + jmp __alltraps + 102269: e9 a7 fc ff ff jmp 101f15 <__alltraps> + +0010226e : +.globl vector93 +vector93: + pushl $0 + 10226e: 6a 00 push $0x0 + pushl $93 + 102270: 6a 5d push $0x5d + jmp __alltraps + 102272: e9 9e fc ff ff jmp 101f15 <__alltraps> + +00102277 : +.globl vector94 +vector94: + pushl $0 + 102277: 6a 00 push $0x0 + pushl $94 + 102279: 6a 5e push $0x5e + jmp __alltraps + 10227b: e9 95 fc ff ff jmp 101f15 <__alltraps> + +00102280 : +.globl vector95 +vector95: + pushl $0 + 102280: 6a 00 push $0x0 + pushl $95 + 102282: 6a 5f push $0x5f + jmp __alltraps + 102284: e9 8c fc ff ff jmp 101f15 <__alltraps> + +00102289 : +.globl vector96 +vector96: + pushl $0 + 102289: 6a 00 push $0x0 + pushl $96 + 10228b: 6a 60 push $0x60 + jmp __alltraps + 10228d: e9 83 fc ff ff jmp 101f15 <__alltraps> + +00102292 : +.globl vector97 +vector97: + pushl $0 + 102292: 6a 00 push $0x0 + pushl $97 + 102294: 6a 61 push $0x61 + jmp __alltraps + 102296: e9 7a fc ff ff jmp 101f15 <__alltraps> + +0010229b : +.globl vector98 +vector98: + pushl $0 + 10229b: 6a 00 push $0x0 + pushl $98 + 10229d: 6a 62 push $0x62 + jmp __alltraps + 10229f: e9 71 fc ff ff jmp 101f15 <__alltraps> + +001022a4 : +.globl vector99 +vector99: + pushl $0 + 1022a4: 6a 00 push $0x0 + pushl $99 + 1022a6: 6a 63 push $0x63 + jmp __alltraps + 1022a8: e9 68 fc ff ff jmp 101f15 <__alltraps> + +001022ad : +.globl vector100 +vector100: + pushl $0 + 1022ad: 6a 00 push $0x0 + pushl $100 + 1022af: 6a 64 push $0x64 + jmp __alltraps + 1022b1: e9 5f fc ff ff jmp 101f15 <__alltraps> + +001022b6 : +.globl vector101 +vector101: + pushl $0 + 1022b6: 6a 00 push $0x0 + pushl $101 + 1022b8: 6a 65 push $0x65 + jmp __alltraps + 1022ba: e9 56 fc ff ff jmp 101f15 <__alltraps> + +001022bf : +.globl vector102 +vector102: + pushl $0 + 1022bf: 6a 00 push $0x0 + pushl $102 + 1022c1: 6a 66 push $0x66 + jmp __alltraps + 1022c3: e9 4d fc ff ff jmp 101f15 <__alltraps> + +001022c8 : +.globl vector103 +vector103: + pushl $0 + 1022c8: 6a 00 push $0x0 + pushl $103 + 1022ca: 6a 67 push $0x67 + jmp __alltraps + 1022cc: e9 44 fc ff ff jmp 101f15 <__alltraps> + +001022d1 : +.globl vector104 +vector104: + pushl $0 + 1022d1: 6a 00 push $0x0 + pushl $104 + 1022d3: 6a 68 push $0x68 + jmp __alltraps + 1022d5: e9 3b fc ff ff jmp 101f15 <__alltraps> + +001022da : +.globl vector105 +vector105: + pushl $0 + 1022da: 6a 00 push $0x0 + pushl $105 + 1022dc: 6a 69 push $0x69 + jmp __alltraps + 1022de: e9 32 fc ff ff jmp 101f15 <__alltraps> + +001022e3 : +.globl vector106 +vector106: + pushl $0 + 1022e3: 6a 00 push $0x0 + pushl $106 + 1022e5: 6a 6a push $0x6a + jmp __alltraps + 1022e7: e9 29 fc ff ff jmp 101f15 <__alltraps> + +001022ec : +.globl vector107 +vector107: + pushl $0 + 1022ec: 6a 00 push $0x0 + pushl $107 + 1022ee: 6a 6b push $0x6b + jmp __alltraps + 1022f0: e9 20 fc ff ff jmp 101f15 <__alltraps> + +001022f5 : +.globl vector108 +vector108: + pushl $0 + 1022f5: 6a 00 push $0x0 + pushl $108 + 1022f7: 6a 6c push $0x6c + jmp __alltraps + 1022f9: e9 17 fc ff ff jmp 101f15 <__alltraps> + +001022fe : +.globl vector109 +vector109: + pushl $0 + 1022fe: 6a 00 push $0x0 + pushl $109 + 102300: 6a 6d push $0x6d + jmp __alltraps + 102302: e9 0e fc ff ff jmp 101f15 <__alltraps> + +00102307 : +.globl vector110 +vector110: + pushl $0 + 102307: 6a 00 push $0x0 + pushl $110 + 102309: 6a 6e push $0x6e + jmp __alltraps + 10230b: e9 05 fc ff ff jmp 101f15 <__alltraps> + +00102310 : +.globl vector111 +vector111: + pushl $0 + 102310: 6a 00 push $0x0 + pushl $111 + 102312: 6a 6f push $0x6f + jmp __alltraps + 102314: e9 fc fb ff ff jmp 101f15 <__alltraps> + +00102319 : +.globl vector112 +vector112: + pushl $0 + 102319: 6a 00 push $0x0 + pushl $112 + 10231b: 6a 70 push $0x70 + jmp __alltraps + 10231d: e9 f3 fb ff ff jmp 101f15 <__alltraps> + +00102322 : +.globl vector113 +vector113: + pushl $0 + 102322: 6a 00 push $0x0 + pushl $113 + 102324: 6a 71 push $0x71 + jmp __alltraps + 102326: e9 ea fb ff ff jmp 101f15 <__alltraps> + +0010232b : +.globl vector114 +vector114: + pushl $0 + 10232b: 6a 00 push $0x0 + pushl $114 + 10232d: 6a 72 push $0x72 + jmp __alltraps + 10232f: e9 e1 fb ff ff jmp 101f15 <__alltraps> + +00102334 : +.globl vector115 +vector115: + pushl $0 + 102334: 6a 00 push $0x0 + pushl $115 + 102336: 6a 73 push $0x73 + jmp __alltraps + 102338: e9 d8 fb ff ff jmp 101f15 <__alltraps> + +0010233d : +.globl vector116 +vector116: + pushl $0 + 10233d: 6a 00 push $0x0 + pushl $116 + 10233f: 6a 74 push $0x74 + jmp __alltraps + 102341: e9 cf fb ff ff jmp 101f15 <__alltraps> + +00102346 : +.globl vector117 +vector117: + pushl $0 + 102346: 6a 00 push $0x0 + pushl $117 + 102348: 6a 75 push $0x75 + jmp __alltraps + 10234a: e9 c6 fb ff ff jmp 101f15 <__alltraps> + +0010234f : +.globl vector118 +vector118: + pushl $0 + 10234f: 6a 00 push $0x0 + pushl $118 + 102351: 6a 76 push $0x76 + jmp __alltraps + 102353: e9 bd fb ff ff jmp 101f15 <__alltraps> + +00102358 : +.globl vector119 +vector119: + pushl $0 + 102358: 6a 00 push $0x0 + pushl $119 + 10235a: 6a 77 push $0x77 + jmp __alltraps + 10235c: e9 b4 fb ff ff jmp 101f15 <__alltraps> + +00102361 : +.globl vector120 +vector120: + pushl $0 + 102361: 6a 00 push $0x0 + pushl $120 + 102363: 6a 78 push $0x78 + jmp __alltraps + 102365: e9 ab fb ff ff jmp 101f15 <__alltraps> + +0010236a : +.globl vector121 +vector121: + pushl $0 + 10236a: 6a 00 push $0x0 + pushl $121 + 10236c: 6a 79 push $0x79 + jmp __alltraps + 10236e: e9 a2 fb ff ff jmp 101f15 <__alltraps> + +00102373 : +.globl vector122 +vector122: + pushl $0 + 102373: 6a 00 push $0x0 + pushl $122 + 102375: 6a 7a push $0x7a + jmp __alltraps + 102377: e9 99 fb ff ff jmp 101f15 <__alltraps> + +0010237c : +.globl vector123 +vector123: + pushl $0 + 10237c: 6a 00 push $0x0 + pushl $123 + 10237e: 6a 7b push $0x7b + jmp __alltraps + 102380: e9 90 fb ff ff jmp 101f15 <__alltraps> + +00102385 : +.globl vector124 +vector124: + pushl $0 + 102385: 6a 00 push $0x0 + pushl $124 + 102387: 6a 7c push $0x7c + jmp __alltraps + 102389: e9 87 fb ff ff jmp 101f15 <__alltraps> + +0010238e : +.globl vector125 +vector125: + pushl $0 + 10238e: 6a 00 push $0x0 + pushl $125 + 102390: 6a 7d push $0x7d + jmp __alltraps + 102392: e9 7e fb ff ff jmp 101f15 <__alltraps> + +00102397 : +.globl vector126 +vector126: + pushl $0 + 102397: 6a 00 push $0x0 + pushl $126 + 102399: 6a 7e push $0x7e + jmp __alltraps + 10239b: e9 75 fb ff ff jmp 101f15 <__alltraps> + +001023a0 : +.globl vector127 +vector127: + pushl $0 + 1023a0: 6a 00 push $0x0 + pushl $127 + 1023a2: 6a 7f push $0x7f + jmp __alltraps + 1023a4: e9 6c fb ff ff jmp 101f15 <__alltraps> + +001023a9 : +.globl vector128 +vector128: + pushl $0 + 1023a9: 6a 00 push $0x0 + pushl $128 + 1023ab: 68 80 00 00 00 push $0x80 + jmp __alltraps + 1023b0: e9 60 fb ff ff jmp 101f15 <__alltraps> + +001023b5 : +.globl vector129 +vector129: + pushl $0 + 1023b5: 6a 00 push $0x0 + pushl $129 + 1023b7: 68 81 00 00 00 push $0x81 + jmp __alltraps + 1023bc: e9 54 fb ff ff jmp 101f15 <__alltraps> + +001023c1 : +.globl vector130 +vector130: + pushl $0 + 1023c1: 6a 00 push $0x0 + pushl $130 + 1023c3: 68 82 00 00 00 push $0x82 + jmp __alltraps + 1023c8: e9 48 fb ff ff jmp 101f15 <__alltraps> + +001023cd : +.globl vector131 +vector131: + pushl $0 + 1023cd: 6a 00 push $0x0 + pushl $131 + 1023cf: 68 83 00 00 00 push $0x83 + jmp __alltraps + 1023d4: e9 3c fb ff ff jmp 101f15 <__alltraps> + +001023d9 : +.globl vector132 +vector132: + pushl $0 + 1023d9: 6a 00 push $0x0 + pushl $132 + 1023db: 68 84 00 00 00 push $0x84 + jmp __alltraps + 1023e0: e9 30 fb ff ff jmp 101f15 <__alltraps> + +001023e5 : +.globl vector133 +vector133: + pushl $0 + 1023e5: 6a 00 push $0x0 + pushl $133 + 1023e7: 68 85 00 00 00 push $0x85 + jmp __alltraps + 1023ec: e9 24 fb ff ff jmp 101f15 <__alltraps> + +001023f1 : +.globl vector134 +vector134: + pushl $0 + 1023f1: 6a 00 push $0x0 + pushl $134 + 1023f3: 68 86 00 00 00 push $0x86 + jmp __alltraps + 1023f8: e9 18 fb ff ff jmp 101f15 <__alltraps> + +001023fd : +.globl vector135 +vector135: + pushl $0 + 1023fd: 6a 00 push $0x0 + pushl $135 + 1023ff: 68 87 00 00 00 push $0x87 + jmp __alltraps + 102404: e9 0c fb ff ff jmp 101f15 <__alltraps> + +00102409 : +.globl vector136 +vector136: + pushl $0 + 102409: 6a 00 push $0x0 + pushl $136 + 10240b: 68 88 00 00 00 push $0x88 + jmp __alltraps + 102410: e9 00 fb ff ff jmp 101f15 <__alltraps> + +00102415 : +.globl vector137 +vector137: + pushl $0 + 102415: 6a 00 push $0x0 + pushl $137 + 102417: 68 89 00 00 00 push $0x89 + jmp __alltraps + 10241c: e9 f4 fa ff ff jmp 101f15 <__alltraps> + +00102421 : +.globl vector138 +vector138: + pushl $0 + 102421: 6a 00 push $0x0 + pushl $138 + 102423: 68 8a 00 00 00 push $0x8a + jmp __alltraps + 102428: e9 e8 fa ff ff jmp 101f15 <__alltraps> + +0010242d : +.globl vector139 +vector139: + pushl $0 + 10242d: 6a 00 push $0x0 + pushl $139 + 10242f: 68 8b 00 00 00 push $0x8b + jmp __alltraps + 102434: e9 dc fa ff ff jmp 101f15 <__alltraps> + +00102439 : +.globl vector140 +vector140: + pushl $0 + 102439: 6a 00 push $0x0 + pushl $140 + 10243b: 68 8c 00 00 00 push $0x8c + jmp __alltraps + 102440: e9 d0 fa ff ff jmp 101f15 <__alltraps> + +00102445 : +.globl vector141 +vector141: + pushl $0 + 102445: 6a 00 push $0x0 + pushl $141 + 102447: 68 8d 00 00 00 push $0x8d + jmp __alltraps + 10244c: e9 c4 fa ff ff jmp 101f15 <__alltraps> + +00102451 : +.globl vector142 +vector142: + pushl $0 + 102451: 6a 00 push $0x0 + pushl $142 + 102453: 68 8e 00 00 00 push $0x8e + jmp __alltraps + 102458: e9 b8 fa ff ff jmp 101f15 <__alltraps> + +0010245d : +.globl vector143 +vector143: + pushl $0 + 10245d: 6a 00 push $0x0 + pushl $143 + 10245f: 68 8f 00 00 00 push $0x8f + jmp __alltraps + 102464: e9 ac fa ff ff jmp 101f15 <__alltraps> + +00102469 : +.globl vector144 +vector144: + pushl $0 + 102469: 6a 00 push $0x0 + pushl $144 + 10246b: 68 90 00 00 00 push $0x90 + jmp __alltraps + 102470: e9 a0 fa ff ff jmp 101f15 <__alltraps> + +00102475 : +.globl vector145 +vector145: + pushl $0 + 102475: 6a 00 push $0x0 + pushl $145 + 102477: 68 91 00 00 00 push $0x91 + jmp __alltraps + 10247c: e9 94 fa ff ff jmp 101f15 <__alltraps> + +00102481 : +.globl vector146 +vector146: + pushl $0 + 102481: 6a 00 push $0x0 + pushl $146 + 102483: 68 92 00 00 00 push $0x92 + jmp __alltraps + 102488: e9 88 fa ff ff jmp 101f15 <__alltraps> + +0010248d : +.globl vector147 +vector147: + pushl $0 + 10248d: 6a 00 push $0x0 + pushl $147 + 10248f: 68 93 00 00 00 push $0x93 + jmp __alltraps + 102494: e9 7c fa ff ff jmp 101f15 <__alltraps> + +00102499 : +.globl vector148 +vector148: + pushl $0 + 102499: 6a 00 push $0x0 + pushl $148 + 10249b: 68 94 00 00 00 push $0x94 + jmp __alltraps + 1024a0: e9 70 fa ff ff jmp 101f15 <__alltraps> + +001024a5 : +.globl vector149 +vector149: + pushl $0 + 1024a5: 6a 00 push $0x0 + pushl $149 + 1024a7: 68 95 00 00 00 push $0x95 + jmp __alltraps + 1024ac: e9 64 fa ff ff jmp 101f15 <__alltraps> + +001024b1 : +.globl vector150 +vector150: + pushl $0 + 1024b1: 6a 00 push $0x0 + pushl $150 + 1024b3: 68 96 00 00 00 push $0x96 + jmp __alltraps + 1024b8: e9 58 fa ff ff jmp 101f15 <__alltraps> + +001024bd : +.globl vector151 +vector151: + pushl $0 + 1024bd: 6a 00 push $0x0 + pushl $151 + 1024bf: 68 97 00 00 00 push $0x97 + jmp __alltraps + 1024c4: e9 4c fa ff ff jmp 101f15 <__alltraps> + +001024c9 : +.globl vector152 +vector152: + pushl $0 + 1024c9: 6a 00 push $0x0 + pushl $152 + 1024cb: 68 98 00 00 00 push $0x98 + jmp __alltraps + 1024d0: e9 40 fa ff ff jmp 101f15 <__alltraps> + +001024d5 : +.globl vector153 +vector153: + pushl $0 + 1024d5: 6a 00 push $0x0 + pushl $153 + 1024d7: 68 99 00 00 00 push $0x99 + jmp __alltraps + 1024dc: e9 34 fa ff ff jmp 101f15 <__alltraps> + +001024e1 : +.globl vector154 +vector154: + pushl $0 + 1024e1: 6a 00 push $0x0 + pushl $154 + 1024e3: 68 9a 00 00 00 push $0x9a + jmp __alltraps + 1024e8: e9 28 fa ff ff jmp 101f15 <__alltraps> + +001024ed : +.globl vector155 +vector155: + pushl $0 + 1024ed: 6a 00 push $0x0 + pushl $155 + 1024ef: 68 9b 00 00 00 push $0x9b + jmp __alltraps + 1024f4: e9 1c fa ff ff jmp 101f15 <__alltraps> + +001024f9 : +.globl vector156 +vector156: + pushl $0 + 1024f9: 6a 00 push $0x0 + pushl $156 + 1024fb: 68 9c 00 00 00 push $0x9c + jmp __alltraps + 102500: e9 10 fa ff ff jmp 101f15 <__alltraps> + +00102505 : +.globl vector157 +vector157: + pushl $0 + 102505: 6a 00 push $0x0 + pushl $157 + 102507: 68 9d 00 00 00 push $0x9d + jmp __alltraps + 10250c: e9 04 fa ff ff jmp 101f15 <__alltraps> + +00102511 : +.globl vector158 +vector158: + pushl $0 + 102511: 6a 00 push $0x0 + pushl $158 + 102513: 68 9e 00 00 00 push $0x9e + jmp __alltraps + 102518: e9 f8 f9 ff ff jmp 101f15 <__alltraps> + +0010251d : +.globl vector159 +vector159: + pushl $0 + 10251d: 6a 00 push $0x0 + pushl $159 + 10251f: 68 9f 00 00 00 push $0x9f + jmp __alltraps + 102524: e9 ec f9 ff ff jmp 101f15 <__alltraps> + +00102529 : +.globl vector160 +vector160: + pushl $0 + 102529: 6a 00 push $0x0 + pushl $160 + 10252b: 68 a0 00 00 00 push $0xa0 + jmp __alltraps + 102530: e9 e0 f9 ff ff jmp 101f15 <__alltraps> + +00102535 : +.globl vector161 +vector161: + pushl $0 + 102535: 6a 00 push $0x0 + pushl $161 + 102537: 68 a1 00 00 00 push $0xa1 + jmp __alltraps + 10253c: e9 d4 f9 ff ff jmp 101f15 <__alltraps> + +00102541 : +.globl vector162 +vector162: + pushl $0 + 102541: 6a 00 push $0x0 + pushl $162 + 102543: 68 a2 00 00 00 push $0xa2 + jmp __alltraps + 102548: e9 c8 f9 ff ff jmp 101f15 <__alltraps> + +0010254d : +.globl vector163 +vector163: + pushl $0 + 10254d: 6a 00 push $0x0 + pushl $163 + 10254f: 68 a3 00 00 00 push $0xa3 + jmp __alltraps + 102554: e9 bc f9 ff ff jmp 101f15 <__alltraps> + +00102559 : +.globl vector164 +vector164: + pushl $0 + 102559: 6a 00 push $0x0 + pushl $164 + 10255b: 68 a4 00 00 00 push $0xa4 + jmp __alltraps + 102560: e9 b0 f9 ff ff jmp 101f15 <__alltraps> + +00102565 : +.globl vector165 +vector165: + pushl $0 + 102565: 6a 00 push $0x0 + pushl $165 + 102567: 68 a5 00 00 00 push $0xa5 + jmp __alltraps + 10256c: e9 a4 f9 ff ff jmp 101f15 <__alltraps> + +00102571 : +.globl vector166 +vector166: + pushl $0 + 102571: 6a 00 push $0x0 + pushl $166 + 102573: 68 a6 00 00 00 push $0xa6 + jmp __alltraps + 102578: e9 98 f9 ff ff jmp 101f15 <__alltraps> + +0010257d : +.globl vector167 +vector167: + pushl $0 + 10257d: 6a 00 push $0x0 + pushl $167 + 10257f: 68 a7 00 00 00 push $0xa7 + jmp __alltraps + 102584: e9 8c f9 ff ff jmp 101f15 <__alltraps> + +00102589 : +.globl vector168 +vector168: + pushl $0 + 102589: 6a 00 push $0x0 + pushl $168 + 10258b: 68 a8 00 00 00 push $0xa8 + jmp __alltraps + 102590: e9 80 f9 ff ff jmp 101f15 <__alltraps> + +00102595 : +.globl vector169 +vector169: + pushl $0 + 102595: 6a 00 push $0x0 + pushl $169 + 102597: 68 a9 00 00 00 push $0xa9 + jmp __alltraps + 10259c: e9 74 f9 ff ff jmp 101f15 <__alltraps> + +001025a1 : +.globl vector170 +vector170: + pushl $0 + 1025a1: 6a 00 push $0x0 + pushl $170 + 1025a3: 68 aa 00 00 00 push $0xaa + jmp __alltraps + 1025a8: e9 68 f9 ff ff jmp 101f15 <__alltraps> + +001025ad : +.globl vector171 +vector171: + pushl $0 + 1025ad: 6a 00 push $0x0 + pushl $171 + 1025af: 68 ab 00 00 00 push $0xab + jmp __alltraps + 1025b4: e9 5c f9 ff ff jmp 101f15 <__alltraps> + +001025b9 : +.globl vector172 +vector172: + pushl $0 + 1025b9: 6a 00 push $0x0 + pushl $172 + 1025bb: 68 ac 00 00 00 push $0xac + jmp __alltraps + 1025c0: e9 50 f9 ff ff jmp 101f15 <__alltraps> + +001025c5 : +.globl vector173 +vector173: + pushl $0 + 1025c5: 6a 00 push $0x0 + pushl $173 + 1025c7: 68 ad 00 00 00 push $0xad + jmp __alltraps + 1025cc: e9 44 f9 ff ff jmp 101f15 <__alltraps> + +001025d1 : +.globl vector174 +vector174: + pushl $0 + 1025d1: 6a 00 push $0x0 + pushl $174 + 1025d3: 68 ae 00 00 00 push $0xae + jmp __alltraps + 1025d8: e9 38 f9 ff ff jmp 101f15 <__alltraps> + +001025dd : +.globl vector175 +vector175: + pushl $0 + 1025dd: 6a 00 push $0x0 + pushl $175 + 1025df: 68 af 00 00 00 push $0xaf + jmp __alltraps + 1025e4: e9 2c f9 ff ff jmp 101f15 <__alltraps> + +001025e9 : +.globl vector176 +vector176: + pushl $0 + 1025e9: 6a 00 push $0x0 + pushl $176 + 1025eb: 68 b0 00 00 00 push $0xb0 + jmp __alltraps + 1025f0: e9 20 f9 ff ff jmp 101f15 <__alltraps> + +001025f5 : +.globl vector177 +vector177: + pushl $0 + 1025f5: 6a 00 push $0x0 + pushl $177 + 1025f7: 68 b1 00 00 00 push $0xb1 + jmp __alltraps + 1025fc: e9 14 f9 ff ff jmp 101f15 <__alltraps> + +00102601 : +.globl vector178 +vector178: + pushl $0 + 102601: 6a 00 push $0x0 + pushl $178 + 102603: 68 b2 00 00 00 push $0xb2 + jmp __alltraps + 102608: e9 08 f9 ff ff jmp 101f15 <__alltraps> + +0010260d : +.globl vector179 +vector179: + pushl $0 + 10260d: 6a 00 push $0x0 + pushl $179 + 10260f: 68 b3 00 00 00 push $0xb3 + jmp __alltraps + 102614: e9 fc f8 ff ff jmp 101f15 <__alltraps> + +00102619 : +.globl vector180 +vector180: + pushl $0 + 102619: 6a 00 push $0x0 + pushl $180 + 10261b: 68 b4 00 00 00 push $0xb4 + jmp __alltraps + 102620: e9 f0 f8 ff ff jmp 101f15 <__alltraps> + +00102625 : +.globl vector181 +vector181: + pushl $0 + 102625: 6a 00 push $0x0 + pushl $181 + 102627: 68 b5 00 00 00 push $0xb5 + jmp __alltraps + 10262c: e9 e4 f8 ff ff jmp 101f15 <__alltraps> + +00102631 : +.globl vector182 +vector182: + pushl $0 + 102631: 6a 00 push $0x0 + pushl $182 + 102633: 68 b6 00 00 00 push $0xb6 + jmp __alltraps + 102638: e9 d8 f8 ff ff jmp 101f15 <__alltraps> + +0010263d : +.globl vector183 +vector183: + pushl $0 + 10263d: 6a 00 push $0x0 + pushl $183 + 10263f: 68 b7 00 00 00 push $0xb7 + jmp __alltraps + 102644: e9 cc f8 ff ff jmp 101f15 <__alltraps> + +00102649 : +.globl vector184 +vector184: + pushl $0 + 102649: 6a 00 push $0x0 + pushl $184 + 10264b: 68 b8 00 00 00 push $0xb8 + jmp __alltraps + 102650: e9 c0 f8 ff ff jmp 101f15 <__alltraps> + +00102655 : +.globl vector185 +vector185: + pushl $0 + 102655: 6a 00 push $0x0 + pushl $185 + 102657: 68 b9 00 00 00 push $0xb9 + jmp __alltraps + 10265c: e9 b4 f8 ff ff jmp 101f15 <__alltraps> + +00102661 : +.globl vector186 +vector186: + pushl $0 + 102661: 6a 00 push $0x0 + pushl $186 + 102663: 68 ba 00 00 00 push $0xba + jmp __alltraps + 102668: e9 a8 f8 ff ff jmp 101f15 <__alltraps> + +0010266d : +.globl vector187 +vector187: + pushl $0 + 10266d: 6a 00 push $0x0 + pushl $187 + 10266f: 68 bb 00 00 00 push $0xbb + jmp __alltraps + 102674: e9 9c f8 ff ff jmp 101f15 <__alltraps> + +00102679 : +.globl vector188 +vector188: + pushl $0 + 102679: 6a 00 push $0x0 + pushl $188 + 10267b: 68 bc 00 00 00 push $0xbc + jmp __alltraps + 102680: e9 90 f8 ff ff jmp 101f15 <__alltraps> + +00102685 : +.globl vector189 +vector189: + pushl $0 + 102685: 6a 00 push $0x0 + pushl $189 + 102687: 68 bd 00 00 00 push $0xbd + jmp __alltraps + 10268c: e9 84 f8 ff ff jmp 101f15 <__alltraps> + +00102691 : +.globl vector190 +vector190: + pushl $0 + 102691: 6a 00 push $0x0 + pushl $190 + 102693: 68 be 00 00 00 push $0xbe + jmp __alltraps + 102698: e9 78 f8 ff ff jmp 101f15 <__alltraps> + +0010269d : +.globl vector191 +vector191: + pushl $0 + 10269d: 6a 00 push $0x0 + pushl $191 + 10269f: 68 bf 00 00 00 push $0xbf + jmp __alltraps + 1026a4: e9 6c f8 ff ff jmp 101f15 <__alltraps> + +001026a9 : +.globl vector192 +vector192: + pushl $0 + 1026a9: 6a 00 push $0x0 + pushl $192 + 1026ab: 68 c0 00 00 00 push $0xc0 + jmp __alltraps + 1026b0: e9 60 f8 ff ff jmp 101f15 <__alltraps> + +001026b5 : +.globl vector193 +vector193: + pushl $0 + 1026b5: 6a 00 push $0x0 + pushl $193 + 1026b7: 68 c1 00 00 00 push $0xc1 + jmp __alltraps + 1026bc: e9 54 f8 ff ff jmp 101f15 <__alltraps> + +001026c1 : +.globl vector194 +vector194: + pushl $0 + 1026c1: 6a 00 push $0x0 + pushl $194 + 1026c3: 68 c2 00 00 00 push $0xc2 + jmp __alltraps + 1026c8: e9 48 f8 ff ff jmp 101f15 <__alltraps> + +001026cd : +.globl vector195 +vector195: + pushl $0 + 1026cd: 6a 00 push $0x0 + pushl $195 + 1026cf: 68 c3 00 00 00 push $0xc3 + jmp __alltraps + 1026d4: e9 3c f8 ff ff jmp 101f15 <__alltraps> + +001026d9 : +.globl vector196 +vector196: + pushl $0 + 1026d9: 6a 00 push $0x0 + pushl $196 + 1026db: 68 c4 00 00 00 push $0xc4 + jmp __alltraps + 1026e0: e9 30 f8 ff ff jmp 101f15 <__alltraps> + +001026e5 : +.globl vector197 +vector197: + pushl $0 + 1026e5: 6a 00 push $0x0 + pushl $197 + 1026e7: 68 c5 00 00 00 push $0xc5 + jmp __alltraps + 1026ec: e9 24 f8 ff ff jmp 101f15 <__alltraps> + +001026f1 : +.globl vector198 +vector198: + pushl $0 + 1026f1: 6a 00 push $0x0 + pushl $198 + 1026f3: 68 c6 00 00 00 push $0xc6 + jmp __alltraps + 1026f8: e9 18 f8 ff ff jmp 101f15 <__alltraps> + +001026fd : +.globl vector199 +vector199: + pushl $0 + 1026fd: 6a 00 push $0x0 + pushl $199 + 1026ff: 68 c7 00 00 00 push $0xc7 + jmp __alltraps + 102704: e9 0c f8 ff ff jmp 101f15 <__alltraps> + +00102709 : +.globl vector200 +vector200: + pushl $0 + 102709: 6a 00 push $0x0 + pushl $200 + 10270b: 68 c8 00 00 00 push $0xc8 + jmp __alltraps + 102710: e9 00 f8 ff ff jmp 101f15 <__alltraps> + +00102715 : +.globl vector201 +vector201: + pushl $0 + 102715: 6a 00 push $0x0 + pushl $201 + 102717: 68 c9 00 00 00 push $0xc9 + jmp __alltraps + 10271c: e9 f4 f7 ff ff jmp 101f15 <__alltraps> + +00102721 : +.globl vector202 +vector202: + pushl $0 + 102721: 6a 00 push $0x0 + pushl $202 + 102723: 68 ca 00 00 00 push $0xca + jmp __alltraps + 102728: e9 e8 f7 ff ff jmp 101f15 <__alltraps> + +0010272d : +.globl vector203 +vector203: + pushl $0 + 10272d: 6a 00 push $0x0 + pushl $203 + 10272f: 68 cb 00 00 00 push $0xcb + jmp __alltraps + 102734: e9 dc f7 ff ff jmp 101f15 <__alltraps> + +00102739 : +.globl vector204 +vector204: + pushl $0 + 102739: 6a 00 push $0x0 + pushl $204 + 10273b: 68 cc 00 00 00 push $0xcc + jmp __alltraps + 102740: e9 d0 f7 ff ff jmp 101f15 <__alltraps> + +00102745 : +.globl vector205 +vector205: + pushl $0 + 102745: 6a 00 push $0x0 + pushl $205 + 102747: 68 cd 00 00 00 push $0xcd + jmp __alltraps + 10274c: e9 c4 f7 ff ff jmp 101f15 <__alltraps> + +00102751 : +.globl vector206 +vector206: + pushl $0 + 102751: 6a 00 push $0x0 + pushl $206 + 102753: 68 ce 00 00 00 push $0xce + jmp __alltraps + 102758: e9 b8 f7 ff ff jmp 101f15 <__alltraps> + +0010275d : +.globl vector207 +vector207: + pushl $0 + 10275d: 6a 00 push $0x0 + pushl $207 + 10275f: 68 cf 00 00 00 push $0xcf + jmp __alltraps + 102764: e9 ac f7 ff ff jmp 101f15 <__alltraps> + +00102769 : +.globl vector208 +vector208: + pushl $0 + 102769: 6a 00 push $0x0 + pushl $208 + 10276b: 68 d0 00 00 00 push $0xd0 + jmp __alltraps + 102770: e9 a0 f7 ff ff jmp 101f15 <__alltraps> + +00102775 : +.globl vector209 +vector209: + pushl $0 + 102775: 6a 00 push $0x0 + pushl $209 + 102777: 68 d1 00 00 00 push $0xd1 + jmp __alltraps + 10277c: e9 94 f7 ff ff jmp 101f15 <__alltraps> + +00102781 : +.globl vector210 +vector210: + pushl $0 + 102781: 6a 00 push $0x0 + pushl $210 + 102783: 68 d2 00 00 00 push $0xd2 + jmp __alltraps + 102788: e9 88 f7 ff ff jmp 101f15 <__alltraps> + +0010278d : +.globl vector211 +vector211: + pushl $0 + 10278d: 6a 00 push $0x0 + pushl $211 + 10278f: 68 d3 00 00 00 push $0xd3 + jmp __alltraps + 102794: e9 7c f7 ff ff jmp 101f15 <__alltraps> + +00102799 : +.globl vector212 +vector212: + pushl $0 + 102799: 6a 00 push $0x0 + pushl $212 + 10279b: 68 d4 00 00 00 push $0xd4 + jmp __alltraps + 1027a0: e9 70 f7 ff ff jmp 101f15 <__alltraps> + +001027a5 : +.globl vector213 +vector213: + pushl $0 + 1027a5: 6a 00 push $0x0 + pushl $213 + 1027a7: 68 d5 00 00 00 push $0xd5 + jmp __alltraps + 1027ac: e9 64 f7 ff ff jmp 101f15 <__alltraps> + +001027b1 : +.globl vector214 +vector214: + pushl $0 + 1027b1: 6a 00 push $0x0 + pushl $214 + 1027b3: 68 d6 00 00 00 push $0xd6 + jmp __alltraps + 1027b8: e9 58 f7 ff ff jmp 101f15 <__alltraps> + +001027bd : +.globl vector215 +vector215: + pushl $0 + 1027bd: 6a 00 push $0x0 + pushl $215 + 1027bf: 68 d7 00 00 00 push $0xd7 + jmp __alltraps + 1027c4: e9 4c f7 ff ff jmp 101f15 <__alltraps> + +001027c9 : +.globl vector216 +vector216: + pushl $0 + 1027c9: 6a 00 push $0x0 + pushl $216 + 1027cb: 68 d8 00 00 00 push $0xd8 + jmp __alltraps + 1027d0: e9 40 f7 ff ff jmp 101f15 <__alltraps> + +001027d5 : +.globl vector217 +vector217: + pushl $0 + 1027d5: 6a 00 push $0x0 + pushl $217 + 1027d7: 68 d9 00 00 00 push $0xd9 + jmp __alltraps + 1027dc: e9 34 f7 ff ff jmp 101f15 <__alltraps> + +001027e1 : +.globl vector218 +vector218: + pushl $0 + 1027e1: 6a 00 push $0x0 + pushl $218 + 1027e3: 68 da 00 00 00 push $0xda + jmp __alltraps + 1027e8: e9 28 f7 ff ff jmp 101f15 <__alltraps> + +001027ed : +.globl vector219 +vector219: + pushl $0 + 1027ed: 6a 00 push $0x0 + pushl $219 + 1027ef: 68 db 00 00 00 push $0xdb + jmp __alltraps + 1027f4: e9 1c f7 ff ff jmp 101f15 <__alltraps> + +001027f9 : +.globl vector220 +vector220: + pushl $0 + 1027f9: 6a 00 push $0x0 + pushl $220 + 1027fb: 68 dc 00 00 00 push $0xdc + jmp __alltraps + 102800: e9 10 f7 ff ff jmp 101f15 <__alltraps> + +00102805 : +.globl vector221 +vector221: + pushl $0 + 102805: 6a 00 push $0x0 + pushl $221 + 102807: 68 dd 00 00 00 push $0xdd + jmp __alltraps + 10280c: e9 04 f7 ff ff jmp 101f15 <__alltraps> + +00102811 : +.globl vector222 +vector222: + pushl $0 + 102811: 6a 00 push $0x0 + pushl $222 + 102813: 68 de 00 00 00 push $0xde + jmp __alltraps + 102818: e9 f8 f6 ff ff jmp 101f15 <__alltraps> + +0010281d : +.globl vector223 +vector223: + pushl $0 + 10281d: 6a 00 push $0x0 + pushl $223 + 10281f: 68 df 00 00 00 push $0xdf + jmp __alltraps + 102824: e9 ec f6 ff ff jmp 101f15 <__alltraps> + +00102829 : +.globl vector224 +vector224: + pushl $0 + 102829: 6a 00 push $0x0 + pushl $224 + 10282b: 68 e0 00 00 00 push $0xe0 + jmp __alltraps + 102830: e9 e0 f6 ff ff jmp 101f15 <__alltraps> + +00102835 : +.globl vector225 +vector225: + pushl $0 + 102835: 6a 00 push $0x0 + pushl $225 + 102837: 68 e1 00 00 00 push $0xe1 + jmp __alltraps + 10283c: e9 d4 f6 ff ff jmp 101f15 <__alltraps> + +00102841 : +.globl vector226 +vector226: + pushl $0 + 102841: 6a 00 push $0x0 + pushl $226 + 102843: 68 e2 00 00 00 push $0xe2 + jmp __alltraps + 102848: e9 c8 f6 ff ff jmp 101f15 <__alltraps> + +0010284d : +.globl vector227 +vector227: + pushl $0 + 10284d: 6a 00 push $0x0 + pushl $227 + 10284f: 68 e3 00 00 00 push $0xe3 + jmp __alltraps + 102854: e9 bc f6 ff ff jmp 101f15 <__alltraps> + +00102859 : +.globl vector228 +vector228: + pushl $0 + 102859: 6a 00 push $0x0 + pushl $228 + 10285b: 68 e4 00 00 00 push $0xe4 + jmp __alltraps + 102860: e9 b0 f6 ff ff jmp 101f15 <__alltraps> + +00102865 : +.globl vector229 +vector229: + pushl $0 + 102865: 6a 00 push $0x0 + pushl $229 + 102867: 68 e5 00 00 00 push $0xe5 + jmp __alltraps + 10286c: e9 a4 f6 ff ff jmp 101f15 <__alltraps> + +00102871 : +.globl vector230 +vector230: + pushl $0 + 102871: 6a 00 push $0x0 + pushl $230 + 102873: 68 e6 00 00 00 push $0xe6 + jmp __alltraps + 102878: e9 98 f6 ff ff jmp 101f15 <__alltraps> + +0010287d : +.globl vector231 +vector231: + pushl $0 + 10287d: 6a 00 push $0x0 + pushl $231 + 10287f: 68 e7 00 00 00 push $0xe7 + jmp __alltraps + 102884: e9 8c f6 ff ff jmp 101f15 <__alltraps> + +00102889 : +.globl vector232 +vector232: + pushl $0 + 102889: 6a 00 push $0x0 + pushl $232 + 10288b: 68 e8 00 00 00 push $0xe8 + jmp __alltraps + 102890: e9 80 f6 ff ff jmp 101f15 <__alltraps> + +00102895 : +.globl vector233 +vector233: + pushl $0 + 102895: 6a 00 push $0x0 + pushl $233 + 102897: 68 e9 00 00 00 push $0xe9 + jmp __alltraps + 10289c: e9 74 f6 ff ff jmp 101f15 <__alltraps> + +001028a1 : +.globl vector234 +vector234: + pushl $0 + 1028a1: 6a 00 push $0x0 + pushl $234 + 1028a3: 68 ea 00 00 00 push $0xea + jmp __alltraps + 1028a8: e9 68 f6 ff ff jmp 101f15 <__alltraps> + +001028ad : +.globl vector235 +vector235: + pushl $0 + 1028ad: 6a 00 push $0x0 + pushl $235 + 1028af: 68 eb 00 00 00 push $0xeb + jmp __alltraps + 1028b4: e9 5c f6 ff ff jmp 101f15 <__alltraps> + +001028b9 : +.globl vector236 +vector236: + pushl $0 + 1028b9: 6a 00 push $0x0 + pushl $236 + 1028bb: 68 ec 00 00 00 push $0xec + jmp __alltraps + 1028c0: e9 50 f6 ff ff jmp 101f15 <__alltraps> + +001028c5 : +.globl vector237 +vector237: + pushl $0 + 1028c5: 6a 00 push $0x0 + pushl $237 + 1028c7: 68 ed 00 00 00 push $0xed + jmp __alltraps + 1028cc: e9 44 f6 ff ff jmp 101f15 <__alltraps> + +001028d1 : +.globl vector238 +vector238: + pushl $0 + 1028d1: 6a 00 push $0x0 + pushl $238 + 1028d3: 68 ee 00 00 00 push $0xee + jmp __alltraps + 1028d8: e9 38 f6 ff ff jmp 101f15 <__alltraps> + +001028dd : +.globl vector239 +vector239: + pushl $0 + 1028dd: 6a 00 push $0x0 + pushl $239 + 1028df: 68 ef 00 00 00 push $0xef + jmp __alltraps + 1028e4: e9 2c f6 ff ff jmp 101f15 <__alltraps> + +001028e9 : +.globl vector240 +vector240: + pushl $0 + 1028e9: 6a 00 push $0x0 + pushl $240 + 1028eb: 68 f0 00 00 00 push $0xf0 + jmp __alltraps + 1028f0: e9 20 f6 ff ff jmp 101f15 <__alltraps> + +001028f5 : +.globl vector241 +vector241: + pushl $0 + 1028f5: 6a 00 push $0x0 + pushl $241 + 1028f7: 68 f1 00 00 00 push $0xf1 + jmp __alltraps + 1028fc: e9 14 f6 ff ff jmp 101f15 <__alltraps> + +00102901 : +.globl vector242 +vector242: + pushl $0 + 102901: 6a 00 push $0x0 + pushl $242 + 102903: 68 f2 00 00 00 push $0xf2 + jmp __alltraps + 102908: e9 08 f6 ff ff jmp 101f15 <__alltraps> + +0010290d : +.globl vector243 +vector243: + pushl $0 + 10290d: 6a 00 push $0x0 + pushl $243 + 10290f: 68 f3 00 00 00 push $0xf3 + jmp __alltraps + 102914: e9 fc f5 ff ff jmp 101f15 <__alltraps> + +00102919 : +.globl vector244 +vector244: + pushl $0 + 102919: 6a 00 push $0x0 + pushl $244 + 10291b: 68 f4 00 00 00 push $0xf4 + jmp __alltraps + 102920: e9 f0 f5 ff ff jmp 101f15 <__alltraps> + +00102925 : +.globl vector245 +vector245: + pushl $0 + 102925: 6a 00 push $0x0 + pushl $245 + 102927: 68 f5 00 00 00 push $0xf5 + jmp __alltraps + 10292c: e9 e4 f5 ff ff jmp 101f15 <__alltraps> + +00102931 : +.globl vector246 +vector246: + pushl $0 + 102931: 6a 00 push $0x0 + pushl $246 + 102933: 68 f6 00 00 00 push $0xf6 + jmp __alltraps + 102938: e9 d8 f5 ff ff jmp 101f15 <__alltraps> + +0010293d : +.globl vector247 +vector247: + pushl $0 + 10293d: 6a 00 push $0x0 + pushl $247 + 10293f: 68 f7 00 00 00 push $0xf7 + jmp __alltraps + 102944: e9 cc f5 ff ff jmp 101f15 <__alltraps> + +00102949 : +.globl vector248 +vector248: + pushl $0 + 102949: 6a 00 push $0x0 + pushl $248 + 10294b: 68 f8 00 00 00 push $0xf8 + jmp __alltraps + 102950: e9 c0 f5 ff ff jmp 101f15 <__alltraps> + +00102955 : +.globl vector249 +vector249: + pushl $0 + 102955: 6a 00 push $0x0 + pushl $249 + 102957: 68 f9 00 00 00 push $0xf9 + jmp __alltraps + 10295c: e9 b4 f5 ff ff jmp 101f15 <__alltraps> + +00102961 : +.globl vector250 +vector250: + pushl $0 + 102961: 6a 00 push $0x0 + pushl $250 + 102963: 68 fa 00 00 00 push $0xfa + jmp __alltraps + 102968: e9 a8 f5 ff ff jmp 101f15 <__alltraps> + +0010296d : +.globl vector251 +vector251: + pushl $0 + 10296d: 6a 00 push $0x0 + pushl $251 + 10296f: 68 fb 00 00 00 push $0xfb + jmp __alltraps + 102974: e9 9c f5 ff ff jmp 101f15 <__alltraps> + +00102979 : +.globl vector252 +vector252: + pushl $0 + 102979: 6a 00 push $0x0 + pushl $252 + 10297b: 68 fc 00 00 00 push $0xfc + jmp __alltraps + 102980: e9 90 f5 ff ff jmp 101f15 <__alltraps> + +00102985 : +.globl vector253 +vector253: + pushl $0 + 102985: 6a 00 push $0x0 + pushl $253 + 102987: 68 fd 00 00 00 push $0xfd + jmp __alltraps + 10298c: e9 84 f5 ff ff jmp 101f15 <__alltraps> + +00102991 : +.globl vector254 +vector254: + pushl $0 + 102991: 6a 00 push $0x0 + pushl $254 + 102993: 68 fe 00 00 00 push $0xfe + jmp __alltraps + 102998: e9 78 f5 ff ff jmp 101f15 <__alltraps> + +0010299d : +.globl vector255 +vector255: + pushl $0 + 10299d: 6a 00 push $0x0 + pushl $255 + 10299f: 68 ff 00 00 00 push $0xff + jmp __alltraps + 1029a4: e9 6c f5 ff ff jmp 101f15 <__alltraps> + +001029a9 : + +extern struct Page *pages; +extern size_t npage; + +static inline ppn_t +page2ppn(struct Page *page) { + 1029a9: 55 push %ebp + 1029aa: 89 e5 mov %esp,%ebp + return page - pages; + 1029ac: 8b 15 00 cf 11 00 mov 0x11cf00,%edx + 1029b2: 8b 45 08 mov 0x8(%ebp),%eax + 1029b5: 29 d0 sub %edx,%eax + 1029b7: c1 f8 02 sar $0x2,%eax + 1029ba: 69 c0 cd cc cc cc imul $0xcccccccd,%eax,%eax +} + 1029c0: 5d pop %ebp + 1029c1: c3 ret + +001029c2 : + +static inline uintptr_t +page2pa(struct Page *page) { + 1029c2: 55 push %ebp + 1029c3: 89 e5 mov %esp,%ebp + 1029c5: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; + 1029c8: 8b 45 08 mov 0x8(%ebp),%eax + 1029cb: 89 04 24 mov %eax,(%esp) + 1029ce: e8 d6 ff ff ff call 1029a9 + 1029d3: c1 e0 0c shl $0xc,%eax +} + 1029d6: 89 ec mov %ebp,%esp + 1029d8: 5d pop %ebp + 1029d9: c3 ret + +001029da : +pde2page(pde_t pde) { + return pa2page(PDE_ADDR(pde)); +} + +static inline int +page_ref(struct Page *page) { + 1029da: 55 push %ebp + 1029db: 89 e5 mov %esp,%ebp + return page->ref; + 1029dd: 8b 45 08 mov 0x8(%ebp),%eax + 1029e0: 8b 00 mov (%eax),%eax +} + 1029e2: 5d pop %ebp + 1029e3: c3 ret + +001029e4 : + +static inline void +set_page_ref(struct Page *page, int val) { + 1029e4: 55 push %ebp + 1029e5: 89 e5 mov %esp,%ebp + page->ref = val; + 1029e7: 8b 45 08 mov 0x8(%ebp),%eax + 1029ea: 8b 55 0c mov 0xc(%ebp),%edx + 1029ed: 89 10 mov %edx,(%eax) +} + 1029ef: 90 nop + 1029f0: 5d pop %ebp + 1029f1: c3 ret + +001029f2 : +#define nr_free (free_area.nr_free) + +//free_list` 用于记录空闲内存块,nr_free` 是空闲内存块的总数。 +//用default_init函数来初始化 `free_list`,并将 `nr_free` 设置为 0。 +static void +default_init(void) { + 1029f2: 55 push %ebp + 1029f3: 89 e5 mov %esp,%ebp + 1029f5: 83 ec 10 sub $0x10,%esp + 1029f8: c7 45 fc e0 ce 11 00 movl $0x11cee0,-0x4(%ebp) + * list_init - initialize a new entry + * @elm: new entry to be initialized + * */ +static inline void +list_init(list_entry_t *elm) { + elm->prev = elm->next = elm; + 1029ff: 8b 45 fc mov -0x4(%ebp),%eax + 102a02: 8b 55 fc mov -0x4(%ebp),%edx + 102a05: 89 50 04 mov %edx,0x4(%eax) + 102a08: 8b 45 fc mov -0x4(%ebp),%eax + 102a0b: 8b 50 04 mov 0x4(%eax),%edx + 102a0e: 8b 45 fc mov -0x4(%ebp),%eax + 102a11: 89 10 mov %edx,(%eax) +} + 102a13: 90 nop + list_init(&free_list); + nr_free = 0; + 102a14: c7 05 e8 ce 11 00 00 movl $0x0,0x11cee8 + 102a1b: 00 00 00 +} + 102a1e: 90 nop + 102a1f: 89 ec mov %ebp,%esp + 102a21: 5d pop %ebp + 102a22: c3 ret + +00102a23 : + +//用于初始化一段连续的物理页,并将它们加入到空闲内存管理系统中. +//struct Page *base:指向要初始化的页块的起始地址。size_t n:要初始化的页的数量。 +static void +default_init_memmap(struct Page *base, size_t n) { + 102a23: 55 push %ebp + 102a24: 89 e5 mov %esp,%ebp + 102a26: 83 ec 58 sub $0x58,%esp + assert(n > 0);//// 确保请求的页数大于零 + 102a29: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 102a2d: 75 24 jne 102a53 + 102a2f: c7 44 24 0c 90 67 10 movl $0x106790,0xc(%esp) + 102a36: 00 + 102a37: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 102a3e: 00 + 102a3f: c7 44 24 04 94 00 00 movl $0x94,0x4(%esp) + 102a46: 00 + 102a47: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 102a4e: e8 e0 e1 ff ff call 100c33 <__panic> + struct Page *p = base;// 指向当前初始化的页 + 102a53: 8b 45 08 mov 0x8(%ebp),%eax + 102a56: 89 45 f4 mov %eax,-0xc(%ebp) + //// 遍历每一页,设置其状态 + for (; p != base + n; p ++) { + 102a59: eb 7d jmp 102ad8 + assert(PageReserved(p));//检查每个页是否被标记为“保留”。若没有被保留,函数将抛出错误。 + 102a5b: 8b 45 f4 mov -0xc(%ebp),%eax + 102a5e: 83 c0 04 add $0x4,%eax + 102a61: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + 102a68: 89 45 ec mov %eax,-0x14(%ebp) + * @addr: the address to count from + * */ +static inline bool +test_bit(int nr, volatile void *addr) { + int oldbit; + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 102a6b: 8b 45 ec mov -0x14(%ebp),%eax + 102a6e: 8b 55 f0 mov -0x10(%ebp),%edx + 102a71: 0f a3 10 bt %edx,(%eax) + 102a74: 19 c0 sbb %eax,%eax + 102a76: 89 45 e8 mov %eax,-0x18(%ebp) + return oldbit != 0; + 102a79: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 102a7d: 0f 95 c0 setne %al + 102a80: 0f b6 c0 movzbl %al,%eax + 102a83: 85 c0 test %eax,%eax + 102a85: 75 24 jne 102aab + 102a87: c7 44 24 0c c1 67 10 movl $0x1067c1,0xc(%esp) + 102a8e: 00 + 102a8f: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 102a96: 00 + 102a97: c7 44 24 04 98 00 00 movl $0x98,0x4(%esp) + 102a9e: 00 + 102a9f: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 102aa6: e8 88 e1 ff ff call 100c33 <__panic> + p->flags = p->property = 0;//将页的 flags 和 property 字段设置为 0,表示该页未分配、未使用。 + 102aab: 8b 45 f4 mov -0xc(%ebp),%eax + 102aae: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax) + 102ab5: 8b 45 f4 mov -0xc(%ebp),%eax + 102ab8: 8b 50 08 mov 0x8(%eax),%edx + 102abb: 8b 45 f4 mov -0xc(%ebp),%eax + 102abe: 89 50 04 mov %edx,0x4(%eax) + set_page_ref(p, 0);//将页的引用计数设置为 0,表明没有任何引用指向此页。 + 102ac1: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 102ac8: 00 + 102ac9: 8b 45 f4 mov -0xc(%ebp),%eax + 102acc: 89 04 24 mov %eax,(%esp) + 102acf: e8 10 ff ff ff call 1029e4 + for (; p != base + n; p ++) { + 102ad4: 83 45 f4 14 addl $0x14,-0xc(%ebp) + 102ad8: 8b 55 0c mov 0xc(%ebp),%edx + 102adb: 89 d0 mov %edx,%eax + 102add: c1 e0 02 shl $0x2,%eax + 102ae0: 01 d0 add %edx,%eax + 102ae2: c1 e0 02 shl $0x2,%eax + 102ae5: 89 c2 mov %eax,%edx + 102ae7: 8b 45 08 mov 0x8(%ebp),%eax + 102aea: 01 d0 add %edx,%eax + 102aec: 39 45 f4 cmp %eax,-0xc(%ebp) + 102aef: 0f 85 66 ff ff ff jne 102a5b + } + // 设置第一个页的 property 为块的总数 + base->property = n; + 102af5: 8b 45 08 mov 0x8(%ebp),%eax + 102af8: 8b 55 0c mov 0xc(%ebp),%edx + 102afb: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(base);// 设置当前页的有效标志 + 102afe: 8b 45 08 mov 0x8(%ebp),%eax + 102b01: 83 c0 04 add $0x4,%eax + 102b04: c7 45 c8 01 00 00 00 movl $0x1,-0x38(%ebp) + 102b0b: 89 45 c4 mov %eax,-0x3c(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); + 102b0e: 8b 45 c4 mov -0x3c(%ebp),%eax + 102b11: 8b 55 c8 mov -0x38(%ebp),%edx + 102b14: 0f ab 10 bts %edx,(%eax) +} + 102b17: 90 nop + nr_free += n;// 更新空闲页计数 + 102b18: 8b 15 e8 ce 11 00 mov 0x11cee8,%edx + 102b1e: 8b 45 0c mov 0xc(%ebp),%eax + 102b21: 01 d0 add %edx,%eax + 102b23: a3 e8 ce 11 00 mov %eax,0x11cee8 + list_add(&free_list, &(base->page_link)); // 将该块添加到空闲列表中 + 102b28: 8b 45 08 mov 0x8(%ebp),%eax + 102b2b: 83 c0 0c add $0xc,%eax + 102b2e: c7 45 e4 e0 ce 11 00 movl $0x11cee0,-0x1c(%ebp) + 102b35: 89 45 e0 mov %eax,-0x20(%ebp) + 102b38: 8b 45 e4 mov -0x1c(%ebp),%eax + 102b3b: 89 45 dc mov %eax,-0x24(%ebp) + 102b3e: 8b 45 e0 mov -0x20(%ebp),%eax + 102b41: 89 45 d8 mov %eax,-0x28(%ebp) + * Insert the new element @elm *after* the element @listelm which + * is already in the list. + * */ +static inline void +list_add_after(list_entry_t *listelm, list_entry_t *elm) { + __list_add(elm, listelm, listelm->next); + 102b44: 8b 45 dc mov -0x24(%ebp),%eax + 102b47: 8b 40 04 mov 0x4(%eax),%eax + 102b4a: 8b 55 d8 mov -0x28(%ebp),%edx + 102b4d: 89 55 d4 mov %edx,-0x2c(%ebp) + 102b50: 8b 55 dc mov -0x24(%ebp),%edx + 102b53: 89 55 d0 mov %edx,-0x30(%ebp) + 102b56: 89 45 cc mov %eax,-0x34(%ebp) + * This is only for internal list manipulation where we know + * the prev/next entries already! + * */ +static inline void +__list_add(list_entry_t *elm, list_entry_t *prev, list_entry_t *next) { + prev->next = next->prev = elm; + 102b59: 8b 45 cc mov -0x34(%ebp),%eax + 102b5c: 8b 55 d4 mov -0x2c(%ebp),%edx + 102b5f: 89 10 mov %edx,(%eax) + 102b61: 8b 45 cc mov -0x34(%ebp),%eax + 102b64: 8b 10 mov (%eax),%edx + 102b66: 8b 45 d0 mov -0x30(%ebp),%eax + 102b69: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; + 102b6c: 8b 45 d4 mov -0x2c(%ebp),%eax + 102b6f: 8b 55 cc mov -0x34(%ebp),%edx + 102b72: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; + 102b75: 8b 45 d4 mov -0x2c(%ebp),%eax + 102b78: 8b 55 d0 mov -0x30(%ebp),%edx + 102b7b: 89 10 mov %edx,(%eax) +} + 102b7d: 90 nop +} + 102b7e: 90 nop +} + 102b7f: 90 nop +} + 102b80: 90 nop + 102b81: 89 ec mov %ebp,%esp + 102b83: 5d pop %ebp + 102b84: c3 ret + +00102b85 : + +//用于分配指定数量的连续物理页。该函数实现了首次适应内存分配算法。 +static struct Page * +default_alloc_pages(size_t n) { + 102b85: 55 push %ebp + 102b86: 89 e5 mov %esp,%ebp + 102b88: 83 ec 68 sub $0x68,%esp + assert(n > 0);// 确保请求的页数大于零 + 102b8b: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 102b8f: 75 24 jne 102bb5 + 102b91: c7 44 24 0c 90 67 10 movl $0x106790,0xc(%esp) + 102b98: 00 + 102b99: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 102ba0: 00 + 102ba1: c7 44 24 04 a6 00 00 movl $0xa6,0x4(%esp) + 102ba8: 00 + 102ba9: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 102bb0: e8 7e e0 ff ff call 100c33 <__panic> + if (n > nr_free) {// 检查请求的页数是否超过空闲页数 + 102bb5: a1 e8 ce 11 00 mov 0x11cee8,%eax + 102bba: 39 45 08 cmp %eax,0x8(%ebp) + 102bbd: 76 0a jbe 102bc9 + return NULL; + 102bbf: b8 00 00 00 00 mov $0x0,%eax + 102bc4: e9 34 01 00 00 jmp 102cfd + } + struct Page *page = NULL;// 初始化分配的页指针 + 102bc9: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + list_entry_t *le = &free_list; // 初始化链表迭代器 + 102bd0: c7 45 f0 e0 ce 11 00 movl $0x11cee0,-0x10(%ebp) + // 遍历空闲列表,寻找第一个满足条件的块 + while ((le = list_next(le)) != &free_list) { + 102bd7: eb 1c jmp 102bf5 + struct Page *p = le2page(le, page_link);// 将链表节点转换为 Page 结构体 + 102bd9: 8b 45 f0 mov -0x10(%ebp),%eax + 102bdc: 83 e8 0c sub $0xc,%eax + 102bdf: 89 45 ec mov %eax,-0x14(%ebp) + if (p->property >= n) {// 检查当前块的页数是否满足请求 + 102be2: 8b 45 ec mov -0x14(%ebp),%eax + 102be5: 8b 40 08 mov 0x8(%eax),%eax + 102be8: 39 45 08 cmp %eax,0x8(%ebp) + 102beb: 77 08 ja 102bf5 + page = p;// 找到合适的块 + 102bed: 8b 45 ec mov -0x14(%ebp),%eax + 102bf0: 89 45 f4 mov %eax,-0xc(%ebp) + break;// 退出循环 + 102bf3: eb 18 jmp 102c0d + 102bf5: 8b 45 f0 mov -0x10(%ebp),%eax + 102bf8: 89 45 e4 mov %eax,-0x1c(%ebp) + return listelm->next; + 102bfb: 8b 45 e4 mov -0x1c(%ebp),%eax + 102bfe: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { + 102c01: 89 45 f0 mov %eax,-0x10(%ebp) + 102c04: 81 7d f0 e0 ce 11 00 cmpl $0x11cee0,-0x10(%ebp) + 102c0b: 75 cc jne 102bd9 + } + } + if (page != NULL) {// 如果找到合适的块 + 102c0d: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 102c11: 0f 84 e3 00 00 00 je 102cfa + list_del(&(page->page_link));// 从空闲列表中删除该块 + 102c17: 8b 45 f4 mov -0xc(%ebp),%eax + 102c1a: 83 c0 0c add $0xc,%eax + 102c1d: 89 45 e0 mov %eax,-0x20(%ebp) + __list_del(listelm->prev, listelm->next); + 102c20: 8b 45 e0 mov -0x20(%ebp),%eax + 102c23: 8b 40 04 mov 0x4(%eax),%eax + 102c26: 8b 55 e0 mov -0x20(%ebp),%edx + 102c29: 8b 12 mov (%edx),%edx + 102c2b: 89 55 dc mov %edx,-0x24(%ebp) + 102c2e: 89 45 d8 mov %eax,-0x28(%ebp) + * This is only for internal list manipulation where we know + * the prev/next entries already! + * */ +static inline void +__list_del(list_entry_t *prev, list_entry_t *next) { + prev->next = next; + 102c31: 8b 45 dc mov -0x24(%ebp),%eax + 102c34: 8b 55 d8 mov -0x28(%ebp),%edx + 102c37: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; + 102c3a: 8b 45 d8 mov -0x28(%ebp),%eax + 102c3d: 8b 55 dc mov -0x24(%ebp),%edx + 102c40: 89 10 mov %edx,(%eax) +} + 102c42: 90 nop +} + 102c43: 90 nop + if (page->property > n) { + 102c44: 8b 45 f4 mov -0xc(%ebp),%eax + 102c47: 8b 40 08 mov 0x8(%eax),%eax + 102c4a: 39 45 08 cmp %eax,0x8(%ebp) + 102c4d: 0f 83 80 00 00 00 jae 102cd3 + struct Page *p = page + n; // 指向剩余的页 + 102c53: 8b 55 08 mov 0x8(%ebp),%edx + 102c56: 89 d0 mov %edx,%eax + 102c58: c1 e0 02 shl $0x2,%eax + 102c5b: 01 d0 add %edx,%eax + 102c5d: c1 e0 02 shl $0x2,%eax + 102c60: 89 c2 mov %eax,%edx + 102c62: 8b 45 f4 mov -0xc(%ebp),%eax + 102c65: 01 d0 add %edx,%eax + 102c67: 89 45 e8 mov %eax,-0x18(%ebp) + p->property = page->property - n;// 更新剩余块的页数 + 102c6a: 8b 45 f4 mov -0xc(%ebp),%eax + 102c6d: 8b 40 08 mov 0x8(%eax),%eax + 102c70: 2b 45 08 sub 0x8(%ebp),%eax + 102c73: 89 c2 mov %eax,%edx + 102c75: 8b 45 e8 mov -0x18(%ebp),%eax + 102c78: 89 50 08 mov %edx,0x8(%eax) + list_add(&free_list, &(p->page_link));// 将剩余块添加回空闲列表 + 102c7b: 8b 45 e8 mov -0x18(%ebp),%eax + 102c7e: 83 c0 0c add $0xc,%eax + 102c81: c7 45 d4 e0 ce 11 00 movl $0x11cee0,-0x2c(%ebp) + 102c88: 89 45 d0 mov %eax,-0x30(%ebp) + 102c8b: 8b 45 d4 mov -0x2c(%ebp),%eax + 102c8e: 89 45 cc mov %eax,-0x34(%ebp) + 102c91: 8b 45 d0 mov -0x30(%ebp),%eax + 102c94: 89 45 c8 mov %eax,-0x38(%ebp) + __list_add(elm, listelm, listelm->next); + 102c97: 8b 45 cc mov -0x34(%ebp),%eax + 102c9a: 8b 40 04 mov 0x4(%eax),%eax + 102c9d: 8b 55 c8 mov -0x38(%ebp),%edx + 102ca0: 89 55 c4 mov %edx,-0x3c(%ebp) + 102ca3: 8b 55 cc mov -0x34(%ebp),%edx + 102ca6: 89 55 c0 mov %edx,-0x40(%ebp) + 102ca9: 89 45 bc mov %eax,-0x44(%ebp) + prev->next = next->prev = elm; + 102cac: 8b 45 bc mov -0x44(%ebp),%eax + 102caf: 8b 55 c4 mov -0x3c(%ebp),%edx + 102cb2: 89 10 mov %edx,(%eax) + 102cb4: 8b 45 bc mov -0x44(%ebp),%eax + 102cb7: 8b 10 mov (%eax),%edx + 102cb9: 8b 45 c0 mov -0x40(%ebp),%eax + 102cbc: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; + 102cbf: 8b 45 c4 mov -0x3c(%ebp),%eax + 102cc2: 8b 55 bc mov -0x44(%ebp),%edx + 102cc5: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; + 102cc8: 8b 45 c4 mov -0x3c(%ebp),%eax + 102ccb: 8b 55 c0 mov -0x40(%ebp),%edx + 102cce: 89 10 mov %edx,(%eax) +} + 102cd0: 90 nop +} + 102cd1: 90 nop +} + 102cd2: 90 nop + } + nr_free -= n;// 减少空闲页的计数 + 102cd3: a1 e8 ce 11 00 mov 0x11cee8,%eax + 102cd8: 2b 45 08 sub 0x8(%ebp),%eax + 102cdb: a3 e8 ce 11 00 mov %eax,0x11cee8 + ClearPageProperty(page); // 清除已分配页的属性 + 102ce0: 8b 45 f4 mov -0xc(%ebp),%eax + 102ce3: 83 c0 04 add $0x4,%eax + 102ce6: c7 45 b8 01 00 00 00 movl $0x1,-0x48(%ebp) + 102ced: 89 45 b4 mov %eax,-0x4c(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); + 102cf0: 8b 45 b4 mov -0x4c(%ebp),%eax + 102cf3: 8b 55 b8 mov -0x48(%ebp),%edx + 102cf6: 0f b3 10 btr %edx,(%eax) +} + 102cf9: 90 nop + } + return page;// 返回分配的页块 + 102cfa: 8b 45 f4 mov -0xc(%ebp),%eax +} + 102cfd: 89 ec mov %ebp,%esp + 102cff: 5d pop %ebp + 102d00: c3 ret + +00102d01 : + +static void +default_free_pages(struct Page *base, size_t n) { + 102d01: 55 push %ebp + 102d02: 89 e5 mov %esp,%ebp + 102d04: 81 ec 98 00 00 00 sub $0x98,%esp + assert(n > 0);// 确保请求释放的页数大于零 + 102d0a: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 102d0e: 75 24 jne 102d34 + 102d10: c7 44 24 0c 90 67 10 movl $0x106790,0xc(%esp) + 102d17: 00 + 102d18: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 102d1f: 00 + 102d20: c7 44 24 04 c3 00 00 movl $0xc3,0x4(%esp) + 102d27: 00 + 102d28: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 102d2f: e8 ff de ff ff call 100c33 <__panic> + struct Page *p = base; + 102d34: 8b 45 08 mov 0x8(%ebp),%eax + 102d37: 89 45 f4 mov %eax,-0xc(%ebp) + // 遍历释放的页,检查状态并重置 + for (; p != base + n; p ++) { + 102d3a: e9 9d 00 00 00 jmp 102ddc + assert(!PageReserved(p) && !PageProperty(p)); // 确保页没有被保留并且没有属性 + 102d3f: 8b 45 f4 mov -0xc(%ebp),%eax + 102d42: 83 c0 04 add $0x4,%eax + 102d45: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp) + 102d4c: 89 45 e8 mov %eax,-0x18(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 102d4f: 8b 45 e8 mov -0x18(%ebp),%eax + 102d52: 8b 55 ec mov -0x14(%ebp),%edx + 102d55: 0f a3 10 bt %edx,(%eax) + 102d58: 19 c0 sbb %eax,%eax + 102d5a: 89 45 e4 mov %eax,-0x1c(%ebp) + return oldbit != 0; + 102d5d: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 102d61: 0f 95 c0 setne %al + 102d64: 0f b6 c0 movzbl %al,%eax + 102d67: 85 c0 test %eax,%eax + 102d69: 75 2c jne 102d97 + 102d6b: 8b 45 f4 mov -0xc(%ebp),%eax + 102d6e: 83 c0 04 add $0x4,%eax + 102d71: c7 45 e0 01 00 00 00 movl $0x1,-0x20(%ebp) + 102d78: 89 45 dc mov %eax,-0x24(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 102d7b: 8b 45 dc mov -0x24(%ebp),%eax + 102d7e: 8b 55 e0 mov -0x20(%ebp),%edx + 102d81: 0f a3 10 bt %edx,(%eax) + 102d84: 19 c0 sbb %eax,%eax + 102d86: 89 45 d8 mov %eax,-0x28(%ebp) + return oldbit != 0; + 102d89: 83 7d d8 00 cmpl $0x0,-0x28(%ebp) + 102d8d: 0f 95 c0 setne %al + 102d90: 0f b6 c0 movzbl %al,%eax + 102d93: 85 c0 test %eax,%eax + 102d95: 74 24 je 102dbb + 102d97: c7 44 24 0c d4 67 10 movl $0x1067d4,0xc(%esp) + 102d9e: 00 + 102d9f: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 102da6: 00 + 102da7: c7 44 24 04 c7 00 00 movl $0xc7,0x4(%esp) + 102dae: 00 + 102daf: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 102db6: e8 78 de ff ff call 100c33 <__panic> + p->flags = 0;// 清除 flags 字段 + 102dbb: 8b 45 f4 mov -0xc(%ebp),%eax + 102dbe: c7 40 04 00 00 00 00 movl $0x0,0x4(%eax) + set_page_ref(p, 0);// 清除引用计数 + 102dc5: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 102dcc: 00 + 102dcd: 8b 45 f4 mov -0xc(%ebp),%eax + 102dd0: 89 04 24 mov %eax,(%esp) + 102dd3: e8 0c fc ff ff call 1029e4 + for (; p != base + n; p ++) { + 102dd8: 83 45 f4 14 addl $0x14,-0xc(%ebp) + 102ddc: 8b 55 0c mov 0xc(%ebp),%edx + 102ddf: 89 d0 mov %edx,%eax + 102de1: c1 e0 02 shl $0x2,%eax + 102de4: 01 d0 add %edx,%eax + 102de6: c1 e0 02 shl $0x2,%eax + 102de9: 89 c2 mov %eax,%edx + 102deb: 8b 45 08 mov 0x8(%ebp),%eax + 102dee: 01 d0 add %edx,%eax + 102df0: 39 45 f4 cmp %eax,-0xc(%ebp) + 102df3: 0f 85 46 ff ff ff jne 102d3f + } + // 设置基页的属性为释放的页数 + base->property = n; + 102df9: 8b 45 08 mov 0x8(%ebp),%eax + 102dfc: 8b 55 0c mov 0xc(%ebp),%edx + 102dff: 89 50 08 mov %edx,0x8(%eax) + SetPageProperty(base);// 设置页的有效标志 + 102e02: 8b 45 08 mov 0x8(%ebp),%eax + 102e05: 83 c0 04 add $0x4,%eax + 102e08: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) + 102e0f: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); + 102e12: 8b 45 cc mov -0x34(%ebp),%eax + 102e15: 8b 55 d0 mov -0x30(%ebp),%edx + 102e18: 0f ab 10 bts %edx,(%eax) +} + 102e1b: 90 nop + 102e1c: c7 45 d4 e0 ce 11 00 movl $0x11cee0,-0x2c(%ebp) + return listelm->next; + 102e23: 8b 45 d4 mov -0x2c(%ebp),%eax + 102e26: 8b 40 04 mov 0x4(%eax),%eax + // 遍历空闲列表,检查是否需要合并 + list_entry_t *le = list_next(&free_list); + 102e29: 89 45 f0 mov %eax,-0x10(%ebp) + while (le != &free_list) { + 102e2c: e9 0e 01 00 00 jmp 102f3f + p = le2page(le, page_link); + 102e31: 8b 45 f0 mov -0x10(%ebp),%eax + 102e34: 83 e8 0c sub $0xc,%eax + 102e37: 89 45 f4 mov %eax,-0xc(%ebp) + 102e3a: 8b 45 f0 mov -0x10(%ebp),%eax + 102e3d: 89 45 c8 mov %eax,-0x38(%ebp) + 102e40: 8b 45 c8 mov -0x38(%ebp),%eax + 102e43: 8b 40 04 mov 0x4(%eax),%eax + le = list_next(le); + 102e46: 89 45 f0 mov %eax,-0x10(%ebp) + // 如果当前页块与释放的页块相邻,合并 + if (base + base->property == p) { + 102e49: 8b 45 08 mov 0x8(%ebp),%eax + 102e4c: 8b 50 08 mov 0x8(%eax),%edx + 102e4f: 89 d0 mov %edx,%eax + 102e51: c1 e0 02 shl $0x2,%eax + 102e54: 01 d0 add %edx,%eax + 102e56: c1 e0 02 shl $0x2,%eax + 102e59: 89 c2 mov %eax,%edx + 102e5b: 8b 45 08 mov 0x8(%ebp),%eax + 102e5e: 01 d0 add %edx,%eax + 102e60: 39 45 f4 cmp %eax,-0xc(%ebp) + 102e63: 75 5d jne 102ec2 + base->property += p->property;// 合并当前页块 + 102e65: 8b 45 08 mov 0x8(%ebp),%eax + 102e68: 8b 50 08 mov 0x8(%eax),%edx + 102e6b: 8b 45 f4 mov -0xc(%ebp),%eax + 102e6e: 8b 40 08 mov 0x8(%eax),%eax + 102e71: 01 c2 add %eax,%edx + 102e73: 8b 45 08 mov 0x8(%ebp),%eax + 102e76: 89 50 08 mov %edx,0x8(%eax) + ClearPageProperty(p);// 清除合并页的属性 + 102e79: 8b 45 f4 mov -0xc(%ebp),%eax + 102e7c: 83 c0 04 add $0x4,%eax + 102e7f: c7 45 b8 01 00 00 00 movl $0x1,-0x48(%ebp) + 102e86: 89 45 b4 mov %eax,-0x4c(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); + 102e89: 8b 45 b4 mov -0x4c(%ebp),%eax + 102e8c: 8b 55 b8 mov -0x48(%ebp),%edx + 102e8f: 0f b3 10 btr %edx,(%eax) +} + 102e92: 90 nop + list_del(&(p->page_link));// 从空闲列表中删除合并页 + 102e93: 8b 45 f4 mov -0xc(%ebp),%eax + 102e96: 83 c0 0c add $0xc,%eax + 102e99: 89 45 c4 mov %eax,-0x3c(%ebp) + __list_del(listelm->prev, listelm->next); + 102e9c: 8b 45 c4 mov -0x3c(%ebp),%eax + 102e9f: 8b 40 04 mov 0x4(%eax),%eax + 102ea2: 8b 55 c4 mov -0x3c(%ebp),%edx + 102ea5: 8b 12 mov (%edx),%edx + 102ea7: 89 55 c0 mov %edx,-0x40(%ebp) + 102eaa: 89 45 bc mov %eax,-0x44(%ebp) + prev->next = next; + 102ead: 8b 45 c0 mov -0x40(%ebp),%eax + 102eb0: 8b 55 bc mov -0x44(%ebp),%edx + 102eb3: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; + 102eb6: 8b 45 bc mov -0x44(%ebp),%eax + 102eb9: 8b 55 c0 mov -0x40(%ebp),%edx + 102ebc: 89 10 mov %edx,(%eax) +} + 102ebe: 90 nop +} + 102ebf: 90 nop + 102ec0: eb 7d jmp 102f3f + } + else if (p + p->property == base) { + 102ec2: 8b 45 f4 mov -0xc(%ebp),%eax + 102ec5: 8b 50 08 mov 0x8(%eax),%edx + 102ec8: 89 d0 mov %edx,%eax + 102eca: c1 e0 02 shl $0x2,%eax + 102ecd: 01 d0 add %edx,%eax + 102ecf: c1 e0 02 shl $0x2,%eax + 102ed2: 89 c2 mov %eax,%edx + 102ed4: 8b 45 f4 mov -0xc(%ebp),%eax + 102ed7: 01 d0 add %edx,%eax + 102ed9: 39 45 08 cmp %eax,0x8(%ebp) + 102edc: 75 61 jne 102f3f + p->property += base->property;// 合并前一个页块 + 102ede: 8b 45 f4 mov -0xc(%ebp),%eax + 102ee1: 8b 50 08 mov 0x8(%eax),%edx + 102ee4: 8b 45 08 mov 0x8(%ebp),%eax + 102ee7: 8b 40 08 mov 0x8(%eax),%eax + 102eea: 01 c2 add %eax,%edx + 102eec: 8b 45 f4 mov -0xc(%ebp),%eax + 102eef: 89 50 08 mov %edx,0x8(%eax) + ClearPageProperty(base);// 清除当前页的属性 + 102ef2: 8b 45 08 mov 0x8(%ebp),%eax + 102ef5: 83 c0 04 add $0x4,%eax + 102ef8: c7 45 a4 01 00 00 00 movl $0x1,-0x5c(%ebp) + 102eff: 89 45 a0 mov %eax,-0x60(%ebp) + asm volatile ("btrl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); + 102f02: 8b 45 a0 mov -0x60(%ebp),%eax + 102f05: 8b 55 a4 mov -0x5c(%ebp),%edx + 102f08: 0f b3 10 btr %edx,(%eax) +} + 102f0b: 90 nop + base = p;// 更新 base 指针 + 102f0c: 8b 45 f4 mov -0xc(%ebp),%eax + 102f0f: 89 45 08 mov %eax,0x8(%ebp) + list_del(&(p->page_link)); // 从空闲列表中删除当前页 + 102f12: 8b 45 f4 mov -0xc(%ebp),%eax + 102f15: 83 c0 0c add $0xc,%eax + 102f18: 89 45 b0 mov %eax,-0x50(%ebp) + __list_del(listelm->prev, listelm->next); + 102f1b: 8b 45 b0 mov -0x50(%ebp),%eax + 102f1e: 8b 40 04 mov 0x4(%eax),%eax + 102f21: 8b 55 b0 mov -0x50(%ebp),%edx + 102f24: 8b 12 mov (%edx),%edx + 102f26: 89 55 ac mov %edx,-0x54(%ebp) + 102f29: 89 45 a8 mov %eax,-0x58(%ebp) + prev->next = next; + 102f2c: 8b 45 ac mov -0x54(%ebp),%eax + 102f2f: 8b 55 a8 mov -0x58(%ebp),%edx + 102f32: 89 50 04 mov %edx,0x4(%eax) + next->prev = prev; + 102f35: 8b 45 a8 mov -0x58(%ebp),%eax + 102f38: 8b 55 ac mov -0x54(%ebp),%edx + 102f3b: 89 10 mov %edx,(%eax) +} + 102f3d: 90 nop +} + 102f3e: 90 nop + while (le != &free_list) { + 102f3f: 81 7d f0 e0 ce 11 00 cmpl $0x11cee0,-0x10(%ebp) + 102f46: 0f 85 e5 fe ff ff jne 102e31 + } + } + nr_free += n;// 更新空闲页的计数 + 102f4c: 8b 15 e8 ce 11 00 mov 0x11cee8,%edx + 102f52: 8b 45 0c mov 0xc(%ebp),%eax + 102f55: 01 d0 add %edx,%eax + 102f57: a3 e8 ce 11 00 mov %eax,0x11cee8 + list_add(&free_list, &(base->page_link));// 将释放的页块添加到空闲列表中 + 102f5c: 8b 45 08 mov 0x8(%ebp),%eax + 102f5f: 83 c0 0c add $0xc,%eax + 102f62: c7 45 9c e0 ce 11 00 movl $0x11cee0,-0x64(%ebp) + 102f69: 89 45 98 mov %eax,-0x68(%ebp) + 102f6c: 8b 45 9c mov -0x64(%ebp),%eax + 102f6f: 89 45 94 mov %eax,-0x6c(%ebp) + 102f72: 8b 45 98 mov -0x68(%ebp),%eax + 102f75: 89 45 90 mov %eax,-0x70(%ebp) + __list_add(elm, listelm, listelm->next); + 102f78: 8b 45 94 mov -0x6c(%ebp),%eax + 102f7b: 8b 40 04 mov 0x4(%eax),%eax + 102f7e: 8b 55 90 mov -0x70(%ebp),%edx + 102f81: 89 55 8c mov %edx,-0x74(%ebp) + 102f84: 8b 55 94 mov -0x6c(%ebp),%edx + 102f87: 89 55 88 mov %edx,-0x78(%ebp) + 102f8a: 89 45 84 mov %eax,-0x7c(%ebp) + prev->next = next->prev = elm; + 102f8d: 8b 45 84 mov -0x7c(%ebp),%eax + 102f90: 8b 55 8c mov -0x74(%ebp),%edx + 102f93: 89 10 mov %edx,(%eax) + 102f95: 8b 45 84 mov -0x7c(%ebp),%eax + 102f98: 8b 10 mov (%eax),%edx + 102f9a: 8b 45 88 mov -0x78(%ebp),%eax + 102f9d: 89 50 04 mov %edx,0x4(%eax) + elm->next = next; + 102fa0: 8b 45 8c mov -0x74(%ebp),%eax + 102fa3: 8b 55 84 mov -0x7c(%ebp),%edx + 102fa6: 89 50 04 mov %edx,0x4(%eax) + elm->prev = prev; + 102fa9: 8b 45 8c mov -0x74(%ebp),%eax + 102fac: 8b 55 88 mov -0x78(%ebp),%edx + 102faf: 89 10 mov %edx,(%eax) +} + 102fb1: 90 nop +} + 102fb2: 90 nop +} + 102fb3: 90 nop +} + 102fb4: 90 nop + 102fb5: 89 ec mov %ebp,%esp + 102fb7: 5d pop %ebp + 102fb8: c3 ret + +00102fb9 : + +//用于返回当前系统中可用的空闲页的数量。 +static size_t +default_nr_free_pages(void) { + 102fb9: 55 push %ebp + 102fba: 89 e5 mov %esp,%ebp + return nr_free;// 返回当前空闲页的数量 + 102fbc: a1 e8 ce 11 00 mov 0x11cee8,%eax +} + 102fc1: 5d pop %ebp + 102fc2: c3 ret + +00102fc3 : + +//basic_check 函数用于测试内存分配和释放的基本功能, +//确保在不同情况下内存管理系统的正确性,包括分配、释放、合并和引用计数等操作。 +static void +basic_check(void) { + 102fc3: 55 push %ebp + 102fc4: 89 e5 mov %esp,%ebp + 102fc6: 83 ec 48 sub $0x48,%esp + struct Page *p0, *p1, *p2; + p0 = p1 = p2 = NULL; + 102fc9: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 102fd0: 8b 45 f4 mov -0xc(%ebp),%eax + 102fd3: 89 45 f0 mov %eax,-0x10(%ebp) + 102fd6: 8b 45 f0 mov -0x10(%ebp),%eax + 102fd9: 89 45 ec mov %eax,-0x14(%ebp) + // 分配三个页面 + assert((p0 = alloc_page()) != NULL); + 102fdc: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 102fe3: e8 ed 0e 00 00 call 103ed5 + 102fe8: 89 45 ec mov %eax,-0x14(%ebp) + 102feb: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) + 102fef: 75 24 jne 103015 + 102ff1: c7 44 24 0c f9 67 10 movl $0x1067f9,0xc(%esp) + 102ff8: 00 + 102ff9: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103000: 00 + 103001: c7 44 24 04 f1 00 00 movl $0xf1,0x4(%esp) + 103008: 00 + 103009: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103010: e8 1e dc ff ff call 100c33 <__panic> + assert((p1 = alloc_page()) != NULL); + 103015: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 10301c: e8 b4 0e 00 00 call 103ed5 + 103021: 89 45 f0 mov %eax,-0x10(%ebp) + 103024: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 103028: 75 24 jne 10304e + 10302a: c7 44 24 0c 15 68 10 movl $0x106815,0xc(%esp) + 103031: 00 + 103032: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103039: 00 + 10303a: c7 44 24 04 f2 00 00 movl $0xf2,0x4(%esp) + 103041: 00 + 103042: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103049: e8 e5 db ff ff call 100c33 <__panic> + assert((p2 = alloc_page()) != NULL); + 10304e: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103055: e8 7b 0e 00 00 call 103ed5 + 10305a: 89 45 f4 mov %eax,-0xc(%ebp) + 10305d: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 103061: 75 24 jne 103087 + 103063: c7 44 24 0c 31 68 10 movl $0x106831,0xc(%esp) + 10306a: 00 + 10306b: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103072: 00 + 103073: c7 44 24 04 f3 00 00 movl $0xf3,0x4(%esp) + 10307a: 00 + 10307b: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103082: e8 ac db ff ff call 100c33 <__panic> + // 确保所有分配的页面是不同的 + assert(p0 != p1 && p0 != p2 && p1 != p2); + 103087: 8b 45 ec mov -0x14(%ebp),%eax + 10308a: 3b 45 f0 cmp -0x10(%ebp),%eax + 10308d: 74 10 je 10309f + 10308f: 8b 45 ec mov -0x14(%ebp),%eax + 103092: 3b 45 f4 cmp -0xc(%ebp),%eax + 103095: 74 08 je 10309f + 103097: 8b 45 f0 mov -0x10(%ebp),%eax + 10309a: 3b 45 f4 cmp -0xc(%ebp),%eax + 10309d: 75 24 jne 1030c3 + 10309f: c7 44 24 0c 50 68 10 movl $0x106850,0xc(%esp) + 1030a6: 00 + 1030a7: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1030ae: 00 + 1030af: c7 44 24 04 f5 00 00 movl $0xf5,0x4(%esp) + 1030b6: 00 + 1030b7: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1030be: e8 70 db ff ff call 100c33 <__panic> + // 确保页面的引用计数为 0 + assert(page_ref(p0) == 0 && page_ref(p1) == 0 && page_ref(p2) == 0); + 1030c3: 8b 45 ec mov -0x14(%ebp),%eax + 1030c6: 89 04 24 mov %eax,(%esp) + 1030c9: e8 0c f9 ff ff call 1029da + 1030ce: 85 c0 test %eax,%eax + 1030d0: 75 1e jne 1030f0 + 1030d2: 8b 45 f0 mov -0x10(%ebp),%eax + 1030d5: 89 04 24 mov %eax,(%esp) + 1030d8: e8 fd f8 ff ff call 1029da + 1030dd: 85 c0 test %eax,%eax + 1030df: 75 0f jne 1030f0 + 1030e1: 8b 45 f4 mov -0xc(%ebp),%eax + 1030e4: 89 04 24 mov %eax,(%esp) + 1030e7: e8 ee f8 ff ff call 1029da + 1030ec: 85 c0 test %eax,%eax + 1030ee: 74 24 je 103114 + 1030f0: c7 44 24 0c 74 68 10 movl $0x106874,0xc(%esp) + 1030f7: 00 + 1030f8: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1030ff: 00 + 103100: c7 44 24 04 f7 00 00 movl $0xf7,0x4(%esp) + 103107: 00 + 103108: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10310f: e8 1f db ff ff call 100c33 <__panic> + // 确保页面地址在合法范围内 + assert(page2pa(p0) < npage * PGSIZE); + 103114: 8b 45 ec mov -0x14(%ebp),%eax + 103117: 89 04 24 mov %eax,(%esp) + 10311a: e8 a3 f8 ff ff call 1029c2 + 10311f: 8b 15 04 cf 11 00 mov 0x11cf04,%edx + 103125: c1 e2 0c shl $0xc,%edx + 103128: 39 d0 cmp %edx,%eax + 10312a: 72 24 jb 103150 + 10312c: c7 44 24 0c b0 68 10 movl $0x1068b0,0xc(%esp) + 103133: 00 + 103134: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10313b: 00 + 10313c: c7 44 24 04 f9 00 00 movl $0xf9,0x4(%esp) + 103143: 00 + 103144: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10314b: e8 e3 da ff ff call 100c33 <__panic> + assert(page2pa(p1) < npage * PGSIZE); + 103150: 8b 45 f0 mov -0x10(%ebp),%eax + 103153: 89 04 24 mov %eax,(%esp) + 103156: e8 67 f8 ff ff call 1029c2 + 10315b: 8b 15 04 cf 11 00 mov 0x11cf04,%edx + 103161: c1 e2 0c shl $0xc,%edx + 103164: 39 d0 cmp %edx,%eax + 103166: 72 24 jb 10318c + 103168: c7 44 24 0c cd 68 10 movl $0x1068cd,0xc(%esp) + 10316f: 00 + 103170: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103177: 00 + 103178: c7 44 24 04 fa 00 00 movl $0xfa,0x4(%esp) + 10317f: 00 + 103180: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103187: e8 a7 da ff ff call 100c33 <__panic> + assert(page2pa(p2) < npage * PGSIZE); + 10318c: 8b 45 f4 mov -0xc(%ebp),%eax + 10318f: 89 04 24 mov %eax,(%esp) + 103192: e8 2b f8 ff ff call 1029c2 + 103197: 8b 15 04 cf 11 00 mov 0x11cf04,%edx + 10319d: c1 e2 0c shl $0xc,%edx + 1031a0: 39 d0 cmp %edx,%eax + 1031a2: 72 24 jb 1031c8 + 1031a4: c7 44 24 0c ea 68 10 movl $0x1068ea,0xc(%esp) + 1031ab: 00 + 1031ac: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1031b3: 00 + 1031b4: c7 44 24 04 fb 00 00 movl $0xfb,0x4(%esp) + 1031bb: 00 + 1031bc: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1031c3: e8 6b da ff ff call 100c33 <__panic> + // 保存当前的空闲页面链表和数量 + list_entry_t free_list_store = free_list; + 1031c8: a1 e0 ce 11 00 mov 0x11cee0,%eax + 1031cd: 8b 15 e4 ce 11 00 mov 0x11cee4,%edx + 1031d3: 89 45 d0 mov %eax,-0x30(%ebp) + 1031d6: 89 55 d4 mov %edx,-0x2c(%ebp) + 1031d9: c7 45 dc e0 ce 11 00 movl $0x11cee0,-0x24(%ebp) + elm->prev = elm->next = elm; + 1031e0: 8b 45 dc mov -0x24(%ebp),%eax + 1031e3: 8b 55 dc mov -0x24(%ebp),%edx + 1031e6: 89 50 04 mov %edx,0x4(%eax) + 1031e9: 8b 45 dc mov -0x24(%ebp),%eax + 1031ec: 8b 50 04 mov 0x4(%eax),%edx + 1031ef: 8b 45 dc mov -0x24(%ebp),%eax + 1031f2: 89 10 mov %edx,(%eax) +} + 1031f4: 90 nop + 1031f5: c7 45 e0 e0 ce 11 00 movl $0x11cee0,-0x20(%ebp) + return list->next == list; + 1031fc: 8b 45 e0 mov -0x20(%ebp),%eax + 1031ff: 8b 40 04 mov 0x4(%eax),%eax + 103202: 39 45 e0 cmp %eax,-0x20(%ebp) + 103205: 0f 94 c0 sete %al + 103208: 0f b6 c0 movzbl %al,%eax + list_init(&free_list);// 初始化空闲列表 + assert(list_empty(&free_list));// 确保空闲列表为空 + 10320b: 85 c0 test %eax,%eax + 10320d: 75 24 jne 103233 + 10320f: c7 44 24 0c 07 69 10 movl $0x106907,0xc(%esp) + 103216: 00 + 103217: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10321e: 00 + 10321f: c7 44 24 04 ff 00 00 movl $0xff,0x4(%esp) + 103226: 00 + 103227: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10322e: e8 00 da ff ff call 100c33 <__panic> + + unsigned int nr_free_store = nr_free;// 保存当前空闲页数量 + 103233: a1 e8 ce 11 00 mov 0x11cee8,%eax + 103238: 89 45 e8 mov %eax,-0x18(%ebp) + nr_free = 0;// 将空闲页数量设为 0 + 10323b: c7 05 e8 ce 11 00 00 movl $0x0,0x11cee8 + 103242: 00 00 00 + // 请求分配页面,但当前没有空闲页面 + assert(alloc_page() == NULL); + 103245: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 10324c: e8 84 0c 00 00 call 103ed5 + 103251: 85 c0 test %eax,%eax + 103253: 74 24 je 103279 + 103255: c7 44 24 0c 1e 69 10 movl $0x10691e,0xc(%esp) + 10325c: 00 + 10325d: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103264: 00 + 103265: c7 44 24 04 04 01 00 movl $0x104,0x4(%esp) + 10326c: 00 + 10326d: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103274: e8 ba d9 ff ff call 100c33 <__panic> + // 释放之前分配的页面 + free_page(p0); + 103279: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 103280: 00 + 103281: 8b 45 ec mov -0x14(%ebp),%eax + 103284: 89 04 24 mov %eax,(%esp) + 103287: e8 83 0c 00 00 call 103f0f + free_page(p1); + 10328c: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 103293: 00 + 103294: 8b 45 f0 mov -0x10(%ebp),%eax + 103297: 89 04 24 mov %eax,(%esp) + 10329a: e8 70 0c 00 00 call 103f0f + free_page(p2); + 10329f: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1032a6: 00 + 1032a7: 8b 45 f4 mov -0xc(%ebp),%eax + 1032aa: 89 04 24 mov %eax,(%esp) + 1032ad: e8 5d 0c 00 00 call 103f0f + assert(nr_free == 3);// 确保释放后空闲页数量为 3 + 1032b2: a1 e8 ce 11 00 mov 0x11cee8,%eax + 1032b7: 83 f8 03 cmp $0x3,%eax + 1032ba: 74 24 je 1032e0 + 1032bc: c7 44 24 0c 33 69 10 movl $0x106933,0xc(%esp) + 1032c3: 00 + 1032c4: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1032cb: 00 + 1032cc: c7 44 24 04 09 01 00 movl $0x109,0x4(%esp) + 1032d3: 00 + 1032d4: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1032db: e8 53 d9 ff ff call 100c33 <__panic> + // 再次分配三个页面 + assert((p0 = alloc_page()) != NULL); + 1032e0: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 1032e7: e8 e9 0b 00 00 call 103ed5 + 1032ec: 89 45 ec mov %eax,-0x14(%ebp) + 1032ef: 83 7d ec 00 cmpl $0x0,-0x14(%ebp) + 1032f3: 75 24 jne 103319 + 1032f5: c7 44 24 0c f9 67 10 movl $0x1067f9,0xc(%esp) + 1032fc: 00 + 1032fd: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103304: 00 + 103305: c7 44 24 04 0b 01 00 movl $0x10b,0x4(%esp) + 10330c: 00 + 10330d: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103314: e8 1a d9 ff ff call 100c33 <__panic> + assert((p1 = alloc_page()) != NULL); + 103319: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103320: e8 b0 0b 00 00 call 103ed5 + 103325: 89 45 f0 mov %eax,-0x10(%ebp) + 103328: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 10332c: 75 24 jne 103352 + 10332e: c7 44 24 0c 15 68 10 movl $0x106815,0xc(%esp) + 103335: 00 + 103336: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10333d: 00 + 10333e: c7 44 24 04 0c 01 00 movl $0x10c,0x4(%esp) + 103345: 00 + 103346: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10334d: e8 e1 d8 ff ff call 100c33 <__panic> + assert((p2 = alloc_page()) != NULL); + 103352: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103359: e8 77 0b 00 00 call 103ed5 + 10335e: 89 45 f4 mov %eax,-0xc(%ebp) + 103361: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 103365: 75 24 jne 10338b + 103367: c7 44 24 0c 31 68 10 movl $0x106831,0xc(%esp) + 10336e: 00 + 10336f: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103376: 00 + 103377: c7 44 24 04 0d 01 00 movl $0x10d,0x4(%esp) + 10337e: 00 + 10337f: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103386: e8 a8 d8 ff ff call 100c33 <__panic> +// 测试空闲页面是否不足 + assert(alloc_page() == NULL); + 10338b: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103392: e8 3e 0b 00 00 call 103ed5 + 103397: 85 c0 test %eax,%eax + 103399: 74 24 je 1033bf + 10339b: c7 44 24 0c 1e 69 10 movl $0x10691e,0xc(%esp) + 1033a2: 00 + 1033a3: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1033aa: 00 + 1033ab: c7 44 24 04 0f 01 00 movl $0x10f,0x4(%esp) + 1033b2: 00 + 1033b3: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1033ba: e8 74 d8 ff ff call 100c33 <__panic> +// 释放 p0,并检查空闲列表 + free_page(p0); + 1033bf: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1033c6: 00 + 1033c7: 8b 45 ec mov -0x14(%ebp),%eax + 1033ca: 89 04 24 mov %eax,(%esp) + 1033cd: e8 3d 0b 00 00 call 103f0f + 1033d2: c7 45 d8 e0 ce 11 00 movl $0x11cee0,-0x28(%ebp) + 1033d9: 8b 45 d8 mov -0x28(%ebp),%eax + 1033dc: 8b 40 04 mov 0x4(%eax),%eax + 1033df: 39 45 d8 cmp %eax,-0x28(%ebp) + 1033e2: 0f 94 c0 sete %al + 1033e5: 0f b6 c0 movzbl %al,%eax + assert(!list_empty(&free_list));// 确保空闲列表不为空 + 1033e8: 85 c0 test %eax,%eax + 1033ea: 74 24 je 103410 + 1033ec: c7 44 24 0c 40 69 10 movl $0x106940,0xc(%esp) + 1033f3: 00 + 1033f4: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1033fb: 00 + 1033fc: c7 44 24 04 12 01 00 movl $0x112,0x4(%esp) + 103403: 00 + 103404: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10340b: e8 23 d8 ff ff call 100c33 <__panic> + + struct Page *p; + // 重新分配 p0,确保取回的是相同的页面 + assert((p = alloc_page()) == p0); + 103410: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103417: e8 b9 0a 00 00 call 103ed5 + 10341c: 89 45 e4 mov %eax,-0x1c(%ebp) + 10341f: 8b 45 e4 mov -0x1c(%ebp),%eax + 103422: 3b 45 ec cmp -0x14(%ebp),%eax + 103425: 74 24 je 10344b + 103427: c7 44 24 0c 58 69 10 movl $0x106958,0xc(%esp) + 10342e: 00 + 10342f: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103436: 00 + 103437: c7 44 24 04 16 01 00 movl $0x116,0x4(%esp) + 10343e: 00 + 10343f: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103446: e8 e8 d7 ff ff call 100c33 <__panic> + assert(alloc_page() == NULL); // 确保没有更多的页面可分配 + 10344b: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103452: e8 7e 0a 00 00 call 103ed5 + 103457: 85 c0 test %eax,%eax + 103459: 74 24 je 10347f + 10345b: c7 44 24 0c 1e 69 10 movl $0x10691e,0xc(%esp) + 103462: 00 + 103463: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10346a: 00 + 10346b: c7 44 24 04 17 01 00 movl $0x117,0x4(%esp) + 103472: 00 + 103473: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10347a: e8 b4 d7 ff ff call 100c33 <__panic> + + assert(nr_free == 0);// 确保当前空闲页面数量为 0 + 10347f: a1 e8 ce 11 00 mov 0x11cee8,%eax + 103484: 85 c0 test %eax,%eax + 103486: 74 24 je 1034ac + 103488: c7 44 24 0c 71 69 10 movl $0x106971,0xc(%esp) + 10348f: 00 + 103490: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103497: 00 + 103498: c7 44 24 04 19 01 00 movl $0x119,0x4(%esp) + 10349f: 00 + 1034a0: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1034a7: e8 87 d7 ff ff call 100c33 <__panic> + // 恢复之前的空闲页面链表和数量 + free_list = free_list_store; + 1034ac: 8b 45 d0 mov -0x30(%ebp),%eax + 1034af: 8b 55 d4 mov -0x2c(%ebp),%edx + 1034b2: a3 e0 ce 11 00 mov %eax,0x11cee0 + 1034b7: 89 15 e4 ce 11 00 mov %edx,0x11cee4 + nr_free = nr_free_store; + 1034bd: 8b 45 e8 mov -0x18(%ebp),%eax + 1034c0: a3 e8 ce 11 00 mov %eax,0x11cee8 + // 释放最后的页面 + free_page(p); + 1034c5: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1034cc: 00 + 1034cd: 8b 45 e4 mov -0x1c(%ebp),%eax + 1034d0: 89 04 24 mov %eax,(%esp) + 1034d3: e8 37 0a 00 00 call 103f0f + free_page(p1); + 1034d8: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1034df: 00 + 1034e0: 8b 45 f0 mov -0x10(%ebp),%eax + 1034e3: 89 04 24 mov %eax,(%esp) + 1034e6: e8 24 0a 00 00 call 103f0f + free_page(p2); + 1034eb: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1034f2: 00 + 1034f3: 8b 45 f4 mov -0xc(%ebp),%eax + 1034f6: 89 04 24 mov %eax,(%esp) + 1034f9: e8 11 0a 00 00 call 103f0f +} + 1034fe: 90 nop + 1034ff: 89 ec mov %ebp,%esp + 103501: 5d pop %ebp + 103502: c3 ret + +00103503 : + +// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) +// NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions! +static void +default_check(void) { + 103503: 55 push %ebp + 103504: 89 e5 mov %esp,%ebp + 103506: 81 ec 98 00 00 00 sub $0x98,%esp + int count = 0, total = 0; + 10350c: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 103513: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) + list_entry_t *le = &free_list; + 10351a: c7 45 ec e0 ce 11 00 movl $0x11cee0,-0x14(%ebp) + // 遍历空闲列表,计算空闲页面的数量和总属性值 + while ((le = list_next(le)) != &free_list) { + 103521: eb 6a jmp 10358d + struct Page *p = le2page(le, page_link); + 103523: 8b 45 ec mov -0x14(%ebp),%eax + 103526: 83 e8 0c sub $0xc,%eax + 103529: 89 45 d4 mov %eax,-0x2c(%ebp) + assert(PageProperty(p));// 确保每个页面的属性是有效的 + 10352c: 8b 45 d4 mov -0x2c(%ebp),%eax + 10352f: 83 c0 04 add $0x4,%eax + 103532: c7 45 d0 01 00 00 00 movl $0x1,-0x30(%ebp) + 103539: 89 45 cc mov %eax,-0x34(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 10353c: 8b 45 cc mov -0x34(%ebp),%eax + 10353f: 8b 55 d0 mov -0x30(%ebp),%edx + 103542: 0f a3 10 bt %edx,(%eax) + 103545: 19 c0 sbb %eax,%eax + 103547: 89 45 c8 mov %eax,-0x38(%ebp) + return oldbit != 0; + 10354a: 83 7d c8 00 cmpl $0x0,-0x38(%ebp) + 10354e: 0f 95 c0 setne %al + 103551: 0f b6 c0 movzbl %al,%eax + 103554: 85 c0 test %eax,%eax + 103556: 75 24 jne 10357c + 103558: c7 44 24 0c 7e 69 10 movl $0x10697e,0xc(%esp) + 10355f: 00 + 103560: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103567: 00 + 103568: c7 44 24 04 2c 01 00 movl $0x12c,0x4(%esp) + 10356f: 00 + 103570: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103577: e8 b7 d6 ff ff call 100c33 <__panic> + count ++, total += p->property;// 累加页面属性 + 10357c: ff 45 f4 incl -0xc(%ebp) + 10357f: 8b 45 d4 mov -0x2c(%ebp),%eax + 103582: 8b 50 08 mov 0x8(%eax),%edx + 103585: 8b 45 f0 mov -0x10(%ebp),%eax + 103588: 01 d0 add %edx,%eax + 10358a: 89 45 f0 mov %eax,-0x10(%ebp) + 10358d: 8b 45 ec mov -0x14(%ebp),%eax + 103590: 89 45 c4 mov %eax,-0x3c(%ebp) + return listelm->next; + 103593: 8b 45 c4 mov -0x3c(%ebp),%eax + 103596: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { + 103599: 89 45 ec mov %eax,-0x14(%ebp) + 10359c: 81 7d ec e0 ce 11 00 cmpl $0x11cee0,-0x14(%ebp) + 1035a3: 0f 85 7a ff ff ff jne 103523 + } + // 确保总属性值与空闲页面数量匹配 + assert(total == nr_free_pages()); + 1035a9: e8 96 09 00 00 call 103f44 + 1035ae: 8b 55 f0 mov -0x10(%ebp),%edx + 1035b1: 39 d0 cmp %edx,%eax + 1035b3: 74 24 je 1035d9 + 1035b5: c7 44 24 0c 8e 69 10 movl $0x10698e,0xc(%esp) + 1035bc: 00 + 1035bd: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1035c4: 00 + 1035c5: c7 44 24 04 30 01 00 movl $0x130,0x4(%esp) + 1035cc: 00 + 1035cd: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1035d4: e8 5a d6 ff ff call 100c33 <__panic> + // 调用 basic_check 以验证基本的内存管理功能 + basic_check(); + 1035d9: e8 e5 f9 ff ff call 102fc3 + // 分配 5 个页面 + struct Page *p0 = alloc_pages(5), *p1, *p2; + 1035de: c7 04 24 05 00 00 00 movl $0x5,(%esp) + 1035e5: e8 eb 08 00 00 call 103ed5 + 1035ea: 89 45 e8 mov %eax,-0x18(%ebp) + assert(p0 != NULL);// 确保成功分配 + 1035ed: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 1035f1: 75 24 jne 103617 + 1035f3: c7 44 24 0c a7 69 10 movl $0x1069a7,0xc(%esp) + 1035fa: 00 + 1035fb: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103602: 00 + 103603: c7 44 24 04 35 01 00 movl $0x135,0x4(%esp) + 10360a: 00 + 10360b: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103612: e8 1c d6 ff ff call 100c33 <__panic> + assert(!PageProperty(p0));// 确保分配的页面不带属性 + 103617: 8b 45 e8 mov -0x18(%ebp),%eax + 10361a: 83 c0 04 add $0x4,%eax + 10361d: c7 45 c0 01 00 00 00 movl $0x1,-0x40(%ebp) + 103624: 89 45 bc mov %eax,-0x44(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 103627: 8b 45 bc mov -0x44(%ebp),%eax + 10362a: 8b 55 c0 mov -0x40(%ebp),%edx + 10362d: 0f a3 10 bt %edx,(%eax) + 103630: 19 c0 sbb %eax,%eax + 103632: 89 45 b8 mov %eax,-0x48(%ebp) + return oldbit != 0; + 103635: 83 7d b8 00 cmpl $0x0,-0x48(%ebp) + 103639: 0f 95 c0 setne %al + 10363c: 0f b6 c0 movzbl %al,%eax + 10363f: 85 c0 test %eax,%eax + 103641: 74 24 je 103667 + 103643: c7 44 24 0c b2 69 10 movl $0x1069b2,0xc(%esp) + 10364a: 00 + 10364b: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103652: 00 + 103653: c7 44 24 04 36 01 00 movl $0x136,0x4(%esp) + 10365a: 00 + 10365b: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103662: e8 cc d5 ff ff call 100c33 <__panic> + // 初始化并检查空闲列表 + list_entry_t free_list_store = free_list; + 103667: a1 e0 ce 11 00 mov 0x11cee0,%eax + 10366c: 8b 15 e4 ce 11 00 mov 0x11cee4,%edx + 103672: 89 45 80 mov %eax,-0x80(%ebp) + 103675: 89 55 84 mov %edx,-0x7c(%ebp) + 103678: c7 45 b0 e0 ce 11 00 movl $0x11cee0,-0x50(%ebp) + elm->prev = elm->next = elm; + 10367f: 8b 45 b0 mov -0x50(%ebp),%eax + 103682: 8b 55 b0 mov -0x50(%ebp),%edx + 103685: 89 50 04 mov %edx,0x4(%eax) + 103688: 8b 45 b0 mov -0x50(%ebp),%eax + 10368b: 8b 50 04 mov 0x4(%eax),%edx + 10368e: 8b 45 b0 mov -0x50(%ebp),%eax + 103691: 89 10 mov %edx,(%eax) +} + 103693: 90 nop + 103694: c7 45 b4 e0 ce 11 00 movl $0x11cee0,-0x4c(%ebp) + return list->next == list; + 10369b: 8b 45 b4 mov -0x4c(%ebp),%eax + 10369e: 8b 40 04 mov 0x4(%eax),%eax + 1036a1: 39 45 b4 cmp %eax,-0x4c(%ebp) + 1036a4: 0f 94 c0 sete %al + 1036a7: 0f b6 c0 movzbl %al,%eax + list_init(&free_list); + assert(list_empty(&free_list));// 确保空闲列表为空 + 1036aa: 85 c0 test %eax,%eax + 1036ac: 75 24 jne 1036d2 + 1036ae: c7 44 24 0c 07 69 10 movl $0x106907,0xc(%esp) + 1036b5: 00 + 1036b6: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1036bd: 00 + 1036be: c7 44 24 04 3a 01 00 movl $0x13a,0x4(%esp) + 1036c5: 00 + 1036c6: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1036cd: e8 61 d5 ff ff call 100c33 <__panic> + assert(alloc_page() == NULL);// 确保没有页面可分配 + 1036d2: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 1036d9: e8 f7 07 00 00 call 103ed5 + 1036de: 85 c0 test %eax,%eax + 1036e0: 74 24 je 103706 + 1036e2: c7 44 24 0c 1e 69 10 movl $0x10691e,0xc(%esp) + 1036e9: 00 + 1036ea: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1036f1: 00 + 1036f2: c7 44 24 04 3b 01 00 movl $0x13b,0x4(%esp) + 1036f9: 00 + 1036fa: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103701: e8 2d d5 ff ff call 100c33 <__panic> + + unsigned int nr_free_store = nr_free;// 保存当前空闲页数 + 103706: a1 e8 ce 11 00 mov 0x11cee8,%eax + 10370b: 89 45 e4 mov %eax,-0x1c(%ebp) + nr_free = 0;// 将空闲页数设为 0 + 10370e: c7 05 e8 ce 11 00 00 movl $0x0,0x11cee8 + 103715: 00 00 00 +// 释放 3 个页面并确保分配页面时没有足够的空闲页 + free_pages(p0 + 2, 3); + 103718: 8b 45 e8 mov -0x18(%ebp),%eax + 10371b: 83 c0 28 add $0x28,%eax + 10371e: c7 44 24 04 03 00 00 movl $0x3,0x4(%esp) + 103725: 00 + 103726: 89 04 24 mov %eax,(%esp) + 103729: e8 e1 07 00 00 call 103f0f + assert(alloc_pages(4) == NULL);// 确保无法分配 4 个页面 + 10372e: c7 04 24 04 00 00 00 movl $0x4,(%esp) + 103735: e8 9b 07 00 00 call 103ed5 + 10373a: 85 c0 test %eax,%eax + 10373c: 74 24 je 103762 + 10373e: c7 44 24 0c c4 69 10 movl $0x1069c4,0xc(%esp) + 103745: 00 + 103746: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10374d: 00 + 10374e: c7 44 24 04 41 01 00 movl $0x141,0x4(%esp) + 103755: 00 + 103756: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10375d: e8 d1 d4 ff ff call 100c33 <__panic> + assert(PageProperty(p0 + 2) && p0[2].property == 3);// 检查页面属性 + 103762: 8b 45 e8 mov -0x18(%ebp),%eax + 103765: 83 c0 28 add $0x28,%eax + 103768: 83 c0 04 add $0x4,%eax + 10376b: c7 45 ac 01 00 00 00 movl $0x1,-0x54(%ebp) + 103772: 89 45 a8 mov %eax,-0x58(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 103775: 8b 45 a8 mov -0x58(%ebp),%eax + 103778: 8b 55 ac mov -0x54(%ebp),%edx + 10377b: 0f a3 10 bt %edx,(%eax) + 10377e: 19 c0 sbb %eax,%eax + 103780: 89 45 a4 mov %eax,-0x5c(%ebp) + return oldbit != 0; + 103783: 83 7d a4 00 cmpl $0x0,-0x5c(%ebp) + 103787: 0f 95 c0 setne %al + 10378a: 0f b6 c0 movzbl %al,%eax + 10378d: 85 c0 test %eax,%eax + 10378f: 74 0e je 10379f + 103791: 8b 45 e8 mov -0x18(%ebp),%eax + 103794: 83 c0 28 add $0x28,%eax + 103797: 8b 40 08 mov 0x8(%eax),%eax + 10379a: 83 f8 03 cmp $0x3,%eax + 10379d: 74 24 je 1037c3 + 10379f: c7 44 24 0c dc 69 10 movl $0x1069dc,0xc(%esp) + 1037a6: 00 + 1037a7: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1037ae: 00 + 1037af: c7 44 24 04 42 01 00 movl $0x142,0x4(%esp) + 1037b6: 00 + 1037b7: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1037be: e8 70 d4 ff ff call 100c33 <__panic> + assert((p1 = alloc_pages(3)) != NULL);// 再次分配 3 个页面 + 1037c3: c7 04 24 03 00 00 00 movl $0x3,(%esp) + 1037ca: e8 06 07 00 00 call 103ed5 + 1037cf: 89 45 e0 mov %eax,-0x20(%ebp) + 1037d2: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) + 1037d6: 75 24 jne 1037fc + 1037d8: c7 44 24 0c 08 6a 10 movl $0x106a08,0xc(%esp) + 1037df: 00 + 1037e0: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1037e7: 00 + 1037e8: c7 44 24 04 43 01 00 movl $0x143,0x4(%esp) + 1037ef: 00 + 1037f0: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1037f7: e8 37 d4 ff ff call 100c33 <__panic> + assert(alloc_page() == NULL);// 确保没有页面可分配 + 1037fc: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103803: e8 cd 06 00 00 call 103ed5 + 103808: 85 c0 test %eax,%eax + 10380a: 74 24 je 103830 + 10380c: c7 44 24 0c 1e 69 10 movl $0x10691e,0xc(%esp) + 103813: 00 + 103814: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10381b: 00 + 10381c: c7 44 24 04 44 01 00 movl $0x144,0x4(%esp) + 103823: 00 + 103824: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10382b: e8 03 d4 ff ff call 100c33 <__panic> + assert(p0 + 2 == p1);// 确保分配的页面是释放的页面 + 103830: 8b 45 e8 mov -0x18(%ebp),%eax + 103833: 83 c0 28 add $0x28,%eax + 103836: 39 45 e0 cmp %eax,-0x20(%ebp) + 103839: 74 24 je 10385f + 10383b: c7 44 24 0c 26 6a 10 movl $0x106a26,0xc(%esp) + 103842: 00 + 103843: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10384a: 00 + 10384b: c7 44 24 04 45 01 00 movl $0x145,0x4(%esp) + 103852: 00 + 103853: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10385a: e8 d4 d3 ff ff call 100c33 <__panic> + + p2 = p0 + 1; // 设置 p2 为 p0 的下一个页面 + 10385f: 8b 45 e8 mov -0x18(%ebp),%eax + 103862: 83 c0 14 add $0x14,%eax + 103865: 89 45 dc mov %eax,-0x24(%ebp) + free_page(p0);// 释放 p0 页面 + 103868: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 10386f: 00 + 103870: 8b 45 e8 mov -0x18(%ebp),%eax + 103873: 89 04 24 mov %eax,(%esp) + 103876: e8 94 06 00 00 call 103f0f + free_pages(p1, 3);// 释放 p1 指向的页面 + 10387b: c7 44 24 04 03 00 00 movl $0x3,0x4(%esp) + 103882: 00 + 103883: 8b 45 e0 mov -0x20(%ebp),%eax + 103886: 89 04 24 mov %eax,(%esp) + 103889: e8 81 06 00 00 call 103f0f + assert(PageProperty(p0) && p0->property == 1); // 检查 p0 属性 + 10388e: 8b 45 e8 mov -0x18(%ebp),%eax + 103891: 83 c0 04 add $0x4,%eax + 103894: c7 45 a0 01 00 00 00 movl $0x1,-0x60(%ebp) + 10389b: 89 45 9c mov %eax,-0x64(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 10389e: 8b 45 9c mov -0x64(%ebp),%eax + 1038a1: 8b 55 a0 mov -0x60(%ebp),%edx + 1038a4: 0f a3 10 bt %edx,(%eax) + 1038a7: 19 c0 sbb %eax,%eax + 1038a9: 89 45 98 mov %eax,-0x68(%ebp) + return oldbit != 0; + 1038ac: 83 7d 98 00 cmpl $0x0,-0x68(%ebp) + 1038b0: 0f 95 c0 setne %al + 1038b3: 0f b6 c0 movzbl %al,%eax + 1038b6: 85 c0 test %eax,%eax + 1038b8: 74 0b je 1038c5 + 1038ba: 8b 45 e8 mov -0x18(%ebp),%eax + 1038bd: 8b 40 08 mov 0x8(%eax),%eax + 1038c0: 83 f8 01 cmp $0x1,%eax + 1038c3: 74 24 je 1038e9 + 1038c5: c7 44 24 0c 34 6a 10 movl $0x106a34,0xc(%esp) + 1038cc: 00 + 1038cd: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1038d4: 00 + 1038d5: c7 44 24 04 4a 01 00 movl $0x14a,0x4(%esp) + 1038dc: 00 + 1038dd: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1038e4: e8 4a d3 ff ff call 100c33 <__panic> + assert(PageProperty(p1) && p1->property == 3); // 检查 p1 属性 + 1038e9: 8b 45 e0 mov -0x20(%ebp),%eax + 1038ec: 83 c0 04 add $0x4,%eax + 1038ef: c7 45 94 01 00 00 00 movl $0x1,-0x6c(%ebp) + 1038f6: 89 45 90 mov %eax,-0x70(%ebp) + asm volatile ("btl %2, %1; sbbl %0,%0" : "=r" (oldbit) : "m" (*(volatile long *)addr), "Ir" (nr)); + 1038f9: 8b 45 90 mov -0x70(%ebp),%eax + 1038fc: 8b 55 94 mov -0x6c(%ebp),%edx + 1038ff: 0f a3 10 bt %edx,(%eax) + 103902: 19 c0 sbb %eax,%eax + 103904: 89 45 8c mov %eax,-0x74(%ebp) + return oldbit != 0; + 103907: 83 7d 8c 00 cmpl $0x0,-0x74(%ebp) + 10390b: 0f 95 c0 setne %al + 10390e: 0f b6 c0 movzbl %al,%eax + 103911: 85 c0 test %eax,%eax + 103913: 74 0b je 103920 + 103915: 8b 45 e0 mov -0x20(%ebp),%eax + 103918: 8b 40 08 mov 0x8(%eax),%eax + 10391b: 83 f8 03 cmp $0x3,%eax + 10391e: 74 24 je 103944 + 103920: c7 44 24 0c 5c 6a 10 movl $0x106a5c,0xc(%esp) + 103927: 00 + 103928: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10392f: 00 + 103930: c7 44 24 04 4b 01 00 movl $0x14b,0x4(%esp) + 103937: 00 + 103938: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10393f: e8 ef d2 ff ff call 100c33 <__panic> +// 确保重分配的页面是之前释放的页面 + assert((p0 = alloc_page()) == p2 - 1); + 103944: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 10394b: e8 85 05 00 00 call 103ed5 + 103950: 89 45 e8 mov %eax,-0x18(%ebp) + 103953: 8b 45 dc mov -0x24(%ebp),%eax + 103956: 83 e8 14 sub $0x14,%eax + 103959: 39 45 e8 cmp %eax,-0x18(%ebp) + 10395c: 74 24 je 103982 + 10395e: c7 44 24 0c 82 6a 10 movl $0x106a82,0xc(%esp) + 103965: 00 + 103966: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 10396d: 00 + 10396e: c7 44 24 04 4d 01 00 movl $0x14d,0x4(%esp) + 103975: 00 + 103976: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 10397d: e8 b1 d2 ff ff call 100c33 <__panic> + free_page(p0);// 释放分配的页面 + 103982: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 103989: 00 + 10398a: 8b 45 e8 mov -0x18(%ebp),%eax + 10398d: 89 04 24 mov %eax,(%esp) + 103990: e8 7a 05 00 00 call 103f0f + assert((p0 = alloc_pages(2)) == p2 + 1);// 分配 2 个页面并检查 + 103995: c7 04 24 02 00 00 00 movl $0x2,(%esp) + 10399c: e8 34 05 00 00 call 103ed5 + 1039a1: 89 45 e8 mov %eax,-0x18(%ebp) + 1039a4: 8b 45 dc mov -0x24(%ebp),%eax + 1039a7: 83 c0 14 add $0x14,%eax + 1039aa: 39 45 e8 cmp %eax,-0x18(%ebp) + 1039ad: 74 24 je 1039d3 + 1039af: c7 44 24 0c a0 6a 10 movl $0x106aa0,0xc(%esp) + 1039b6: 00 + 1039b7: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 1039be: 00 + 1039bf: c7 44 24 04 4f 01 00 movl $0x14f,0x4(%esp) + 1039c6: 00 + 1039c7: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 1039ce: e8 60 d2 ff ff call 100c33 <__panic> +// 释放页面并检查空闲状态 + free_pages(p0, 2); + 1039d3: c7 44 24 04 02 00 00 movl $0x2,0x4(%esp) + 1039da: 00 + 1039db: 8b 45 e8 mov -0x18(%ebp),%eax + 1039de: 89 04 24 mov %eax,(%esp) + 1039e1: e8 29 05 00 00 call 103f0f + free_page(p2); + 1039e6: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1039ed: 00 + 1039ee: 8b 45 dc mov -0x24(%ebp),%eax + 1039f1: 89 04 24 mov %eax,(%esp) + 1039f4: e8 16 05 00 00 call 103f0f +// 再次分配 5 个页面 + assert((p0 = alloc_pages(5)) != NULL); + 1039f9: c7 04 24 05 00 00 00 movl $0x5,(%esp) + 103a00: e8 d0 04 00 00 call 103ed5 + 103a05: 89 45 e8 mov %eax,-0x18(%ebp) + 103a08: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 103a0c: 75 24 jne 103a32 + 103a0e: c7 44 24 0c c0 6a 10 movl $0x106ac0,0xc(%esp) + 103a15: 00 + 103a16: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103a1d: 00 + 103a1e: c7 44 24 04 54 01 00 movl $0x154,0x4(%esp) + 103a25: 00 + 103a26: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103a2d: e8 01 d2 ff ff call 100c33 <__panic> + assert(alloc_page() == NULL);// 确保没有额外页面可分配 + 103a32: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 103a39: e8 97 04 00 00 call 103ed5 + 103a3e: 85 c0 test %eax,%eax + 103a40: 74 24 je 103a66 + 103a42: c7 44 24 0c 1e 69 10 movl $0x10691e,0xc(%esp) + 103a49: 00 + 103a4a: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103a51: 00 + 103a52: c7 44 24 04 55 01 00 movl $0x155,0x4(%esp) + 103a59: 00 + 103a5a: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103a61: e8 cd d1 ff ff call 100c33 <__panic> + + assert(nr_free == 0);// 确保空闲页数为 0 + 103a66: a1 e8 ce 11 00 mov 0x11cee8,%eax + 103a6b: 85 c0 test %eax,%eax + 103a6d: 74 24 je 103a93 + 103a6f: c7 44 24 0c 71 69 10 movl $0x106971,0xc(%esp) + 103a76: 00 + 103a77: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103a7e: 00 + 103a7f: c7 44 24 04 57 01 00 movl $0x157,0x4(%esp) + 103a86: 00 + 103a87: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103a8e: e8 a0 d1 ff ff call 100c33 <__panic> + nr_free = nr_free_store;// 恢复空闲页数 + 103a93: 8b 45 e4 mov -0x1c(%ebp),%eax + 103a96: a3 e8 ce 11 00 mov %eax,0x11cee8 +// 恢复空闲列表状态 + free_list = free_list_store; + 103a9b: 8b 45 80 mov -0x80(%ebp),%eax + 103a9e: 8b 55 84 mov -0x7c(%ebp),%edx + 103aa1: a3 e0 ce 11 00 mov %eax,0x11cee0 + 103aa6: 89 15 e4 ce 11 00 mov %edx,0x11cee4 + free_pages(p0, 5);// 释放所有分配的页面 + 103aac: c7 44 24 04 05 00 00 movl $0x5,0x4(%esp) + 103ab3: 00 + 103ab4: 8b 45 e8 mov -0x18(%ebp),%eax + 103ab7: 89 04 24 mov %eax,(%esp) + 103aba: e8 50 04 00 00 call 103f0f + // 验证空闲列表的一致性 + le = &free_list; + 103abf: c7 45 ec e0 ce 11 00 movl $0x11cee0,-0x14(%ebp) + while ((le = list_next(le)) != &free_list) { + 103ac6: eb 5a jmp 103b22 + assert(le->next->prev == le && le->prev->next == le);// 验证双向链表 + 103ac8: 8b 45 ec mov -0x14(%ebp),%eax + 103acb: 8b 40 04 mov 0x4(%eax),%eax + 103ace: 8b 00 mov (%eax),%eax + 103ad0: 39 45 ec cmp %eax,-0x14(%ebp) + 103ad3: 75 0d jne 103ae2 + 103ad5: 8b 45 ec mov -0x14(%ebp),%eax + 103ad8: 8b 00 mov (%eax),%eax + 103ada: 8b 40 04 mov 0x4(%eax),%eax + 103add: 39 45 ec cmp %eax,-0x14(%ebp) + 103ae0: 74 24 je 103b06 + 103ae2: c7 44 24 0c e0 6a 10 movl $0x106ae0,0xc(%esp) + 103ae9: 00 + 103aea: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103af1: 00 + 103af2: c7 44 24 04 5f 01 00 movl $0x15f,0x4(%esp) + 103af9: 00 + 103afa: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103b01: e8 2d d1 ff ff call 100c33 <__panic> + struct Page *p = le2page(le, page_link);// 更新计数和总属性值 + 103b06: 8b 45 ec mov -0x14(%ebp),%eax + 103b09: 83 e8 0c sub $0xc,%eax + 103b0c: 89 45 d8 mov %eax,-0x28(%ebp) + count --, total -= p->property; + 103b0f: ff 4d f4 decl -0xc(%ebp) + 103b12: 8b 55 f0 mov -0x10(%ebp),%edx + 103b15: 8b 45 d8 mov -0x28(%ebp),%eax + 103b18: 8b 48 08 mov 0x8(%eax),%ecx + 103b1b: 89 d0 mov %edx,%eax + 103b1d: 29 c8 sub %ecx,%eax + 103b1f: 89 45 f0 mov %eax,-0x10(%ebp) + 103b22: 8b 45 ec mov -0x14(%ebp),%eax + 103b25: 89 45 88 mov %eax,-0x78(%ebp) + return listelm->next; + 103b28: 8b 45 88 mov -0x78(%ebp),%eax + 103b2b: 8b 40 04 mov 0x4(%eax),%eax + while ((le = list_next(le)) != &free_list) { + 103b2e: 89 45 ec mov %eax,-0x14(%ebp) + 103b31: 81 7d ec e0 ce 11 00 cmpl $0x11cee0,-0x14(%ebp) + 103b38: 75 8e jne 103ac8 + } + assert(count == 0);// 确保所有页面都已处理 + 103b3a: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 103b3e: 74 24 je 103b64 + 103b40: c7 44 24 0c 0d 6b 10 movl $0x106b0d,0xc(%esp) + 103b47: 00 + 103b48: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103b4f: 00 + 103b50: c7 44 24 04 63 01 00 movl $0x163,0x4(%esp) + 103b57: 00 + 103b58: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103b5f: e8 cf d0 ff ff call 100c33 <__panic> + assert(total == 0);// 确保总属性值为 0 + 103b64: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 103b68: 74 24 je 103b8e + 103b6a: c7 44 24 0c 18 6b 10 movl $0x106b18,0xc(%esp) + 103b71: 00 + 103b72: c7 44 24 08 96 67 10 movl $0x106796,0x8(%esp) + 103b79: 00 + 103b7a: c7 44 24 04 64 01 00 movl $0x164,0x4(%esp) + 103b81: 00 + 103b82: c7 04 24 ab 67 10 00 movl $0x1067ab,(%esp) + 103b89: e8 a5 d0 ff ff call 100c33 <__panic> +} + 103b8e: 90 nop + 103b8f: 89 ec mov %ebp,%esp + 103b91: 5d pop %ebp + 103b92: c3 ret + +00103b93 : +page2ppn(struct Page *page) { + 103b93: 55 push %ebp + 103b94: 89 e5 mov %esp,%ebp + return page - pages; + 103b96: 8b 15 00 cf 11 00 mov 0x11cf00,%edx + 103b9c: 8b 45 08 mov 0x8(%ebp),%eax + 103b9f: 29 d0 sub %edx,%eax + 103ba1: c1 f8 02 sar $0x2,%eax + 103ba4: 69 c0 cd cc cc cc imul $0xcccccccd,%eax,%eax +} + 103baa: 5d pop %ebp + 103bab: c3 ret + +00103bac : +page2pa(struct Page *page) { + 103bac: 55 push %ebp + 103bad: 89 e5 mov %esp,%ebp + 103baf: 83 ec 04 sub $0x4,%esp + return page2ppn(page) << PGSHIFT; + 103bb2: 8b 45 08 mov 0x8(%ebp),%eax + 103bb5: 89 04 24 mov %eax,(%esp) + 103bb8: e8 d6 ff ff ff call 103b93 + 103bbd: c1 e0 0c shl $0xc,%eax +} + 103bc0: 89 ec mov %ebp,%esp + 103bc2: 5d pop %ebp + 103bc3: c3 ret + +00103bc4 : +pa2page(uintptr_t pa) { + 103bc4: 55 push %ebp + 103bc5: 89 e5 mov %esp,%ebp + 103bc7: 83 ec 18 sub $0x18,%esp + if (PPN(pa) >= npage) { + 103bca: 8b 45 08 mov 0x8(%ebp),%eax + 103bcd: c1 e8 0c shr $0xc,%eax + 103bd0: 89 c2 mov %eax,%edx + 103bd2: a1 04 cf 11 00 mov 0x11cf04,%eax + 103bd7: 39 c2 cmp %eax,%edx + 103bd9: 72 1c jb 103bf7 + panic("pa2page called with invalid pa"); + 103bdb: c7 44 24 08 54 6b 10 movl $0x106b54,0x8(%esp) + 103be2: 00 + 103be3: c7 44 24 04 5a 00 00 movl $0x5a,0x4(%esp) + 103bea: 00 + 103beb: c7 04 24 73 6b 10 00 movl $0x106b73,(%esp) + 103bf2: e8 3c d0 ff ff call 100c33 <__panic> + return &pages[PPN(pa)]; + 103bf7: 8b 0d 00 cf 11 00 mov 0x11cf00,%ecx + 103bfd: 8b 45 08 mov 0x8(%ebp),%eax + 103c00: c1 e8 0c shr $0xc,%eax + 103c03: 89 c2 mov %eax,%edx + 103c05: 89 d0 mov %edx,%eax + 103c07: c1 e0 02 shl $0x2,%eax + 103c0a: 01 d0 add %edx,%eax + 103c0c: c1 e0 02 shl $0x2,%eax + 103c0f: 01 c8 add %ecx,%eax +} + 103c11: 89 ec mov %ebp,%esp + 103c13: 5d pop %ebp + 103c14: c3 ret + +00103c15 : +page2kva(struct Page *page) { + 103c15: 55 push %ebp + 103c16: 89 e5 mov %esp,%ebp + 103c18: 83 ec 28 sub $0x28,%esp + return KADDR(page2pa(page)); + 103c1b: 8b 45 08 mov 0x8(%ebp),%eax + 103c1e: 89 04 24 mov %eax,(%esp) + 103c21: e8 86 ff ff ff call 103bac + 103c26: 89 45 f4 mov %eax,-0xc(%ebp) + 103c29: 8b 45 f4 mov -0xc(%ebp),%eax + 103c2c: c1 e8 0c shr $0xc,%eax + 103c2f: 89 45 f0 mov %eax,-0x10(%ebp) + 103c32: a1 04 cf 11 00 mov 0x11cf04,%eax + 103c37: 39 45 f0 cmp %eax,-0x10(%ebp) + 103c3a: 72 23 jb 103c5f + 103c3c: 8b 45 f4 mov -0xc(%ebp),%eax + 103c3f: 89 44 24 0c mov %eax,0xc(%esp) + 103c43: c7 44 24 08 84 6b 10 movl $0x106b84,0x8(%esp) + 103c4a: 00 + 103c4b: c7 44 24 04 61 00 00 movl $0x61,0x4(%esp) + 103c52: 00 + 103c53: c7 04 24 73 6b 10 00 movl $0x106b73,(%esp) + 103c5a: e8 d4 cf ff ff call 100c33 <__panic> + 103c5f: 8b 45 f4 mov -0xc(%ebp),%eax + 103c62: 2d 00 00 00 40 sub $0x40000000,%eax +} + 103c67: 89 ec mov %ebp,%esp + 103c69: 5d pop %ebp + 103c6a: c3 ret + +00103c6b : +pte2page(pte_t pte) { + 103c6b: 55 push %ebp + 103c6c: 89 e5 mov %esp,%ebp + 103c6e: 83 ec 18 sub $0x18,%esp + if (!(pte & PTE_P)) { + 103c71: 8b 45 08 mov 0x8(%ebp),%eax + 103c74: 83 e0 01 and $0x1,%eax + 103c77: 85 c0 test %eax,%eax + 103c79: 75 1c jne 103c97 + panic("pte2page called with invalid pte"); + 103c7b: c7 44 24 08 a8 6b 10 movl $0x106ba8,0x8(%esp) + 103c82: 00 + 103c83: c7 44 24 04 6c 00 00 movl $0x6c,0x4(%esp) + 103c8a: 00 + 103c8b: c7 04 24 73 6b 10 00 movl $0x106b73,(%esp) + 103c92: e8 9c cf ff ff call 100c33 <__panic> + return pa2page(PTE_ADDR(pte)); + 103c97: 8b 45 08 mov 0x8(%ebp),%eax + 103c9a: 25 00 f0 ff ff and $0xfffff000,%eax + 103c9f: 89 04 24 mov %eax,(%esp) + 103ca2: e8 1d ff ff ff call 103bc4 +} + 103ca7: 89 ec mov %ebp,%esp + 103ca9: 5d pop %ebp + 103caa: c3 ret + +00103cab : +pde2page(pde_t pde) { + 103cab: 55 push %ebp + 103cac: 89 e5 mov %esp,%ebp + 103cae: 83 ec 18 sub $0x18,%esp + return pa2page(PDE_ADDR(pde)); + 103cb1: 8b 45 08 mov 0x8(%ebp),%eax + 103cb4: 25 00 f0 ff ff and $0xfffff000,%eax + 103cb9: 89 04 24 mov %eax,(%esp) + 103cbc: e8 03 ff ff ff call 103bc4 +} + 103cc1: 89 ec mov %ebp,%esp + 103cc3: 5d pop %ebp + 103cc4: c3 ret + +00103cc5 : +page_ref(struct Page *page) { + 103cc5: 55 push %ebp + 103cc6: 89 e5 mov %esp,%ebp + return page->ref; + 103cc8: 8b 45 08 mov 0x8(%ebp),%eax + 103ccb: 8b 00 mov (%eax),%eax +} + 103ccd: 5d pop %ebp + 103cce: c3 ret + +00103ccf : +set_page_ref(struct Page *page, int val) { + 103ccf: 55 push %ebp + 103cd0: 89 e5 mov %esp,%ebp + page->ref = val; + 103cd2: 8b 45 08 mov 0x8(%ebp),%eax + 103cd5: 8b 55 0c mov 0xc(%ebp),%edx + 103cd8: 89 10 mov %edx,(%eax) +} + 103cda: 90 nop + 103cdb: 5d pop %ebp + 103cdc: c3 ret + +00103cdd : + +static inline int +page_ref_inc(struct Page *page) { + 103cdd: 55 push %ebp + 103cde: 89 e5 mov %esp,%ebp + page->ref += 1; + 103ce0: 8b 45 08 mov 0x8(%ebp),%eax + 103ce3: 8b 00 mov (%eax),%eax + 103ce5: 8d 50 01 lea 0x1(%eax),%edx + 103ce8: 8b 45 08 mov 0x8(%ebp),%eax + 103ceb: 89 10 mov %edx,(%eax) + return page->ref; + 103ced: 8b 45 08 mov 0x8(%ebp),%eax + 103cf0: 8b 00 mov (%eax),%eax +} + 103cf2: 5d pop %ebp + 103cf3: c3 ret + +00103cf4 : + +static inline int +page_ref_dec(struct Page *page) { + 103cf4: 55 push %ebp + 103cf5: 89 e5 mov %esp,%ebp + page->ref -= 1; + 103cf7: 8b 45 08 mov 0x8(%ebp),%eax + 103cfa: 8b 00 mov (%eax),%eax + 103cfc: 8d 50 ff lea -0x1(%eax),%edx + 103cff: 8b 45 08 mov 0x8(%ebp),%eax + 103d02: 89 10 mov %edx,(%eax) + return page->ref; + 103d04: 8b 45 08 mov 0x8(%ebp),%eax + 103d07: 8b 00 mov (%eax),%eax +} + 103d09: 5d pop %ebp + 103d0a: c3 ret + +00103d0b <__intr_save>: +__intr_save(void) { + 103d0b: 55 push %ebp + 103d0c: 89 e5 mov %esp,%ebp + 103d0e: 83 ec 18 sub $0x18,%esp + asm volatile ("pushfl; popl %0" : "=r" (eflags)); + 103d11: 9c pushf + 103d12: 58 pop %eax + 103d13: 89 45 f4 mov %eax,-0xc(%ebp) + return eflags; + 103d16: 8b 45 f4 mov -0xc(%ebp),%eax + if (read_eflags() & FL_IF) { + 103d19: 25 00 02 00 00 and $0x200,%eax + 103d1e: 85 c0 test %eax,%eax + 103d20: 74 0c je 103d2e <__intr_save+0x23> + intr_disable(); + 103d22: e8 65 d9 ff ff call 10168c + return 1; + 103d27: b8 01 00 00 00 mov $0x1,%eax + 103d2c: eb 05 jmp 103d33 <__intr_save+0x28> + return 0; + 103d2e: b8 00 00 00 00 mov $0x0,%eax +} + 103d33: 89 ec mov %ebp,%esp + 103d35: 5d pop %ebp + 103d36: c3 ret + +00103d37 <__intr_restore>: +__intr_restore(bool flag) { + 103d37: 55 push %ebp + 103d38: 89 e5 mov %esp,%ebp + 103d3a: 83 ec 08 sub $0x8,%esp + if (flag) { + 103d3d: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 103d41: 74 05 je 103d48 <__intr_restore+0x11> + intr_enable(); + 103d43: e8 3c d9 ff ff call 101684 +} + 103d48: 90 nop + 103d49: 89 ec mov %ebp,%esp + 103d4b: 5d pop %ebp + 103d4c: c3 ret + +00103d4d : + * data/code segement registers for kernel. + * lgdt - 加载全局描述符表寄存器并重置内核的数据/代码段寄存器。 + * */ +//定义了一个静态内联函数 lgdt,接收一个指向伪描述符(struct pseudodesc)的指针 pd +static inline void +lgdt(struct pseudodesc *pd) { + 103d4d: 55 push %ebp + 103d4e: 89 e5 mov %esp,%ebp + asm volatile ("lgdt (%0)" :: "r" (pd));//这行汇编代码使用 lgdt 指令加载 GDT。%0 被替换为指向 pd 的指针,告诉处理器 GDT 的地址。 + 103d50: 8b 45 08 mov 0x8(%ebp),%eax + 103d53: 0f 01 10 lgdtl (%eax) + asm volatile ("movw %%ax, %%gs" :: "a" (USER_DS));//将 USER_DS(用户数据段)的值移动到 gs 段寄存器。 + 103d56: b8 23 00 00 00 mov $0x23,%eax + 103d5b: 8e e8 mov %eax,%gs + asm volatile ("movw %%ax, %%fs" :: "a" (USER_DS));//将 USER_DS 的值移动到 fs 段寄存器。 + 103d5d: b8 23 00 00 00 mov $0x23,%eax + 103d62: 8e e0 mov %eax,%fs + asm volatile ("movw %%ax, %%es" :: "a" (KERNEL_DS));//将 KERNEL_DS(内核数据段)的值移动到 es 段寄存器。 + 103d64: b8 10 00 00 00 mov $0x10,%eax + 103d69: 8e c0 mov %eax,%es + asm volatile ("movw %%ax, %%ds" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ds 段寄存器 + 103d6b: b8 10 00 00 00 mov $0x10,%eax + 103d70: 8e d8 mov %eax,%ds + asm volatile ("movw %%ax, %%ss" :: "a" (KERNEL_DS));//将 KERNEL_DS 的值移动到 ss 段寄存器 + 103d72: b8 10 00 00 00 mov $0x10,%eax + 103d77: 8e d0 mov %eax,%ss + // reload cs + //通过 ljmp 指令重新加载代码段寄存器 cs,并跳转到标签 1。 + asm volatile ("ljmp %0, $1f\n 1:\n" :: "i" (KERNEL_CS)); + 103d79: ea 80 3d 10 00 08 00 ljmp $0x8,$0x103d80 +} + 103d80: 90 nop + 103d81: 5d pop %ebp + 103d82: c3 ret + +00103d83 : + * load_esp0 - 修改默认任务状态段中的 ESP0,以便在从用户态陷入内核态时能够使用不同的内核栈。 + * */ +//uintptr_t esp0:这是新的堆栈指针,通常指向内核栈的顶部。 +//修改当前任务状态段(TSS)中的 ESP0 值。ESP0 是在从用户态切换到内核态时,CPU 使用的内核栈指针。 +void +load_esp0(uintptr_t esp0) { + 103d83: 55 push %ebp + 103d84: 89 e5 mov %esp,%ebp + ts.ts_esp0 = esp0; + 103d86: 8b 45 08 mov 0x8(%ebp),%eax + 103d89: a3 24 cf 11 00 mov %eax,0x11cf24 +} + 103d8e: 90 nop + 103d8f: 5d pop %ebp + 103d90: c3 ret + +00103d91 : + +/* gdt_init - initialize the default GDT and TSS */ +/* gdt_init - 初始化默认的 GDT 和 TSS */ +static void +gdt_init(void) { + 103d91: 55 push %ebp + 103d92: 89 e5 mov %esp,%ebp + 103d94: 83 ec 14 sub $0x14,%esp + // 设置启动内核栈和默认的 SS0 + // set boot kernel stack and default SS0 + load_esp0((uintptr_t)bootstacktop); + 103d97: b8 00 90 11 00 mov $0x119000,%eax + 103d9c: 89 04 24 mov %eax,(%esp) + 103d9f: e8 df ff ff ff call 103d83 + ts.ts_ss0 = KERNEL_DS; + 103da4: 66 c7 05 28 cf 11 00 movw $0x10,0x11cf28 + 103dab: 10 00 + // 初始化 GDT 中的 TSS 字段 + // initialize the TSS filed of the gdt + gdt[SEG_TSS] = SEGTSS(STS_T32A, (uintptr_t)&ts, sizeof(ts), DPL_KERNEL); + 103dad: 66 c7 05 28 9a 11 00 movw $0x68,0x119a28 + 103db4: 68 00 + 103db6: b8 20 cf 11 00 mov $0x11cf20,%eax + 103dbb: 0f b7 c0 movzwl %ax,%eax + 103dbe: 66 a3 2a 9a 11 00 mov %ax,0x119a2a + 103dc4: b8 20 cf 11 00 mov $0x11cf20,%eax + 103dc9: c1 e8 10 shr $0x10,%eax + 103dcc: a2 2c 9a 11 00 mov %al,0x119a2c + 103dd1: 0f b6 05 2d 9a 11 00 movzbl 0x119a2d,%eax + 103dd8: 24 f0 and $0xf0,%al + 103dda: 0c 09 or $0x9,%al + 103ddc: a2 2d 9a 11 00 mov %al,0x119a2d + 103de1: 0f b6 05 2d 9a 11 00 movzbl 0x119a2d,%eax + 103de8: 24 ef and $0xef,%al + 103dea: a2 2d 9a 11 00 mov %al,0x119a2d + 103def: 0f b6 05 2d 9a 11 00 movzbl 0x119a2d,%eax + 103df6: 24 9f and $0x9f,%al + 103df8: a2 2d 9a 11 00 mov %al,0x119a2d + 103dfd: 0f b6 05 2d 9a 11 00 movzbl 0x119a2d,%eax + 103e04: 0c 80 or $0x80,%al + 103e06: a2 2d 9a 11 00 mov %al,0x119a2d + 103e0b: 0f b6 05 2e 9a 11 00 movzbl 0x119a2e,%eax + 103e12: 24 f0 and $0xf0,%al + 103e14: a2 2e 9a 11 00 mov %al,0x119a2e + 103e19: 0f b6 05 2e 9a 11 00 movzbl 0x119a2e,%eax + 103e20: 24 ef and $0xef,%al + 103e22: a2 2e 9a 11 00 mov %al,0x119a2e + 103e27: 0f b6 05 2e 9a 11 00 movzbl 0x119a2e,%eax + 103e2e: 24 df and $0xdf,%al + 103e30: a2 2e 9a 11 00 mov %al,0x119a2e + 103e35: 0f b6 05 2e 9a 11 00 movzbl 0x119a2e,%eax + 103e3c: 0c 40 or $0x40,%al + 103e3e: a2 2e 9a 11 00 mov %al,0x119a2e + 103e43: 0f b6 05 2e 9a 11 00 movzbl 0x119a2e,%eax + 103e4a: 24 7f and $0x7f,%al + 103e4c: a2 2e 9a 11 00 mov %al,0x119a2e + 103e51: b8 20 cf 11 00 mov $0x11cf20,%eax + 103e56: c1 e8 18 shr $0x18,%eax + 103e59: a2 2f 9a 11 00 mov %al,0x119a2f + // 使用lgdt加载全局描述符表,更新所有段寄存器 + // reload all segment registers + lgdt(&gdt_pd); + 103e5e: c7 04 24 30 9a 11 00 movl $0x119a30,(%esp) + 103e65: e8 e3 fe ff ff call 103d4d + 103e6a: 66 c7 45 fe 28 00 movw $0x28,-0x2(%ebp) + asm volatile ("ltr %0" :: "r" (sel) : "memory"); + 103e70: 0f b7 45 fe movzwl -0x2(%ebp),%eax + 103e74: 0f 00 d8 ltr %ax +} + 103e77: 90 nop + // 加载 TSS,使 CPU 在进行特权级切换时能够正确使用 TSS。 + // load the TSS + ltr(GD_TSS); +} + 103e78: 90 nop + 103e79: 89 ec mov %ebp,%esp + 103e7b: 5d pop %ebp + 103e7c: c3 ret + +00103e7d : + +//init_pmm_manager - initialize a pmm_manager instance +//初始化一个 pmm_manager 实例 +static void +init_pmm_manager(void) { + 103e7d: 55 push %ebp + 103e7e: 89 e5 mov %esp,%ebp + 103e80: 83 ec 18 sub $0x18,%esp + //将 pmm_manager 指向默认的 PMM 管理器实例。 + pmm_manager = &default_pmm_manager; + 103e83: c7 05 0c cf 11 00 38 movl $0x106b38,0x11cf0c + 103e8a: 6b 10 00 + //使用 cprintf 打印当前内存管理器的名称。 + cprintf("memory management: %s\n", pmm_manager->name); + 103e8d: a1 0c cf 11 00 mov 0x11cf0c,%eax + 103e92: 8b 00 mov (%eax),%eax + 103e94: 89 44 24 04 mov %eax,0x4(%esp) + 103e98: c7 04 24 d4 6b 10 00 movl $0x106bd4,(%esp) + 103e9f: e8 c2 c4 ff ff call 100366 + //调用 PMM 管理器的初始化函数,以设置和准备内存管理的相关数据结构。 + pmm_manager->init(); + 103ea4: a1 0c cf 11 00 mov 0x11cf0c,%eax + 103ea9: 8b 40 04 mov 0x4(%eax),%eax + 103eac: ff d0 call *%eax +} + 103eae: 90 nop + 103eaf: 89 ec mov %ebp,%esp + 103eb1: 5d pop %ebp + 103eb2: c3 ret + +00103eb3 : + +//init_memmap - call pmm->init_memmap to build Page struct for free memory +// init_memmap - 调用 pmm->init_memmap 构建空闲内存的 Page 结构 +//struct Page *base:指向内存页的基础地址。 size_t n:要初始化的页数。 +static void +init_memmap(struct Page *base, size_t n) { + 103eb3: 55 push %ebp + 103eb4: 89 e5 mov %esp,%ebp + 103eb6: 83 ec 18 sub $0x18,%esp + pmm_manager->init_memmap(base, n); + 103eb9: a1 0c cf 11 00 mov 0x11cf0c,%eax + 103ebe: 8b 40 08 mov 0x8(%eax),%eax + 103ec1: 8b 55 0c mov 0xc(%ebp),%edx + 103ec4: 89 54 24 04 mov %edx,0x4(%esp) + 103ec8: 8b 55 08 mov 0x8(%ebp),%edx + 103ecb: 89 14 24 mov %edx,(%esp) + 103ece: ff d0 call *%eax +} + 103ed0: 90 nop + 103ed1: 89 ec mov %ebp,%esp + 103ed3: 5d pop %ebp + 103ed4: c3 ret + +00103ed5 : + +//alloc_pages - call pmm->alloc_pages to allocate a continuous n*PAGESIZE memory +// alloc_pages - 调用 pmm->alloc_pages 分配连续的 n*PAGESIZE 内存 +struct Page * +alloc_pages(size_t n) { + 103ed5: 55 push %ebp + 103ed6: 89 e5 mov %esp,%ebp + 103ed8: 83 ec 28 sub $0x28,%esp + struct Page *page=NULL; + 103edb: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在分配内存时发生中断。 + local_intr_save(intr_flag); + 103ee2: e8 24 fe ff ff call 103d0b <__intr_save> + 103ee7: 89 45 f0 mov %eax,-0x10(%ebp) + { + //调用物理内存管理器的 alloc_pages 函数分配 n 页的内存。 + page = pmm_manager->alloc_pages(n); + 103eea: a1 0c cf 11 00 mov 0x11cf0c,%eax + 103eef: 8b 40 0c mov 0xc(%eax),%eax + 103ef2: 8b 55 08 mov 0x8(%ebp),%edx + 103ef5: 89 14 24 mov %edx,(%esp) + 103ef8: ff d0 call *%eax + 103efa: 89 45 f4 mov %eax,-0xc(%ebp) + } + //恢复之前保存的中断状态。 + local_intr_restore(intr_flag); + 103efd: 8b 45 f0 mov -0x10(%ebp),%eax + 103f00: 89 04 24 mov %eax,(%esp) + 103f03: e8 2f fe ff ff call 103d37 <__intr_restore> + return page; + 103f08: 8b 45 f4 mov -0xc(%ebp),%eax +} + 103f0b: 89 ec mov %ebp,%esp + 103f0d: 5d pop %ebp + 103f0e: c3 ret + +00103f0f : + +//free_pages - call pmm->free_pages to free a continuous n*PAGESIZE memory +// free_pages - 调用 pmm->free_pages 释放连续的 n*PAGESIZE 内存 +//struct Page *base:指向要释放的内存页的基础地址。size_t n:要释放的页数。 +void +free_pages(struct Page *base, size_t n) { + 103f0f: 55 push %ebp + 103f10: 89 e5 mov %esp,%ebp + 103f12: 83 ec 28 sub $0x28,%esp + bool intr_flag; + //使用 local_intr_save 保存当前的中断状态,以避免在释放内存时发生中断。 + local_intr_save(intr_flag); + 103f15: e8 f1 fd ff ff call 103d0b <__intr_save> + 103f1a: 89 45 f4 mov %eax,-0xc(%ebp) + { + //调用物理内存管理器的 free_pages 函数释放 n 页的内存。 + pmm_manager->free_pages(base, n); + 103f1d: a1 0c cf 11 00 mov 0x11cf0c,%eax + 103f22: 8b 40 10 mov 0x10(%eax),%eax + 103f25: 8b 55 0c mov 0xc(%ebp),%edx + 103f28: 89 54 24 04 mov %edx,0x4(%esp) + 103f2c: 8b 55 08 mov 0x8(%ebp),%edx + 103f2f: 89 14 24 mov %edx,(%esp) + 103f32: ff d0 call *%eax + } + local_intr_restore(intr_flag); + 103f34: 8b 45 f4 mov -0xc(%ebp),%eax + 103f37: 89 04 24 mov %eax,(%esp) + 103f3a: e8 f8 fd ff ff call 103d37 <__intr_restore> +} + 103f3f: 90 nop + 103f40: 89 ec mov %ebp,%esp + 103f42: 5d pop %ebp + 103f43: c3 ret + +00103f44 : + +//nr_free_pages - call pmm->nr_free_pages to get the size (nr*PAGESIZE) +//of current free memory +// nr_free_pages - 调用 pmm->nr_free_pages 获取当前空闲内存的大小 (nr * PAGESIZE) +size_t +nr_free_pages(void) { + 103f44: 55 push %ebp + 103f45: 89 e5 mov %esp,%ebp + 103f47: 83 ec 28 sub $0x28,%esp + size_t ret;// 定义变量 ret 用于存储返回的空闲内存大小 + bool intr_flag;// 定义变量 intr_flag 用于保存中断状态 + local_intr_save(intr_flag);// 保存当前中断状态,并禁用中断 + 103f4a: e8 bc fd ff ff call 103d0b <__intr_save> + 103f4f: 89 45 f4 mov %eax,-0xc(%ebp) + { + ret = pmm_manager->nr_free_pages();// 调用物理内存管理器的函数获取空闲内存页数 + 103f52: a1 0c cf 11 00 mov 0x11cf0c,%eax + 103f57: 8b 40 14 mov 0x14(%eax),%eax + 103f5a: ff d0 call *%eax + 103f5c: 89 45 f0 mov %eax,-0x10(%ebp) + } + local_intr_restore(intr_flag);// 恢复之前保存的中断状态 + 103f5f: 8b 45 f4 mov -0xc(%ebp),%eax + 103f62: 89 04 24 mov %eax,(%esp) + 103f65: e8 cd fd ff ff call 103d37 <__intr_restore> + return ret;// 返回空闲内存的大小 + 103f6a: 8b 45 f0 mov -0x10(%ebp),%eax +} + 103f6d: 89 ec mov %ebp,%esp + 103f6f: 5d pop %ebp + 103f70: c3 ret + +00103f71 : + +/* pmm_init - initialize the physical memory management */ +/* pmm_init - 初始化物理内存管理 */ +static void +page_init(void) { + 103f71: 55 push %ebp + 103f72: 89 e5 mov %esp,%ebp + 103f74: 57 push %edi + 103f75: 56 push %esi + 103f76: 53 push %ebx + 103f77: 81 ec 9c 00 00 00 sub $0x9c,%esp + // 获取物理内存映射信息,存于特定地址 + struct e820map *memmap = (struct e820map *)(0x8000 + KERNBASE); + 103f7d: c7 45 c4 00 80 00 c0 movl $0xc0008000,-0x3c(%ebp) + uint64_t maxpa = 0;// 初始化最大物理地址为0 + 103f84: c7 45 e0 00 00 00 00 movl $0x0,-0x20(%ebp) + 103f8b: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + + cprintf("e820map:\n");// 打印“e820map”标题 + 103f92: c7 04 24 eb 6b 10 00 movl $0x106beb,(%esp) + 103f99: e8 c8 c3 ff ff call 100366 + int i; + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 + 103f9e: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 103fa5: e9 0c 01 00 00 jmp 1040b6 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size; // 获取每个区域的起始和结束地址 + 103faa: 8b 4d c4 mov -0x3c(%ebp),%ecx + 103fad: 8b 55 dc mov -0x24(%ebp),%edx + 103fb0: 89 d0 mov %edx,%eax + 103fb2: c1 e0 02 shl $0x2,%eax + 103fb5: 01 d0 add %edx,%eax + 103fb7: c1 e0 02 shl $0x2,%eax + 103fba: 01 c8 add %ecx,%eax + 103fbc: 8b 50 08 mov 0x8(%eax),%edx + 103fbf: 8b 40 04 mov 0x4(%eax),%eax + 103fc2: 89 45 a0 mov %eax,-0x60(%ebp) + 103fc5: 89 55 a4 mov %edx,-0x5c(%ebp) + 103fc8: 8b 4d c4 mov -0x3c(%ebp),%ecx + 103fcb: 8b 55 dc mov -0x24(%ebp),%edx + 103fce: 89 d0 mov %edx,%eax + 103fd0: c1 e0 02 shl $0x2,%eax + 103fd3: 01 d0 add %edx,%eax + 103fd5: c1 e0 02 shl $0x2,%eax + 103fd8: 01 c8 add %ecx,%eax + 103fda: 8b 48 0c mov 0xc(%eax),%ecx + 103fdd: 8b 58 10 mov 0x10(%eax),%ebx + 103fe0: 8b 45 a0 mov -0x60(%ebp),%eax + 103fe3: 8b 55 a4 mov -0x5c(%ebp),%edx + 103fe6: 01 c8 add %ecx,%eax + 103fe8: 11 da adc %ebx,%edx + 103fea: 89 45 98 mov %eax,-0x68(%ebp) + 103fed: 89 55 9c mov %edx,-0x64(%ebp) + cprintf(" memory: %08llx, [%08llx, %08llx], type = %d.\n",// 打印内存区域的信息 + 103ff0: 8b 4d c4 mov -0x3c(%ebp),%ecx + 103ff3: 8b 55 dc mov -0x24(%ebp),%edx + 103ff6: 89 d0 mov %edx,%eax + 103ff8: c1 e0 02 shl $0x2,%eax + 103ffb: 01 d0 add %edx,%eax + 103ffd: c1 e0 02 shl $0x2,%eax + 104000: 01 c8 add %ecx,%eax + 104002: 83 c0 14 add $0x14,%eax + 104005: 8b 00 mov (%eax),%eax + 104007: 89 85 7c ff ff ff mov %eax,-0x84(%ebp) + 10400d: 8b 45 98 mov -0x68(%ebp),%eax + 104010: 8b 55 9c mov -0x64(%ebp),%edx + 104013: 83 c0 ff add $0xffffffff,%eax + 104016: 83 d2 ff adc $0xffffffff,%edx + 104019: 89 c6 mov %eax,%esi + 10401b: 89 d7 mov %edx,%edi + 10401d: 8b 4d c4 mov -0x3c(%ebp),%ecx + 104020: 8b 55 dc mov -0x24(%ebp),%edx + 104023: 89 d0 mov %edx,%eax + 104025: c1 e0 02 shl $0x2,%eax + 104028: 01 d0 add %edx,%eax + 10402a: c1 e0 02 shl $0x2,%eax + 10402d: 01 c8 add %ecx,%eax + 10402f: 8b 48 0c mov 0xc(%eax),%ecx + 104032: 8b 58 10 mov 0x10(%eax),%ebx + 104035: 8b 85 7c ff ff ff mov -0x84(%ebp),%eax + 10403b: 89 44 24 1c mov %eax,0x1c(%esp) + 10403f: 89 74 24 14 mov %esi,0x14(%esp) + 104043: 89 7c 24 18 mov %edi,0x18(%esp) + 104047: 8b 45 a0 mov -0x60(%ebp),%eax + 10404a: 8b 55 a4 mov -0x5c(%ebp),%edx + 10404d: 89 44 24 0c mov %eax,0xc(%esp) + 104051: 89 54 24 10 mov %edx,0x10(%esp) + 104055: 89 4c 24 04 mov %ecx,0x4(%esp) + 104059: 89 5c 24 08 mov %ebx,0x8(%esp) + 10405d: c7 04 24 f8 6b 10 00 movl $0x106bf8,(%esp) + 104064: e8 fd c2 ff ff call 100366 + memmap->map[i].size, begin, end - 1, memmap->map[i].type); + if (memmap->map[i].type == E820_ARM) { // 检查内存类型是否为可用内存 + 104069: 8b 4d c4 mov -0x3c(%ebp),%ecx + 10406c: 8b 55 dc mov -0x24(%ebp),%edx + 10406f: 89 d0 mov %edx,%eax + 104071: c1 e0 02 shl $0x2,%eax + 104074: 01 d0 add %edx,%eax + 104076: c1 e0 02 shl $0x2,%eax + 104079: 01 c8 add %ecx,%eax + 10407b: 83 c0 14 add $0x14,%eax + 10407e: 8b 00 mov (%eax),%eax + 104080: 83 f8 01 cmp $0x1,%eax + 104083: 75 2e jne 1040b3 + if (maxpa < end && begin < KMEMSIZE) {// 检查当前区域是否在有效范围内 + 104085: 8b 45 e0 mov -0x20(%ebp),%eax + 104088: 8b 55 e4 mov -0x1c(%ebp),%edx + 10408b: 3b 45 98 cmp -0x68(%ebp),%eax + 10408e: 89 d0 mov %edx,%eax + 104090: 1b 45 9c sbb -0x64(%ebp),%eax + 104093: 73 1e jae 1040b3 + 104095: ba ff ff ff 37 mov $0x37ffffff,%edx + 10409a: b8 00 00 00 00 mov $0x0,%eax + 10409f: 3b 55 a0 cmp -0x60(%ebp),%edx + 1040a2: 1b 45 a4 sbb -0x5c(%ebp),%eax + 1040a5: 72 0c jb 1040b3 + maxpa = end;// 更新最大物理地址 + 1040a7: 8b 45 98 mov -0x68(%ebp),%eax + 1040aa: 8b 55 9c mov -0x64(%ebp),%edx + 1040ad: 89 45 e0 mov %eax,-0x20(%ebp) + 1040b0: 89 55 e4 mov %edx,-0x1c(%ebp) + for (i = 0; i < memmap->nr_map; i ++) {// 遍历内存映射数组 + 1040b3: ff 45 dc incl -0x24(%ebp) + 1040b6: 8b 45 c4 mov -0x3c(%ebp),%eax + 1040b9: 8b 00 mov (%eax),%eax + 1040bb: 39 45 dc cmp %eax,-0x24(%ebp) + 1040be: 0f 8c e6 fe ff ff jl 103faa + } + } + } + if (maxpa > KMEMSIZE) {// 如果最大物理地址超过了预定义的内存上限 + 1040c4: ba 00 00 00 38 mov $0x38000000,%edx + 1040c9: b8 00 00 00 00 mov $0x0,%eax + 1040ce: 3b 55 e0 cmp -0x20(%ebp),%edx + 1040d1: 1b 45 e4 sbb -0x1c(%ebp),%eax + 1040d4: 73 0e jae 1040e4 + maxpa = KMEMSIZE;// 将其限制为内存上限 + 1040d6: c7 45 e0 00 00 00 38 movl $0x38000000,-0x20(%ebp) + 1040dd: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + } + + extern char end[];// 引入全局变量 end,指向内存的结束位置 + + npage = maxpa / PGSIZE; // 计算可用页数 + 1040e4: 8b 45 e0 mov -0x20(%ebp),%eax + 1040e7: 8b 55 e4 mov -0x1c(%ebp),%edx + 1040ea: 0f ac d0 0c shrd $0xc,%edx,%eax + 1040ee: c1 ea 0c shr $0xc,%edx + 1040f1: a3 04 cf 11 00 mov %eax,0x11cf04 + pages = (struct Page *)ROUNDUP((void *)end, PGSIZE);// 将 end 对齐到页边界,指向页结构数组的开头 + 1040f6: c7 45 c0 00 10 00 00 movl $0x1000,-0x40(%ebp) + 1040fd: b8 8c cf 11 00 mov $0x11cf8c,%eax + 104102: 8d 50 ff lea -0x1(%eax),%edx + 104105: 8b 45 c0 mov -0x40(%ebp),%eax + 104108: 01 d0 add %edx,%eax + 10410a: 89 45 bc mov %eax,-0x44(%ebp) + 10410d: 8b 45 bc mov -0x44(%ebp),%eax + 104110: ba 00 00 00 00 mov $0x0,%edx + 104115: f7 75 c0 divl -0x40(%ebp) + 104118: 8b 45 bc mov -0x44(%ebp),%eax + 10411b: 29 d0 sub %edx,%eax + 10411d: a3 00 cf 11 00 mov %eax,0x11cf00 + + for (i = 0; i < npage; i ++) {// 遍历每一页 + 104122: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 104129: eb 2f jmp 10415a + SetPageReserved(pages + i);// 将每一页标记为保留状态 + 10412b: 8b 0d 00 cf 11 00 mov 0x11cf00,%ecx + 104131: 8b 55 dc mov -0x24(%ebp),%edx + 104134: 89 d0 mov %edx,%eax + 104136: c1 e0 02 shl $0x2,%eax + 104139: 01 d0 add %edx,%eax + 10413b: c1 e0 02 shl $0x2,%eax + 10413e: 01 c8 add %ecx,%eax + 104140: 83 c0 04 add $0x4,%eax + 104143: c7 45 94 00 00 00 00 movl $0x0,-0x6c(%ebp) + 10414a: 89 45 90 mov %eax,-0x70(%ebp) + asm volatile ("btsl %1, %0" :"=m" (*(volatile long *)addr) : "Ir" (nr)); + 10414d: 8b 45 90 mov -0x70(%ebp),%eax + 104150: 8b 55 94 mov -0x6c(%ebp),%edx + 104153: 0f ab 10 bts %edx,(%eax) +} + 104156: 90 nop + for (i = 0; i < npage; i ++) {// 遍历每一页 + 104157: ff 45 dc incl -0x24(%ebp) + 10415a: 8b 55 dc mov -0x24(%ebp),%edx + 10415d: a1 04 cf 11 00 mov 0x11cf04,%eax + 104162: 39 c2 cmp %eax,%edx + 104164: 72 c5 jb 10412b + } + + uintptr_t freemem = PADDR((uintptr_t)pages + sizeof(struct Page) * npage);// 计算可用内存的起始地址 + 104166: 8b 15 04 cf 11 00 mov 0x11cf04,%edx + 10416c: 89 d0 mov %edx,%eax + 10416e: c1 e0 02 shl $0x2,%eax + 104171: 01 d0 add %edx,%eax + 104173: c1 e0 02 shl $0x2,%eax + 104176: 89 c2 mov %eax,%edx + 104178: a1 00 cf 11 00 mov 0x11cf00,%eax + 10417d: 01 d0 add %edx,%eax + 10417f: 89 45 b8 mov %eax,-0x48(%ebp) + 104182: 81 7d b8 ff ff ff bf cmpl $0xbfffffff,-0x48(%ebp) + 104189: 77 23 ja 1041ae + 10418b: 8b 45 b8 mov -0x48(%ebp),%eax + 10418e: 89 44 24 0c mov %eax,0xc(%esp) + 104192: c7 44 24 08 28 6c 10 movl $0x106c28,0x8(%esp) + 104199: 00 + 10419a: c7 44 24 04 0c 01 00 movl $0x10c,0x4(%esp) + 1041a1: 00 + 1041a2: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1041a9: e8 85 ca ff ff call 100c33 <__panic> + 1041ae: 8b 45 b8 mov -0x48(%ebp),%eax + 1041b1: 05 00 00 00 40 add $0x40000000,%eax + 1041b6: 89 45 b4 mov %eax,-0x4c(%ebp) + + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 + 1041b9: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 1041c0: e9 53 01 00 00 jmp 104318 + uint64_t begin = memmap->map[i].addr, end = begin + memmap->map[i].size;// 获取每个区域的起始和结束地址 + 1041c5: 8b 4d c4 mov -0x3c(%ebp),%ecx + 1041c8: 8b 55 dc mov -0x24(%ebp),%edx + 1041cb: 89 d0 mov %edx,%eax + 1041cd: c1 e0 02 shl $0x2,%eax + 1041d0: 01 d0 add %edx,%eax + 1041d2: c1 e0 02 shl $0x2,%eax + 1041d5: 01 c8 add %ecx,%eax + 1041d7: 8b 50 08 mov 0x8(%eax),%edx + 1041da: 8b 40 04 mov 0x4(%eax),%eax + 1041dd: 89 45 d0 mov %eax,-0x30(%ebp) + 1041e0: 89 55 d4 mov %edx,-0x2c(%ebp) + 1041e3: 8b 4d c4 mov -0x3c(%ebp),%ecx + 1041e6: 8b 55 dc mov -0x24(%ebp),%edx + 1041e9: 89 d0 mov %edx,%eax + 1041eb: c1 e0 02 shl $0x2,%eax + 1041ee: 01 d0 add %edx,%eax + 1041f0: c1 e0 02 shl $0x2,%eax + 1041f3: 01 c8 add %ecx,%eax + 1041f5: 8b 48 0c mov 0xc(%eax),%ecx + 1041f8: 8b 58 10 mov 0x10(%eax),%ebx + 1041fb: 8b 45 d0 mov -0x30(%ebp),%eax + 1041fe: 8b 55 d4 mov -0x2c(%ebp),%edx + 104201: 01 c8 add %ecx,%eax + 104203: 11 da adc %ebx,%edx + 104205: 89 45 c8 mov %eax,-0x38(%ebp) + 104208: 89 55 cc mov %edx,-0x34(%ebp) + if (memmap->map[i].type == E820_ARM) {// 如果区域类型为可用内存 + 10420b: 8b 4d c4 mov -0x3c(%ebp),%ecx + 10420e: 8b 55 dc mov -0x24(%ebp),%edx + 104211: 89 d0 mov %edx,%eax + 104213: c1 e0 02 shl $0x2,%eax + 104216: 01 d0 add %edx,%eax + 104218: c1 e0 02 shl $0x2,%eax + 10421b: 01 c8 add %ecx,%eax + 10421d: 83 c0 14 add $0x14,%eax + 104220: 8b 00 mov (%eax),%eax + 104222: 83 f8 01 cmp $0x1,%eax + 104225: 0f 85 ea 00 00 00 jne 104315 + if (begin < freemem) { // 如果起始地址小于可用内存地址 + 10422b: 8b 45 b4 mov -0x4c(%ebp),%eax + 10422e: ba 00 00 00 00 mov $0x0,%edx + 104233: 8b 4d d4 mov -0x2c(%ebp),%ecx + 104236: 39 45 d0 cmp %eax,-0x30(%ebp) + 104239: 19 d1 sbb %edx,%ecx + 10423b: 73 0d jae 10424a + begin = freemem;// 将起始地址设置为可用内存地址 + 10423d: 8b 45 b4 mov -0x4c(%ebp),%eax + 104240: 89 45 d0 mov %eax,-0x30(%ebp) + 104243: c7 45 d4 00 00 00 00 movl $0x0,-0x2c(%ebp) + } + if (end > KMEMSIZE) {// 如果结束地址超过内存上限 + 10424a: ba 00 00 00 38 mov $0x38000000,%edx + 10424f: b8 00 00 00 00 mov $0x0,%eax + 104254: 3b 55 c8 cmp -0x38(%ebp),%edx + 104257: 1b 45 cc sbb -0x34(%ebp),%eax + 10425a: 73 0e jae 10426a + end = KMEMSIZE;// 将其限制为内存上限 + 10425c: c7 45 c8 00 00 00 38 movl $0x38000000,-0x38(%ebp) + 104263: c7 45 cc 00 00 00 00 movl $0x0,-0x34(%ebp) + } + if (begin < end) {// 如果起始地址小于结束地址 + 10426a: 8b 45 d0 mov -0x30(%ebp),%eax + 10426d: 8b 55 d4 mov -0x2c(%ebp),%edx + 104270: 3b 45 c8 cmp -0x38(%ebp),%eax + 104273: 89 d0 mov %edx,%eax + 104275: 1b 45 cc sbb -0x34(%ebp),%eax + 104278: 0f 83 97 00 00 00 jae 104315 + begin = ROUNDUP(begin, PGSIZE);// 将起始地址对齐到页边界 + 10427e: c7 45 b0 00 10 00 00 movl $0x1000,-0x50(%ebp) + 104285: 8b 55 d0 mov -0x30(%ebp),%edx + 104288: 8b 45 b0 mov -0x50(%ebp),%eax + 10428b: 01 d0 add %edx,%eax + 10428d: 48 dec %eax + 10428e: 89 45 ac mov %eax,-0x54(%ebp) + 104291: 8b 45 ac mov -0x54(%ebp),%eax + 104294: ba 00 00 00 00 mov $0x0,%edx + 104299: f7 75 b0 divl -0x50(%ebp) + 10429c: 8b 45 ac mov -0x54(%ebp),%eax + 10429f: 29 d0 sub %edx,%eax + 1042a1: ba 00 00 00 00 mov $0x0,%edx + 1042a6: 89 45 d0 mov %eax,-0x30(%ebp) + 1042a9: 89 55 d4 mov %edx,-0x2c(%ebp) + end = ROUNDDOWN(end, PGSIZE);// 将结束地址对齐到页边界 + 1042ac: 8b 45 c8 mov -0x38(%ebp),%eax + 1042af: 89 45 a8 mov %eax,-0x58(%ebp) + 1042b2: 8b 45 a8 mov -0x58(%ebp),%eax + 1042b5: ba 00 00 00 00 mov $0x0,%edx + 1042ba: 89 c7 mov %eax,%edi + 1042bc: 81 e7 00 f0 ff ff and $0xfffff000,%edi + 1042c2: 89 7d 80 mov %edi,-0x80(%ebp) + 1042c5: 89 d0 mov %edx,%eax + 1042c7: 83 e0 00 and $0x0,%eax + 1042ca: 89 45 84 mov %eax,-0x7c(%ebp) + 1042cd: 8b 45 80 mov -0x80(%ebp),%eax + 1042d0: 8b 55 84 mov -0x7c(%ebp),%edx + 1042d3: 89 45 c8 mov %eax,-0x38(%ebp) + 1042d6: 89 55 cc mov %edx,-0x34(%ebp) + if (begin < end) {// 如果调整后的起始地址仍小于结束地址 + 1042d9: 8b 45 d0 mov -0x30(%ebp),%eax + 1042dc: 8b 55 d4 mov -0x2c(%ebp),%edx + 1042df: 3b 45 c8 cmp -0x38(%ebp),%eax + 1042e2: 89 d0 mov %edx,%eax + 1042e4: 1b 45 cc sbb -0x34(%ebp),%eax + 1042e7: 73 2c jae 104315 + init_memmap(pa2page(begin), (end - begin) / PGSIZE);// 初始化内存页映射 + 1042e9: 8b 45 c8 mov -0x38(%ebp),%eax + 1042ec: 8b 55 cc mov -0x34(%ebp),%edx + 1042ef: 2b 45 d0 sub -0x30(%ebp),%eax + 1042f2: 1b 55 d4 sbb -0x2c(%ebp),%edx + 1042f5: 0f ac d0 0c shrd $0xc,%edx,%eax + 1042f9: c1 ea 0c shr $0xc,%edx + 1042fc: 89 c3 mov %eax,%ebx + 1042fe: 8b 45 d0 mov -0x30(%ebp),%eax + 104301: 89 04 24 mov %eax,(%esp) + 104304: e8 bb f8 ff ff call 103bc4 + 104309: 89 5c 24 04 mov %ebx,0x4(%esp) + 10430d: 89 04 24 mov %eax,(%esp) + 104310: e8 9e fb ff ff call 103eb3 + for (i = 0; i < memmap->nr_map; i ++) {// 再次遍历内存映射 + 104315: ff 45 dc incl -0x24(%ebp) + 104318: 8b 45 c4 mov -0x3c(%ebp),%eax + 10431b: 8b 00 mov (%eax),%eax + 10431d: 39 45 dc cmp %eax,-0x24(%ebp) + 104320: 0f 8c 9f fe ff ff jl 1041c5 + } + } + } + } +} + 104326: 90 nop + 104327: 90 nop + 104328: 81 c4 9c 00 00 00 add $0x9c,%esp + 10432e: 5b pop %ebx + 10432f: 5e pop %esi + 104330: 5f pop %edi + 104331: 5d pop %ebp + 104332: c3 ret + +00104333 : +//la: 需要映射的线性地址(经过 x86 段映射后的地址) +// size: memory size size: 内存大小 +// pa: physical address of this memory pa:该内存的物理地址 +// perm: permission of this memory perm: 该内存的权限 +static void +boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, uintptr_t pa, uint32_t perm) { + 104333: 55 push %ebp + 104334: 89 e5 mov %esp,%ebp + 104336: 83 ec 38 sub $0x38,%esp + // 确保线性地址和物理地址的页偏移相同 + assert(PGOFF(la) == PGOFF(pa)); + 104339: 8b 45 0c mov 0xc(%ebp),%eax + 10433c: 33 45 14 xor 0x14(%ebp),%eax + 10433f: 25 ff 0f 00 00 and $0xfff,%eax + 104344: 85 c0 test %eax,%eax + 104346: 74 24 je 10436c + 104348: c7 44 24 0c 5a 6c 10 movl $0x106c5a,0xc(%esp) + 10434f: 00 + 104350: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104357: 00 + 104358: c7 44 24 04 2d 01 00 movl $0x12d,0x4(%esp) + 10435f: 00 + 104360: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104367: e8 c7 c8 ff ff call 100c33 <__panic> + // 计算需要映射的页数,ROUNDUP 将总大小对齐到下一个页大小的边界 + size_t n = ROUNDUP(size + PGOFF(la), PGSIZE) / PGSIZE; + 10436c: c7 45 f0 00 10 00 00 movl $0x1000,-0x10(%ebp) + 104373: 8b 45 0c mov 0xc(%ebp),%eax + 104376: 25 ff 0f 00 00 and $0xfff,%eax + 10437b: 89 c2 mov %eax,%edx + 10437d: 8b 45 10 mov 0x10(%ebp),%eax + 104380: 01 c2 add %eax,%edx + 104382: 8b 45 f0 mov -0x10(%ebp),%eax + 104385: 01 d0 add %edx,%eax + 104387: 48 dec %eax + 104388: 89 45 ec mov %eax,-0x14(%ebp) + 10438b: 8b 45 ec mov -0x14(%ebp),%eax + 10438e: ba 00 00 00 00 mov $0x0,%edx + 104393: f7 75 f0 divl -0x10(%ebp) + 104396: 8b 45 ec mov -0x14(%ebp),%eax + 104399: 29 d0 sub %edx,%eax + 10439b: c1 e8 0c shr $0xc,%eax + 10439e: 89 45 f4 mov %eax,-0xc(%ebp) + // 将线性地址向下对齐到页边界 + la = ROUNDDOWN(la, PGSIZE); + 1043a1: 8b 45 0c mov 0xc(%ebp),%eax + 1043a4: 89 45 e8 mov %eax,-0x18(%ebp) + 1043a7: 8b 45 e8 mov -0x18(%ebp),%eax + 1043aa: 25 00 f0 ff ff and $0xfffff000,%eax + 1043af: 89 45 0c mov %eax,0xc(%ebp) + // 将物理地址向下对齐到页边界 + pa = ROUNDDOWN(pa, PGSIZE); + 1043b2: 8b 45 14 mov 0x14(%ebp),%eax + 1043b5: 89 45 e4 mov %eax,-0x1c(%ebp) + 1043b8: 8b 45 e4 mov -0x1c(%ebp),%eax + 1043bb: 25 00 f0 ff ff and $0xfffff000,%eax + 1043c0: 89 45 14 mov %eax,0x14(%ebp) + // 循环遍历每一页,直到映射的页数为零 + for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { + 1043c3: eb 68 jmp 10442d + // 获取当前页的页表项指针,如果不存在则创建新的页表项 + pte_t *ptep = get_pte(pgdir, la, 1); + 1043c5: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) + 1043cc: 00 + 1043cd: 8b 45 0c mov 0xc(%ebp),%eax + 1043d0: 89 44 24 04 mov %eax,0x4(%esp) + 1043d4: 8b 45 08 mov 0x8(%ebp),%eax + 1043d7: 89 04 24 mov %eax,(%esp) + 1043da: e8 88 01 00 00 call 104567 + 1043df: 89 45 e0 mov %eax,-0x20(%ebp) + // 确保页表项指针不为空 + assert(ptep != NULL); + 1043e2: 83 7d e0 00 cmpl $0x0,-0x20(%ebp) + 1043e6: 75 24 jne 10440c + 1043e8: c7 44 24 0c 86 6c 10 movl $0x106c86,0xc(%esp) + 1043ef: 00 + 1043f0: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 1043f7: 00 + 1043f8: c7 44 24 04 39 01 00 movl $0x139,0x4(%esp) + 1043ff: 00 + 104400: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104407: e8 27 c8 ff ff call 100c33 <__panic> + // 设置页表项,包含物理地址、存在位和权限 + *ptep = pa | PTE_P | perm; + 10440c: 8b 45 14 mov 0x14(%ebp),%eax + 10440f: 0b 45 18 or 0x18(%ebp),%eax + 104412: 83 c8 01 or $0x1,%eax + 104415: 89 c2 mov %eax,%edx + 104417: 8b 45 e0 mov -0x20(%ebp),%eax + 10441a: 89 10 mov %edx,(%eax) + for (; n > 0; n --, la += PGSIZE, pa += PGSIZE) { + 10441c: ff 4d f4 decl -0xc(%ebp) + 10441f: 81 45 0c 00 10 00 00 addl $0x1000,0xc(%ebp) + 104426: 81 45 14 00 10 00 00 addl $0x1000,0x14(%ebp) + 10442d: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 104431: 75 92 jne 1043c5 + } +} + 104433: 90 nop + 104434: 90 nop + 104435: 89 ec mov %ebp,%esp + 104437: 5d pop %ebp + 104438: c3 ret + +00104439 : +// return value: the kernel virtual address of this allocated page +//note: this function is used to get the memory for PDT(Page Directory Table)&PT(Page Table) +//boot_alloc_page - 使用 pmm->alloc_pages(1) 分配一页内存.返回值: 分配的页面的内核虚拟地址 +//注意: 此函数用于获取页目录表(PDT)和页表(PT)的内存 +static void * +boot_alloc_page(void) { + 104439: 55 push %ebp + 10443a: 89 e5 mov %esp,%ebp + 10443c: 83 ec 28 sub $0x28,%esp + struct Page *p = alloc_page();// 调用分配页面的函数 + 10443f: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 104446: e8 8a fa ff ff call 103ed5 + 10444b: 89 45 f4 mov %eax,-0xc(%ebp) + if (p == NULL) {// 检查分配是否成功 + 10444e: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 104452: 75 1c jne 104470 + panic("boot_alloc_page failed.\n");// 如果分配失败,则触发异常 + 104454: c7 44 24 08 93 6c 10 movl $0x106c93,0x8(%esp) + 10445b: 00 + 10445c: c7 44 24 04 48 01 00 movl $0x148,0x4(%esp) + 104463: 00 + 104464: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10446b: e8 c3 c7 ff ff call 100c33 <__panic> + } + return page2kva(p);// 返回分配页面的内核虚拟地址 + 104470: 8b 45 f4 mov -0xc(%ebp),%eax + 104473: 89 04 24 mov %eax,(%esp) + 104476: e8 9a f7 ff ff call 103c15 +} + 10447b: 89 ec mov %ebp,%esp + 10447d: 5d pop %ebp + 10447e: c3 ret + +0010447f : +//pmm_init - setup a pmm to manage physical memory, build PDT&PT to setup paging mechanism +// - check the correctness of pmm & paging mechanism, print PDT&PT +//pmm_init - 设置物理内存管理器,构建页目录表(PDT)和页表(PT),以设置分页机制 +// - 检查物理内存管理器和分页机制的正确性,打印页目录表和页表 +void +pmm_init(void) { + 10447f: 55 push %ebp + 104480: 89 e5 mov %esp,%ebp + 104482: 83 ec 38 sub $0x38,%esp + // We've already enabled paging + // 我们已经启用了分页 + boot_cr3 = PADDR(boot_pgdir); + 104485: a1 e0 99 11 00 mov 0x1199e0,%eax + 10448a: 89 45 f4 mov %eax,-0xc(%ebp) + 10448d: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) + 104494: 77 23 ja 1044b9 + 104496: 8b 45 f4 mov -0xc(%ebp),%eax + 104499: 89 44 24 0c mov %eax,0xc(%esp) + 10449d: c7 44 24 08 28 6c 10 movl $0x106c28,0x8(%esp) + 1044a4: 00 + 1044a5: c7 44 24 04 55 01 00 movl $0x155,0x4(%esp) + 1044ac: 00 + 1044ad: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1044b4: e8 7a c7 ff ff call 100c33 <__panic> + 1044b9: 8b 45 f4 mov -0xc(%ebp),%eax + 1044bc: 05 00 00 00 40 add $0x40000000,%eax + 1044c1: a3 08 cf 11 00 mov %eax,0x11cf08 + // 我们需要分配/释放物理内存(粒度为 4KB 或其他大小)。 + // 因此在 pmm.h 中定义了物理内存管理器的框架(struct pmm_manager)。 + // 首先,我们应该基于该框架初始化一个物理内存管理器(pmm)。 + // 然后 pmm 可以分配/释放物理内存。 + // 现在,first_fit/best_fit/worst_fit/buddy_system 的 pmm 都可用。 + init_pmm_manager();// 初始化物理内存管理器 + 1044c6: e8 b2 f9 ff ff call 103e7d + + // detect physical memory space, reserve already used memory, + // then use pmm->init_memmap to create free page list + // 检测物理内存空间,保留已经使用的内存, + // 然后使用 pmm->init_memmap 创建空闲页面列表 + page_init();// 初始化页面管理 + 1044cb: e8 a1 fa ff ff call 103f71 + + //use pmm->check to verify the correctness of the alloc/free function in a pmm + // 使用 pmm->check 验证 pmm 中分配/释放函数的正确性 + check_alloc_page();// 检查页面分配功能 + 1044d0: e8 ed 03 00 00 call 1048c2 + + check_pgdir();// 检查页目录的状态 + 1044d5: e8 09 04 00 00 call 1048e3 + + // recursively insert boot_pgdir in itself + // to form a virtual page table at virtual address VPT + // 递归地将 boot_pgdir 插入到自身中 + // 在虚拟地址 VPT 处形成虚拟页表 + boot_pgdir[PDX(VPT)] = PADDR(boot_pgdir) | PTE_P | PTE_W;// 设置页目录项,映射自身 + 1044da: a1 e0 99 11 00 mov 0x1199e0,%eax + 1044df: 89 45 f0 mov %eax,-0x10(%ebp) + 1044e2: 81 7d f0 ff ff ff bf cmpl $0xbfffffff,-0x10(%ebp) + 1044e9: 77 23 ja 10450e + 1044eb: 8b 45 f0 mov -0x10(%ebp),%eax + 1044ee: 89 44 24 0c mov %eax,0xc(%esp) + 1044f2: c7 44 24 08 28 6c 10 movl $0x106c28,0x8(%esp) + 1044f9: 00 + 1044fa: c7 44 24 04 75 01 00 movl $0x175,0x4(%esp) + 104501: 00 + 104502: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104509: e8 25 c7 ff ff call 100c33 <__panic> + 10450e: 8b 45 f0 mov -0x10(%ebp),%eax + 104511: 8d 90 00 00 00 40 lea 0x40000000(%eax),%edx + 104517: a1 e0 99 11 00 mov 0x1199e0,%eax + 10451c: 05 ac 0f 00 00 add $0xfac,%eax + 104521: 83 ca 03 or $0x3,%edx + 104524: 89 10 mov %edx,(%eax) + + // map all physical memory to linear memory with base linear addr KERNBASE + // linear_addr KERNBASE ~ KERNBASE + KMEMSIZE = phy_addr 0 ~ KMEMSIZE + // 将所有物理内存映射到线性内存,基地址为 KERNBASE + // 线性地址 KERNBASE ~ KERNBASE + KMEMSIZE = 物理地址 0 ~ KMEMSIZE + boot_map_segment(boot_pgdir, KERNBASE, KMEMSIZE, 0, PTE_W);// 映射物理内存 + 104526: a1 e0 99 11 00 mov 0x1199e0,%eax + 10452b: c7 44 24 10 02 00 00 movl $0x2,0x10(%esp) + 104532: 00 + 104533: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) + 10453a: 00 + 10453b: c7 44 24 08 00 00 00 movl $0x38000000,0x8(%esp) + 104542: 38 + 104543: c7 44 24 04 00 00 00 movl $0xc0000000,0x4(%esp) + 10454a: c0 + 10454b: 89 04 24 mov %eax,(%esp) + 10454e: e8 e0 fd ff ff call 104333 + // then set kernel stack (ss:esp) in TSS, setup TSS in gdt, load TSS + // 由于我们正在使用引导加载程序的 GDT, + // 我们应该重新加载 GDT(第二次,也是最后一次),以获取用户段和 TSS + // 映射虚拟地址 0 ~ 4G = 线性地址 0 ~ 4G + // 然后在 TSS 中设置内核栈 (ss:esp),在 gdt 中设置 TSS,加载 TSS + gdt_init();// 初始化全局描述符表 + 104553: e8 39 f8 ff ff call 103d91 + + //now the basic virtual memory map(see memalyout.h) is established. + //check the correctness of the basic virtual memory map. + // 现在基本的虚拟内存映射(见 memlayout.h)已建立。 + // 检查基础虚拟内存映射的正确性。 + check_boot_pgdir(); // 检查页目录的正确性 + 104558: e8 24 0a 00 00 call 104f81 + + print_pgdir(); // 打印页目录表 + 10455d: e8 a1 0e 00 00 call 105403 + +} + 104562: 90 nop + 104563: 89 ec mov %ebp,%esp + 104565: 5d pop %ebp + 104566: c3 ret + +00104567 : +// pgdir: 页目录的内核虚拟基地址 +// la: 需要映射的线性地址 +// create: 一个逻辑值,决定是否为页表分配一页 +// 返回值:该 PTE 的内核虚拟地址 +pte_t * +get_pte(pde_t *pgdir, uintptr_t la, bool create) { + 104567: 55 push %ebp + 104568: 89 e5 mov %esp,%ebp + 10456a: 83 ec 38 sub $0x38,%esp + // (7) set page directory entry's permission + } + return NULL; // (8) return page table entry +#endif + // (1) 找到页目录项 + pde_t *pdep = &pgdir[PDX(la)];// 使用 PDX 宏获取页目录索引 + 10456d: 8b 45 0c mov 0xc(%ebp),%eax + 104570: c1 e8 16 shr $0x16,%eax + 104573: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx + 10457a: 8b 45 08 mov 0x8(%ebp),%eax + 10457d: 01 d0 add %edx,%eax + 10457f: 89 45 f4 mov %eax,-0xc(%ebp) + // (2) 检查页目录项是否存在 + if (!(*pdep & PTE_P)) {// 如果页目录项的存在位 PTE_P 没有被设置 + 104582: 8b 45 f4 mov -0xc(%ebp),%eax + 104585: 8b 00 mov (%eax),%eax + 104587: 83 e0 01 and $0x1,%eax + 10458a: 85 c0 test %eax,%eax + 10458c: 0f 85 af 00 00 00 jne 104641 + struct Page *page;// 声明一个指针,用于指向新分配的页面 + // 检查是否允许创建新页表,或者分配页表失败 + if (!create || (page = alloc_page()) == NULL) {// 如果不允许创建或分配失败 + 104592: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 104596: 74 15 je 1045ad + 104598: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 10459f: e8 31 f9 ff ff call 103ed5 + 1045a4: 89 45 f0 mov %eax,-0x10(%ebp) + 1045a7: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 1045ab: 75 0a jne 1045b7 + return NULL;// 返回 NULL,表示无法获取页表 + 1045ad: b8 00 00 00 00 mov $0x0,%eax + 1045b2: e9 e7 00 00 00 jmp 10469e + } + // 设置新分配页面的引用计数为 1 + set_page_ref(page, 1); + 1045b7: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1045be: 00 + 1045bf: 8b 45 f0 mov -0x10(%ebp),%eax + 1045c2: 89 04 24 mov %eax,(%esp) + 1045c5: e8 05 f7 ff ff call 103ccf + uintptr_t pa = page2pa(page);// 获取新分配页面的物理地址 + 1045ca: 8b 45 f0 mov -0x10(%ebp),%eax + 1045cd: 89 04 24 mov %eax,(%esp) + 1045d0: e8 d7 f5 ff ff call 103bac + 1045d5: 89 45 ec mov %eax,-0x14(%ebp) + memset(KADDR(pa), 0, PGSIZE);// 清空新分配的页表内容,初始化为零 + 1045d8: 8b 45 ec mov -0x14(%ebp),%eax + 1045db: 89 45 e8 mov %eax,-0x18(%ebp) + 1045de: 8b 45 e8 mov -0x18(%ebp),%eax + 1045e1: c1 e8 0c shr $0xc,%eax + 1045e4: 89 45 e4 mov %eax,-0x1c(%ebp) + 1045e7: a1 04 cf 11 00 mov 0x11cf04,%eax + 1045ec: 39 45 e4 cmp %eax,-0x1c(%ebp) + 1045ef: 72 23 jb 104614 + 1045f1: 8b 45 e8 mov -0x18(%ebp),%eax + 1045f4: 89 44 24 0c mov %eax,0xc(%esp) + 1045f8: c7 44 24 08 84 6b 10 movl $0x106b84,0x8(%esp) + 1045ff: 00 + 104600: c7 44 24 04 ce 01 00 movl $0x1ce,0x4(%esp) + 104607: 00 + 104608: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10460f: e8 1f c6 ff ff call 100c33 <__panic> + 104614: 8b 45 e8 mov -0x18(%ebp),%eax + 104617: 2d 00 00 00 40 sub $0x40000000,%eax + 10461c: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) + 104623: 00 + 104624: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 10462b: 00 + 10462c: 89 04 24 mov %eax,(%esp) + 10462f: e8 d4 18 00 00 call 105f08 + // 更新页目录项,设置物理地址和权限位 + *pdep = pa | PTE_U | PTE_W | PTE_P;// 将物理地址和权限位(用户可访问、可写、有效)合并设置 + 104634: 8b 45 ec mov -0x14(%ebp),%eax + 104637: 83 c8 07 or $0x7,%eax + 10463a: 89 c2 mov %eax,%edx + 10463c: 8b 45 f4 mov -0xc(%ebp),%eax + 10463f: 89 10 mov %edx,(%eax) + } + // 返回指定线性地址 la 对应的页表项的内核虚拟地址 + return &((pte_t *)KADDR(PDE_ADDR(*pdep)))[PTX(la)];// 计算并返回页表项的指针 + 104641: 8b 45 f4 mov -0xc(%ebp),%eax + 104644: 8b 00 mov (%eax),%eax + 104646: 25 00 f0 ff ff and $0xfffff000,%eax + 10464b: 89 45 e0 mov %eax,-0x20(%ebp) + 10464e: 8b 45 e0 mov -0x20(%ebp),%eax + 104651: c1 e8 0c shr $0xc,%eax + 104654: 89 45 dc mov %eax,-0x24(%ebp) + 104657: a1 04 cf 11 00 mov 0x11cf04,%eax + 10465c: 39 45 dc cmp %eax,-0x24(%ebp) + 10465f: 72 23 jb 104684 + 104661: 8b 45 e0 mov -0x20(%ebp),%eax + 104664: 89 44 24 0c mov %eax,0xc(%esp) + 104668: c7 44 24 08 84 6b 10 movl $0x106b84,0x8(%esp) + 10466f: 00 + 104670: c7 44 24 04 d3 01 00 movl $0x1d3,0x4(%esp) + 104677: 00 + 104678: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10467f: e8 af c5 ff ff call 100c33 <__panic> + 104684: 8b 45 e0 mov -0x20(%ebp),%eax + 104687: 2d 00 00 00 40 sub $0x40000000,%eax + 10468c: 89 c2 mov %eax,%edx + 10468e: 8b 45 0c mov 0xc(%ebp),%eax + 104691: c1 e8 0c shr $0xc,%eax + 104694: 25 ff 03 00 00 and $0x3ff,%eax + 104699: c1 e0 02 shl $0x2,%eax + 10469c: 01 d0 add %edx,%eax +} + 10469e: 89 ec mov %ebp,%esp + 1046a0: 5d pop %ebp + 1046a1: c3 ret + +001046a2 : + +//get_page - get related Page struct for linear address la using PDT pgdir +// get_page - 获取与线性地址 la 相关的 Page 结构体,使用页目录 pgdir +struct Page * +get_page(pde_t *pgdir, uintptr_t la, pte_t **ptep_store) { + 1046a2: 55 push %ebp + 1046a3: 89 e5 mov %esp,%ebp + 1046a5: 83 ec 28 sub $0x28,%esp + // 调用 get_pte 函数获取对应线性地址 la 的页表项指针 + pte_t *ptep = get_pte(pgdir, la, 0); + 1046a8: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 1046af: 00 + 1046b0: 8b 45 0c mov 0xc(%ebp),%eax + 1046b3: 89 44 24 04 mov %eax,0x4(%esp) + 1046b7: 8b 45 08 mov 0x8(%ebp),%eax + 1046ba: 89 04 24 mov %eax,(%esp) + 1046bd: e8 a5 fe ff ff call 104567 + 1046c2: 89 45 f4 mov %eax,-0xc(%ebp) + // 如果 ptep_store 指针不为 NULL,将 ptep 存储到 ptep_store 指向的位置 + if (ptep_store != NULL) { + 1046c5: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 1046c9: 74 08 je 1046d3 + *ptep_store = ptep; // 存储当前页表项的指针 + 1046cb: 8b 45 10 mov 0x10(%ebp),%eax + 1046ce: 8b 55 f4 mov -0xc(%ebp),%edx + 1046d1: 89 10 mov %edx,(%eax) + } + // 检查 ptep 是否有效以及页表项的存在位 PTE_P 是否被设置 + if (ptep != NULL && *ptep & PTE_P) { + 1046d3: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 1046d7: 74 1b je 1046f4 + 1046d9: 8b 45 f4 mov -0xc(%ebp),%eax + 1046dc: 8b 00 mov (%eax),%eax + 1046de: 83 e0 01 and $0x1,%eax + 1046e1: 85 c0 test %eax,%eax + 1046e3: 74 0f je 1046f4 + // 返回与页表项对应的 Page 结构体 + return pte2page(*ptep);// 将页表项转换为对应的 Page 结构 + 1046e5: 8b 45 f4 mov -0xc(%ebp),%eax + 1046e8: 8b 00 mov (%eax),%eax + 1046ea: 89 04 24 mov %eax,(%esp) + 1046ed: e8 79 f5 ff ff call 103c6b + 1046f2: eb 05 jmp 1046f9 + } + // 如果未找到有效的页,返回 NULL + return NULL; + 1046f4: b8 00 00 00 00 mov $0x0,%eax +} + 1046f9: 89 ec mov %ebp,%esp + 1046fb: 5d pop %ebp + 1046fc: c3 ret + +001046fd : + +//page_remove_pte - free an Page sturct which is related linear address la +// - and clean(invalidate) pte which is related linear address la +//note: PT is changed, so the TLB need to be invalidate +static inline void +page_remove_pte(pde_t *pgdir, uintptr_t la, pte_t *ptep) { + 1046fd: 55 push %ebp + 1046fe: 89 e5 mov %esp,%ebp + 104700: 83 ec 28 sub $0x28,%esp + //(4) and free this page when page reference reachs 0 + //(5) clear second page table entry + //(6) flush tlb + } +#endif + if (*ptep & PTE_P) { + 104703: 8b 45 10 mov 0x10(%ebp),%eax + 104706: 8b 00 mov (%eax),%eax + 104708: 83 e0 01 and $0x1,%eax + 10470b: 85 c0 test %eax,%eax + 10470d: 74 4d je 10475c + struct Page *page = pte2page(*ptep);// 找到对应的物理页 + 10470f: 8b 45 10 mov 0x10(%ebp),%eax + 104712: 8b 00 mov (%eax),%eax + 104714: 89 04 24 mov %eax,(%esp) + 104717: e8 4f f5 ff ff call 103c6b + 10471c: 89 45 f4 mov %eax,-0xc(%ebp) + // 减少物理页的引用计数,如果引用计数为零,释放该物理页 + if (page_ref_dec(page) == 0) { + 10471f: 8b 45 f4 mov -0xc(%ebp),%eax + 104722: 89 04 24 mov %eax,(%esp) + 104725: e8 ca f5 ff ff call 103cf4 + 10472a: 85 c0 test %eax,%eax + 10472c: 75 13 jne 104741 + free_page(page); + 10472e: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 104735: 00 + 104736: 8b 45 f4 mov -0xc(%ebp),%eax + 104739: 89 04 24 mov %eax,(%esp) + 10473c: e8 ce f7 ff ff call 103f0f + } + *ptep = 0;// 清除页表项 + 104741: 8b 45 10 mov 0x10(%ebp),%eax + 104744: c7 00 00 00 00 00 movl $0x0,(%eax) + tlb_invalidate(pgdir, la);// 刷新 TLB + 10474a: 8b 45 0c mov 0xc(%ebp),%eax + 10474d: 89 44 24 04 mov %eax,0x4(%esp) + 104751: 8b 45 08 mov 0x8(%ebp),%eax + 104754: 89 04 24 mov %eax,(%esp) + 104757: e8 07 01 00 00 call 104863 + } +} + 10475c: 90 nop + 10475d: 89 ec mov %ebp,%esp + 10475f: 5d pop %ebp + 104760: c3 ret + +00104761 : + +//page_remove - free an Page which is related linear address la and has an validated pte +//移除一个虚拟地址对应的页面 +void +page_remove(pde_t *pgdir, uintptr_t la) { + 104761: 55 push %ebp + 104762: 89 e5 mov %esp,%ebp + 104764: 83 ec 28 sub $0x28,%esp + //调用 get_pte 函数获取给定虚拟地址 la 对应的页表项指针 ptep。 + pte_t *ptep = get_pte(pgdir, la, 0); + 104767: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 10476e: 00 + 10476f: 8b 45 0c mov 0xc(%ebp),%eax + 104772: 89 44 24 04 mov %eax,0x4(%esp) + 104776: 8b 45 08 mov 0x8(%ebp),%eax + 104779: 89 04 24 mov %eax,(%esp) + 10477c: e8 e6 fd ff ff call 104567 + 104781: 89 45 f4 mov %eax,-0xc(%ebp) + //如果 ptep 不为 NULL,则调用 page_remove_pte 函数移除该页表项。 + if (ptep != NULL) { + 104784: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 104788: 74 19 je 1047a3 + page_remove_pte(pgdir, la, ptep); + 10478a: 8b 45 f4 mov -0xc(%ebp),%eax + 10478d: 89 44 24 08 mov %eax,0x8(%esp) + 104791: 8b 45 0c mov 0xc(%ebp),%eax + 104794: 89 44 24 04 mov %eax,0x4(%esp) + 104798: 8b 45 08 mov 0x8(%ebp),%eax + 10479b: 89 04 24 mov %eax,(%esp) + 10479e: e8 5a ff ff ff call 1046fd + } +} + 1047a3: 90 nop + 1047a4: 89 ec mov %ebp,%esp + 1047a6: 5d pop %ebp + 1047a7: c3 ret + +001047a8 : +// perm: the permission of this Page which is setted in related pte +// return value: always 0 +//note: PT is changed, so the TLB need to be invalidate +//将一个页面插入到页表中。 +int +page_insert(pde_t *pgdir, struct Page *page, uintptr_t la, uint32_t perm) { + 1047a8: 55 push %ebp + 1047a9: 89 e5 mov %esp,%ebp + 1047ab: 83 ec 28 sub $0x28,%esp + //通过 get_pte 函数获取指定虚拟地址 la 对应的页表项指针 ptep。 + pte_t *ptep = get_pte(pgdir, la, 1); + 1047ae: c7 44 24 08 01 00 00 movl $0x1,0x8(%esp) + 1047b5: 00 + 1047b6: 8b 45 10 mov 0x10(%ebp),%eax + 1047b9: 89 44 24 04 mov %eax,0x4(%esp) + 1047bd: 8b 45 08 mov 0x8(%ebp),%eax + 1047c0: 89 04 24 mov %eax,(%esp) + 1047c3: e8 9f fd ff ff call 104567 + 1047c8: 89 45 f4 mov %eax,-0xc(%ebp) + //如果 ptep 为 NULL,表示内存分配失败,返回 -E_NO_MEM。 + if (ptep == NULL) { + 1047cb: 83 7d f4 00 cmpl $0x0,-0xc(%ebp) + 1047cf: 75 0a jne 1047db + return -E_NO_MEM; + 1047d1: b8 fc ff ff ff mov $0xfffffffc,%eax + 1047d6: e9 84 00 00 00 jmp 10485f + } + //调用 page_ref_inc 增加页面的引用计数。 + page_ref_inc(page); + 1047db: 8b 45 0c mov 0xc(%ebp),%eax + 1047de: 89 04 24 mov %eax,(%esp) + 1047e1: e8 f7 f4 ff ff call 103cdd + //如果页表项已存在且指向当前页面,则减少页面引用计数。 + if (*ptep & PTE_P) { + 1047e6: 8b 45 f4 mov -0xc(%ebp),%eax + 1047e9: 8b 00 mov (%eax),%eax + 1047eb: 83 e0 01 and $0x1,%eax + 1047ee: 85 c0 test %eax,%eax + 1047f0: 74 3e je 104830 + struct Page *p = pte2page(*ptep); + 1047f2: 8b 45 f4 mov -0xc(%ebp),%eax + 1047f5: 8b 00 mov (%eax),%eax + 1047f7: 89 04 24 mov %eax,(%esp) + 1047fa: e8 6c f4 ff ff call 103c6b + 1047ff: 89 45 f0 mov %eax,-0x10(%ebp) + if (p == page) { + 104802: 8b 45 f0 mov -0x10(%ebp),%eax + 104805: 3b 45 0c cmp 0xc(%ebp),%eax + 104808: 75 0d jne 104817 + page_ref_dec(page); + 10480a: 8b 45 0c mov 0xc(%ebp),%eax + 10480d: 89 04 24 mov %eax,(%esp) + 104810: e8 df f4 ff ff call 103cf4 + 104815: eb 19 jmp 104830 + } + //如果页表项已存在但指向其他页面,则调用 page_remove_pte 移除旧的页表项。 + else { + page_remove_pte(pgdir, la, ptep); + 104817: 8b 45 f4 mov -0xc(%ebp),%eax + 10481a: 89 44 24 08 mov %eax,0x8(%esp) + 10481e: 8b 45 10 mov 0x10(%ebp),%eax + 104821: 89 44 24 04 mov %eax,0x4(%esp) + 104825: 8b 45 08 mov 0x8(%ebp),%eax + 104828: 89 04 24 mov %eax,(%esp) + 10482b: e8 cd fe ff ff call 1046fd + } + } + *ptep = page2pa(page) | PTE_P | perm; + 104830: 8b 45 0c mov 0xc(%ebp),%eax + 104833: 89 04 24 mov %eax,(%esp) + 104836: e8 71 f3 ff ff call 103bac + 10483b: 0b 45 14 or 0x14(%ebp),%eax + 10483e: 83 c8 01 or $0x1,%eax + 104841: 89 c2 mov %eax,%edx + 104843: 8b 45 f4 mov -0xc(%ebp),%eax + 104846: 89 10 mov %edx,(%eax) + tlb_invalidate(pgdir, la);//刷新 TLB + 104848: 8b 45 10 mov 0x10(%ebp),%eax + 10484b: 89 44 24 04 mov %eax,0x4(%esp) + 10484f: 8b 45 08 mov 0x8(%ebp),%eax + 104852: 89 04 24 mov %eax,(%esp) + 104855: e8 09 00 00 00 call 104863 + return 0; + 10485a: b8 00 00 00 00 mov $0x0,%eax +} + 10485f: 89 ec mov %ebp,%esp + 104861: 5d pop %ebp + 104862: c3 ret + +00104863 : + +// invalidate a TLB entry, but only if the page tables being +// edited are the ones currently in use by the processor. +//无效化指定地址的TLB条目 +void +tlb_invalidate(pde_t *pgdir, uintptr_t la) { + 104863: 55 push %ebp + 104864: 89 e5 mov %esp,%ebp + 104866: 83 ec 28 sub $0x28,%esp +} + +static inline uintptr_t +rcr3(void) { + uintptr_t cr3; + asm volatile ("mov %%cr3, %0" : "=r" (cr3) :: "memory"); + 104869: 0f 20 d8 mov %cr3,%eax + 10486c: 89 45 f0 mov %eax,-0x10(%ebp) + return cr3; + 10486f: 8b 55 f0 mov -0x10(%ebp),%edx + //检查当前页目录地址是否与传入的页目录地址相同。 + if (rcr3() == PADDR(pgdir)) { + 104872: 8b 45 08 mov 0x8(%ebp),%eax + 104875: 89 45 f4 mov %eax,-0xc(%ebp) + 104878: 81 7d f4 ff ff ff bf cmpl $0xbfffffff,-0xc(%ebp) + 10487f: 77 23 ja 1048a4 + 104881: 8b 45 f4 mov -0xc(%ebp),%eax + 104884: 89 44 24 0c mov %eax,0xc(%esp) + 104888: c7 44 24 08 28 6c 10 movl $0x106c28,0x8(%esp) + 10488f: 00 + 104890: c7 44 24 04 47 02 00 movl $0x247,0x4(%esp) + 104897: 00 + 104898: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10489f: e8 8f c3 ff ff call 100c33 <__panic> + 1048a4: 8b 45 f4 mov -0xc(%ebp),%eax + 1048a7: 05 00 00 00 40 add $0x40000000,%eax + 1048ac: 39 d0 cmp %edx,%eax + 1048ae: 75 0d jne 1048bd + //如果相同,则调用 invlpg 函数无效化指定线性地址的TLB条目。 + invlpg((void *)la); + 1048b0: 8b 45 0c mov 0xc(%ebp),%eax + 1048b3: 89 45 ec mov %eax,-0x14(%ebp) +} + +static inline void +invlpg(void *addr) { + asm volatile ("invlpg (%0)" :: "r" (addr) : "memory"); + 1048b6: 8b 45 ec mov -0x14(%ebp),%eax + 1048b9: 0f 01 38 invlpg (%eax) +} + 1048bc: 90 nop + } +} + 1048bd: 90 nop + 1048be: 89 ec mov %ebp,%esp + 1048c0: 5d pop %ebp + 1048c1: c3 ret + +001048c2 : + +static void +check_alloc_page(void) { + 1048c2: 55 push %ebp + 1048c3: 89 e5 mov %esp,%ebp + 1048c5: 83 ec 18 sub $0x18,%esp + //调用内存管理器的 check 方法,用于检查内存分配是否正常。 + pmm_manager->check(); + 1048c8: a1 0c cf 11 00 mov 0x11cf0c,%eax + 1048cd: 8b 40 18 mov 0x18(%eax),%eax + 1048d0: ff d0 call *%eax + cprintf("check_alloc_page() succeeded!\n"); + 1048d2: c7 04 24 ac 6c 10 00 movl $0x106cac,(%esp) + 1048d9: e8 88 ba ff ff call 100366 +} + 1048de: 90 nop + 1048df: 89 ec mov %ebp,%esp + 1048e1: 5d pop %ebp + 1048e2: c3 ret + +001048e3 : +//用于验证页目录和页表的正确性。 +static void +check_pgdir(void) { + 1048e3: 55 push %ebp + 1048e4: 89 e5 mov %esp,%ebp + 1048e6: 83 ec 38 sub $0x38,%esp + //确保内存页面数量在合理范围内 + assert(npage <= KMEMSIZE / PGSIZE); + 1048e9: a1 04 cf 11 00 mov 0x11cf04,%eax + 1048ee: 3d 00 80 03 00 cmp $0x38000,%eax + 1048f3: 76 24 jbe 104919 + 1048f5: c7 44 24 0c cb 6c 10 movl $0x106ccb,0xc(%esp) + 1048fc: 00 + 1048fd: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104904: 00 + 104905: c7 44 24 04 57 02 00 movl $0x257,0x4(%esp) + 10490c: 00 + 10490d: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104914: e8 1a c3 ff ff call 100c33 <__panic> + //确保页目录不为空且对齐, + assert(boot_pgdir != NULL && (uint32_t)PGOFF(boot_pgdir) == 0); + 104919: a1 e0 99 11 00 mov 0x1199e0,%eax + 10491e: 85 c0 test %eax,%eax + 104920: 74 0e je 104930 + 104922: a1 e0 99 11 00 mov 0x1199e0,%eax + 104927: 25 ff 0f 00 00 and $0xfff,%eax + 10492c: 85 c0 test %eax,%eax + 10492e: 74 24 je 104954 + 104930: c7 44 24 0c e8 6c 10 movl $0x106ce8,0xc(%esp) + 104937: 00 + 104938: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 10493f: 00 + 104940: c7 44 24 04 59 02 00 movl $0x259,0x4(%esp) + 104947: 00 + 104948: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10494f: e8 df c2 ff ff call 100c33 <__panic> + //确保虚拟地址 0x0 没有映射任何页面 + assert(get_page(boot_pgdir, 0x0, NULL) == NULL); + 104954: a1 e0 99 11 00 mov 0x1199e0,%eax + 104959: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 104960: 00 + 104961: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 104968: 00 + 104969: 89 04 24 mov %eax,(%esp) + 10496c: e8 31 fd ff ff call 1046a2 + 104971: 85 c0 test %eax,%eax + 104973: 74 24 je 104999 + 104975: c7 44 24 0c 20 6d 10 movl $0x106d20,0xc(%esp) + 10497c: 00 + 10497d: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104984: 00 + 104985: c7 44 24 04 5b 02 00 movl $0x25b,0x4(%esp) + 10498c: 00 + 10498d: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104994: e8 9a c2 ff ff call 100c33 <__panic> + + //定义两个页面指针 p1 和 p2 + struct Page *p1, *p2; + //分配一个页面 p1 + p1 = alloc_page(); + 104999: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 1049a0: e8 30 f5 ff ff call 103ed5 + 1049a5: 89 45 f4 mov %eax,-0xc(%ebp) + //将 p1 插入到虚拟地址 0x0 + assert(page_insert(boot_pgdir, p1, 0x0, 0) == 0); + 1049a8: a1 e0 99 11 00 mov 0x1199e0,%eax + 1049ad: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) + 1049b4: 00 + 1049b5: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 1049bc: 00 + 1049bd: 8b 55 f4 mov -0xc(%ebp),%edx + 1049c0: 89 54 24 04 mov %edx,0x4(%esp) + 1049c4: 89 04 24 mov %eax,(%esp) + 1049c7: e8 dc fd ff ff call 1047a8 + 1049cc: 85 c0 test %eax,%eax + 1049ce: 74 24 je 1049f4 + 1049d0: c7 44 24 0c 48 6d 10 movl $0x106d48,0xc(%esp) + 1049d7: 00 + 1049d8: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 1049df: 00 + 1049e0: c7 44 24 04 62 02 00 movl $0x262,0x4(%esp) + 1049e7: 00 + 1049e8: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1049ef: e8 3f c2 ff ff call 100c33 <__panic> + + // 获取虚拟地址 0x0 对应的页表项指针 + pte_t *ptep; + assert((ptep = get_pte(boot_pgdir, 0x0, 0)) != NULL); + 1049f4: a1 e0 99 11 00 mov 0x1199e0,%eax + 1049f9: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 104a00: 00 + 104a01: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 104a08: 00 + 104a09: 89 04 24 mov %eax,(%esp) + 104a0c: e8 56 fb ff ff call 104567 + 104a11: 89 45 f0 mov %eax,-0x10(%ebp) + 104a14: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 104a18: 75 24 jne 104a3e + 104a1a: c7 44 24 0c 74 6d 10 movl $0x106d74,0xc(%esp) + 104a21: 00 + 104a22: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104a29: 00 + 104a2a: c7 44 24 04 66 02 00 movl $0x266,0x4(%esp) + 104a31: 00 + 104a32: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104a39: e8 f5 c1 ff ff call 100c33 <__panic> + // 验证页表项对应的页面是 p1 + assert(pte2page(*ptep) == p1); + 104a3e: 8b 45 f0 mov -0x10(%ebp),%eax + 104a41: 8b 00 mov (%eax),%eax + 104a43: 89 04 24 mov %eax,(%esp) + 104a46: e8 20 f2 ff ff call 103c6b + 104a4b: 39 45 f4 cmp %eax,-0xc(%ebp) + 104a4e: 74 24 je 104a74 + 104a50: c7 44 24 0c a1 6d 10 movl $0x106da1,0xc(%esp) + 104a57: 00 + 104a58: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104a5f: 00 + 104a60: c7 44 24 04 68 02 00 movl $0x268,0x4(%esp) + 104a67: 00 + 104a68: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104a6f: e8 bf c1 ff ff call 100c33 <__panic> + // 验证 p1 的引用计数为 1 + assert(page_ref(p1) == 1); + 104a74: 8b 45 f4 mov -0xc(%ebp),%eax + 104a77: 89 04 24 mov %eax,(%esp) + 104a7a: e8 46 f2 ff ff call 103cc5 + 104a7f: 83 f8 01 cmp $0x1,%eax + 104a82: 74 24 je 104aa8 + 104a84: c7 44 24 0c b7 6d 10 movl $0x106db7,0xc(%esp) + 104a8b: 00 + 104a8c: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104a93: 00 + 104a94: c7 44 24 04 6a 02 00 movl $0x26a,0x4(%esp) + 104a9b: 00 + 104a9c: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104aa3: e8 8b c1 ff ff call 100c33 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + ptep = &((pte_t *)KADDR(PDE_ADDR(boot_pgdir[0])))[1]; + 104aa8: a1 e0 99 11 00 mov 0x1199e0,%eax + 104aad: 8b 00 mov (%eax),%eax + 104aaf: 25 00 f0 ff ff and $0xfffff000,%eax + 104ab4: 89 45 ec mov %eax,-0x14(%ebp) + 104ab7: 8b 45 ec mov -0x14(%ebp),%eax + 104aba: c1 e8 0c shr $0xc,%eax + 104abd: 89 45 e8 mov %eax,-0x18(%ebp) + 104ac0: a1 04 cf 11 00 mov 0x11cf04,%eax + 104ac5: 39 45 e8 cmp %eax,-0x18(%ebp) + 104ac8: 72 23 jb 104aed + 104aca: 8b 45 ec mov -0x14(%ebp),%eax + 104acd: 89 44 24 0c mov %eax,0xc(%esp) + 104ad1: c7 44 24 08 84 6b 10 movl $0x106b84,0x8(%esp) + 104ad8: 00 + 104ad9: c7 44 24 04 6c 02 00 movl $0x26c,0x4(%esp) + 104ae0: 00 + 104ae1: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104ae8: e8 46 c1 ff ff call 100c33 <__panic> + 104aed: 8b 45 ec mov -0x14(%ebp),%eax + 104af0: 2d 00 00 00 40 sub $0x40000000,%eax + 104af5: 83 c0 04 add $0x4,%eax + 104af8: 89 45 f0 mov %eax,-0x10(%ebp) + assert(get_pte(boot_pgdir, PGSIZE, 0) == ptep); + 104afb: a1 e0 99 11 00 mov 0x1199e0,%eax + 104b00: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 104b07: 00 + 104b08: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) + 104b0f: 00 + 104b10: 89 04 24 mov %eax,(%esp) + 104b13: e8 4f fa ff ff call 104567 + 104b18: 39 45 f0 cmp %eax,-0x10(%ebp) + 104b1b: 74 24 je 104b41 + 104b1d: c7 44 24 0c cc 6d 10 movl $0x106dcc,0xc(%esp) + 104b24: 00 + 104b25: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104b2c: 00 + 104b2d: c7 44 24 04 6d 02 00 movl $0x26d,0x4(%esp) + 104b34: 00 + 104b35: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104b3c: e8 f2 c0 ff ff call 100c33 <__panic> + // 分配一个页面 p2 + p2 = alloc_page(); + 104b41: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 104b48: e8 88 f3 ff ff call 103ed5 + 104b4d: 89 45 e4 mov %eax,-0x1c(%ebp) + // 将 p2 插入到虚拟地址 PGSIZE,并设置用户和写权限 + assert(page_insert(boot_pgdir, p2, PGSIZE, PTE_U | PTE_W) == 0); + 104b50: a1 e0 99 11 00 mov 0x1199e0,%eax + 104b55: c7 44 24 0c 06 00 00 movl $0x6,0xc(%esp) + 104b5c: 00 + 104b5d: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) + 104b64: 00 + 104b65: 8b 55 e4 mov -0x1c(%ebp),%edx + 104b68: 89 54 24 04 mov %edx,0x4(%esp) + 104b6c: 89 04 24 mov %eax,(%esp) + 104b6f: e8 34 fc ff ff call 1047a8 + 104b74: 85 c0 test %eax,%eax + 104b76: 74 24 je 104b9c + 104b78: c7 44 24 0c f4 6d 10 movl $0x106df4,0xc(%esp) + 104b7f: 00 + 104b80: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104b87: 00 + 104b88: c7 44 24 04 71 02 00 movl $0x271,0x4(%esp) + 104b8f: 00 + 104b90: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104b97: e8 97 c0 ff ff call 100c33 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); + 104b9c: a1 e0 99 11 00 mov 0x1199e0,%eax + 104ba1: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 104ba8: 00 + 104ba9: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) + 104bb0: 00 + 104bb1: 89 04 24 mov %eax,(%esp) + 104bb4: e8 ae f9 ff ff call 104567 + 104bb9: 89 45 f0 mov %eax,-0x10(%ebp) + 104bbc: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 104bc0: 75 24 jne 104be6 + 104bc2: c7 44 24 0c 2c 6e 10 movl $0x106e2c,0xc(%esp) + 104bc9: 00 + 104bca: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104bd1: 00 + 104bd2: c7 44 24 04 73 02 00 movl $0x273,0x4(%esp) + 104bd9: 00 + 104bda: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104be1: e8 4d c0 ff ff call 100c33 <__panic> + // 验证页表项设置了用户权限 + assert(*ptep & PTE_U); + 104be6: 8b 45 f0 mov -0x10(%ebp),%eax + 104be9: 8b 00 mov (%eax),%eax + 104beb: 83 e0 04 and $0x4,%eax + 104bee: 85 c0 test %eax,%eax + 104bf0: 75 24 jne 104c16 + 104bf2: c7 44 24 0c 5c 6e 10 movl $0x106e5c,0xc(%esp) + 104bf9: 00 + 104bfa: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104c01: 00 + 104c02: c7 44 24 04 75 02 00 movl $0x275,0x4(%esp) + 104c09: 00 + 104c0a: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104c11: e8 1d c0 ff ff call 100c33 <__panic> + // 验证页表项设置了写权限 + assert(*ptep & PTE_W); + 104c16: 8b 45 f0 mov -0x10(%ebp),%eax + 104c19: 8b 00 mov (%eax),%eax + 104c1b: 83 e0 02 and $0x2,%eax + 104c1e: 85 c0 test %eax,%eax + 104c20: 75 24 jne 104c46 + 104c22: c7 44 24 0c 6a 6e 10 movl $0x106e6a,0xc(%esp) + 104c29: 00 + 104c2a: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104c31: 00 + 104c32: c7 44 24 04 77 02 00 movl $0x277,0x4(%esp) + 104c39: 00 + 104c3a: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104c41: e8 ed bf ff ff call 100c33 <__panic> + // 验证页目录项设置了用户权限 + assert(boot_pgdir[0] & PTE_U); + 104c46: a1 e0 99 11 00 mov 0x1199e0,%eax + 104c4b: 8b 00 mov (%eax),%eax + 104c4d: 83 e0 04 and $0x4,%eax + 104c50: 85 c0 test %eax,%eax + 104c52: 75 24 jne 104c78 + 104c54: c7 44 24 0c 78 6e 10 movl $0x106e78,0xc(%esp) + 104c5b: 00 + 104c5c: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104c63: 00 + 104c64: c7 44 24 04 79 02 00 movl $0x279,0x4(%esp) + 104c6b: 00 + 104c6c: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104c73: e8 bb bf ff ff call 100c33 <__panic> + // 验证 p2 的引用计数为 1 + assert(page_ref(p2) == 1); + 104c78: 8b 45 e4 mov -0x1c(%ebp),%eax + 104c7b: 89 04 24 mov %eax,(%esp) + 104c7e: e8 42 f0 ff ff call 103cc5 + 104c83: 83 f8 01 cmp $0x1,%eax + 104c86: 74 24 je 104cac + 104c88: c7 44 24 0c 8e 6e 10 movl $0x106e8e,0xc(%esp) + 104c8f: 00 + 104c90: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104c97: 00 + 104c98: c7 44 24 04 7b 02 00 movl $0x27b,0x4(%esp) + 104c9f: 00 + 104ca0: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104ca7: e8 87 bf ff ff call 100c33 <__panic> + + // 将 p1 插入到虚拟地址 PGSIZE,替换掉 p2 + assert(page_insert(boot_pgdir, p1, PGSIZE, 0) == 0); + 104cac: a1 e0 99 11 00 mov 0x1199e0,%eax + 104cb1: c7 44 24 0c 00 00 00 movl $0x0,0xc(%esp) + 104cb8: 00 + 104cb9: c7 44 24 08 00 10 00 movl $0x1000,0x8(%esp) + 104cc0: 00 + 104cc1: 8b 55 f4 mov -0xc(%ebp),%edx + 104cc4: 89 54 24 04 mov %edx,0x4(%esp) + 104cc8: 89 04 24 mov %eax,(%esp) + 104ccb: e8 d8 fa ff ff call 1047a8 + 104cd0: 85 c0 test %eax,%eax + 104cd2: 74 24 je 104cf8 + 104cd4: c7 44 24 0c a0 6e 10 movl $0x106ea0,0xc(%esp) + 104cdb: 00 + 104cdc: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104ce3: 00 + 104ce4: c7 44 24 04 7e 02 00 movl $0x27e,0x4(%esp) + 104ceb: 00 + 104cec: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104cf3: e8 3b bf ff ff call 100c33 <__panic> + // 验证 p1 的引用计数增加到 2 + assert(page_ref(p1) == 2); + 104cf8: 8b 45 f4 mov -0xc(%ebp),%eax + 104cfb: 89 04 24 mov %eax,(%esp) + 104cfe: e8 c2 ef ff ff call 103cc5 + 104d03: 83 f8 02 cmp $0x2,%eax + 104d06: 74 24 je 104d2c + 104d08: c7 44 24 0c cc 6e 10 movl $0x106ecc,0xc(%esp) + 104d0f: 00 + 104d10: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104d17: 00 + 104d18: c7 44 24 04 80 02 00 movl $0x280,0x4(%esp) + 104d1f: 00 + 104d20: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104d27: e8 07 bf ff ff call 100c33 <__panic> + // 验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); + 104d2c: 8b 45 e4 mov -0x1c(%ebp),%eax + 104d2f: 89 04 24 mov %eax,(%esp) + 104d32: e8 8e ef ff ff call 103cc5 + 104d37: 85 c0 test %eax,%eax + 104d39: 74 24 je 104d5f + 104d3b: c7 44 24 0c de 6e 10 movl $0x106ede,0xc(%esp) + 104d42: 00 + 104d43: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104d4a: 00 + 104d4b: c7 44 24 04 82 02 00 movl $0x282,0x4(%esp) + 104d52: 00 + 104d53: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104d5a: e8 d4 be ff ff call 100c33 <__panic> + // 获取虚拟地址 PGSIZE 对应的页表项指针 + assert((ptep = get_pte(boot_pgdir, PGSIZE, 0)) != NULL); + 104d5f: a1 e0 99 11 00 mov 0x1199e0,%eax + 104d64: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 104d6b: 00 + 104d6c: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) + 104d73: 00 + 104d74: 89 04 24 mov %eax,(%esp) + 104d77: e8 eb f7 ff ff call 104567 + 104d7c: 89 45 f0 mov %eax,-0x10(%ebp) + 104d7f: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 104d83: 75 24 jne 104da9 + 104d85: c7 44 24 0c 2c 6e 10 movl $0x106e2c,0xc(%esp) + 104d8c: 00 + 104d8d: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104d94: 00 + 104d95: c7 44 24 04 84 02 00 movl $0x284,0x4(%esp) + 104d9c: 00 + 104d9d: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104da4: e8 8a be ff ff call 100c33 <__panic> + // 验证页表项对应的页面是 p1 + assert(pte2page(*ptep) == p1); + 104da9: 8b 45 f0 mov -0x10(%ebp),%eax + 104dac: 8b 00 mov (%eax),%eax + 104dae: 89 04 24 mov %eax,(%esp) + 104db1: e8 b5 ee ff ff call 103c6b + 104db6: 39 45 f4 cmp %eax,-0xc(%ebp) + 104db9: 74 24 je 104ddf + 104dbb: c7 44 24 0c a1 6d 10 movl $0x106da1,0xc(%esp) + 104dc2: 00 + 104dc3: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104dca: 00 + 104dcb: c7 44 24 04 86 02 00 movl $0x286,0x4(%esp) + 104dd2: 00 + 104dd3: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104dda: e8 54 be ff ff call 100c33 <__panic> + // 验证页表项没有设置用户权限 + assert((*ptep & PTE_U) == 0); + 104ddf: 8b 45 f0 mov -0x10(%ebp),%eax + 104de2: 8b 00 mov (%eax),%eax + 104de4: 83 e0 04 and $0x4,%eax + 104de7: 85 c0 test %eax,%eax + 104de9: 74 24 je 104e0f + 104deb: c7 44 24 0c f0 6e 10 movl $0x106ef0,0xc(%esp) + 104df2: 00 + 104df3: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104dfa: 00 + 104dfb: c7 44 24 04 88 02 00 movl $0x288,0x4(%esp) + 104e02: 00 + 104e03: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104e0a: e8 24 be ff ff call 100c33 <__panic> + + //移除虚拟地址 0x0 的映射, + page_remove(boot_pgdir, 0x0); + 104e0f: a1 e0 99 11 00 mov 0x1199e0,%eax + 104e14: c7 44 24 04 00 00 00 movl $0x0,0x4(%esp) + 104e1b: 00 + 104e1c: 89 04 24 mov %eax,(%esp) + 104e1f: e8 3d f9 ff ff call 104761 + //验证 p1 的引用计数减少到 1。 + assert(page_ref(p1) == 1); + 104e24: 8b 45 f4 mov -0xc(%ebp),%eax + 104e27: 89 04 24 mov %eax,(%esp) + 104e2a: e8 96 ee ff ff call 103cc5 + 104e2f: 83 f8 01 cmp $0x1,%eax + 104e32: 74 24 je 104e58 + 104e34: c7 44 24 0c b7 6d 10 movl $0x106db7,0xc(%esp) + 104e3b: 00 + 104e3c: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104e43: 00 + 104e44: c7 44 24 04 8d 02 00 movl $0x28d,0x4(%esp) + 104e4b: 00 + 104e4c: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104e53: e8 db bd ff ff call 100c33 <__panic> + //验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); + 104e58: 8b 45 e4 mov -0x1c(%ebp),%eax + 104e5b: 89 04 24 mov %eax,(%esp) + 104e5e: e8 62 ee ff ff call 103cc5 + 104e63: 85 c0 test %eax,%eax + 104e65: 74 24 je 104e8b + 104e67: c7 44 24 0c de 6e 10 movl $0x106ede,0xc(%esp) + 104e6e: 00 + 104e6f: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104e76: 00 + 104e77: c7 44 24 04 8f 02 00 movl $0x28f,0x4(%esp) + 104e7e: 00 + 104e7f: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104e86: e8 a8 bd ff ff call 100c33 <__panic> + + //移除虚拟地址 PGSIZE 的映射, + page_remove(boot_pgdir, PGSIZE); + 104e8b: a1 e0 99 11 00 mov 0x1199e0,%eax + 104e90: c7 44 24 04 00 10 00 movl $0x1000,0x4(%esp) + 104e97: 00 + 104e98: 89 04 24 mov %eax,(%esp) + 104e9b: e8 c1 f8 ff ff call 104761 + //验证 p1 的引用计数减少到 0 + assert(page_ref(p1) == 0); + 104ea0: 8b 45 f4 mov -0xc(%ebp),%eax + 104ea3: 89 04 24 mov %eax,(%esp) + 104ea6: e8 1a ee ff ff call 103cc5 + 104eab: 85 c0 test %eax,%eax + 104ead: 74 24 je 104ed3 + 104eaf: c7 44 24 0c 05 6f 10 movl $0x106f05,0xc(%esp) + 104eb6: 00 + 104eb7: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104ebe: 00 + 104ebf: c7 44 24 04 94 02 00 movl $0x294,0x4(%esp) + 104ec6: 00 + 104ec7: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104ece: e8 60 bd ff ff call 100c33 <__panic> + //验证 p2 的引用计数减少到 0 + assert(page_ref(p2) == 0); + 104ed3: 8b 45 e4 mov -0x1c(%ebp),%eax + 104ed6: 89 04 24 mov %eax,(%esp) + 104ed9: e8 e7 ed ff ff call 103cc5 + 104ede: 85 c0 test %eax,%eax + 104ee0: 74 24 je 104f06 + 104ee2: c7 44 24 0c de 6e 10 movl $0x106ede,0xc(%esp) + 104ee9: 00 + 104eea: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104ef1: 00 + 104ef2: c7 44 24 04 96 02 00 movl $0x296,0x4(%esp) + 104ef9: 00 + 104efa: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104f01: e8 2d bd ff ff call 100c33 <__panic> + + //验证页目录的第一页表的引用计数为 1。 + assert(page_ref(pde2page(boot_pgdir[0])) == 1); + 104f06: a1 e0 99 11 00 mov 0x1199e0,%eax + 104f0b: 8b 00 mov (%eax),%eax + 104f0d: 89 04 24 mov %eax,(%esp) + 104f10: e8 96 ed ff ff call 103cab + 104f15: 89 04 24 mov %eax,(%esp) + 104f18: e8 a8 ed ff ff call 103cc5 + 104f1d: 83 f8 01 cmp $0x1,%eax + 104f20: 74 24 je 104f46 + 104f22: c7 44 24 0c 18 6f 10 movl $0x106f18,0xc(%esp) + 104f29: 00 + 104f2a: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 104f31: 00 + 104f32: c7 44 24 04 99 02 00 movl $0x299,0x4(%esp) + 104f39: 00 + 104f3a: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104f41: e8 ed bc ff ff call 100c33 <__panic> + //释放页目录的第一页表 + free_page(pde2page(boot_pgdir[0])); + 104f46: a1 e0 99 11 00 mov 0x1199e0,%eax + 104f4b: 8b 00 mov (%eax),%eax + 104f4d: 89 04 24 mov %eax,(%esp) + 104f50: e8 56 ed ff ff call 103cab + 104f55: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 104f5c: 00 + 104f5d: 89 04 24 mov %eax,(%esp) + 104f60: e8 aa ef ff ff call 103f0f + //清空页目录的第一页表 + boot_pgdir[0] = 0; + 104f65: a1 e0 99 11 00 mov 0x1199e0,%eax + 104f6a: c7 00 00 00 00 00 movl $0x0,(%eax) + + cprintf("check_pgdir() succeeded!\n"); + 104f70: c7 04 24 3f 6f 10 00 movl $0x106f3f,(%esp) + 104f77: e8 ea b3 ff ff call 100366 +} + 104f7c: 90 nop + 104f7d: 89 ec mov %ebp,%esp + 104f7f: 5d pop %ebp + 104f80: c3 ret + +00104f81 : + +//检查内核页表 boot_pgdir 的正确性 +static void +check_boot_pgdir(void) { + 104f81: 55 push %ebp + 104f82: 89 e5 mov %esp,%ebp + 104f84: 83 ec 38 sub $0x38,%esp + pte_t *ptep;// 定义一个指向页表项的指针 + int i; + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 + 104f87: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + 104f8e: e9 ca 00 00 00 jmp 10505d + // 获取第 i 个页面的页表项,并确保其不为空 + assert((ptep = get_pte(boot_pgdir, (uintptr_t)KADDR(i), 0)) != NULL); + 104f93: 8b 45 f4 mov -0xc(%ebp),%eax + 104f96: 89 45 e4 mov %eax,-0x1c(%ebp) + 104f99: 8b 45 e4 mov -0x1c(%ebp),%eax + 104f9c: c1 e8 0c shr $0xc,%eax + 104f9f: 89 45 e0 mov %eax,-0x20(%ebp) + 104fa2: a1 04 cf 11 00 mov 0x11cf04,%eax + 104fa7: 39 45 e0 cmp %eax,-0x20(%ebp) + 104faa: 72 23 jb 104fcf + 104fac: 8b 45 e4 mov -0x1c(%ebp),%eax + 104faf: 89 44 24 0c mov %eax,0xc(%esp) + 104fb3: c7 44 24 08 84 6b 10 movl $0x106b84,0x8(%esp) + 104fba: 00 + 104fbb: c7 44 24 04 a9 02 00 movl $0x2a9,0x4(%esp) + 104fc2: 00 + 104fc3: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 104fca: e8 64 bc ff ff call 100c33 <__panic> + 104fcf: 8b 45 e4 mov -0x1c(%ebp),%eax + 104fd2: 2d 00 00 00 40 sub $0x40000000,%eax + 104fd7: 89 c2 mov %eax,%edx + 104fd9: a1 e0 99 11 00 mov 0x1199e0,%eax + 104fde: c7 44 24 08 00 00 00 movl $0x0,0x8(%esp) + 104fe5: 00 + 104fe6: 89 54 24 04 mov %edx,0x4(%esp) + 104fea: 89 04 24 mov %eax,(%esp) + 104fed: e8 75 f5 ff ff call 104567 + 104ff2: 89 45 dc mov %eax,-0x24(%ebp) + 104ff5: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 104ff9: 75 24 jne 10501f + 104ffb: c7 44 24 0c 5c 6f 10 movl $0x106f5c,0xc(%esp) + 105002: 00 + 105003: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 10500a: 00 + 10500b: c7 44 24 04 a9 02 00 movl $0x2a9,0x4(%esp) + 105012: 00 + 105013: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10501a: e8 14 bc ff ff call 100c33 <__panic> + // 验证页表项的物理地址是否正确 + assert(PTE_ADDR(*ptep) == i); + 10501f: 8b 45 dc mov -0x24(%ebp),%eax + 105022: 8b 00 mov (%eax),%eax + 105024: 25 00 f0 ff ff and $0xfffff000,%eax + 105029: 89 c2 mov %eax,%edx + 10502b: 8b 45 f4 mov -0xc(%ebp),%eax + 10502e: 39 c2 cmp %eax,%edx + 105030: 74 24 je 105056 + 105032: c7 44 24 0c 99 6f 10 movl $0x106f99,0xc(%esp) + 105039: 00 + 10503a: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 105041: 00 + 105042: c7 44 24 04 ab 02 00 movl $0x2ab,0x4(%esp) + 105049: 00 + 10504a: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 105051: e8 dd bb ff ff call 100c33 <__panic> + for (i = 0; i < npage; i += PGSIZE) {// 遍历所有页面 + 105056: 81 45 f4 00 10 00 00 addl $0x1000,-0xc(%ebp) + 10505d: 8b 55 f4 mov -0xc(%ebp),%edx + 105060: a1 04 cf 11 00 mov 0x11cf04,%eax + 105065: 39 c2 cmp %eax,%edx + 105067: 0f 82 26 ff ff ff jb 104f93 + } + // 验证页目录项的物理地址是否正确 + assert(PDE_ADDR(boot_pgdir[PDX(VPT)]) == PADDR(boot_pgdir)); + 10506d: a1 e0 99 11 00 mov 0x1199e0,%eax + 105072: 05 ac 0f 00 00 add $0xfac,%eax + 105077: 8b 00 mov (%eax),%eax + 105079: 25 00 f0 ff ff and $0xfffff000,%eax + 10507e: 89 c2 mov %eax,%edx + 105080: a1 e0 99 11 00 mov 0x1199e0,%eax + 105085: 89 45 f0 mov %eax,-0x10(%ebp) + 105088: 81 7d f0 ff ff ff bf cmpl $0xbfffffff,-0x10(%ebp) + 10508f: 77 23 ja 1050b4 + 105091: 8b 45 f0 mov -0x10(%ebp),%eax + 105094: 89 44 24 0c mov %eax,0xc(%esp) + 105098: c7 44 24 08 28 6c 10 movl $0x106c28,0x8(%esp) + 10509f: 00 + 1050a0: c7 44 24 04 ae 02 00 movl $0x2ae,0x4(%esp) + 1050a7: 00 + 1050a8: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1050af: e8 7f bb ff ff call 100c33 <__panic> + 1050b4: 8b 45 f0 mov -0x10(%ebp),%eax + 1050b7: 05 00 00 00 40 add $0x40000000,%eax + 1050bc: 39 d0 cmp %edx,%eax + 1050be: 74 24 je 1050e4 + 1050c0: c7 44 24 0c b0 6f 10 movl $0x106fb0,0xc(%esp) + 1050c7: 00 + 1050c8: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 1050cf: 00 + 1050d0: c7 44 24 04 ae 02 00 movl $0x2ae,0x4(%esp) + 1050d7: 00 + 1050d8: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1050df: e8 4f bb ff ff call 100c33 <__panic> + + assert(boot_pgdir[0] == 0);// 确保页目录的第一个项为0 + 1050e4: a1 e0 99 11 00 mov 0x1199e0,%eax + 1050e9: 8b 00 mov (%eax),%eax + 1050eb: 85 c0 test %eax,%eax + 1050ed: 74 24 je 105113 + 1050ef: c7 44 24 0c e4 6f 10 movl $0x106fe4,0xc(%esp) + 1050f6: 00 + 1050f7: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 1050fe: 00 + 1050ff: c7 44 24 04 b0 02 00 movl $0x2b0,0x4(%esp) + 105106: 00 + 105107: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10510e: e8 20 bb ff ff call 100c33 <__panic> + + struct Page *p;// 定义一个指向页面的指针 + p = alloc_page();// 分配一个页面 + 105113: c7 04 24 01 00 00 00 movl $0x1,(%esp) + 10511a: e8 b6 ed ff ff call 103ed5 + 10511f: 89 45 ec mov %eax,-0x14(%ebp) + // 将页面插入到虚拟地址 0x100,并确保操作成功 + assert(page_insert(boot_pgdir, p, 0x100, PTE_W) == 0); + 105122: a1 e0 99 11 00 mov 0x1199e0,%eax + 105127: c7 44 24 0c 02 00 00 movl $0x2,0xc(%esp) + 10512e: 00 + 10512f: c7 44 24 08 00 01 00 movl $0x100,0x8(%esp) + 105136: 00 + 105137: 8b 55 ec mov -0x14(%ebp),%edx + 10513a: 89 54 24 04 mov %edx,0x4(%esp) + 10513e: 89 04 24 mov %eax,(%esp) + 105141: e8 62 f6 ff ff call 1047a8 + 105146: 85 c0 test %eax,%eax + 105148: 74 24 je 10516e + 10514a: c7 44 24 0c f8 6f 10 movl $0x106ff8,0xc(%esp) + 105151: 00 + 105152: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 105159: 00 + 10515a: c7 44 24 04 b5 02 00 movl $0x2b5,0x4(%esp) + 105161: 00 + 105162: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 105169: e8 c5 ba ff ff call 100c33 <__panic> + assert(page_ref(p) == 1);// 验证页面的引用计数为1 + 10516e: 8b 45 ec mov -0x14(%ebp),%eax + 105171: 89 04 24 mov %eax,(%esp) + 105174: e8 4c eb ff ff call 103cc5 + 105179: 83 f8 01 cmp $0x1,%eax + 10517c: 74 24 je 1051a2 + 10517e: c7 44 24 0c 26 70 10 movl $0x107026,0xc(%esp) + 105185: 00 + 105186: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 10518d: 00 + 10518e: c7 44 24 04 b6 02 00 movl $0x2b6,0x4(%esp) + 105195: 00 + 105196: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10519d: e8 91 ba ff ff call 100c33 <__panic> + // 将页面插入到虚拟地址 0x100 + PGSIZE,并确保操作成功 + assert(page_insert(boot_pgdir, p, 0x100 + PGSIZE, PTE_W) == 0); + 1051a2: a1 e0 99 11 00 mov 0x1199e0,%eax + 1051a7: c7 44 24 0c 02 00 00 movl $0x2,0xc(%esp) + 1051ae: 00 + 1051af: c7 44 24 08 00 11 00 movl $0x1100,0x8(%esp) + 1051b6: 00 + 1051b7: 8b 55 ec mov -0x14(%ebp),%edx + 1051ba: 89 54 24 04 mov %edx,0x4(%esp) + 1051be: 89 04 24 mov %eax,(%esp) + 1051c1: e8 e2 f5 ff ff call 1047a8 + 1051c6: 85 c0 test %eax,%eax + 1051c8: 74 24 je 1051ee + 1051ca: c7 44 24 0c 38 70 10 movl $0x107038,0xc(%esp) + 1051d1: 00 + 1051d2: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 1051d9: 00 + 1051da: c7 44 24 04 b8 02 00 movl $0x2b8,0x4(%esp) + 1051e1: 00 + 1051e2: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1051e9: e8 45 ba ff ff call 100c33 <__panic> + assert(page_ref(p) == 2);// 验证页面的引用计数为2 + 1051ee: 8b 45 ec mov -0x14(%ebp),%eax + 1051f1: 89 04 24 mov %eax,(%esp) + 1051f4: e8 cc ea ff ff call 103cc5 + 1051f9: 83 f8 02 cmp $0x2,%eax + 1051fc: 74 24 je 105222 + 1051fe: c7 44 24 0c 6f 70 10 movl $0x10706f,0xc(%esp) + 105205: 00 + 105206: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 10520d: 00 + 10520e: c7 44 24 04 b9 02 00 movl $0x2b9,0x4(%esp) + 105215: 00 + 105216: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 10521d: e8 11 ba ff ff call 100c33 <__panic> + + const char *str = "ucore: Hello world!!";// 定义一个字符串 + 105222: c7 45 e8 80 70 10 00 movl $0x107080,-0x18(%ebp) + strcpy((void *)0x100, str);// 将字符串复制到虚拟地址 0x100 + 105229: 8b 45 e8 mov -0x18(%ebp),%eax + 10522c: 89 44 24 04 mov %eax,0x4(%esp) + 105230: c7 04 24 00 01 00 00 movl $0x100,(%esp) + 105237: e8 fc 09 00 00 call 105c38 + // 验证两个映射地址的数据是否一致 + assert(strcmp((void *)0x100, (void *)(0x100 + PGSIZE)) == 0); + 10523c: c7 44 24 04 00 11 00 movl $0x1100,0x4(%esp) + 105243: 00 + 105244: c7 04 24 00 01 00 00 movl $0x100,(%esp) + 10524b: e8 60 0a 00 00 call 105cb0 + 105250: 85 c0 test %eax,%eax + 105252: 74 24 je 105278 + 105254: c7 44 24 0c 98 70 10 movl $0x107098,0xc(%esp) + 10525b: 00 + 10525c: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 105263: 00 + 105264: c7 44 24 04 be 02 00 movl $0x2be,0x4(%esp) + 10526b: 00 + 10526c: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 105273: e8 bb b9 ff ff call 100c33 <__panic> + // 在页面的 0x100 偏移处设置字符串结束符 + *(char *)(page2kva(p) + 0x100) = '\0'; + 105278: 8b 45 ec mov -0x14(%ebp),%eax + 10527b: 89 04 24 mov %eax,(%esp) + 10527e: e8 92 e9 ff ff call 103c15 + 105283: 05 00 01 00 00 add $0x100,%eax + 105288: c6 00 00 movb $0x0,(%eax) + assert(strlen((const char *)0x100) == 0);// 验证字符串长度为0 + 10528b: c7 04 24 00 01 00 00 movl $0x100,(%esp) + 105292: e8 47 09 00 00 call 105bde + 105297: 85 c0 test %eax,%eax + 105299: 74 24 je 1052bf + 10529b: c7 44 24 0c d0 70 10 movl $0x1070d0,0xc(%esp) + 1052a2: 00 + 1052a3: c7 44 24 08 71 6c 10 movl $0x106c71,0x8(%esp) + 1052aa: 00 + 1052ab: c7 44 24 04 c1 02 00 movl $0x2c1,0x4(%esp) + 1052b2: 00 + 1052b3: c7 04 24 4c 6c 10 00 movl $0x106c4c,(%esp) + 1052ba: e8 74 b9 ff ff call 100c33 <__panic> + + free_page(p);// 释放页面 p + 1052bf: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1052c6: 00 + 1052c7: 8b 45 ec mov -0x14(%ebp),%eax + 1052ca: 89 04 24 mov %eax,(%esp) + 1052cd: e8 3d ec ff ff call 103f0f + free_page(pde2page(boot_pgdir[0]));// 释放页目录项对应的页面 + 1052d2: a1 e0 99 11 00 mov 0x1199e0,%eax + 1052d7: 8b 00 mov (%eax),%eax + 1052d9: 89 04 24 mov %eax,(%esp) + 1052dc: e8 ca e9 ff ff call 103cab + 1052e1: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp) + 1052e8: 00 + 1052e9: 89 04 24 mov %eax,(%esp) + 1052ec: e8 1e ec ff ff call 103f0f + boot_pgdir[0] = 0;// 将页目录的第一个项设为0 + 1052f1: a1 e0 99 11 00 mov 0x1199e0,%eax + 1052f6: c7 00 00 00 00 00 movl $0x0,(%eax) + + cprintf("check_boot_pgdir() succeeded!\n");// 输出成功信息 + 1052fc: c7 04 24 f4 70 10 00 movl $0x1070f4,(%esp) + 105303: e8 5e b0 ff ff call 100366 +} + 105308: 90 nop + 105309: 89 ec mov %ebp,%esp + 10530b: 5d pop %ebp + 10530c: c3 ret + +0010530d : + +//perm2str - use string 'u,r,w,-' to present the permission +static const char * +perm2str(int perm) { + 10530d: 55 push %ebp + 10530e: 89 e5 mov %esp,%ebp + //定义一个静态字符数组 str,长度为4 + static char str[4]; + //如果 perm 与 PTE_U 按位与的结果不为0,则 str[0] 设置为 'u',否则设置为 '-' + str[0] = (perm & PTE_U) ? 'u' : '-'; + 105310: 8b 45 08 mov 0x8(%ebp),%eax + 105313: 83 e0 04 and $0x4,%eax + 105316: 85 c0 test %eax,%eax + 105318: 74 04 je 10531e + 10531a: b0 75 mov $0x75,%al + 10531c: eb 02 jmp 105320 + 10531e: b0 2d mov $0x2d,%al + 105320: a2 88 cf 11 00 mov %al,0x11cf88 + //str[1] 始终设置为 'r' + str[1] = 'r'; + 105325: c6 05 89 cf 11 00 72 movb $0x72,0x11cf89 + //如果 perm 与 PTE_W 按位与的结果不为0,则 str[2] 设置为 'w',否则设置为 '-' + str[2] = (perm & PTE_W) ? 'w' : '-'; + 10532c: 8b 45 08 mov 0x8(%ebp),%eax + 10532f: 83 e0 02 and $0x2,%eax + 105332: 85 c0 test %eax,%eax + 105334: 74 04 je 10533a + 105336: b0 77 mov $0x77,%al + 105338: eb 02 jmp 10533c + 10533a: b0 2d mov $0x2d,%al + 10533c: a2 8a cf 11 00 mov %al,0x11cf8a + //str[3] 设置为字符串结束符 \0 + str[3] = '\0'; + 105341: c6 05 8b cf 11 00 00 movb $0x0,0x11cf8b + return str; + 105348: b8 88 cf 11 00 mov $0x11cf88,%eax +} + 10534d: 5d pop %ebp + 10534e: c3 ret + +0010534f : +// left_store: the pointer of the high side of table's next range +// right_store: the pointer of the low side of table's next range +// return value: 0 - not a invalid item range, perm - a valid item range with perm permission +//从页表中获取指定范围内的有效项,并根据权限进行处理。 +static int +get_pgtable_items(size_t left, size_t right, size_t start, uintptr_t *table, size_t *left_store, size_t *right_store) { + 10534f: 55 push %ebp + 105350: 89 e5 mov %esp,%ebp + 105352: 83 ec 10 sub $0x10,%esp + if (start >= right) {// 检查起始索引是否超出右边界 + 105355: 8b 45 10 mov 0x10(%ebp),%eax + 105358: 3b 45 0c cmp 0xc(%ebp),%eax + 10535b: 72 0d jb 10536a + return 0;// 如果超出右边界,返回0 + 10535d: b8 00 00 00 00 mov $0x0,%eax + 105362: e9 98 00 00 00 jmp 1053ff + } + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) + start ++;// 索引递增 + 105367: ff 45 10 incl 0x10(%ebp) + while (start < right && !(table[start] & PTE_P)) {// 查找第一个有效项(PTE_P位为1的项) + 10536a: 8b 45 10 mov 0x10(%ebp),%eax + 10536d: 3b 45 0c cmp 0xc(%ebp),%eax + 105370: 73 18 jae 10538a + 105372: 8b 45 10 mov 0x10(%ebp),%eax + 105375: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx + 10537c: 8b 45 14 mov 0x14(%ebp),%eax + 10537f: 01 d0 add %edx,%eax + 105381: 8b 00 mov (%eax),%eax + 105383: 83 e0 01 and $0x1,%eax + 105386: 85 c0 test %eax,%eax + 105388: 74 dd je 105367 + } + if (start < right) {// 检查是否找到有效项 + 10538a: 8b 45 10 mov 0x10(%ebp),%eax + 10538d: 3b 45 0c cmp 0xc(%ebp),%eax + 105390: 73 68 jae 1053fa + if (left_store != NULL) {// 如果left_store不为NULL + 105392: 83 7d 18 00 cmpl $0x0,0x18(%ebp) + 105396: 74 08 je 1053a0 + *left_store = start;// 记录左边界索引 + 105398: 8b 45 18 mov 0x18(%ebp),%eax + 10539b: 8b 55 10 mov 0x10(%ebp),%edx + 10539e: 89 10 mov %edx,(%eax) + } + int perm = (table[start ++] & PTE_USER);// 获取当前项的用户权限位并递增索引 + 1053a0: 8b 45 10 mov 0x10(%ebp),%eax + 1053a3: 8d 50 01 lea 0x1(%eax),%edx + 1053a6: 89 55 10 mov %edx,0x10(%ebp) + 1053a9: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx + 1053b0: 8b 45 14 mov 0x14(%ebp),%eax + 1053b3: 01 d0 add %edx,%eax + 1053b5: 8b 00 mov (%eax),%eax + 1053b7: 83 e0 07 and $0x7,%eax + 1053ba: 89 45 fc mov %eax,-0x4(%ebp) + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 + 1053bd: eb 03 jmp 1053c2 + start ++;// 索引递增 + 1053bf: ff 45 10 incl 0x10(%ebp) + while (start < right && (table[start] & PTE_USER) == perm) {// 查找具有相同用户权限的连续项 + 1053c2: 8b 45 10 mov 0x10(%ebp),%eax + 1053c5: 3b 45 0c cmp 0xc(%ebp),%eax + 1053c8: 73 1d jae 1053e7 + 1053ca: 8b 45 10 mov 0x10(%ebp),%eax + 1053cd: 8d 14 85 00 00 00 00 lea 0x0(,%eax,4),%edx + 1053d4: 8b 45 14 mov 0x14(%ebp),%eax + 1053d7: 01 d0 add %edx,%eax + 1053d9: 8b 00 mov (%eax),%eax + 1053db: 83 e0 07 and $0x7,%eax + 1053de: 89 c2 mov %eax,%edx + 1053e0: 8b 45 fc mov -0x4(%ebp),%eax + 1053e3: 39 c2 cmp %eax,%edx + 1053e5: 74 d8 je 1053bf + } + if (right_store != NULL) {// 如果right_store不为NULL + 1053e7: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 1053eb: 74 08 je 1053f5 + *right_store = start;// 记录右边界索引 + 1053ed: 8b 45 1c mov 0x1c(%ebp),%eax + 1053f0: 8b 55 10 mov 0x10(%ebp),%edx + 1053f3: 89 10 mov %edx,(%eax) + } + return perm;// 返回用户权限位 + 1053f5: 8b 45 fc mov -0x4(%ebp),%eax + 1053f8: eb 05 jmp 1053ff + } + return 0;// 如果未找到有效项,返回0 + 1053fa: b8 00 00 00 00 mov $0x0,%eax +} + 1053ff: 89 ec mov %ebp,%esp + 105401: 5d pop %ebp + 105402: c3 ret + +00105403 : + +//print_pgdir - print the PDT&PT +void +print_pgdir(void) { + 105403: 55 push %ebp + 105404: 89 e5 mov %esp,%ebp + 105406: 57 push %edi + 105407: 56 push %esi + 105408: 53 push %ebx + 105409: 83 ec 4c sub $0x4c,%esp + cprintf("-------------------- BEGIN --------------------\n"); + 10540c: c7 04 24 14 71 10 00 movl $0x107114,(%esp) + 105413: e8 4e af ff ff call 100366 + // 定义变量 left, right 和 perm + size_t left, right = 0, perm; + 105418: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + // 遍历页目录项 + while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { + 10541f: e9 f2 00 00 00 jmp 105516 + // 打印页目录项的信息 + cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, + 105424: 8b 45 e4 mov -0x1c(%ebp),%eax + 105427: 89 04 24 mov %eax,(%esp) + 10542a: e8 de fe ff ff call 10530d + left * PTSIZE, right * PTSIZE, (right - left) * PTSIZE, perm2str(perm)); + 10542f: 8b 55 dc mov -0x24(%ebp),%edx + 105432: 8b 4d e0 mov -0x20(%ebp),%ecx + 105435: 29 ca sub %ecx,%edx + cprintf("PDE(%03x) %08x-%08x %08x %s\n", right - left, + 105437: 89 d6 mov %edx,%esi + 105439: c1 e6 16 shl $0x16,%esi + 10543c: 8b 55 dc mov -0x24(%ebp),%edx + 10543f: 89 d3 mov %edx,%ebx + 105441: c1 e3 16 shl $0x16,%ebx + 105444: 8b 55 e0 mov -0x20(%ebp),%edx + 105447: 89 d1 mov %edx,%ecx + 105449: c1 e1 16 shl $0x16,%ecx + 10544c: 8b 55 dc mov -0x24(%ebp),%edx + 10544f: 8b 7d e0 mov -0x20(%ebp),%edi + 105452: 29 fa sub %edi,%edx + 105454: 89 44 24 14 mov %eax,0x14(%esp) + 105458: 89 74 24 10 mov %esi,0x10(%esp) + 10545c: 89 5c 24 0c mov %ebx,0xc(%esp) + 105460: 89 4c 24 08 mov %ecx,0x8(%esp) + 105464: 89 54 24 04 mov %edx,0x4(%esp) + 105468: c7 04 24 45 71 10 00 movl $0x107145,(%esp) + 10546f: e8 f2 ae ff ff call 100366 + // 计算页表项的起始和结束索引 + size_t l, r = left * NPTEENTRY; + 105474: 8b 45 e0 mov -0x20(%ebp),%eax + 105477: c1 e0 0a shl $0xa,%eax + 10547a: 89 45 d4 mov %eax,-0x2c(%ebp) + // 遍历页表项 + while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { + 10547d: eb 50 jmp 1054cf + // 打印页表项的信息 + cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, + 10547f: 8b 45 e4 mov -0x1c(%ebp),%eax + 105482: 89 04 24 mov %eax,(%esp) + 105485: e8 83 fe ff ff call 10530d + l * PGSIZE, r * PGSIZE, (r - l) * PGSIZE, perm2str(perm)); + 10548a: 8b 55 d4 mov -0x2c(%ebp),%edx + 10548d: 8b 4d d8 mov -0x28(%ebp),%ecx + 105490: 29 ca sub %ecx,%edx + cprintf(" |-- PTE(%05x) %08x-%08x %08x %s\n", r - l, + 105492: 89 d6 mov %edx,%esi + 105494: c1 e6 0c shl $0xc,%esi + 105497: 8b 55 d4 mov -0x2c(%ebp),%edx + 10549a: 89 d3 mov %edx,%ebx + 10549c: c1 e3 0c shl $0xc,%ebx + 10549f: 8b 55 d8 mov -0x28(%ebp),%edx + 1054a2: 89 d1 mov %edx,%ecx + 1054a4: c1 e1 0c shl $0xc,%ecx + 1054a7: 8b 55 d4 mov -0x2c(%ebp),%edx + 1054aa: 8b 7d d8 mov -0x28(%ebp),%edi + 1054ad: 29 fa sub %edi,%edx + 1054af: 89 44 24 14 mov %eax,0x14(%esp) + 1054b3: 89 74 24 10 mov %esi,0x10(%esp) + 1054b7: 89 5c 24 0c mov %ebx,0xc(%esp) + 1054bb: 89 4c 24 08 mov %ecx,0x8(%esp) + 1054bf: 89 54 24 04 mov %edx,0x4(%esp) + 1054c3: c7 04 24 64 71 10 00 movl $0x107164,(%esp) + 1054ca: e8 97 ae ff ff call 100366 + while ((perm = get_pgtable_items(left * NPTEENTRY, right * NPTEENTRY, r, vpt, &l, &r)) != 0) { + 1054cf: be 00 00 c0 fa mov $0xfac00000,%esi + 1054d4: 8b 45 d4 mov -0x2c(%ebp),%eax + 1054d7: 8b 55 dc mov -0x24(%ebp),%edx + 1054da: 89 d3 mov %edx,%ebx + 1054dc: c1 e3 0a shl $0xa,%ebx + 1054df: 8b 55 e0 mov -0x20(%ebp),%edx + 1054e2: 89 d1 mov %edx,%ecx + 1054e4: c1 e1 0a shl $0xa,%ecx + 1054e7: 8d 55 d4 lea -0x2c(%ebp),%edx + 1054ea: 89 54 24 14 mov %edx,0x14(%esp) + 1054ee: 8d 55 d8 lea -0x28(%ebp),%edx + 1054f1: 89 54 24 10 mov %edx,0x10(%esp) + 1054f5: 89 74 24 0c mov %esi,0xc(%esp) + 1054f9: 89 44 24 08 mov %eax,0x8(%esp) + 1054fd: 89 5c 24 04 mov %ebx,0x4(%esp) + 105501: 89 0c 24 mov %ecx,(%esp) + 105504: e8 46 fe ff ff call 10534f + 105509: 89 45 e4 mov %eax,-0x1c(%ebp) + 10550c: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 105510: 0f 85 69 ff ff ff jne 10547f + while ((perm = get_pgtable_items(0, NPDEENTRY, right, vpd, &left, &right)) != 0) { + 105516: b9 00 b0 fe fa mov $0xfafeb000,%ecx + 10551b: 8b 45 dc mov -0x24(%ebp),%eax + 10551e: 8d 55 dc lea -0x24(%ebp),%edx + 105521: 89 54 24 14 mov %edx,0x14(%esp) + 105525: 8d 55 e0 lea -0x20(%ebp),%edx + 105528: 89 54 24 10 mov %edx,0x10(%esp) + 10552c: 89 4c 24 0c mov %ecx,0xc(%esp) + 105530: 89 44 24 08 mov %eax,0x8(%esp) + 105534: c7 44 24 04 00 04 00 movl $0x400,0x4(%esp) + 10553b: 00 + 10553c: c7 04 24 00 00 00 00 movl $0x0,(%esp) + 105543: e8 07 fe ff ff call 10534f + 105548: 89 45 e4 mov %eax,-0x1c(%ebp) + 10554b: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 10554f: 0f 85 cf fe ff ff jne 105424 + } + } + cprintf("--------------------- END ---------------------\n"); + 105555: c7 04 24 88 71 10 00 movl $0x107188,(%esp) + 10555c: e8 05 ae ff ff call 100366 +} + 105561: 90 nop + 105562: 83 c4 4c add $0x4c,%esp + 105565: 5b pop %ebx + 105566: 5e pop %esi + 105567: 5f pop %edi + 105568: 5d pop %ebp + 105569: c3 ret + +0010556a : + * @width: maximum number of digits, if the actual width is less than @width, use @padc instead + * @padc: character that padded on the left if the actual width is less than @width + * */ +static void +printnum(void (*putch)(int, void*), void *putdat, + unsigned long long num, unsigned base, int width, int padc) { + 10556a: 55 push %ebp + 10556b: 89 e5 mov %esp,%ebp + 10556d: 83 ec 58 sub $0x58,%esp + 105570: 8b 45 10 mov 0x10(%ebp),%eax + 105573: 89 45 d0 mov %eax,-0x30(%ebp) + 105576: 8b 45 14 mov 0x14(%ebp),%eax + 105579: 89 45 d4 mov %eax,-0x2c(%ebp) + unsigned long long result = num; + 10557c: 8b 45 d0 mov -0x30(%ebp),%eax + 10557f: 8b 55 d4 mov -0x2c(%ebp),%edx + 105582: 89 45 e8 mov %eax,-0x18(%ebp) + 105585: 89 55 ec mov %edx,-0x14(%ebp) + unsigned mod = do_div(result, base); + 105588: 8b 45 18 mov 0x18(%ebp),%eax + 10558b: 89 45 e4 mov %eax,-0x1c(%ebp) + 10558e: 8b 45 e8 mov -0x18(%ebp),%eax + 105591: 8b 55 ec mov -0x14(%ebp),%edx + 105594: 89 45 e0 mov %eax,-0x20(%ebp) + 105597: 89 55 f0 mov %edx,-0x10(%ebp) + 10559a: 8b 45 f0 mov -0x10(%ebp),%eax + 10559d: 89 45 f4 mov %eax,-0xc(%ebp) + 1055a0: 83 7d f0 00 cmpl $0x0,-0x10(%ebp) + 1055a4: 74 1c je 1055c2 + 1055a6: 8b 45 f0 mov -0x10(%ebp),%eax + 1055a9: ba 00 00 00 00 mov $0x0,%edx + 1055ae: f7 75 e4 divl -0x1c(%ebp) + 1055b1: 89 55 f4 mov %edx,-0xc(%ebp) + 1055b4: 8b 45 f0 mov -0x10(%ebp),%eax + 1055b7: ba 00 00 00 00 mov $0x0,%edx + 1055bc: f7 75 e4 divl -0x1c(%ebp) + 1055bf: 89 45 f0 mov %eax,-0x10(%ebp) + 1055c2: 8b 45 e0 mov -0x20(%ebp),%eax + 1055c5: 8b 55 f4 mov -0xc(%ebp),%edx + 1055c8: f7 75 e4 divl -0x1c(%ebp) + 1055cb: 89 45 e0 mov %eax,-0x20(%ebp) + 1055ce: 89 55 dc mov %edx,-0x24(%ebp) + 1055d1: 8b 45 e0 mov -0x20(%ebp),%eax + 1055d4: 8b 55 f0 mov -0x10(%ebp),%edx + 1055d7: 89 45 e8 mov %eax,-0x18(%ebp) + 1055da: 89 55 ec mov %edx,-0x14(%ebp) + 1055dd: 8b 45 dc mov -0x24(%ebp),%eax + 1055e0: 89 45 d8 mov %eax,-0x28(%ebp) + + // first recursively print all preceding (more significant) digits + if (num >= base) { + 1055e3: 8b 45 18 mov 0x18(%ebp),%eax + 1055e6: ba 00 00 00 00 mov $0x0,%edx + 1055eb: 8b 4d d4 mov -0x2c(%ebp),%ecx + 1055ee: 39 45 d0 cmp %eax,-0x30(%ebp) + 1055f1: 19 d1 sbb %edx,%ecx + 1055f3: 72 4c jb 105641 + printnum(putch, putdat, result, base, width - 1, padc); + 1055f5: 8b 45 1c mov 0x1c(%ebp),%eax + 1055f8: 8d 50 ff lea -0x1(%eax),%edx + 1055fb: 8b 45 20 mov 0x20(%ebp),%eax + 1055fe: 89 44 24 18 mov %eax,0x18(%esp) + 105602: 89 54 24 14 mov %edx,0x14(%esp) + 105606: 8b 45 18 mov 0x18(%ebp),%eax + 105609: 89 44 24 10 mov %eax,0x10(%esp) + 10560d: 8b 45 e8 mov -0x18(%ebp),%eax + 105610: 8b 55 ec mov -0x14(%ebp),%edx + 105613: 89 44 24 08 mov %eax,0x8(%esp) + 105617: 89 54 24 0c mov %edx,0xc(%esp) + 10561b: 8b 45 0c mov 0xc(%ebp),%eax + 10561e: 89 44 24 04 mov %eax,0x4(%esp) + 105622: 8b 45 08 mov 0x8(%ebp),%eax + 105625: 89 04 24 mov %eax,(%esp) + 105628: e8 3d ff ff ff call 10556a + 10562d: eb 1b jmp 10564a + } else { + // print any needed pad characters before first digit + while (-- width > 0) + putch(padc, putdat); + 10562f: 8b 45 0c mov 0xc(%ebp),%eax + 105632: 89 44 24 04 mov %eax,0x4(%esp) + 105636: 8b 45 20 mov 0x20(%ebp),%eax + 105639: 89 04 24 mov %eax,(%esp) + 10563c: 8b 45 08 mov 0x8(%ebp),%eax + 10563f: ff d0 call *%eax + while (-- width > 0) + 105641: ff 4d 1c decl 0x1c(%ebp) + 105644: 83 7d 1c 00 cmpl $0x0,0x1c(%ebp) + 105648: 7f e5 jg 10562f + } + // then print this (the least significant) digit + putch("0123456789abcdef"[mod], putdat); + 10564a: 8b 45 d8 mov -0x28(%ebp),%eax + 10564d: 05 3c 72 10 00 add $0x10723c,%eax + 105652: 0f b6 00 movzbl (%eax),%eax + 105655: 0f be c0 movsbl %al,%eax + 105658: 8b 55 0c mov 0xc(%ebp),%edx + 10565b: 89 54 24 04 mov %edx,0x4(%esp) + 10565f: 89 04 24 mov %eax,(%esp) + 105662: 8b 45 08 mov 0x8(%ebp),%eax + 105665: ff d0 call *%eax +} + 105667: 90 nop + 105668: 89 ec mov %ebp,%esp + 10566a: 5d pop %ebp + 10566b: c3 ret + +0010566c : + * getuint - get an unsigned int of various possible sizes from a varargs list + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static unsigned long long +getuint(va_list *ap, int lflag) { + 10566c: 55 push %ebp + 10566d: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 10566f: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 105673: 7e 14 jle 105689 + return va_arg(*ap, unsigned long long); + 105675: 8b 45 08 mov 0x8(%ebp),%eax + 105678: 8b 00 mov (%eax),%eax + 10567a: 8d 48 08 lea 0x8(%eax),%ecx + 10567d: 8b 55 08 mov 0x8(%ebp),%edx + 105680: 89 0a mov %ecx,(%edx) + 105682: 8b 50 04 mov 0x4(%eax),%edx + 105685: 8b 00 mov (%eax),%eax + 105687: eb 30 jmp 1056b9 + } + else if (lflag) { + 105689: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 10568d: 74 16 je 1056a5 + return va_arg(*ap, unsigned long); + 10568f: 8b 45 08 mov 0x8(%ebp),%eax + 105692: 8b 00 mov (%eax),%eax + 105694: 8d 48 04 lea 0x4(%eax),%ecx + 105697: 8b 55 08 mov 0x8(%ebp),%edx + 10569a: 89 0a mov %ecx,(%edx) + 10569c: 8b 00 mov (%eax),%eax + 10569e: ba 00 00 00 00 mov $0x0,%edx + 1056a3: eb 14 jmp 1056b9 + } + else { + return va_arg(*ap, unsigned int); + 1056a5: 8b 45 08 mov 0x8(%ebp),%eax + 1056a8: 8b 00 mov (%eax),%eax + 1056aa: 8d 48 04 lea 0x4(%eax),%ecx + 1056ad: 8b 55 08 mov 0x8(%ebp),%edx + 1056b0: 89 0a mov %ecx,(%edx) + 1056b2: 8b 00 mov (%eax),%eax + 1056b4: ba 00 00 00 00 mov $0x0,%edx + } +} + 1056b9: 5d pop %ebp + 1056ba: c3 ret + +001056bb : + * getint - same as getuint but signed, we can't use getuint because of sign extension + * @ap: a varargs list pointer + * @lflag: determines the size of the vararg that @ap points to + * */ +static long long +getint(va_list *ap, int lflag) { + 1056bb: 55 push %ebp + 1056bc: 89 e5 mov %esp,%ebp + if (lflag >= 2) { + 1056be: 83 7d 0c 01 cmpl $0x1,0xc(%ebp) + 1056c2: 7e 14 jle 1056d8 + return va_arg(*ap, long long); + 1056c4: 8b 45 08 mov 0x8(%ebp),%eax + 1056c7: 8b 00 mov (%eax),%eax + 1056c9: 8d 48 08 lea 0x8(%eax),%ecx + 1056cc: 8b 55 08 mov 0x8(%ebp),%edx + 1056cf: 89 0a mov %ecx,(%edx) + 1056d1: 8b 50 04 mov 0x4(%eax),%edx + 1056d4: 8b 00 mov (%eax),%eax + 1056d6: eb 28 jmp 105700 + } + else if (lflag) { + 1056d8: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 1056dc: 74 12 je 1056f0 + return va_arg(*ap, long); + 1056de: 8b 45 08 mov 0x8(%ebp),%eax + 1056e1: 8b 00 mov (%eax),%eax + 1056e3: 8d 48 04 lea 0x4(%eax),%ecx + 1056e6: 8b 55 08 mov 0x8(%ebp),%edx + 1056e9: 89 0a mov %ecx,(%edx) + 1056eb: 8b 00 mov (%eax),%eax + 1056ed: 99 cltd + 1056ee: eb 10 jmp 105700 + } + else { + return va_arg(*ap, int); + 1056f0: 8b 45 08 mov 0x8(%ebp),%eax + 1056f3: 8b 00 mov (%eax),%eax + 1056f5: 8d 48 04 lea 0x4(%eax),%ecx + 1056f8: 8b 55 08 mov 0x8(%ebp),%edx + 1056fb: 89 0a mov %ecx,(%edx) + 1056fd: 8b 00 mov (%eax),%eax + 1056ff: 99 cltd + } +} + 105700: 5d pop %ebp + 105701: c3 ret + +00105702 : + * @putch: specified putch function, print a single character + * @putdat: used by @putch function + * @fmt: the format string to use + * */ +void +printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...) { + 105702: 55 push %ebp + 105703: 89 e5 mov %esp,%ebp + 105705: 83 ec 28 sub $0x28,%esp + va_list ap; + + va_start(ap, fmt); + 105708: 8d 45 14 lea 0x14(%ebp),%eax + 10570b: 89 45 f4 mov %eax,-0xc(%ebp) + vprintfmt(putch, putdat, fmt, ap); + 10570e: 8b 45 f4 mov -0xc(%ebp),%eax + 105711: 89 44 24 0c mov %eax,0xc(%esp) + 105715: 8b 45 10 mov 0x10(%ebp),%eax + 105718: 89 44 24 08 mov %eax,0x8(%esp) + 10571c: 8b 45 0c mov 0xc(%ebp),%eax + 10571f: 89 44 24 04 mov %eax,0x4(%esp) + 105723: 8b 45 08 mov 0x8(%ebp),%eax + 105726: 89 04 24 mov %eax,(%esp) + 105729: e8 05 00 00 00 call 105733 + va_end(ap); +} + 10572e: 90 nop + 10572f: 89 ec mov %ebp,%esp + 105731: 5d pop %ebp + 105732: c3 ret + +00105733 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want printfmt() instead. + * */ +void +vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap) { + 105733: 55 push %ebp + 105734: 89 e5 mov %esp,%ebp + 105736: 56 push %esi + 105737: 53 push %ebx + 105738: 83 ec 40 sub $0x40,%esp + register int ch, err; + unsigned long long num; + int base, width, precision, lflag, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt ++) != '%') { + 10573b: eb 17 jmp 105754 + if (ch == '\0') { + 10573d: 85 db test %ebx,%ebx + 10573f: 0f 84 bf 03 00 00 je 105b04 + return; + } + putch(ch, putdat); + 105745: 8b 45 0c mov 0xc(%ebp),%eax + 105748: 89 44 24 04 mov %eax,0x4(%esp) + 10574c: 89 1c 24 mov %ebx,(%esp) + 10574f: 8b 45 08 mov 0x8(%ebp),%eax + 105752: ff d0 call *%eax + while ((ch = *(unsigned char *)fmt ++) != '%') { + 105754: 8b 45 10 mov 0x10(%ebp),%eax + 105757: 8d 50 01 lea 0x1(%eax),%edx + 10575a: 89 55 10 mov %edx,0x10(%ebp) + 10575d: 0f b6 00 movzbl (%eax),%eax + 105760: 0f b6 d8 movzbl %al,%ebx + 105763: 83 fb 25 cmp $0x25,%ebx + 105766: 75 d5 jne 10573d + } + + // Process a %-escape sequence + char padc = ' '; + 105768: c6 45 db 20 movb $0x20,-0x25(%ebp) + width = precision = -1; + 10576c: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + 105773: 8b 45 e4 mov -0x1c(%ebp),%eax + 105776: 89 45 e8 mov %eax,-0x18(%ebp) + lflag = altflag = 0; + 105779: c7 45 dc 00 00 00 00 movl $0x0,-0x24(%ebp) + 105780: 8b 45 dc mov -0x24(%ebp),%eax + 105783: 89 45 e0 mov %eax,-0x20(%ebp) + + reswitch: + switch (ch = *(unsigned char *)fmt ++) { + 105786: 8b 45 10 mov 0x10(%ebp),%eax + 105789: 8d 50 01 lea 0x1(%eax),%edx + 10578c: 89 55 10 mov %edx,0x10(%ebp) + 10578f: 0f b6 00 movzbl (%eax),%eax + 105792: 0f b6 d8 movzbl %al,%ebx + 105795: 8d 43 dd lea -0x23(%ebx),%eax + 105798: 83 f8 55 cmp $0x55,%eax + 10579b: 0f 87 37 03 00 00 ja 105ad8 + 1057a1: 8b 04 85 60 72 10 00 mov 0x107260(,%eax,4),%eax + 1057a8: ff e0 jmp *%eax + + // flag to pad on the right + case '-': + padc = '-'; + 1057aa: c6 45 db 2d movb $0x2d,-0x25(%ebp) + goto reswitch; + 1057ae: eb d6 jmp 105786 + + // flag to pad with 0's instead of spaces + case '0': + padc = '0'; + 1057b0: c6 45 db 30 movb $0x30,-0x25(%ebp) + goto reswitch; + 1057b4: eb d0 jmp 105786 + + // width field + case '1' ... '9': + for (precision = 0; ; ++ fmt) { + 1057b6: c7 45 e4 00 00 00 00 movl $0x0,-0x1c(%ebp) + precision = precision * 10 + ch - '0'; + 1057bd: 8b 55 e4 mov -0x1c(%ebp),%edx + 1057c0: 89 d0 mov %edx,%eax + 1057c2: c1 e0 02 shl $0x2,%eax + 1057c5: 01 d0 add %edx,%eax + 1057c7: 01 c0 add %eax,%eax + 1057c9: 01 d8 add %ebx,%eax + 1057cb: 83 e8 30 sub $0x30,%eax + 1057ce: 89 45 e4 mov %eax,-0x1c(%ebp) + ch = *fmt; + 1057d1: 8b 45 10 mov 0x10(%ebp),%eax + 1057d4: 0f b6 00 movzbl (%eax),%eax + 1057d7: 0f be d8 movsbl %al,%ebx + if (ch < '0' || ch > '9') { + 1057da: 83 fb 2f cmp $0x2f,%ebx + 1057dd: 7e 38 jle 105817 + 1057df: 83 fb 39 cmp $0x39,%ebx + 1057e2: 7f 33 jg 105817 + for (precision = 0; ; ++ fmt) { + 1057e4: ff 45 10 incl 0x10(%ebp) + precision = precision * 10 + ch - '0'; + 1057e7: eb d4 jmp 1057bd + } + } + goto process_precision; + + case '*': + precision = va_arg(ap, int); + 1057e9: 8b 45 14 mov 0x14(%ebp),%eax + 1057ec: 8d 50 04 lea 0x4(%eax),%edx + 1057ef: 89 55 14 mov %edx,0x14(%ebp) + 1057f2: 8b 00 mov (%eax),%eax + 1057f4: 89 45 e4 mov %eax,-0x1c(%ebp) + goto process_precision; + 1057f7: eb 1f jmp 105818 + + case '.': + if (width < 0) + 1057f9: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 1057fd: 79 87 jns 105786 + width = 0; + 1057ff: c7 45 e8 00 00 00 00 movl $0x0,-0x18(%ebp) + goto reswitch; + 105806: e9 7b ff ff ff jmp 105786 + + case '#': + altflag = 1; + 10580b: c7 45 dc 01 00 00 00 movl $0x1,-0x24(%ebp) + goto reswitch; + 105812: e9 6f ff ff ff jmp 105786 + goto process_precision; + 105817: 90 nop + + process_precision: + if (width < 0) + 105818: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 10581c: 0f 89 64 ff ff ff jns 105786 + width = precision, precision = -1; + 105822: 8b 45 e4 mov -0x1c(%ebp),%eax + 105825: 89 45 e8 mov %eax,-0x18(%ebp) + 105828: c7 45 e4 ff ff ff ff movl $0xffffffff,-0x1c(%ebp) + goto reswitch; + 10582f: e9 52 ff ff ff jmp 105786 + + // long flag (doubled for long long) + case 'l': + lflag ++; + 105834: ff 45 e0 incl -0x20(%ebp) + goto reswitch; + 105837: e9 4a ff ff ff jmp 105786 + + // character + case 'c': + putch(va_arg(ap, int), putdat); + 10583c: 8b 45 14 mov 0x14(%ebp),%eax + 10583f: 8d 50 04 lea 0x4(%eax),%edx + 105842: 89 55 14 mov %edx,0x14(%ebp) + 105845: 8b 00 mov (%eax),%eax + 105847: 8b 55 0c mov 0xc(%ebp),%edx + 10584a: 89 54 24 04 mov %edx,0x4(%esp) + 10584e: 89 04 24 mov %eax,(%esp) + 105851: 8b 45 08 mov 0x8(%ebp),%eax + 105854: ff d0 call *%eax + break; + 105856: e9 a4 02 00 00 jmp 105aff + + // error message + case 'e': + err = va_arg(ap, int); + 10585b: 8b 45 14 mov 0x14(%ebp),%eax + 10585e: 8d 50 04 lea 0x4(%eax),%edx + 105861: 89 55 14 mov %edx,0x14(%ebp) + 105864: 8b 18 mov (%eax),%ebx + if (err < 0) { + 105866: 85 db test %ebx,%ebx + 105868: 79 02 jns 10586c + err = -err; + 10586a: f7 db neg %ebx + } + if (err > MAXERROR || (p = error_string[err]) == NULL) { + 10586c: 83 fb 06 cmp $0x6,%ebx + 10586f: 7f 0b jg 10587c + 105871: 8b 34 9d 20 72 10 00 mov 0x107220(,%ebx,4),%esi + 105878: 85 f6 test %esi,%esi + 10587a: 75 23 jne 10589f + printfmt(putch, putdat, "error %d", err); + 10587c: 89 5c 24 0c mov %ebx,0xc(%esp) + 105880: c7 44 24 08 4d 72 10 movl $0x10724d,0x8(%esp) + 105887: 00 + 105888: 8b 45 0c mov 0xc(%ebp),%eax + 10588b: 89 44 24 04 mov %eax,0x4(%esp) + 10588f: 8b 45 08 mov 0x8(%ebp),%eax + 105892: 89 04 24 mov %eax,(%esp) + 105895: e8 68 fe ff ff call 105702 + } + else { + printfmt(putch, putdat, "%s", p); + } + break; + 10589a: e9 60 02 00 00 jmp 105aff + printfmt(putch, putdat, "%s", p); + 10589f: 89 74 24 0c mov %esi,0xc(%esp) + 1058a3: c7 44 24 08 56 72 10 movl $0x107256,0x8(%esp) + 1058aa: 00 + 1058ab: 8b 45 0c mov 0xc(%ebp),%eax + 1058ae: 89 44 24 04 mov %eax,0x4(%esp) + 1058b2: 8b 45 08 mov 0x8(%ebp),%eax + 1058b5: 89 04 24 mov %eax,(%esp) + 1058b8: e8 45 fe ff ff call 105702 + break; + 1058bd: e9 3d 02 00 00 jmp 105aff + + // string + case 's': + if ((p = va_arg(ap, char *)) == NULL) { + 1058c2: 8b 45 14 mov 0x14(%ebp),%eax + 1058c5: 8d 50 04 lea 0x4(%eax),%edx + 1058c8: 89 55 14 mov %edx,0x14(%ebp) + 1058cb: 8b 30 mov (%eax),%esi + 1058cd: 85 f6 test %esi,%esi + 1058cf: 75 05 jne 1058d6 + p = "(null)"; + 1058d1: be 59 72 10 00 mov $0x107259,%esi + } + if (width > 0 && padc != '-') { + 1058d6: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 1058da: 7e 76 jle 105952 + 1058dc: 80 7d db 2d cmpb $0x2d,-0x25(%ebp) + 1058e0: 74 70 je 105952 + for (width -= strnlen(p, precision); width > 0; width --) { + 1058e2: 8b 45 e4 mov -0x1c(%ebp),%eax + 1058e5: 89 44 24 04 mov %eax,0x4(%esp) + 1058e9: 89 34 24 mov %esi,(%esp) + 1058ec: e8 16 03 00 00 call 105c07 + 1058f1: 89 c2 mov %eax,%edx + 1058f3: 8b 45 e8 mov -0x18(%ebp),%eax + 1058f6: 29 d0 sub %edx,%eax + 1058f8: 89 45 e8 mov %eax,-0x18(%ebp) + 1058fb: eb 16 jmp 105913 + putch(padc, putdat); + 1058fd: 0f be 45 db movsbl -0x25(%ebp),%eax + 105901: 8b 55 0c mov 0xc(%ebp),%edx + 105904: 89 54 24 04 mov %edx,0x4(%esp) + 105908: 89 04 24 mov %eax,(%esp) + 10590b: 8b 45 08 mov 0x8(%ebp),%eax + 10590e: ff d0 call *%eax + for (width -= strnlen(p, precision); width > 0; width --) { + 105910: ff 4d e8 decl -0x18(%ebp) + 105913: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 105917: 7f e4 jg 1058fd + } + } + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 105919: eb 37 jmp 105952 + if (altflag && (ch < ' ' || ch > '~')) { + 10591b: 83 7d dc 00 cmpl $0x0,-0x24(%ebp) + 10591f: 74 1f je 105940 + 105921: 83 fb 1f cmp $0x1f,%ebx + 105924: 7e 05 jle 10592b + 105926: 83 fb 7e cmp $0x7e,%ebx + 105929: 7e 15 jle 105940 + putch('?', putdat); + 10592b: 8b 45 0c mov 0xc(%ebp),%eax + 10592e: 89 44 24 04 mov %eax,0x4(%esp) + 105932: c7 04 24 3f 00 00 00 movl $0x3f,(%esp) + 105939: 8b 45 08 mov 0x8(%ebp),%eax + 10593c: ff d0 call *%eax + 10593e: eb 0f jmp 10594f + } + else { + putch(ch, putdat); + 105940: 8b 45 0c mov 0xc(%ebp),%eax + 105943: 89 44 24 04 mov %eax,0x4(%esp) + 105947: 89 1c 24 mov %ebx,(%esp) + 10594a: 8b 45 08 mov 0x8(%ebp),%eax + 10594d: ff d0 call *%eax + for (; (ch = *p ++) != '\0' && (precision < 0 || -- precision >= 0); width --) { + 10594f: ff 4d e8 decl -0x18(%ebp) + 105952: 89 f0 mov %esi,%eax + 105954: 8d 70 01 lea 0x1(%eax),%esi + 105957: 0f b6 00 movzbl (%eax),%eax + 10595a: 0f be d8 movsbl %al,%ebx + 10595d: 85 db test %ebx,%ebx + 10595f: 74 27 je 105988 + 105961: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 105965: 78 b4 js 10591b + 105967: ff 4d e4 decl -0x1c(%ebp) + 10596a: 83 7d e4 00 cmpl $0x0,-0x1c(%ebp) + 10596e: 79 ab jns 10591b + } + } + for (; width > 0; width --) { + 105970: eb 16 jmp 105988 + putch(' ', putdat); + 105972: 8b 45 0c mov 0xc(%ebp),%eax + 105975: 89 44 24 04 mov %eax,0x4(%esp) + 105979: c7 04 24 20 00 00 00 movl $0x20,(%esp) + 105980: 8b 45 08 mov 0x8(%ebp),%eax + 105983: ff d0 call *%eax + for (; width > 0; width --) { + 105985: ff 4d e8 decl -0x18(%ebp) + 105988: 83 7d e8 00 cmpl $0x0,-0x18(%ebp) + 10598c: 7f e4 jg 105972 + } + break; + 10598e: e9 6c 01 00 00 jmp 105aff + + // (signed) decimal + case 'd': + num = getint(&ap, lflag); + 105993: 8b 45 e0 mov -0x20(%ebp),%eax + 105996: 89 44 24 04 mov %eax,0x4(%esp) + 10599a: 8d 45 14 lea 0x14(%ebp),%eax + 10599d: 89 04 24 mov %eax,(%esp) + 1059a0: e8 16 fd ff ff call 1056bb + 1059a5: 89 45 f0 mov %eax,-0x10(%ebp) + 1059a8: 89 55 f4 mov %edx,-0xc(%ebp) + if ((long long)num < 0) { + 1059ab: 8b 45 f0 mov -0x10(%ebp),%eax + 1059ae: 8b 55 f4 mov -0xc(%ebp),%edx + 1059b1: 85 d2 test %edx,%edx + 1059b3: 79 26 jns 1059db + putch('-', putdat); + 1059b5: 8b 45 0c mov 0xc(%ebp),%eax + 1059b8: 89 44 24 04 mov %eax,0x4(%esp) + 1059bc: c7 04 24 2d 00 00 00 movl $0x2d,(%esp) + 1059c3: 8b 45 08 mov 0x8(%ebp),%eax + 1059c6: ff d0 call *%eax + num = -(long long)num; + 1059c8: 8b 45 f0 mov -0x10(%ebp),%eax + 1059cb: 8b 55 f4 mov -0xc(%ebp),%edx + 1059ce: f7 d8 neg %eax + 1059d0: 83 d2 00 adc $0x0,%edx + 1059d3: f7 da neg %edx + 1059d5: 89 45 f0 mov %eax,-0x10(%ebp) + 1059d8: 89 55 f4 mov %edx,-0xc(%ebp) + } + base = 10; + 1059db: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 1059e2: e9 a8 00 00 00 jmp 105a8f + + // unsigned decimal + case 'u': + num = getuint(&ap, lflag); + 1059e7: 8b 45 e0 mov -0x20(%ebp),%eax + 1059ea: 89 44 24 04 mov %eax,0x4(%esp) + 1059ee: 8d 45 14 lea 0x14(%ebp),%eax + 1059f1: 89 04 24 mov %eax,(%esp) + 1059f4: e8 73 fc ff ff call 10566c + 1059f9: 89 45 f0 mov %eax,-0x10(%ebp) + 1059fc: 89 55 f4 mov %edx,-0xc(%ebp) + base = 10; + 1059ff: c7 45 ec 0a 00 00 00 movl $0xa,-0x14(%ebp) + goto number; + 105a06: e9 84 00 00 00 jmp 105a8f + + // (unsigned) octal + case 'o': + num = getuint(&ap, lflag); + 105a0b: 8b 45 e0 mov -0x20(%ebp),%eax + 105a0e: 89 44 24 04 mov %eax,0x4(%esp) + 105a12: 8d 45 14 lea 0x14(%ebp),%eax + 105a15: 89 04 24 mov %eax,(%esp) + 105a18: e8 4f fc ff ff call 10566c + 105a1d: 89 45 f0 mov %eax,-0x10(%ebp) + 105a20: 89 55 f4 mov %edx,-0xc(%ebp) + base = 8; + 105a23: c7 45 ec 08 00 00 00 movl $0x8,-0x14(%ebp) + goto number; + 105a2a: eb 63 jmp 105a8f + + // pointer + case 'p': + putch('0', putdat); + 105a2c: 8b 45 0c mov 0xc(%ebp),%eax + 105a2f: 89 44 24 04 mov %eax,0x4(%esp) + 105a33: c7 04 24 30 00 00 00 movl $0x30,(%esp) + 105a3a: 8b 45 08 mov 0x8(%ebp),%eax + 105a3d: ff d0 call *%eax + putch('x', putdat); + 105a3f: 8b 45 0c mov 0xc(%ebp),%eax + 105a42: 89 44 24 04 mov %eax,0x4(%esp) + 105a46: c7 04 24 78 00 00 00 movl $0x78,(%esp) + 105a4d: 8b 45 08 mov 0x8(%ebp),%eax + 105a50: ff d0 call *%eax + num = (unsigned long long)(uintptr_t)va_arg(ap, void *); + 105a52: 8b 45 14 mov 0x14(%ebp),%eax + 105a55: 8d 50 04 lea 0x4(%eax),%edx + 105a58: 89 55 14 mov %edx,0x14(%ebp) + 105a5b: 8b 00 mov (%eax),%eax + 105a5d: 89 45 f0 mov %eax,-0x10(%ebp) + 105a60: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + base = 16; + 105a67: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + goto number; + 105a6e: eb 1f jmp 105a8f + + // (unsigned) hexadecimal + case 'x': + num = getuint(&ap, lflag); + 105a70: 8b 45 e0 mov -0x20(%ebp),%eax + 105a73: 89 44 24 04 mov %eax,0x4(%esp) + 105a77: 8d 45 14 lea 0x14(%ebp),%eax + 105a7a: 89 04 24 mov %eax,(%esp) + 105a7d: e8 ea fb ff ff call 10566c + 105a82: 89 45 f0 mov %eax,-0x10(%ebp) + 105a85: 89 55 f4 mov %edx,-0xc(%ebp) + base = 16; + 105a88: c7 45 ec 10 00 00 00 movl $0x10,-0x14(%ebp) + number: + printnum(putch, putdat, num, base, width, padc); + 105a8f: 0f be 55 db movsbl -0x25(%ebp),%edx + 105a93: 8b 45 ec mov -0x14(%ebp),%eax + 105a96: 89 54 24 18 mov %edx,0x18(%esp) + 105a9a: 8b 55 e8 mov -0x18(%ebp),%edx + 105a9d: 89 54 24 14 mov %edx,0x14(%esp) + 105aa1: 89 44 24 10 mov %eax,0x10(%esp) + 105aa5: 8b 45 f0 mov -0x10(%ebp),%eax + 105aa8: 8b 55 f4 mov -0xc(%ebp),%edx + 105aab: 89 44 24 08 mov %eax,0x8(%esp) + 105aaf: 89 54 24 0c mov %edx,0xc(%esp) + 105ab3: 8b 45 0c mov 0xc(%ebp),%eax + 105ab6: 89 44 24 04 mov %eax,0x4(%esp) + 105aba: 8b 45 08 mov 0x8(%ebp),%eax + 105abd: 89 04 24 mov %eax,(%esp) + 105ac0: e8 a5 fa ff ff call 10556a + break; + 105ac5: eb 38 jmp 105aff + + // escaped '%' character + case '%': + putch(ch, putdat); + 105ac7: 8b 45 0c mov 0xc(%ebp),%eax + 105aca: 89 44 24 04 mov %eax,0x4(%esp) + 105ace: 89 1c 24 mov %ebx,(%esp) + 105ad1: 8b 45 08 mov 0x8(%ebp),%eax + 105ad4: ff d0 call *%eax + break; + 105ad6: eb 27 jmp 105aff + + // unrecognized escape sequence - just print it literally + default: + putch('%', putdat); + 105ad8: 8b 45 0c mov 0xc(%ebp),%eax + 105adb: 89 44 24 04 mov %eax,0x4(%esp) + 105adf: c7 04 24 25 00 00 00 movl $0x25,(%esp) + 105ae6: 8b 45 08 mov 0x8(%ebp),%eax + 105ae9: ff d0 call *%eax + for (fmt --; fmt[-1] != '%'; fmt --) + 105aeb: ff 4d 10 decl 0x10(%ebp) + 105aee: eb 03 jmp 105af3 + 105af0: ff 4d 10 decl 0x10(%ebp) + 105af3: 8b 45 10 mov 0x10(%ebp),%eax + 105af6: 48 dec %eax + 105af7: 0f b6 00 movzbl (%eax),%eax + 105afa: 3c 25 cmp $0x25,%al + 105afc: 75 f2 jne 105af0 + /* do nothing */; + break; + 105afe: 90 nop + while (1) { + 105aff: e9 37 fc ff ff jmp 10573b + return; + 105b04: 90 nop + } + } +} + 105b05: 83 c4 40 add $0x40,%esp + 105b08: 5b pop %ebx + 105b09: 5e pop %esi + 105b0a: 5d pop %ebp + 105b0b: c3 ret + +00105b0c : + * sprintputch - 'print' a single character in a buffer + * @ch: the character will be printed + * @b: the buffer to place the character @ch + * */ +static void +sprintputch(int ch, struct sprintbuf *b) { + 105b0c: 55 push %ebp + 105b0d: 89 e5 mov %esp,%ebp + b->cnt ++; + 105b0f: 8b 45 0c mov 0xc(%ebp),%eax + 105b12: 8b 40 08 mov 0x8(%eax),%eax + 105b15: 8d 50 01 lea 0x1(%eax),%edx + 105b18: 8b 45 0c mov 0xc(%ebp),%eax + 105b1b: 89 50 08 mov %edx,0x8(%eax) + if (b->buf < b->ebuf) { + 105b1e: 8b 45 0c mov 0xc(%ebp),%eax + 105b21: 8b 10 mov (%eax),%edx + 105b23: 8b 45 0c mov 0xc(%ebp),%eax + 105b26: 8b 40 04 mov 0x4(%eax),%eax + 105b29: 39 c2 cmp %eax,%edx + 105b2b: 73 12 jae 105b3f + *b->buf ++ = ch; + 105b2d: 8b 45 0c mov 0xc(%ebp),%eax + 105b30: 8b 00 mov (%eax),%eax + 105b32: 8d 48 01 lea 0x1(%eax),%ecx + 105b35: 8b 55 0c mov 0xc(%ebp),%edx + 105b38: 89 0a mov %ecx,(%edx) + 105b3a: 8b 55 08 mov 0x8(%ebp),%edx + 105b3d: 88 10 mov %dl,(%eax) + } +} + 105b3f: 90 nop + 105b40: 5d pop %ebp + 105b41: c3 ret + +00105b42 : + * @str: the buffer to place the result into + * @size: the size of buffer, including the trailing null space + * @fmt: the format string to use + * */ +int +snprintf(char *str, size_t size, const char *fmt, ...) { + 105b42: 55 push %ebp + 105b43: 89 e5 mov %esp,%ebp + 105b45: 83 ec 28 sub $0x28,%esp + va_list ap; + int cnt; + va_start(ap, fmt); + 105b48: 8d 45 14 lea 0x14(%ebp),%eax + 105b4b: 89 45 f0 mov %eax,-0x10(%ebp) + cnt = vsnprintf(str, size, fmt, ap); + 105b4e: 8b 45 f0 mov -0x10(%ebp),%eax + 105b51: 89 44 24 0c mov %eax,0xc(%esp) + 105b55: 8b 45 10 mov 0x10(%ebp),%eax + 105b58: 89 44 24 08 mov %eax,0x8(%esp) + 105b5c: 8b 45 0c mov 0xc(%ebp),%eax + 105b5f: 89 44 24 04 mov %eax,0x4(%esp) + 105b63: 8b 45 08 mov 0x8(%ebp),%eax + 105b66: 89 04 24 mov %eax,(%esp) + 105b69: e8 0a 00 00 00 call 105b78 + 105b6e: 89 45 f4 mov %eax,-0xc(%ebp) + va_end(ap); + return cnt; + 105b71: 8b 45 f4 mov -0xc(%ebp),%eax +} + 105b74: 89 ec mov %ebp,%esp + 105b76: 5d pop %ebp + 105b77: c3 ret + +00105b78 : + * + * Call this function if you are already dealing with a va_list. + * Or you probably want snprintf() instead. + * */ +int +vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { + 105b78: 55 push %ebp + 105b79: 89 e5 mov %esp,%ebp + 105b7b: 83 ec 28 sub $0x28,%esp + struct sprintbuf b = {str, str + size - 1, 0}; + 105b7e: 8b 45 08 mov 0x8(%ebp),%eax + 105b81: 89 45 ec mov %eax,-0x14(%ebp) + 105b84: 8b 45 0c mov 0xc(%ebp),%eax + 105b87: 8d 50 ff lea -0x1(%eax),%edx + 105b8a: 8b 45 08 mov 0x8(%ebp),%eax + 105b8d: 01 d0 add %edx,%eax + 105b8f: 89 45 f0 mov %eax,-0x10(%ebp) + 105b92: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) + if (str == NULL || b.buf > b.ebuf) { + 105b99: 83 7d 08 00 cmpl $0x0,0x8(%ebp) + 105b9d: 74 0a je 105ba9 + 105b9f: 8b 55 ec mov -0x14(%ebp),%edx + 105ba2: 8b 45 f0 mov -0x10(%ebp),%eax + 105ba5: 39 c2 cmp %eax,%edx + 105ba7: 76 07 jbe 105bb0 + return -E_INVAL; + 105ba9: b8 fd ff ff ff mov $0xfffffffd,%eax + 105bae: eb 2a jmp 105bda + } + // print the string to the buffer + vprintfmt((void*)sprintputch, &b, fmt, ap); + 105bb0: 8b 45 14 mov 0x14(%ebp),%eax + 105bb3: 89 44 24 0c mov %eax,0xc(%esp) + 105bb7: 8b 45 10 mov 0x10(%ebp),%eax + 105bba: 89 44 24 08 mov %eax,0x8(%esp) + 105bbe: 8d 45 ec lea -0x14(%ebp),%eax + 105bc1: 89 44 24 04 mov %eax,0x4(%esp) + 105bc5: c7 04 24 0c 5b 10 00 movl $0x105b0c,(%esp) + 105bcc: e8 62 fb ff ff call 105733 + // null terminate the buffer + *b.buf = '\0'; + 105bd1: 8b 45 ec mov -0x14(%ebp),%eax + 105bd4: c6 00 00 movb $0x0,(%eax) + return b.cnt; + 105bd7: 8b 45 f4 mov -0xc(%ebp),%eax +} + 105bda: 89 ec mov %ebp,%esp + 105bdc: 5d pop %ebp + 105bdd: c3 ret + +00105bde : + * @s: the input string + * + * The strlen() function returns the length of string @s. + * */ +size_t +strlen(const char *s) { + 105bde: 55 push %ebp + 105bdf: 89 e5 mov %esp,%ebp + 105be1: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 105be4: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (*s ++ != '\0') { + 105beb: eb 03 jmp 105bf0 + cnt ++; + 105bed: ff 45 fc incl -0x4(%ebp) + while (*s ++ != '\0') { + 105bf0: 8b 45 08 mov 0x8(%ebp),%eax + 105bf3: 8d 50 01 lea 0x1(%eax),%edx + 105bf6: 89 55 08 mov %edx,0x8(%ebp) + 105bf9: 0f b6 00 movzbl (%eax),%eax + 105bfc: 84 c0 test %al,%al + 105bfe: 75 ed jne 105bed + } + return cnt; + 105c00: 8b 45 fc mov -0x4(%ebp),%eax +} + 105c03: 89 ec mov %ebp,%esp + 105c05: 5d pop %ebp + 105c06: c3 ret + +00105c07 : + * The return value is strlen(s), if that is less than @len, or + * @len if there is no '\0' character among the first @len characters + * pointed by @s. + * */ +size_t +strnlen(const char *s, size_t len) { + 105c07: 55 push %ebp + 105c08: 89 e5 mov %esp,%ebp + 105c0a: 83 ec 10 sub $0x10,%esp + size_t cnt = 0; + 105c0d: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 105c14: eb 03 jmp 105c19 + cnt ++; + 105c16: ff 45 fc incl -0x4(%ebp) + while (cnt < len && *s ++ != '\0') { + 105c19: 8b 45 fc mov -0x4(%ebp),%eax + 105c1c: 3b 45 0c cmp 0xc(%ebp),%eax + 105c1f: 73 10 jae 105c31 + 105c21: 8b 45 08 mov 0x8(%ebp),%eax + 105c24: 8d 50 01 lea 0x1(%eax),%edx + 105c27: 89 55 08 mov %edx,0x8(%ebp) + 105c2a: 0f b6 00 movzbl (%eax),%eax + 105c2d: 84 c0 test %al,%al + 105c2f: 75 e5 jne 105c16 + } + return cnt; + 105c31: 8b 45 fc mov -0x4(%ebp),%eax +} + 105c34: 89 ec mov %ebp,%esp + 105c36: 5d pop %ebp + 105c37: c3 ret + +00105c38 : + * To avoid overflows, the size of array pointed by @dst should be long enough to + * contain the same string as @src (including the terminating null character), and + * should not overlap in memory with @src. + * */ +char * +strcpy(char *dst, const char *src) { + 105c38: 55 push %ebp + 105c39: 89 e5 mov %esp,%ebp + 105c3b: 57 push %edi + 105c3c: 56 push %esi + 105c3d: 83 ec 20 sub $0x20,%esp + 105c40: 8b 45 08 mov 0x8(%ebp),%eax + 105c43: 89 45 f4 mov %eax,-0xc(%ebp) + 105c46: 8b 45 0c mov 0xc(%ebp),%eax + 105c49: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_STRCPY +#define __HAVE_ARCH_STRCPY +static inline char * +__strcpy(char *dst, const char *src) { + int d0, d1, d2; + asm volatile ( + 105c4c: 8b 55 f0 mov -0x10(%ebp),%edx + 105c4f: 8b 45 f4 mov -0xc(%ebp),%eax + 105c52: 89 d1 mov %edx,%ecx + 105c54: 89 c2 mov %eax,%edx + 105c56: 89 ce mov %ecx,%esi + 105c58: 89 d7 mov %edx,%edi + 105c5a: ac lods %ds:(%esi),%al + 105c5b: aa stos %al,%es:(%edi) + 105c5c: 84 c0 test %al,%al + 105c5e: 75 fa jne 105c5a + 105c60: 89 fa mov %edi,%edx + 105c62: 89 f1 mov %esi,%ecx + 105c64: 89 4d ec mov %ecx,-0x14(%ebp) + 105c67: 89 55 e8 mov %edx,-0x18(%ebp) + 105c6a: 89 45 e4 mov %eax,-0x1c(%ebp) + "stosb;" + "testb %%al, %%al;" + "jne 1b;" + : "=&S" (d0), "=&D" (d1), "=&a" (d2) + : "0" (src), "1" (dst) : "memory"); + return dst; + 105c6d: 8b 45 f4 mov -0xc(%ebp),%eax + char *p = dst; + while ((*p ++ = *src ++) != '\0') + /* nothing */; + return dst; +#endif /* __HAVE_ARCH_STRCPY */ +} + 105c70: 83 c4 20 add $0x20,%esp + 105c73: 5e pop %esi + 105c74: 5f pop %edi + 105c75: 5d pop %ebp + 105c76: c3 ret + +00105c77 : + * @len: maximum number of characters to be copied from @src + * + * The return value is @dst + * */ +char * +strncpy(char *dst, const char *src, size_t len) { + 105c77: 55 push %ebp + 105c78: 89 e5 mov %esp,%ebp + 105c7a: 83 ec 10 sub $0x10,%esp + char *p = dst; + 105c7d: 8b 45 08 mov 0x8(%ebp),%eax + 105c80: 89 45 fc mov %eax,-0x4(%ebp) + while (len > 0) { + 105c83: eb 1e jmp 105ca3 + if ((*p = *src) != '\0') { + 105c85: 8b 45 0c mov 0xc(%ebp),%eax + 105c88: 0f b6 10 movzbl (%eax),%edx + 105c8b: 8b 45 fc mov -0x4(%ebp),%eax + 105c8e: 88 10 mov %dl,(%eax) + 105c90: 8b 45 fc mov -0x4(%ebp),%eax + 105c93: 0f b6 00 movzbl (%eax),%eax + 105c96: 84 c0 test %al,%al + 105c98: 74 03 je 105c9d + src ++; + 105c9a: ff 45 0c incl 0xc(%ebp) + } + p ++, len --; + 105c9d: ff 45 fc incl -0x4(%ebp) + 105ca0: ff 4d 10 decl 0x10(%ebp) + while (len > 0) { + 105ca3: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 105ca7: 75 dc jne 105c85 + } + return dst; + 105ca9: 8b 45 08 mov 0x8(%ebp),%eax +} + 105cac: 89 ec mov %ebp,%esp + 105cae: 5d pop %ebp + 105caf: c3 ret + +00105cb0 : + * - A value greater than zero indicates that the first character that does + * not match has a greater value in @s1 than in @s2; + * - And a value less than zero indicates the opposite. + * */ +int +strcmp(const char *s1, const char *s2) { + 105cb0: 55 push %ebp + 105cb1: 89 e5 mov %esp,%ebp + 105cb3: 57 push %edi + 105cb4: 56 push %esi + 105cb5: 83 ec 20 sub $0x20,%esp + 105cb8: 8b 45 08 mov 0x8(%ebp),%eax + 105cbb: 89 45 f4 mov %eax,-0xc(%ebp) + 105cbe: 8b 45 0c mov 0xc(%ebp),%eax + 105cc1: 89 45 f0 mov %eax,-0x10(%ebp) + asm volatile ( + 105cc4: 8b 55 f4 mov -0xc(%ebp),%edx + 105cc7: 8b 45 f0 mov -0x10(%ebp),%eax + 105cca: 89 d1 mov %edx,%ecx + 105ccc: 89 c2 mov %eax,%edx + 105cce: 89 ce mov %ecx,%esi + 105cd0: 89 d7 mov %edx,%edi + 105cd2: ac lods %ds:(%esi),%al + 105cd3: ae scas %es:(%edi),%al + 105cd4: 75 08 jne 105cde + 105cd6: 84 c0 test %al,%al + 105cd8: 75 f8 jne 105cd2 + 105cda: 31 c0 xor %eax,%eax + 105cdc: eb 04 jmp 105ce2 + 105cde: 19 c0 sbb %eax,%eax + 105ce0: 0c 01 or $0x1,%al + 105ce2: 89 fa mov %edi,%edx + 105ce4: 89 f1 mov %esi,%ecx + 105ce6: 89 45 ec mov %eax,-0x14(%ebp) + 105ce9: 89 4d e8 mov %ecx,-0x18(%ebp) + 105cec: 89 55 e4 mov %edx,-0x1c(%ebp) + return ret; + 105cef: 8b 45 ec mov -0x14(%ebp),%eax + while (*s1 != '\0' && *s1 == *s2) { + s1 ++, s2 ++; + } + return (int)((unsigned char)*s1 - (unsigned char)*s2); +#endif /* __HAVE_ARCH_STRCMP */ +} + 105cf2: 83 c4 20 add $0x20,%esp + 105cf5: 5e pop %esi + 105cf6: 5f pop %edi + 105cf7: 5d pop %ebp + 105cf8: c3 ret + +00105cf9 : + * they are equal to each other, it continues with the following pairs until + * the characters differ, until a terminating null-character is reached, or + * until @n characters match in both strings, whichever happens first. + * */ +int +strncmp(const char *s1, const char *s2, size_t n) { + 105cf9: 55 push %ebp + 105cfa: 89 e5 mov %esp,%ebp + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 105cfc: eb 09 jmp 105d07 + n --, s1 ++, s2 ++; + 105cfe: ff 4d 10 decl 0x10(%ebp) + 105d01: ff 45 08 incl 0x8(%ebp) + 105d04: ff 45 0c incl 0xc(%ebp) + while (n > 0 && *s1 != '\0' && *s1 == *s2) { + 105d07: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 105d0b: 74 1a je 105d27 + 105d0d: 8b 45 08 mov 0x8(%ebp),%eax + 105d10: 0f b6 00 movzbl (%eax),%eax + 105d13: 84 c0 test %al,%al + 105d15: 74 10 je 105d27 + 105d17: 8b 45 08 mov 0x8(%ebp),%eax + 105d1a: 0f b6 10 movzbl (%eax),%edx + 105d1d: 8b 45 0c mov 0xc(%ebp),%eax + 105d20: 0f b6 00 movzbl (%eax),%eax + 105d23: 38 c2 cmp %al,%dl + 105d25: 74 d7 je 105cfe + } + return (n == 0) ? 0 : (int)((unsigned char)*s1 - (unsigned char)*s2); + 105d27: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 105d2b: 74 18 je 105d45 + 105d2d: 8b 45 08 mov 0x8(%ebp),%eax + 105d30: 0f b6 00 movzbl (%eax),%eax + 105d33: 0f b6 d0 movzbl %al,%edx + 105d36: 8b 45 0c mov 0xc(%ebp),%eax + 105d39: 0f b6 00 movzbl (%eax),%eax + 105d3c: 0f b6 c8 movzbl %al,%ecx + 105d3f: 89 d0 mov %edx,%eax + 105d41: 29 c8 sub %ecx,%eax + 105d43: eb 05 jmp 105d4a + 105d45: b8 00 00 00 00 mov $0x0,%eax +} + 105d4a: 5d pop %ebp + 105d4b: c3 ret + +00105d4c : + * + * The strchr() function returns a pointer to the first occurrence of + * character in @s. If the value is not found, the function returns 'NULL'. + * */ +char * +strchr(const char *s, char c) { + 105d4c: 55 push %ebp + 105d4d: 89 e5 mov %esp,%ebp + 105d4f: 83 ec 04 sub $0x4,%esp + 105d52: 8b 45 0c mov 0xc(%ebp),%eax + 105d55: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 105d58: eb 13 jmp 105d6d + if (*s == c) { + 105d5a: 8b 45 08 mov 0x8(%ebp),%eax + 105d5d: 0f b6 00 movzbl (%eax),%eax + 105d60: 38 45 fc cmp %al,-0x4(%ebp) + 105d63: 75 05 jne 105d6a + return (char *)s; + 105d65: 8b 45 08 mov 0x8(%ebp),%eax + 105d68: eb 12 jmp 105d7c + } + s ++; + 105d6a: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 105d6d: 8b 45 08 mov 0x8(%ebp),%eax + 105d70: 0f b6 00 movzbl (%eax),%eax + 105d73: 84 c0 test %al,%al + 105d75: 75 e3 jne 105d5a + } + return NULL; + 105d77: b8 00 00 00 00 mov $0x0,%eax +} + 105d7c: 89 ec mov %ebp,%esp + 105d7e: 5d pop %ebp + 105d7f: c3 ret + +00105d80 : + * The strfind() function is like strchr() except that if @c is + * not found in @s, then it returns a pointer to the null byte at the + * end of @s, rather than 'NULL'. + * */ +char * +strfind(const char *s, char c) { + 105d80: 55 push %ebp + 105d81: 89 e5 mov %esp,%ebp + 105d83: 83 ec 04 sub $0x4,%esp + 105d86: 8b 45 0c mov 0xc(%ebp),%eax + 105d89: 88 45 fc mov %al,-0x4(%ebp) + while (*s != '\0') { + 105d8c: eb 0e jmp 105d9c + if (*s == c) { + 105d8e: 8b 45 08 mov 0x8(%ebp),%eax + 105d91: 0f b6 00 movzbl (%eax),%eax + 105d94: 38 45 fc cmp %al,-0x4(%ebp) + 105d97: 74 0f je 105da8 + break; + } + s ++; + 105d99: ff 45 08 incl 0x8(%ebp) + while (*s != '\0') { + 105d9c: 8b 45 08 mov 0x8(%ebp),%eax + 105d9f: 0f b6 00 movzbl (%eax),%eax + 105da2: 84 c0 test %al,%al + 105da4: 75 e8 jne 105d8e + 105da6: eb 01 jmp 105da9 + break; + 105da8: 90 nop + } + return (char *)s; + 105da9: 8b 45 08 mov 0x8(%ebp),%eax +} + 105dac: 89 ec mov %ebp,%esp + 105dae: 5d pop %ebp + 105daf: c3 ret + +00105db0 : + * an optional "0x" or "0X" prefix. + * + * The strtol() function returns the converted integral number as a long int value. + * */ +long +strtol(const char *s, char **endptr, int base) { + 105db0: 55 push %ebp + 105db1: 89 e5 mov %esp,%ebp + 105db3: 83 ec 10 sub $0x10,%esp + int neg = 0; + 105db6: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp) + long val = 0; + 105dbd: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) + + // gobble initial whitespace + while (*s == ' ' || *s == '\t') { + 105dc4: eb 03 jmp 105dc9 + s ++; + 105dc6: ff 45 08 incl 0x8(%ebp) + while (*s == ' ' || *s == '\t') { + 105dc9: 8b 45 08 mov 0x8(%ebp),%eax + 105dcc: 0f b6 00 movzbl (%eax),%eax + 105dcf: 3c 20 cmp $0x20,%al + 105dd1: 74 f3 je 105dc6 + 105dd3: 8b 45 08 mov 0x8(%ebp),%eax + 105dd6: 0f b6 00 movzbl (%eax),%eax + 105dd9: 3c 09 cmp $0x9,%al + 105ddb: 74 e9 je 105dc6 + } + + // plus/minus sign + if (*s == '+') { + 105ddd: 8b 45 08 mov 0x8(%ebp),%eax + 105de0: 0f b6 00 movzbl (%eax),%eax + 105de3: 3c 2b cmp $0x2b,%al + 105de5: 75 05 jne 105dec + s ++; + 105de7: ff 45 08 incl 0x8(%ebp) + 105dea: eb 14 jmp 105e00 + } + else if (*s == '-') { + 105dec: 8b 45 08 mov 0x8(%ebp),%eax + 105def: 0f b6 00 movzbl (%eax),%eax + 105df2: 3c 2d cmp $0x2d,%al + 105df4: 75 0a jne 105e00 + s ++, neg = 1; + 105df6: ff 45 08 incl 0x8(%ebp) + 105df9: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) + } + + // hex or octal base prefix + if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x')) { + 105e00: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 105e04: 74 06 je 105e0c + 105e06: 83 7d 10 10 cmpl $0x10,0x10(%ebp) + 105e0a: 75 22 jne 105e2e + 105e0c: 8b 45 08 mov 0x8(%ebp),%eax + 105e0f: 0f b6 00 movzbl (%eax),%eax + 105e12: 3c 30 cmp $0x30,%al + 105e14: 75 18 jne 105e2e + 105e16: 8b 45 08 mov 0x8(%ebp),%eax + 105e19: 40 inc %eax + 105e1a: 0f b6 00 movzbl (%eax),%eax + 105e1d: 3c 78 cmp $0x78,%al + 105e1f: 75 0d jne 105e2e + s += 2, base = 16; + 105e21: 83 45 08 02 addl $0x2,0x8(%ebp) + 105e25: c7 45 10 10 00 00 00 movl $0x10,0x10(%ebp) + 105e2c: eb 29 jmp 105e57 + } + else if (base == 0 && s[0] == '0') { + 105e2e: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 105e32: 75 16 jne 105e4a + 105e34: 8b 45 08 mov 0x8(%ebp),%eax + 105e37: 0f b6 00 movzbl (%eax),%eax + 105e3a: 3c 30 cmp $0x30,%al + 105e3c: 75 0c jne 105e4a + s ++, base = 8; + 105e3e: ff 45 08 incl 0x8(%ebp) + 105e41: c7 45 10 08 00 00 00 movl $0x8,0x10(%ebp) + 105e48: eb 0d jmp 105e57 + } + else if (base == 0) { + 105e4a: 83 7d 10 00 cmpl $0x0,0x10(%ebp) + 105e4e: 75 07 jne 105e57 + base = 10; + 105e50: c7 45 10 0a 00 00 00 movl $0xa,0x10(%ebp) + + // digits + while (1) { + int dig; + + if (*s >= '0' && *s <= '9') { + 105e57: 8b 45 08 mov 0x8(%ebp),%eax + 105e5a: 0f b6 00 movzbl (%eax),%eax + 105e5d: 3c 2f cmp $0x2f,%al + 105e5f: 7e 1b jle 105e7c + 105e61: 8b 45 08 mov 0x8(%ebp),%eax + 105e64: 0f b6 00 movzbl (%eax),%eax + 105e67: 3c 39 cmp $0x39,%al + 105e69: 7f 11 jg 105e7c + dig = *s - '0'; + 105e6b: 8b 45 08 mov 0x8(%ebp),%eax + 105e6e: 0f b6 00 movzbl (%eax),%eax + 105e71: 0f be c0 movsbl %al,%eax + 105e74: 83 e8 30 sub $0x30,%eax + 105e77: 89 45 f4 mov %eax,-0xc(%ebp) + 105e7a: eb 48 jmp 105ec4 + } + else if (*s >= 'a' && *s <= 'z') { + 105e7c: 8b 45 08 mov 0x8(%ebp),%eax + 105e7f: 0f b6 00 movzbl (%eax),%eax + 105e82: 3c 60 cmp $0x60,%al + 105e84: 7e 1b jle 105ea1 + 105e86: 8b 45 08 mov 0x8(%ebp),%eax + 105e89: 0f b6 00 movzbl (%eax),%eax + 105e8c: 3c 7a cmp $0x7a,%al + 105e8e: 7f 11 jg 105ea1 + dig = *s - 'a' + 10; + 105e90: 8b 45 08 mov 0x8(%ebp),%eax + 105e93: 0f b6 00 movzbl (%eax),%eax + 105e96: 0f be c0 movsbl %al,%eax + 105e99: 83 e8 57 sub $0x57,%eax + 105e9c: 89 45 f4 mov %eax,-0xc(%ebp) + 105e9f: eb 23 jmp 105ec4 + } + else if (*s >= 'A' && *s <= 'Z') { + 105ea1: 8b 45 08 mov 0x8(%ebp),%eax + 105ea4: 0f b6 00 movzbl (%eax),%eax + 105ea7: 3c 40 cmp $0x40,%al + 105ea9: 7e 3b jle 105ee6 + 105eab: 8b 45 08 mov 0x8(%ebp),%eax + 105eae: 0f b6 00 movzbl (%eax),%eax + 105eb1: 3c 5a cmp $0x5a,%al + 105eb3: 7f 31 jg 105ee6 + dig = *s - 'A' + 10; + 105eb5: 8b 45 08 mov 0x8(%ebp),%eax + 105eb8: 0f b6 00 movzbl (%eax),%eax + 105ebb: 0f be c0 movsbl %al,%eax + 105ebe: 83 e8 37 sub $0x37,%eax + 105ec1: 89 45 f4 mov %eax,-0xc(%ebp) + } + else { + break; + } + if (dig >= base) { + 105ec4: 8b 45 f4 mov -0xc(%ebp),%eax + 105ec7: 3b 45 10 cmp 0x10(%ebp),%eax + 105eca: 7d 19 jge 105ee5 + break; + } + s ++, val = (val * base) + dig; + 105ecc: ff 45 08 incl 0x8(%ebp) + 105ecf: 8b 45 f8 mov -0x8(%ebp),%eax + 105ed2: 0f af 45 10 imul 0x10(%ebp),%eax + 105ed6: 89 c2 mov %eax,%edx + 105ed8: 8b 45 f4 mov -0xc(%ebp),%eax + 105edb: 01 d0 add %edx,%eax + 105edd: 89 45 f8 mov %eax,-0x8(%ebp) + while (1) { + 105ee0: e9 72 ff ff ff jmp 105e57 + break; + 105ee5: 90 nop + // we don't properly detect overflow! + } + + if (endptr) { + 105ee6: 83 7d 0c 00 cmpl $0x0,0xc(%ebp) + 105eea: 74 08 je 105ef4 + *endptr = (char *) s; + 105eec: 8b 45 0c mov 0xc(%ebp),%eax + 105eef: 8b 55 08 mov 0x8(%ebp),%edx + 105ef2: 89 10 mov %edx,(%eax) + } + return (neg ? -val : val); + 105ef4: 83 7d fc 00 cmpl $0x0,-0x4(%ebp) + 105ef8: 74 07 je 105f01 + 105efa: 8b 45 f8 mov -0x8(%ebp),%eax + 105efd: f7 d8 neg %eax + 105eff: eb 03 jmp 105f04 + 105f01: 8b 45 f8 mov -0x8(%ebp),%eax +} + 105f04: 89 ec mov %ebp,%esp + 105f06: 5d pop %ebp + 105f07: c3 ret + +00105f08 : + * @n: number of bytes to be set to the value + * + * The memset() function returns @s. + * */ +void * +memset(void *s, char c, size_t n) { + 105f08: 55 push %ebp + 105f09: 89 e5 mov %esp,%ebp + 105f0b: 83 ec 28 sub $0x28,%esp + 105f0e: 89 7d fc mov %edi,-0x4(%ebp) + 105f11: 8b 45 0c mov 0xc(%ebp),%eax + 105f14: 88 45 d8 mov %al,-0x28(%ebp) +#ifdef __HAVE_ARCH_MEMSET + return __memset(s, c, n); + 105f17: 0f be 55 d8 movsbl -0x28(%ebp),%edx + 105f1b: 8b 45 08 mov 0x8(%ebp),%eax + 105f1e: 89 45 f8 mov %eax,-0x8(%ebp) + 105f21: 88 55 f7 mov %dl,-0x9(%ebp) + 105f24: 8b 45 10 mov 0x10(%ebp),%eax + 105f27: 89 45 f0 mov %eax,-0x10(%ebp) +#ifndef __HAVE_ARCH_MEMSET +#define __HAVE_ARCH_MEMSET +static inline void * +__memset(void *s, char c, size_t n) { + int d0, d1; + asm volatile ( + 105f2a: 8b 4d f0 mov -0x10(%ebp),%ecx + 105f2d: 0f b6 45 f7 movzbl -0x9(%ebp),%eax + 105f31: 8b 55 f8 mov -0x8(%ebp),%edx + 105f34: 89 d7 mov %edx,%edi + 105f36: f3 aa rep stos %al,%es:(%edi) + 105f38: 89 fa mov %edi,%edx + 105f3a: 89 4d ec mov %ecx,-0x14(%ebp) + 105f3d: 89 55 e8 mov %edx,-0x18(%ebp) + "rep; stosb;" + : "=&c" (d0), "=&D" (d1) + : "0" (n), "a" (c), "1" (s) + : "memory"); + return s; + 105f40: 8b 45 f8 mov -0x8(%ebp),%eax + while (n -- > 0) { + *p ++ = c; + } + return s; +#endif /* __HAVE_ARCH_MEMSET */ +} + 105f43: 8b 7d fc mov -0x4(%ebp),%edi + 105f46: 89 ec mov %ebp,%esp + 105f48: 5d pop %ebp + 105f49: c3 ret + +00105f4a : + * @n: number of bytes to copy + * + * The memmove() function returns @dst. + * */ +void * +memmove(void *dst, const void *src, size_t n) { + 105f4a: 55 push %ebp + 105f4b: 89 e5 mov %esp,%ebp + 105f4d: 57 push %edi + 105f4e: 56 push %esi + 105f4f: 53 push %ebx + 105f50: 83 ec 30 sub $0x30,%esp + 105f53: 8b 45 08 mov 0x8(%ebp),%eax + 105f56: 89 45 f0 mov %eax,-0x10(%ebp) + 105f59: 8b 45 0c mov 0xc(%ebp),%eax + 105f5c: 89 45 ec mov %eax,-0x14(%ebp) + 105f5f: 8b 45 10 mov 0x10(%ebp),%eax + 105f62: 89 45 e8 mov %eax,-0x18(%ebp) + +#ifndef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE +static inline void * +__memmove(void *dst, const void *src, size_t n) { + if (dst < src) { + 105f65: 8b 45 f0 mov -0x10(%ebp),%eax + 105f68: 3b 45 ec cmp -0x14(%ebp),%eax + 105f6b: 73 42 jae 105faf + 105f6d: 8b 45 f0 mov -0x10(%ebp),%eax + 105f70: 89 45 e4 mov %eax,-0x1c(%ebp) + 105f73: 8b 45 ec mov -0x14(%ebp),%eax + 105f76: 89 45 e0 mov %eax,-0x20(%ebp) + 105f79: 8b 45 e8 mov -0x18(%ebp),%eax + 105f7c: 89 45 dc mov %eax,-0x24(%ebp) + "andl $3, %%ecx;" + "jz 1f;" + "rep; movsb;" + "1:" + : "=&c" (d0), "=&D" (d1), "=&S" (d2) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 105f7f: 8b 45 dc mov -0x24(%ebp),%eax + 105f82: c1 e8 02 shr $0x2,%eax + 105f85: 89 c1 mov %eax,%ecx + asm volatile ( + 105f87: 8b 55 e4 mov -0x1c(%ebp),%edx + 105f8a: 8b 45 e0 mov -0x20(%ebp),%eax + 105f8d: 89 d7 mov %edx,%edi + 105f8f: 89 c6 mov %eax,%esi + 105f91: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 105f93: 8b 4d dc mov -0x24(%ebp),%ecx + 105f96: 83 e1 03 and $0x3,%ecx + 105f99: 74 02 je 105f9d + 105f9b: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 105f9d: 89 f0 mov %esi,%eax + 105f9f: 89 fa mov %edi,%edx + 105fa1: 89 4d d8 mov %ecx,-0x28(%ebp) + 105fa4: 89 55 d4 mov %edx,-0x2c(%ebp) + 105fa7: 89 45 d0 mov %eax,-0x30(%ebp) + : "memory"); + return dst; + 105faa: 8b 45 e4 mov -0x1c(%ebp),%eax + return __memcpy(dst, src, n); + 105fad: eb 36 jmp 105fe5 + : "0" (n), "1" (n - 1 + src), "2" (n - 1 + dst) + 105faf: 8b 45 e8 mov -0x18(%ebp),%eax + 105fb2: 8d 50 ff lea -0x1(%eax),%edx + 105fb5: 8b 45 ec mov -0x14(%ebp),%eax + 105fb8: 01 c2 add %eax,%edx + 105fba: 8b 45 e8 mov -0x18(%ebp),%eax + 105fbd: 8d 48 ff lea -0x1(%eax),%ecx + 105fc0: 8b 45 f0 mov -0x10(%ebp),%eax + 105fc3: 8d 1c 01 lea (%ecx,%eax,1),%ebx + asm volatile ( + 105fc6: 8b 45 e8 mov -0x18(%ebp),%eax + 105fc9: 89 c1 mov %eax,%ecx + 105fcb: 89 d8 mov %ebx,%eax + 105fcd: 89 d6 mov %edx,%esi + 105fcf: 89 c7 mov %eax,%edi + 105fd1: fd std + 105fd2: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 105fd4: fc cld + 105fd5: 89 f8 mov %edi,%eax + 105fd7: 89 f2 mov %esi,%edx + 105fd9: 89 4d cc mov %ecx,-0x34(%ebp) + 105fdc: 89 55 c8 mov %edx,-0x38(%ebp) + 105fdf: 89 45 c4 mov %eax,-0x3c(%ebp) + return dst; + 105fe2: 8b 45 f0 mov -0x10(%ebp),%eax + *d ++ = *s ++; + } + } + return dst; +#endif /* __HAVE_ARCH_MEMMOVE */ +} + 105fe5: 83 c4 30 add $0x30,%esp + 105fe8: 5b pop %ebx + 105fe9: 5e pop %esi + 105fea: 5f pop %edi + 105feb: 5d pop %ebp + 105fec: c3 ret + +00105fed : + * it always copies exactly @n bytes. To avoid overflows, the size of arrays pointed + * by both @src and @dst, should be at least @n bytes, and should not overlap + * (for overlapping memory area, memmove is a safer approach). + * */ +void * +memcpy(void *dst, const void *src, size_t n) { + 105fed: 55 push %ebp + 105fee: 89 e5 mov %esp,%ebp + 105ff0: 57 push %edi + 105ff1: 56 push %esi + 105ff2: 83 ec 20 sub $0x20,%esp + 105ff5: 8b 45 08 mov 0x8(%ebp),%eax + 105ff8: 89 45 f4 mov %eax,-0xc(%ebp) + 105ffb: 8b 45 0c mov 0xc(%ebp),%eax + 105ffe: 89 45 f0 mov %eax,-0x10(%ebp) + 106001: 8b 45 10 mov 0x10(%ebp),%eax + 106004: 89 45 ec mov %eax,-0x14(%ebp) + : "0" (n / 4), "g" (n), "1" (dst), "2" (src) + 106007: 8b 45 ec mov -0x14(%ebp),%eax + 10600a: c1 e8 02 shr $0x2,%eax + 10600d: 89 c1 mov %eax,%ecx + asm volatile ( + 10600f: 8b 55 f4 mov -0xc(%ebp),%edx + 106012: 8b 45 f0 mov -0x10(%ebp),%eax + 106015: 89 d7 mov %edx,%edi + 106017: 89 c6 mov %eax,%esi + 106019: f3 a5 rep movsl %ds:(%esi),%es:(%edi) + 10601b: 8b 4d ec mov -0x14(%ebp),%ecx + 10601e: 83 e1 03 and $0x3,%ecx + 106021: 74 02 je 106025 + 106023: f3 a4 rep movsb %ds:(%esi),%es:(%edi) + 106025: 89 f0 mov %esi,%eax + 106027: 89 fa mov %edi,%edx + 106029: 89 4d e8 mov %ecx,-0x18(%ebp) + 10602c: 89 55 e4 mov %edx,-0x1c(%ebp) + 10602f: 89 45 e0 mov %eax,-0x20(%ebp) + return dst; + 106032: 8b 45 f4 mov -0xc(%ebp),%eax + while (n -- > 0) { + *d ++ = *s ++; + } + return dst; +#endif /* __HAVE_ARCH_MEMCPY */ +} + 106035: 83 c4 20 add $0x20,%esp + 106038: 5e pop %esi + 106039: 5f pop %edi + 10603a: 5d pop %ebp + 10603b: c3 ret + +0010603c : + * match in both memory blocks has a greater value in @v1 than in @v2 + * as if evaluated as unsigned char values; + * - And a value less than zero indicates the opposite. + * */ +int +memcmp(const void *v1, const void *v2, size_t n) { + 10603c: 55 push %ebp + 10603d: 89 e5 mov %esp,%ebp + 10603f: 83 ec 10 sub $0x10,%esp + const char *s1 = (const char *)v1; + 106042: 8b 45 08 mov 0x8(%ebp),%eax + 106045: 89 45 fc mov %eax,-0x4(%ebp) + const char *s2 = (const char *)v2; + 106048: 8b 45 0c mov 0xc(%ebp),%eax + 10604b: 89 45 f8 mov %eax,-0x8(%ebp) + while (n -- > 0) { + 10604e: eb 2e jmp 10607e + if (*s1 != *s2) { + 106050: 8b 45 fc mov -0x4(%ebp),%eax + 106053: 0f b6 10 movzbl (%eax),%edx + 106056: 8b 45 f8 mov -0x8(%ebp),%eax + 106059: 0f b6 00 movzbl (%eax),%eax + 10605c: 38 c2 cmp %al,%dl + 10605e: 74 18 je 106078 + return (int)((unsigned char)*s1 - (unsigned char)*s2); + 106060: 8b 45 fc mov -0x4(%ebp),%eax + 106063: 0f b6 00 movzbl (%eax),%eax + 106066: 0f b6 d0 movzbl %al,%edx + 106069: 8b 45 f8 mov -0x8(%ebp),%eax + 10606c: 0f b6 00 movzbl (%eax),%eax + 10606f: 0f b6 c8 movzbl %al,%ecx + 106072: 89 d0 mov %edx,%eax + 106074: 29 c8 sub %ecx,%eax + 106076: eb 18 jmp 106090 + } + s1 ++, s2 ++; + 106078: ff 45 fc incl -0x4(%ebp) + 10607b: ff 45 f8 incl -0x8(%ebp) + while (n -- > 0) { + 10607e: 8b 45 10 mov 0x10(%ebp),%eax + 106081: 8d 50 ff lea -0x1(%eax),%edx + 106084: 89 55 10 mov %edx,0x10(%ebp) + 106087: 85 c0 test %eax,%eax + 106089: 75 c5 jne 106050 + } + return 0; + 10608b: b8 00 00 00 00 mov $0x0,%eax +} + 106090: 89 ec mov %ebp,%esp + 106092: 5d pop %ebp + 106093: c3 ret diff --git a/labcodes/lab2/obj/kernel_nopage.sym b/labcodes/lab2/obj/kernel_nopage.sym new file mode 100644 index 00000000..54c2aa6e --- /dev/null +++ b/labcodes/lab2/obj/kernel_nopage.sym @@ -0,0 +1,461 @@ +00000000 entry.o +0010001e next +00100034 spin +0011b000 __boot_pt1 +00000400 i +00000000 init.c +0010021b lab1_switch_test +00100144 lab1_print_cur_status +0011c000 round.0 +00100204 lab1_switch_to_user +00100211 lab1_switch_to_kernel +00000000 readline.c +0011c020 buf +00000000 stdio.c +0010030e cputch +00000000 kdebug.c +00100411 stab_binsearch +001009c2 read_eip +00000000 kmonitor.c +00119000 commands +001009db parse +00100a94 runcmd +00000000 panic.c +0011c420 is_panic +00000000 clock.c +00000000 console.c +00100d6d __intr_save +00100d99 __intr_restore +00100daf delay +0011c440 crt_buf +0011c444 crt_pos +0011c446 addr_6845 +00100dfa cga_init +0011c448 serial_exists +00100ee2 serial_init +00100fcf lpt_putc_sub +0010104d lpt_putc +0010108f cga_putc +00101285 serial_putc_sub +001012e1 serial_putc +0011c460 cons +00101323 cons_intr +00101372 serial_proc_data +00119040 shiftcode +00119140 togglecode +00119240 normalmap +00119340 shiftmap +00119440 ctlmap +00119540 charcode +001013eb kbd_proc_data +0011c668 shift.0 +00101572 kbd_intr +00101589 kbd_init +00000000 intr.c +00000000 picirq.c +00119550 irq_mask +0011c66c did_init +00101694 pic_setmask +00000000 trap.c +00101870 print_ticks +0011c6e0 idt +00119560 idt_pd +00101a04 trapname +00106740 excnames.0 +00119580 IA32flags +00101cb7 trap_dispatch +00000000 default_pmm.c +001029a9 page2ppn +001029c2 page2pa +001029da page_ref +001029e4 set_page_ref +001029f2 default_init +00102a23 default_init_memmap +00102b85 default_alloc_pages +00102d01 default_free_pages +00102fb9 default_nr_free_pages +00102fc3 basic_check +00103503 default_check +00000000 pmm.c +00103b93 page2ppn +00103bac page2pa +00103bc4 pa2page +00103c15 page2kva +00103c6b pte2page +00103cab pde2page +00103cc5 page_ref +00103ccf set_page_ref +00103cdd page_ref_inc +00103cf4 page_ref_dec +00103d0b __intr_save +00103d37 __intr_restore +0011cf20 ts +00119a00 gdt +00119a30 gdt_pd +00103d4d lgdt +00103d91 gdt_init +00103e7d init_pmm_manager +00103eb3 init_memmap +00103f71 page_init +00104333 boot_map_segment +00104439 boot_alloc_page +001048c2 check_alloc_page +001048e3 check_pgdir +00104f81 check_boot_pgdir +001046fd page_remove_pte +0010530d perm2str +0011cf88 str.0 +0010534f get_pgtable_items +00000000 printfmt.c +00107220 error_string +0010556a printnum +0010566c getuint +001056bb getint +00105b0c sprintputch +00000000 string.c +00102901 vector242 +00102358 vector119 +00100889 print_kerninfo +00102238 vector87 +0010222f vector86 +0010296d vector251 +00105c38 strcpy +0010225c vector91 +00102052 vector33 +00102541 vector162 +001027a5 vector213 +001022f5 vector108 +001020ac vector43 +00100000 kern_entry +00100c1f mon_backtrace +00102565 vector165 +00102655 vector185 +00102334 vector115 +00102373 vector122 +001047a8 page_insert +001024f9 vector156 +00102925 vector245 +00102685 vector189 +00101f76 vector7 +0010214e vector61 +00102001 vector24 +00102310 vector111 +00102709 vector200 +00102184 vector67 +00102421 vector138 +001021c3 vector74 +00105f4a memmove +0010212a vector57 +00105b42 snprintf +00101a4a print_trapframe +001027b1 vector214 +00105733 vprintfmt +001022a4 vector99 +001046a2 get_page +00101f15 __alltraps +00101613 cons_getc +00102445 vector141 +00100cfa is_kernel_panic +001025b9 vector172 +001009d5 print_stackframe +001028f5 vector241 +00102985 vector253 +00101f52 vector3 +00101f49 vector2 +0010284d vector227 +00102781 vector210 +00102829 vector224 +0010209a vector41 +00100366 cprintf +00101fe6 vector21 +001025f5 vector177 +0010234f vector118 +0010219f vector70 +00102196 vector69 +001028c5 vector237 +00102169 vector64 +0010201c vector27 +001023d9 vector132 +00102661 vector186 +001027d5 vector217 +00105fed memcpy +00101f40 vector1 +00102601 vector178 +0010207f vector38 +001028d1 vector238 +00100257 readline +001023e5 vector133 +001021ba vector73 +00102469 vector144 +00106bd0 vpd +00100036 kern_init +00102991 vector254 +001022b6 vector101 +0010278d vector211 +001025d1 vector174 +0010290d vector243 +001023a9 vector128 +00102202 vector81 +00103f0f free_pages +00101fa4 vector13 +00105b78 vsnprintf +001020f4 vector51 +00101fbb vector16 +00119a36 edata +001015a5 cons_init +0011cf0c pmm_manager +001028e9 vector240 +0010210f vector54 +00101fd4 vector19 +00112aac __STAB_END__ +00102265 vector92 +00102919 vector244 +00103d83 load_esp0 +00102439 vector140 +001020be vector45 +001021f0 vector79 +00102865 vector229 +00102511 vector158 +001016f1 pic_enable +00102088 vector39 +00102589 vector168 +00102064 vector35 +00102322 vector113 +00112aad __STABSTR_BEGIN__ +0010238e vector125 +00100c33 __panic +001027c9 vector216 +00102160 vector63 +00102013 vector26 +001013cb serial_intr +001026b5 vector193 +001026d9 vector196 +001000ff grade_backtrace0 +00102775 vector209 +00101f5b vector4 +001025a1 vector170 +00102409 vector136 +00101f8f vector10 +00102751 vector206 +0010299d vector255 +00102625 vector181 +0010213c vector59 +0010011c grade_backtrace +00102226 vector85 +0010221d vector84 +0010263d vector183 +0010251d vector159 +00102799 vector212 +001020d0 vector47 +00105db0 strtol +00102859 vector228 +001020a3 vector42 +0010232b vector114 +00105c07 strnlen +001025dd vector175 +0010245d vector143 +001023c1 vector130 +00106b38 default_pmm_manager +00102931 vector246 +00101f86 vector9 +00102451 vector142 +001022ad vector100 +00102715 vector201 +0010188f idt_init +0010091d print_debuginfo +00102145 vector60 +00101ff8 vector23 +001028b9 vector236 +0011cf04 npage +0010287d vector231 +0010217b vector66 +0010202e vector29 +00105403 print_pgdir +001023fd vector135 +00100b4c kmonitor +001021de vector77 +00102619 vector180 +00100d04 clock_init +00102769 vector208 +0010229b vector98 +00102292 vector97 +00103f44 nr_free_pages +001025e9 vector176 +001026c1 vector194 +00102049 vector32 +0011cf08 boot_cr3 +0011cf8c end +001026fd vector199 +001023cd vector131 +00102979 vector252 +00101f37 vector0 +00105d80 strfind +001015d4 cons_putc +00106094 etext +00102475 vector145 +001022ec vector107 +001199e0 boot_pgdir +00102091 vector40 +00101684 intr_enable +001022bf vector102 +00102121 vector56 +0010218d vector68 +00101f6d vector6 +001023b5 vector129 +001026e5 vector197 +001024c9 vector152 +001195e0 __vectors +00102871 vector230 +00105cf9 strncmp +00104567 get_pte +00102076 vector37 +00102745 vector205 +00102535 vector161 +00105c77 strncpy +001021a8 vector71 +00102529 vector160 +001027bd vector215 +00102505 vector157 +0010168c intr_disable +00101bfd print_regs +00102319 vector112 +001000a7 grade_backtrace2 +00102631 vector182 +00101f9d vector12 +0010603c memcmp +001022fe vector109 +00101fdd vector20 +00102106 vector53 +00101fcb vector18 +00102280 vector95 +00102841 vector226 +001020e2 vector49 +001020b5 vector44 +001021e7 vector78 +001025c5 vector173 +00102346 vector117 +00101a35 trap_in_kernel +0010220b vector82 +00102811 vector222 +00101f7f vector8 +001024a5 vector149 +0010038e cputchar +00105f08 memset +00102889 vector232 +001022e3 vector106 +001027f9 vector220 +00102253 vector90 +0010254d vector163 +001028a1 vector234 +00102157 vector62 +0010200a vector25 +001026f1 vector198 +00102361 vector120 +001003f5 getchar +00104761 page_remove +001020eb vector50 +00101fb2 vector15 +00105702 printfmt +001024bd vector151 +00102214 vector83 +0010224a vector89 +00102241 vector88 +00101eff trap +0010260d vector179 +0010205b vector34 +00116044 __STABSTR_END__ +001020c7 vector46 +00105cb0 strcmp +001023f1 vector134 +0010281d vector223 +001027e1 vector218 +00100561 debuginfo_eip +00101726 pic_init +00102835 vector225 +0010266d vector187 +0010447f pmm_init +00102037 vector30 +001023a0 vector127 +0011c424 ticks +001026a9 vector192 +00102571 vector166 +001021d5 vector76 +001021cc vector75 +001026cd vector195 +001024b1 vector150 +00102133 vector58 +00102949 vector248 +0010237c vector123 +00102289 vector96 +00102040 vector31 +0010272d vector203 +00103ed5 alloc_pages +0010242d vector139 +001024d5 vector153 +00102559 vector164 +0010236a vector121 +0011c680 switchk2u +00101f64 vector5 +0010257d vector167 +001024ed vector155 +00102955 vector249 +00106bcc vpt +00102961 vector250 +00102385 vector124 +00102307 vector110 +00102739 vector204 +00101f2c __trapret +00100331 vcprintf +00102415 vector137 +00100cb1 __warn +0010293d vector247 +00101fef vector22 +00102721 vector202 +001021b1 vector72 +00102118 vector55 +001003a4 cputs +00119000 bootstacktop +00102397 vector126 +00102172 vector65 +00102025 vector28 +00102595 vector169 +00102895 vector233 +0010248d vector147 +00117000 bootstack +0011a000 __boot_pgdir +001022d1 vector104 +0011cee0 free_area +0010233d vector116 +001073b8 __STAB_BEGIN__ +001020fd vector52 +00101fc4 vector17 +00102649 vector184 +00105bde strlen +0010275d vector207 +00102691 vector190 +001028dd vector239 +00102277 vector94 +0010226e vector93 +00102679 vector188 +00105d4c strchr +001020d9 vector48 +001000ce grade_backtrace1 +001027ed vector219 +00102499 vector148 +00102805 vector221 +001021f9 vector80 +001025ad vector171 +001024e1 vector154 +0010206d vector36 +0011c6cc switchu2k +001028ad vector235 +001022da vector105 +00100c0b mon_kerninfo +0011cf00 pages +00102481 vector146 +0010269d vector191 +001022c8 vector103 +00100bae mon_help +00101f96 vector11 +00104863 tlb_invalidate +00101fab vector14 diff --git a/labcodes/lab2/obj/libs/printfmt.d b/labcodes/lab2/obj/libs/printfmt.d new file mode 100644 index 00000000..7f093e2c --- /dev/null +++ b/labcodes/lab2/obj/libs/printfmt.d @@ -0,0 +1,2 @@ +obj/libs/printfmt.o obj/libs/printfmt.d: libs/printfmt.c libs/defs.h \ + libs/x86.h libs/error.h libs/stdio.h libs/stdarg.h libs/string.h diff --git a/labcodes/lab2/obj/libs/printfmt.o b/labcodes/lab2/obj/libs/printfmt.o new file mode 100644 index 0000000000000000000000000000000000000000..41a9c32cc965f862c9cc3ae6f994003b4da58691 GIT binary patch literal 9372 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 literal 0 HcmV?d00001 diff --git a/labcodes/lab2/obj/sign/tools/sign.d b/labcodes/lab2/obj/sign/tools/sign.d new file mode 100644 index 00000000..c988243d --- /dev/null +++ b/labcodes/lab2/obj/sign/tools/sign.d @@ -0,0 +1 @@ +obj/sign/tools/sign.o obj/sign/tools/sign.d: tools/sign.c diff --git a/labcodes/lab2/obj/sign/tools/sign.o b/labcodes/lab2/obj/sign/tools/sign.o new file mode 100644 index 0000000000000000000000000000000000000000..d4583e5ee05bc80566637a2bd339454555428ddf GIT binary patch literal 17456 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 g_Y)G0L2QLMrgnub{Fw!7YP$a4