1
0

asmasm.asm 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131
  1. ;; This file is part of asmc, a bootstrapping OS with minimal seed
  2. ;; Copyright (C) 2018 Giovanni Mascellani <gio@debian.org>
  3. ;; https://gitlab.com/giomasce/asmc
  4. ;; This program is free software: you can redistribute it and/or modify
  5. ;; it under the terms of the GNU General Public License as published by
  6. ;; the Free Software Foundation, either version 3 of the License, or
  7. ;; (at your option) any later version.
  8. ;; This program is distributed in the hope that it will be useful,
  9. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. ;; GNU General Public License for more details.
  12. ;; You should have received a copy of the GNU General Public License
  13. ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. OP_PUSH equ 0
  15. OP_POP equ 1
  16. OP_ADD equ 2
  17. OP_SUB equ 3
  18. OP_MOV equ 4
  19. OP_CMP equ 5
  20. OP_AND equ 6
  21. OP_OR equ 7
  22. OP_JMP equ 8
  23. OP_CALL equ 9
  24. OP_JE equ 10
  25. OP_JNE equ 11
  26. OP_JA equ 12
  27. OP_JNA equ 13
  28. OP_JAE equ 14
  29. OP_JNAE equ 15
  30. OP_JB equ 16
  31. OP_JNB equ 17
  32. OP_JBE equ 18
  33. OP_JNBE equ 19
  34. OP_JG equ 20
  35. OP_JNG equ 21
  36. OP_JGE equ 22
  37. OP_JNGE equ 23
  38. OP_JL equ 24
  39. OP_JNL equ 25
  40. OP_JLE equ 26
  41. OP_JNLE equ 27
  42. OP_MUL equ 28
  43. OP_IMUL equ 29
  44. OP_INT equ 30
  45. OP_RET equ 31
  46. OP_IN equ 32
  47. OP_OUT equ 33
  48. OP_DIV equ 34
  49. OP_IDIV equ 35
  50. OP_NEG equ 36
  51. OP_NOT equ 37
  52. OP_XOR equ 38
  53. OP_TEST equ 39
  54. OP_HLT equ 40
  55. OP_RDPMC equ 41
  56. OP_RDMSR equ 42
  57. OP_WRMSR equ 43
  58. OP_CPUID equ 44
  59. OP_SHL equ 45
  60. OP_SHR equ 46
  61. OP_SAL equ 47
  62. OP_SAR equ 48
  63. OP_CDQ equ 49
  64. section .data
  65. opcode_names:
  66. db 'push'
  67. db 0
  68. db 'pop'
  69. db 0
  70. db 'add'
  71. db 0
  72. db 'sub'
  73. db 0
  74. db 'mov'
  75. db 0
  76. db 'cmp'
  77. db 0
  78. db 'and'
  79. db 0
  80. db 'or'
  81. db 0
  82. db 'jmp'
  83. db 0
  84. db 'call'
  85. db 0
  86. db 'je'
  87. db 0
  88. db 'jne'
  89. db 0
  90. db 'ja'
  91. db 0
  92. db 'jna'
  93. db 0
  94. db 'jae'
  95. db 0
  96. db 'jnae'
  97. db 0
  98. db 'jb'
  99. db 0
  100. db 'jnb'
  101. db 0
  102. db 'jbe'
  103. db 0
  104. db 'jnbe'
  105. db 0
  106. db 'jg'
  107. db 0
  108. db 'jng'
  109. db 0
  110. db 'jge'
  111. db 0
  112. db 'jnge'
  113. db 0
  114. db 'jl'
  115. db 0
  116. db 'jnl'
  117. db 0
  118. db 'jle'
  119. db 0
  120. db 'jnle'
  121. db 0
  122. db 'mul'
  123. db 0
  124. db 'imul'
  125. db 0
  126. db 'int'
  127. db 0
  128. db 'ret'
  129. db 0
  130. db 'in'
  131. db 0
  132. db 'out'
  133. db 0
  134. db 'div'
  135. db 0
  136. db 'idiv'
  137. db 0
  138. db 'neg'
  139. db 0
  140. db 'not'
  141. db 0
  142. db 'xor'
  143. db 0
  144. db 'test'
  145. db 0
  146. db 'hlt'
  147. db 0
  148. db 'rdpmc'
  149. db 0
  150. db 'rdmsr'
  151. db 0
  152. db 'wrmsr'
  153. db 0
  154. db 'cpuid'
  155. db 0
  156. db 'shl'
  157. db 0
  158. db 'shr'
  159. db 0
  160. db 'sal'
  161. db 0
  162. db 'sar'
  163. db 0
  164. db 'cdq'
  165. db 0
  166. db 0
  167. opcode_funcs:
  168. dd process_push_like ; OP_PUSH
  169. dd process_push_like ; OP_POP
  170. dd process_add_like ; OP_ADD
  171. dd process_add_like ; OP_SUB
  172. dd process_add_like ; OP_MOV
  173. dd process_add_like ; OP_CMP
  174. dd process_add_like ; OP_AND
  175. dd process_add_like ; OP_OR
  176. dd process_jmp_like ; OP_JMP
  177. dd process_jmp_like ; OP_CALL
  178. dd process_jmp_like ; OP_JE
  179. dd process_jmp_like ; OP_JNE
  180. dd process_jmp_like ; OP_JA
  181. dd process_jmp_like ; OP_JNA
  182. dd process_jmp_like ; OP_JAE
  183. dd process_jmp_like ; OP_JNAE
  184. dd process_jmp_like ; OP_JB
  185. dd process_jmp_like ; OP_JNB
  186. dd process_jmp_like ; OP_JBE
  187. dd process_jmp_like ; OP_JNBE
  188. dd process_jmp_like ; OP_JG
  189. dd process_jmp_like ; OP_JNG
  190. dd process_jmp_like ; OP_JGE
  191. dd process_jmp_like ; OP_JNGE
  192. dd process_jmp_like ; OP_JL
  193. dd process_jmp_like ; OP_JNL
  194. dd process_jmp_like ; OP_JLE
  195. dd process_jmp_like ; OP_JNLE
  196. dd process_jmp_like ; OP_MUL
  197. dd process_jmp_like ; OP_IMUL
  198. dd process_int ; OP_INT
  199. dd process_ret_like ; OP_RET
  200. dd process_in_like ; OP_IN
  201. dd process_in_like ; OP_OUT
  202. dd process_jmp_like ; OP_DIV
  203. dd process_jmp_like ; OP_IDIV
  204. dd process_jmp_like ; OP_NEG
  205. dd process_jmp_like ; OP_NOT
  206. dd process_add_like ; OP_XOR
  207. dd process_add_like ; OP_TEST
  208. dd process_hlt ; OP_HLT
  209. dd process_ret_like ; OP_RDPMC
  210. dd process_ret_like ; OP_RDMSR
  211. dd process_ret_like ; OP_WRMSR
  212. dd process_ret_like ; OP_CPUID
  213. dd process_push_like ; OP_SHL
  214. dd process_push_like ; OP_SHR
  215. dd process_push_like ; OP_SAL
  216. dd process_push_like ; OP_SAR
  217. dd process_ret_like ; OP_CDQ
  218. empty_opcode:
  219. dd 0xf0 ; OP_PUSH
  220. dd 0xf0 ; OP_POP
  221. dd 0xf0 ; OP_ADD
  222. dd 0xf0 ; OP_SUB
  223. dd 0xf0 ; OP_MOV
  224. dd 0xf0 ; OP_CMP
  225. dd 0xf0 ; OP_AND
  226. dd 0xf0 ; OP_OR
  227. dd 0xf0 ; OP_JMP
  228. dd 0xf0 ; OP_CALL
  229. dd 0xf0 ; OP_JE
  230. dd 0xf0 ; OP_JNE
  231. dd 0xf0 ; OP_JA
  232. dd 0xf0 ; OP_JNA
  233. dd 0xf0 ; OP_JAE
  234. dd 0xf0 ; OP_JNAE
  235. dd 0xf0 ; OP_JB
  236. dd 0xf0 ; OP_JNB
  237. dd 0xf0 ; OP_JBE
  238. dd 0xf0 ; OP_JNBE
  239. dd 0xf0 ; OP_JG
  240. dd 0xf0 ; OP_JNG
  241. dd 0xf0 ; OP_JGE
  242. dd 0xf0 ; OP_JNGE
  243. dd 0xf0 ; OP_JL
  244. dd 0xf0 ; OP_JNL
  245. dd 0xf0 ; OP_JLE
  246. dd 0xf0 ; OP_JNLE
  247. dd 0xf0 ; OP_MUL
  248. dd 0xf0 ; OP_IMUL
  249. dd 0xf0 ; OP_INT
  250. dd 0xc3 ; OP_RET
  251. dd 0xf0 ; OP_IN
  252. dd 0xf0 ; OP_OUT
  253. dd 0xf0 ; OP_DIV
  254. dd 0xf0 ; OP_IDIV
  255. dd 0xf0 ; OP_NEG
  256. dd 0xf0 ; OP_NOT
  257. dd 0xf0 ; OP_XOR
  258. dd 0xf0 ; OP_TEST
  259. dd 0xf0 ; OP_HLT
  260. dd 0x1330f ; OP_RDPMC
  261. dd 0x1320f ; OP_RDMSR
  262. dd 0x1300f ; OP_WRMSR
  263. dd 0x1a20f ; OP_CPUID
  264. dd 0xf0 ; OP_SHL
  265. dd 0xf0 ; OP_SHR
  266. dd 0xf0 ; OP_SAL
  267. dd 0xf0 ; OP_SAR
  268. dd 0x99 ; OP_CDQ
  269. rm32_opcode:
  270. dd 0x06ff ; OP_PUSH
  271. dd 0x008f ; OP_POP
  272. dd 0xf0 ; OP_ADD
  273. dd 0xf0 ; OP_SUB
  274. dd 0xf0 ; OP_MOV
  275. dd 0xf0 ; OP_CMP
  276. dd 0xf0 ; OP_AND
  277. dd 0xf0 ; OP_OR
  278. dd 0x04ff ; OP_JMP
  279. dd 0x02ff ; OP_CALL
  280. dd 0xf0 ; OP_JE
  281. dd 0xf0 ; OP_JNE
  282. dd 0xf0 ; OP_JA
  283. dd 0xf0 ; OP_JNA
  284. dd 0xf0 ; OP_JAE
  285. dd 0xf0 ; OP_JNAE
  286. dd 0xf0 ; OP_JB
  287. dd 0xf0 ; OP_JNB
  288. dd 0xf0 ; OP_JBE
  289. dd 0xf0 ; OP_JNBE
  290. dd 0xf0 ; OP_JG
  291. dd 0xf0 ; OP_JNG
  292. dd 0xf0 ; OP_JGE
  293. dd 0xf0 ; OP_JNGE
  294. dd 0xf0 ; OP_JL
  295. dd 0xf0 ; OP_JNL
  296. dd 0xf0 ; OP_JLE
  297. dd 0xf0 ; OP_JNLE
  298. dd 0x04f7 ; OP_MUL
  299. dd 0x05f7 ; OP_IMUL
  300. dd 0xf0 ; OP_INT
  301. dd 0xf0 ; OP_RET
  302. dd 0xf0 ; OP_IN
  303. dd 0xf0 ; OP_OUT
  304. dd 0x06f7 ; OP_DIV
  305. dd 0x07f7 ; OP_IDIV
  306. dd 0x03f7 ; OP_NEG
  307. dd 0x02f7 ; OP_NOT
  308. dd 0xf0 ; OP_XOR
  309. dd 0xf0 ; OP_TEST
  310. dd 0xf0 ; OP_HLT
  311. dd 0xf0 ; OP_RDPMC
  312. dd 0xf0 ; OP_RDMSR
  313. dd 0xf0 ; OP_WRMSR
  314. dd 0xf0 ; OP_CPUID
  315. dd 0x04d3 ; OP_SHL
  316. dd 0x05d3 ; OP_SHR
  317. dd 0x04d3 ; OP_SAL
  318. dd 0x07d3 ; OP_SAR
  319. dd 0xf0 ; OP_CDQ
  320. imm32_opcode:
  321. dd 0xf0 ; OP_PUSH
  322. dd 0xf0 ; OP_POP
  323. dd 0xf0 ; OP_ADD
  324. dd 0xf0 ; OP_SUB
  325. dd 0xf0 ; OP_MOV
  326. dd 0xf0 ; OP_CMP
  327. dd 0xf0 ; OP_AND
  328. dd 0xf0 ; OP_OR
  329. dd 0xe9 ; OP_JMP
  330. dd 0xe8 ; OP_CALL
  331. dd 0x1840f ; OP_JE
  332. dd 0x1850f ; OP_JNE
  333. dd 0x1870f ; OP_JA
  334. dd 0x1860f ; OP_JNA
  335. dd 0x1830f ; OP_JAE
  336. dd 0x1820f ; OP_JNAE
  337. dd 0x1820f ; OP_JB
  338. dd 0x1830f ; OP_JNB
  339. dd 0x1860f ; OP_JBE
  340. dd 0x1870f ; OP_JNBE
  341. dd 0x18f0f ; OP_JG
  342. dd 0x18e0f ; OP_JNG
  343. dd 0x18d0f ; OP_JGE
  344. dd 0x18c0f ; OP_JNGE
  345. dd 0x18c0f ; OP_JL
  346. dd 0x18d0f ; OP_JNL
  347. dd 0x18e0f ; OP_JLE
  348. dd 0x18f0f ; OP_JNLE
  349. dd 0xf0 ; OP_MUL
  350. dd 0xf0 ; OP_IMUL
  351. dd 0xf0 ; OP_INT
  352. dd 0xf0 ; OP_RET
  353. dd 0xf0 ; OP_IN
  354. dd 0xf0 ; OP_OUT
  355. dd 0xf0 ; OP_DIV
  356. dd 0xf0 ; OP_IDIV
  357. dd 0xf0 ; OP_NEG
  358. dd 0xf0 ; OP_NOT
  359. dd 0xf0 ; OP_XOR
  360. dd 0xf0 ; OP_TEST
  361. dd 0xf0 ; OP_HLT
  362. dd 0xf0 ; OP_RDPMC
  363. dd 0xf0 ; OP_RDMSR
  364. dd 0xf0 ; OP_WRMSR
  365. dd 0xf0 ; OP_CPUID
  366. dd 0xf0 ; OP_SHL
  367. dd 0xf0 ; OP_SHR
  368. dd 0xf0 ; OP_SAL
  369. dd 0xf0 ; OP_SAR
  370. dd 0xf0 ; OP_CDQ
  371. r8rm8_opcode:
  372. dd 0xf0 ; OP_PUSH
  373. dd 0xf0 ; OP_POP
  374. dd 0x02 ; OP_ADD
  375. dd 0x2a ; OP_SUB
  376. dd 0x8a ; OP_MOV
  377. dd 0x3a ; OP_CMP
  378. dd 0x22 ; OP_AND
  379. dd 0x0a ; OP_OR
  380. dd 0xf0 ; OP_JMP
  381. dd 0xf0 ; OP_CALL
  382. dd 0xf0 ; OP_JE
  383. dd 0xf0 ; OP_JNE
  384. dd 0xf0 ; OP_JA
  385. dd 0xf0 ; OP_JNA
  386. dd 0xf0 ; OP_JAE
  387. dd 0xf0 ; OP_JNAE
  388. dd 0xf0 ; OP_JB
  389. dd 0xf0 ; OP_JNB
  390. dd 0xf0 ; OP_JBE
  391. dd 0xf0 ; OP_JNBE
  392. dd 0xf0 ; OP_JG
  393. dd 0xf0 ; OP_JNG
  394. dd 0xf0 ; OP_JGE
  395. dd 0xf0 ; OP_JNGE
  396. dd 0xf0 ; OP_JL
  397. dd 0xf0 ; OP_JNL
  398. dd 0xf0 ; OP_JLE
  399. dd 0xf0 ; OP_JNLE
  400. dd 0xf0 ; OP_MUL
  401. dd 0xf0 ; OP_IMUL
  402. dd 0xf0 ; OP_INT
  403. dd 0xf0 ; OP_RET
  404. dd 0xf0 ; OP_IN
  405. dd 0xf0 ; OP_OUT
  406. dd 0xf0 ; OP_DIV
  407. dd 0xf0 ; OP_IDIV
  408. dd 0xf0 ; OP_NEG
  409. dd 0xf0 ; OP_NOT
  410. dd 0x32 ; OP_XOR
  411. dd 0x84 ; OP_TEST
  412. dd 0xf0 ; OP_HLT
  413. dd 0xf0 ; OP_RDPMC
  414. dd 0xf0 ; OP_RDMSR
  415. dd 0xf0 ; OP_WRMSR
  416. dd 0xf0 ; OP_CPUID
  417. dd 0xf0 ; OP_SHL
  418. dd 0xf0 ; OP_SHR
  419. dd 0xf0 ; OP_SAL
  420. dd 0xf0 ; OP_SAR
  421. dd 0xf0 ; OP_CDQ
  422. r32rm32_opcode:
  423. dd 0xf0 ; OP_PUSH
  424. dd 0xf0 ; OP_POP
  425. dd 0x03 ; OP_ADD
  426. dd 0x2b ; OP_SUB
  427. dd 0x8b ; OP_MOV
  428. dd 0x3b ; OP_CMP
  429. dd 0x23 ; OP_AND
  430. dd 0x0b ; OP_OR
  431. dd 0xf0 ; OP_JMP
  432. dd 0xf0 ; OP_CALL
  433. dd 0xf0 ; OP_JE
  434. dd 0xf0 ; OP_JNE
  435. dd 0xf0 ; OP_JA
  436. dd 0xf0 ; OP_JNA
  437. dd 0xf0 ; OP_JAE
  438. dd 0xf0 ; OP_JNAE
  439. dd 0xf0 ; OP_JB
  440. dd 0xf0 ; OP_JNB
  441. dd 0xf0 ; OP_JBE
  442. dd 0xf0 ; OP_JNBE
  443. dd 0xf0 ; OP_JG
  444. dd 0xf0 ; OP_JNG
  445. dd 0xf0 ; OP_JGE
  446. dd 0xf0 ; OP_JNGE
  447. dd 0xf0 ; OP_JL
  448. dd 0xf0 ; OP_JNL
  449. dd 0xf0 ; OP_JLE
  450. dd 0xf0 ; OP_JNLE
  451. dd 0xf0 ; OP_MUL
  452. dd 0xf0 ; OP_IMUL
  453. dd 0xf0 ; OP_INT
  454. dd 0xf0 ; OP_RET
  455. dd 0xf0 ; OP_IN
  456. dd 0xf0 ; OP_OUT
  457. dd 0xf0 ; OP_DIV
  458. dd 0xf0 ; OP_IDIV
  459. dd 0xf0 ; OP_NEG
  460. dd 0xf0 ; OP_NOT
  461. dd 0x33 ; OP_XOR
  462. dd 0x85 ; OP_TEST
  463. dd 0xf0 ; OP_HLT
  464. dd 0xf0 ; OP_RDPMC
  465. dd 0xf0 ; OP_RDMSR
  466. dd 0xf0 ; OP_WRMSR
  467. dd 0xf0 ; OP_CPUID
  468. dd 0xf0 ; OP_SHL
  469. dd 0xf0 ; OP_SHR
  470. dd 0xf0 ; OP_SAL
  471. dd 0xf0 ; OP_SAR
  472. dd 0xf0 ; OP_CDQ
  473. rm8r8_opcode:
  474. dd 0xf0 ; OP_PUSH
  475. dd 0xf0 ; OP_POP
  476. dd 0x00 ; OP_ADD
  477. dd 0x28 ; OP_SUB
  478. dd 0x88 ; OP_MOV
  479. dd 0x38 ; OP_CMP
  480. dd 0x20 ; OP_AND
  481. dd 0x08 ; OP_OR
  482. dd 0xf0 ; OP_JMP
  483. dd 0xf0 ; OP_CALL
  484. dd 0xf0 ; OP_JE
  485. dd 0xf0 ; OP_JNE
  486. dd 0xf0 ; OP_JA
  487. dd 0xf0 ; OP_JNA
  488. dd 0xf0 ; OP_JAE
  489. dd 0xf0 ; OP_JNAE
  490. dd 0xf0 ; OP_JB
  491. dd 0xf0 ; OP_JNB
  492. dd 0xf0 ; OP_JBE
  493. dd 0xf0 ; OP_JNBE
  494. dd 0xf0 ; OP_JG
  495. dd 0xf0 ; OP_JNG
  496. dd 0xf0 ; OP_JGE
  497. dd 0xf0 ; OP_JNGE
  498. dd 0xf0 ; OP_JL
  499. dd 0xf0 ; OP_JNL
  500. dd 0xf0 ; OP_JLE
  501. dd 0xf0 ; OP_JNLE
  502. dd 0xf0 ; OP_MUL
  503. dd 0xf0 ; OP_IMUL
  504. dd 0xf0 ; OP_INT
  505. dd 0xf0 ; OP_RET
  506. dd 0xf0 ; OP_IN
  507. dd 0xf0 ; OP_OUT
  508. dd 0xf0 ; OP_DIV
  509. dd 0xf0 ; OP_IDIV
  510. dd 0xf0 ; OP_NEG
  511. dd 0xf0 ; OP_NOT
  512. dd 0x30 ; OP_XOR
  513. dd 0x84 ; OP_TEST
  514. dd 0xf0 ; OP_HLT
  515. dd 0xf0 ; OP_RDPMC
  516. dd 0xf0 ; OP_RDMSR
  517. dd 0xf0 ; OP_WRMSR
  518. dd 0xf0 ; OP_CPUID
  519. dd 0xf0 ; OP_SHL
  520. dd 0xf0 ; OP_SHR
  521. dd 0xf0 ; OP_SAL
  522. dd 0xf0 ; OP_SAR
  523. dd 0xf0 ; OP_CDQ
  524. rm32r32_opcode:
  525. dd 0xf0 ; OP_PUSH
  526. dd 0xf0 ; OP_POP
  527. dd 0x01 ; OP_ADD
  528. dd 0x29 ; OP_SUB
  529. dd 0x89 ; OP_MOV
  530. dd 0x39 ; OP_CMP
  531. dd 0x21 ; OP_AND
  532. dd 0x09 ; OP_OR
  533. dd 0xf0 ; OP_JMP
  534. dd 0xf0 ; OP_CALL
  535. dd 0xf0 ; OP_JE
  536. dd 0xf0 ; OP_JNE
  537. dd 0xf0 ; OP_JA
  538. dd 0xf0 ; OP_JNA
  539. dd 0xf0 ; OP_JAE
  540. dd 0xf0 ; OP_JNAE
  541. dd 0xf0 ; OP_JB
  542. dd 0xf0 ; OP_JNB
  543. dd 0xf0 ; OP_JBE
  544. dd 0xf0 ; OP_JNBE
  545. dd 0xf0 ; OP_JG
  546. dd 0xf0 ; OP_JNG
  547. dd 0xf0 ; OP_JGE
  548. dd 0xf0 ; OP_JNGE
  549. dd 0xf0 ; OP_JL
  550. dd 0xf0 ; OP_JNL
  551. dd 0xf0 ; OP_JLE
  552. dd 0xf0 ; OP_JNLE
  553. dd 0xf0 ; OP_MUL
  554. dd 0xf0 ; OP_IMUL
  555. dd 0xf0 ; OP_INT
  556. dd 0xf0 ; OP_RET
  557. dd 0xf0 ; OP_IN
  558. dd 0xf0 ; OP_OUT
  559. dd 0xf0 ; OP_DIV
  560. dd 0xf0 ; OP_IDIV
  561. dd 0xf0 ; OP_NEG
  562. dd 0xf0 ; OP_NOT
  563. dd 0x31 ; OP_XOR
  564. dd 0x85 ; OP_TEST
  565. dd 0xf0 ; OP_HLT
  566. dd 0xf0 ; OP_RDPMC
  567. dd 0xf0 ; OP_RDMSR
  568. dd 0xf0 ; OP_WRMSR
  569. dd 0xf0 ; OP_CPUID
  570. dd 0xf0 ; OP_SHL
  571. dd 0xf0 ; OP_SHR
  572. dd 0xf0 ; OP_SAL
  573. dd 0xf0 ; OP_SAR
  574. dd 0xf0 ; OP_CDQ
  575. rm8imm8_opcode:
  576. dd 0xf0 ; OP_PUSH
  577. dd 0xf0 ; OP_POP
  578. dd 0x0080 ; OP_ADD
  579. dd 0x0580 ; OP_SUB
  580. dd 0x00c6 ; OP_MOV
  581. dd 0x0780 ; OP_CMP
  582. dd 0x0480 ; OP_AND
  583. dd 0x0180 ; OP_OR
  584. dd 0xf0 ; OP_JMP
  585. dd 0xf0 ; OP_CALL
  586. dd 0xf0 ; OP_JE
  587. dd 0xf0 ; OP_JNE
  588. dd 0xf0 ; OP_JA
  589. dd 0xf0 ; OP_JNA
  590. dd 0xf0 ; OP_JAE
  591. dd 0xf0 ; OP_JNAE
  592. dd 0xf0 ; OP_JB
  593. dd 0xf0 ; OP_JNB
  594. dd 0xf0 ; OP_JBE
  595. dd 0xf0 ; OP_JNBE
  596. dd 0xf0 ; OP_JG
  597. dd 0xf0 ; OP_JNG
  598. dd 0xf0 ; OP_JGE
  599. dd 0xf0 ; OP_JNGE
  600. dd 0xf0 ; OP_JL
  601. dd 0xf0 ; OP_JNL
  602. dd 0xf0 ; OP_JLE
  603. dd 0xf0 ; OP_JNLE
  604. dd 0xf0 ; OP_MUL
  605. dd 0xf0 ; OP_IMUL
  606. dd 0xf0 ; OP_INT
  607. dd 0xf0 ; OP_RET
  608. dd 0xf0 ; OP_IN
  609. dd 0xf0 ; OP_OUT
  610. dd 0xf0 ; OP_DIV
  611. dd 0xf0 ; OP_IDIV
  612. dd 0xf0 ; OP_NEG
  613. dd 0xf0 ; OP_NOT
  614. dd 0x0680 ; OP_XOR
  615. dd 0x00f6 ; OP_TEST
  616. dd 0xf0 ; OP_HLT
  617. dd 0xf0 ; OP_RDPMC
  618. dd 0xf0 ; OP_RDMSR
  619. dd 0xf0 ; OP_WRMSR
  620. dd 0xf0 ; OP_CPUID
  621. dd 0xf0 ; OP_SHL
  622. dd 0xf0 ; OP_SHR
  623. dd 0xf0 ; OP_SAL
  624. dd 0xf0 ; OP_SAR
  625. dd 0xf0 ; OP_CDQ
  626. rm32imm32_opcode:
  627. dd 0xf0 ; OP_PUSH
  628. dd 0xf0 ; OP_POP
  629. dd 0x0081 ; OP_ADD
  630. dd 0x0581 ; OP_SUB
  631. dd 0x00c7 ; OP_MOV
  632. dd 0x0781 ; OP_CMP
  633. dd 0x0481 ; OP_AND
  634. dd 0x0181 ; OP_OR
  635. dd 0xf0 ; OP_JMP
  636. dd 0xf0 ; OP_CALL
  637. dd 0xf0 ; OP_JE
  638. dd 0xf0 ; OP_JNE
  639. dd 0xf0 ; OP_JA
  640. dd 0xf0 ; OP_JNA
  641. dd 0xf0 ; OP_JAE
  642. dd 0xf0 ; OP_JNAE
  643. dd 0xf0 ; OP_JB
  644. dd 0xf0 ; OP_JNB
  645. dd 0xf0 ; OP_JBE
  646. dd 0xf0 ; OP_JNBE
  647. dd 0xf0 ; OP_JG
  648. dd 0xf0 ; OP_JNG
  649. dd 0xf0 ; OP_JGE
  650. dd 0xf0 ; OP_JNGE
  651. dd 0xf0 ; OP_JL
  652. dd 0xf0 ; OP_JNL
  653. dd 0xf0 ; OP_JLE
  654. dd 0xf0 ; OP_JNLE
  655. dd 0xf0 ; OP_MUL
  656. dd 0xf0 ; OP_IMUL
  657. dd 0xf0 ; OP_INT
  658. dd 0xf0 ; OP_RET
  659. dd 0xf0 ; OP_IN
  660. dd 0xf0 ; OP_OUT
  661. dd 0xf0 ; OP_DIV
  662. dd 0xf0 ; OP_IDIV
  663. dd 0xf0 ; OP_NEG
  664. dd 0xf0 ; OP_NOT
  665. dd 0x0681 ; OP_XOR
  666. dd 0x00f7 ; OP_TEST
  667. dd 0xf0 ; OP_HLT
  668. dd 0xf0 ; OP_RDPMC
  669. dd 0xf0 ; OP_RDMSR
  670. dd 0xf0 ; OP_WRMSR
  671. dd 0xf0 ; OP_CPUID
  672. dd 0xf0 ; OP_SHL
  673. dd 0xf0 ; OP_SHR
  674. dd 0xf0 ; OP_SAL
  675. dd 0xf0 ; OP_SAR
  676. dd 0xf0 ; OP_CDQ
  677. reg_eax:
  678. db 'eax'
  679. db 0
  680. reg_ecx:
  681. db 'ecx'
  682. db 0
  683. reg_edx:
  684. db 'edx'
  685. db 0
  686. reg_ebx:
  687. db 'ebx'
  688. db 0
  689. reg_esp:
  690. db 'esp'
  691. db 0
  692. reg_ebp:
  693. db 'ebp'
  694. db 0
  695. reg_esi:
  696. db 'esi'
  697. db 0
  698. reg_edi:
  699. db 'edi'
  700. db 0
  701. reg_al:
  702. db 'al'
  703. db 0
  704. reg_cl:
  705. db 'cl'
  706. db 0
  707. reg_dl:
  708. db 'dl'
  709. db 0
  710. reg_bl:
  711. db 'bl'
  712. db 0
  713. reg_ah:
  714. db 'ah'
  715. db 0
  716. reg_ch:
  717. db 'ch'
  718. db 0
  719. reg_dh:
  720. db 'dh'
  721. db 0
  722. reg_bh:
  723. db 'bh'
  724. db 0
  725. reg_ax:
  726. db 'ax'
  727. db 0
  728. reg_dx:
  729. db 'dx'
  730. db 0
  731. str_BYTE:
  732. db 'BYTE'
  733. db 0
  734. str_DWORD:
  735. db 'DWORD'
  736. db 0
  737. str_resb:
  738. db 'resb'
  739. db 0
  740. str_resd:
  741. db 'resd'
  742. db 0
  743. str_dd:
  744. db 'dd'
  745. db 0
  746. str_db:
  747. db 'db'
  748. db 0
  749. str_section:
  750. db 'section'
  751. db 0
  752. str_org:
  753. db 'org'
  754. db 0
  755. str_bits:
  756. db 'bits'
  757. db 0
  758. str_global:
  759. db 'global'
  760. db 0
  761. str_align:
  762. db 'align'
  763. db 0
  764. str_extern:
  765. db 'extern'
  766. db 0
  767. str_equ:
  768. db 'equ'
  769. db 0
  770. str_decoding_line:
  771. db 'Decoding line: '
  772. db 0
  773. str_empty:
  774. db 0
  775. str_ass_finished1:
  776. db 'Finished assembling a file with '
  777. db 0
  778. str_ass_finished2:
  779. db ' lines!'
  780. db NEWLINE
  781. db 0
  782. str_symb_num1:
  783. db 'There are now '
  784. db 0
  785. str_symb_num2:
  786. db ' known symbols.'
  787. db NEWLINE
  788. db 0
  789. section .bss
  790. input_buf_ptr:
  791. resd 1
  792. section .text
  793. global get_input_buf
  794. get_input_buf:
  795. mov eax, input_buf_ptr
  796. mov eax, [eax]
  797. ret
  798. global get_opcode_names
  799. get_opcode_names:
  800. mov eax, opcode_names
  801. ret
  802. global get_opcode_funcs
  803. get_opcode_funcs:
  804. mov eax, opcode_funcs
  805. ret
  806. global get_rm32_opcode
  807. get_rm32_opcode:
  808. mov eax, rm32_opcode
  809. ret
  810. global get_imm32_opcode
  811. get_imm32_opcode:
  812. mov eax, imm32_opcode
  813. ret
  814. global get_rm8r8_opcode
  815. get_rm8r8_opcode:
  816. mov eax, rm8r8_opcode
  817. ret
  818. global get_rm32r32_opcode
  819. get_rm32r32_opcode:
  820. mov eax, rm32r32_opcode
  821. ret
  822. global get_r8rm8_opcode
  823. get_r8rm8_opcode:
  824. mov eax, r8rm8_opcode
  825. ret
  826. global get_r32rm32_opcode
  827. get_r32rm32_opcode:
  828. mov eax, r32rm32_opcode
  829. ret
  830. global get_rm8imm8_opcode
  831. get_rm8imm8_opcode:
  832. mov eax, rm8imm8_opcode
  833. ret
  834. global get_rm32imm32_opcode
  835. get_rm32imm32_opcode:
  836. mov eax, rm32imm32_opcode
  837. ret
  838. global assert
  839. assert:
  840. cmp DWORD [esp+4], 0
  841. jne assert_return
  842. call platform_panic
  843. assert_return:
  844. ret
  845. global readline
  846. readline:
  847. push ebp
  848. mov ebp, esp
  849. readline_begin_loop:
  850. ;; If len is zero, jump to panic
  851. cmp DWORD [ebp+16], 0
  852. je platform_panic
  853. ;; Call platform_read_char
  854. mov ecx, [ebp+8]
  855. push ecx
  856. call platform_read_char
  857. add esp, 4
  858. ;; Store the buffer address in edx
  859. mov edx, [ebp+12]
  860. ;; Handle newline and eof
  861. cmp eax, NEWLINE
  862. je readline_newline_found
  863. cmp eax, 0xffffffff
  864. je readline_eof_found
  865. ;; Copy a byte
  866. mov [edx], al
  867. ;; Increment the buffer and decrement the length
  868. add edx, 1
  869. mov [ebp+12], edx
  870. mov ecx, [ebp+16]
  871. sub ecx, 1
  872. mov [ebp+16], ecx
  873. jmp readline_begin_loop
  874. ;; On newline, store the string terminator and return 0
  875. readline_newline_found:
  876. mov BYTE [edx], 0
  877. mov eax, 0
  878. jmp readline_ret
  879. ;; On eof, store the string terminator and return 1
  880. readline_eof_found:
  881. mov BYTE [edx], 0
  882. mov eax, 1
  883. jmp readline_ret
  884. readline_ret:
  885. pop ebp
  886. ret
  887. global trimstr
  888. trimstr:
  889. ;; Load registers (eax for writing, ecx for reading)
  890. mov eax, [esp+4]
  891. mov ecx, eax
  892. ;; Skip the initial whitespace
  893. trimstr_skip_initial:
  894. cmp BYTE [ecx], SPACE
  895. je trimstr_initial_white
  896. cmp BYTE [ecx], TAB
  897. je trimstr_initial_white
  898. jmp trimstr_copy_loop
  899. trimstr_initial_white:
  900. add ecx, 1
  901. jmp trimstr_skip_initial
  902. ;; Copy until the string terminator
  903. trimstr_copy_loop:
  904. cmp BYTE [ecx], 0
  905. mov dl, [ecx]
  906. mov [eax], dl
  907. je trimstr_trim_end
  908. add ecx, 1
  909. add eax, 1
  910. jmp trimstr_copy_loop
  911. ;; Replace the final whitespace with terminators
  912. trimstr_trim_end:
  913. sub eax, 1
  914. trimstr_trim_loop2:
  915. cmp eax, [esp+4]
  916. jb trimstr_ret
  917. cmp BYTE [eax], SPACE
  918. je trimstr_final_white
  919. cmp BYTE [eax], TAB
  920. je trimstr_final_white
  921. jmp trimstr_ret
  922. trimstr_final_white:
  923. mov BYTE [eax], 0
  924. sub eax, 1
  925. jmp trimstr_trim_loop2
  926. trimstr_ret:
  927. ret
  928. global remove_spaces
  929. remove_spaces:
  930. ;; Load registers (eax for writing, ecx for reading)
  931. mov eax, [esp+4]
  932. mov ecx, eax
  933. ;; Main loop
  934. remove_spaces_loop:
  935. ;; Copy the byte and, if found terminator, stop
  936. cmp BYTE [ecx], 0
  937. mov dl, [ecx]
  938. mov [eax], dl
  939. je remove_spaces_ret
  940. ;; Advance the read pointer; advance the write pointer only if we
  941. ;; did not found whitespace
  942. add ecx, 1
  943. cmp dl, SPACE
  944. je remove_spaces_loop
  945. cmp dl, TAB
  946. je remove_spaces_loop
  947. add eax, 1
  948. jmp remove_spaces_loop
  949. remove_spaces_ret:
  950. ret
  951. global isstrpref
  952. isstrpref:
  953. ;; Load registers
  954. mov eax, [esp+4]
  955. mov ecx, [esp+8]
  956. isstrpref_loop:
  957. ;; If the first string is finished, then return 1
  958. mov dl, [eax]
  959. cmp dl, 0
  960. jne isstrpref_after_cmp1
  961. mov eax, 1
  962. ret
  963. isstrpref_after_cmp1:
  964. ;; If the characters do not match, return 0
  965. cmp dl, [ecx]
  966. je isstrpref_after_cmp2
  967. mov eax, 0
  968. ret
  969. isstrpref_after_cmp2:
  970. ;; Increment both pointers and restart
  971. add eax, 1
  972. add ecx, 1
  973. jmp isstrpref_loop
  974. global decode_reg32
  975. decode_reg32:
  976. ;; Save and load registers
  977. push ebx
  978. mov ebx, [esp+8]
  979. push esi
  980. ;; Compare the argument with each possible register name
  981. mov esi, 0
  982. push reg_eax
  983. push ebx
  984. call strcmp
  985. add esp, 8
  986. cmp eax, 0
  987. je decode_reg32_ret
  988. mov esi, 1
  989. push reg_ecx
  990. push ebx
  991. call strcmp
  992. add esp, 8
  993. cmp eax, 0
  994. je decode_reg32_ret
  995. mov esi, 2
  996. push reg_edx
  997. push ebx
  998. call strcmp
  999. add esp, 8
  1000. cmp eax, 0
  1001. je decode_reg32_ret
  1002. mov esi, 3
  1003. push reg_ebx
  1004. push ebx
  1005. call strcmp
  1006. add esp, 8
  1007. cmp eax, 0
  1008. je decode_reg32_ret
  1009. mov esi, 4
  1010. push reg_esp
  1011. push ebx
  1012. call strcmp
  1013. add esp, 8
  1014. cmp eax, 0
  1015. je decode_reg32_ret
  1016. mov esi, 5
  1017. push reg_ebp
  1018. push ebx
  1019. call strcmp
  1020. add esp, 8
  1021. cmp eax, 0
  1022. je decode_reg32_ret
  1023. mov esi, 6
  1024. push reg_esi
  1025. push ebx
  1026. call strcmp
  1027. add esp, 8
  1028. cmp eax, 0
  1029. je decode_reg32_ret
  1030. mov esi, 7
  1031. push reg_edi
  1032. push ebx
  1033. call strcmp
  1034. add esp, 8
  1035. cmp eax, 0
  1036. je decode_reg32_ret
  1037. ;; Return -1 if none matched
  1038. mov esi, 0xffffffff
  1039. decode_reg32_ret:
  1040. mov eax, esi
  1041. pop esi
  1042. pop ebx
  1043. ret
  1044. global decode_reg8
  1045. decode_reg8:
  1046. ;; Save and load registers
  1047. push ebx
  1048. mov ebx, [esp+8]
  1049. push esi
  1050. ;; Compare the argument with each possible register name
  1051. mov esi, 0
  1052. push reg_al
  1053. push ebx
  1054. call strcmp
  1055. add esp, 8
  1056. cmp eax, 0
  1057. je decode_reg8_ret
  1058. mov esi, 1
  1059. push reg_cl
  1060. push ebx
  1061. call strcmp
  1062. add esp, 8
  1063. cmp eax, 0
  1064. je decode_reg8_ret
  1065. mov esi, 2
  1066. push reg_dl
  1067. push ebx
  1068. call strcmp
  1069. add esp, 8
  1070. cmp eax, 0
  1071. je decode_reg8_ret
  1072. mov esi, 3
  1073. push reg_bl
  1074. push ebx
  1075. call strcmp
  1076. add esp, 8
  1077. cmp eax, 0
  1078. je decode_reg8_ret
  1079. mov esi, 4
  1080. push reg_ah
  1081. push ebx
  1082. call strcmp
  1083. add esp, 8
  1084. cmp eax, 0
  1085. je decode_reg8_ret
  1086. mov esi, 5
  1087. push reg_ch
  1088. push ebx
  1089. call strcmp
  1090. add esp, 8
  1091. cmp eax, 0
  1092. je decode_reg8_ret
  1093. mov esi, 6
  1094. push reg_dh
  1095. push ebx
  1096. call strcmp
  1097. add esp, 8
  1098. cmp eax, 0
  1099. je decode_reg8_ret
  1100. mov esi, 7
  1101. push reg_bh
  1102. push ebx
  1103. call strcmp
  1104. add esp, 8
  1105. cmp eax, 0
  1106. je decode_reg8_ret
  1107. ;; Return -1 if none matched
  1108. mov esi, 0xffffffff
  1109. decode_reg8_ret:
  1110. mov eax, esi
  1111. pop esi
  1112. pop ebx
  1113. ret
  1114. global decode_number_or_symbol
  1115. decode_number_or_symbol:
  1116. push ebp
  1117. mov ebp, esp
  1118. ;; Call decode_number
  1119. mov eax, [ebp+12]
  1120. push eax
  1121. mov eax, [ebp+8]
  1122. push eax
  1123. call decode_number
  1124. add esp, 8
  1125. ;; If decode_number succeded, return 1
  1126. cmp eax, 1
  1127. jne decode_number_or_symbol_after_number
  1128. jmp decode_number_or_symbol_ret
  1129. decode_number_or_symbol_after_number:
  1130. ;; Branch to appropriate stage (in particular, if third argument is
  1131. ;; true assume stage 1)
  1132. mov edx, stage
  1133. mov eax, [edx]
  1134. cmp eax, 1
  1135. je decode_number_or_symbol_stage1
  1136. cmp DWORD [ebp+16], 0
  1137. jne decode_number_or_symbol_stage1
  1138. cmp eax, 0
  1139. je decode_number_or_symbol_stage0
  1140. jmp platform_panic
  1141. decode_number_or_symbol_stage0:
  1142. ;; Set the number to placeholder 0 and return 1
  1143. mov eax, [ebp+12]
  1144. mov DWORD [eax], 0
  1145. mov eax, 1
  1146. jmp decode_number_or_symbol_ret
  1147. decode_number_or_symbol_stage1:
  1148. ;; Call find_symbol and return what it returns
  1149. push 0
  1150. push DWORD [ebp+12]
  1151. push DWORD [ebp+8]
  1152. call find_symbol
  1153. add esp, 12
  1154. jmp decode_number_or_symbol_ret
  1155. decode_number_or_symbol_ret:
  1156. pop ebp
  1157. ret
  1158. global decode_operand
  1159. decode_operand:
  1160. push ebp
  1161. mov ebp, esp
  1162. push ebx
  1163. push esi
  1164. ;; Use ebx for the input string
  1165. mov ebx, [ebp+8]
  1166. ;; Call remove_spaces
  1167. push ebx
  1168. call remove_spaces
  1169. add esp, 4
  1170. ;; Use cl and ch to remember if we found 8 or 32 bits code
  1171. mov ecx, 0
  1172. ;; Search for BYTE prefix
  1173. push ecx
  1174. push ebx
  1175. push str_BYTE
  1176. call isstrpref
  1177. add esp, 8
  1178. pop ecx
  1179. cmp eax, 0
  1180. je decode_operand_after_byte_search
  1181. add ebx, 4
  1182. mov cl, 1
  1183. ;; Search for DWORD prefix
  1184. decode_operand_after_byte_search:
  1185. push ecx
  1186. push ebx
  1187. push str_DWORD
  1188. call isstrpref
  1189. add esp, 8
  1190. pop ecx
  1191. cmp eax, 0
  1192. je decode_operand_after_dword_search
  1193. add ebx, 5
  1194. mov ch, 1
  1195. ;; Check that at most one prefix was found
  1196. decode_operand_after_dword_search:
  1197. mov dl, cl
  1198. and dl, ch
  1199. cmp dl, 0
  1200. jne platform_panic
  1201. ;; Check whether the operand is direct or indirect
  1202. cmp BYTE [ebx], SQ_OPEN
  1203. jne decode_operand_direct
  1204. ;; Indirect operand: mark as such and consume character
  1205. mov edx, [ebp+12]
  1206. mov DWORD [edx], 0
  1207. add ebx, 1
  1208. ;; In this branch cl and ch are not used, so we can save them in the
  1209. ;; caller space and then recycle the register
  1210. mov edx, [ebp+24]
  1211. mov DWORD [edx], 0
  1212. mov [edx], cl
  1213. mov edx, [ebp+28]
  1214. mov DWORD [edx], 0
  1215. mov [edx], ch
  1216. ;; Search for the plus
  1217. push PLUS
  1218. push ebx
  1219. call find_char
  1220. add esp, 8
  1221. cmp eax, 0xffffffff
  1222. jne decode_operand_have_plus
  1223. ;; There is no plus, so the displacement is zero
  1224. mov edx, [ebp+20]
  1225. mov DWORD [edx], 0
  1226. ;; Search for the closed bracket
  1227. push SQ_CLOSED
  1228. push ebx
  1229. call find_char
  1230. add esp, 8
  1231. cmp eax, 0xffffffff
  1232. je decode_operand_ret_false
  1233. ;; Check that the following character is a terminator
  1234. mov ecx, ebx
  1235. add ecx, eax
  1236. cmp BYTE [ecx+1], 0
  1237. jne decode_operand_ret_false
  1238. ;; Overwrite the closed bracket with a terminator and recognize the
  1239. ;; register name (which must be a 32 bits register)
  1240. mov BYTE [ecx], 0
  1241. push ebx
  1242. call decode_reg32
  1243. add esp, 4
  1244. ;; Save its value in the caller space and return appropriately
  1245. mov edx, [ebp+16]
  1246. mov [edx], eax
  1247. cmp eax, 0xffffffff
  1248. je decode_operand_ret_false
  1249. jmp decode_operand_ret_true
  1250. decode_operand_have_plus:
  1251. ;; Overwrite the plus with a terminator and recognize the register
  1252. ;; name
  1253. mov esi, ebx
  1254. add esi, eax
  1255. mov BYTE [esi], 0
  1256. push ebx
  1257. call decode_reg32
  1258. add esp, 4
  1259. ;; Save the register in the caller space and return 0 if it failed
  1260. mov edx, [ebp+16]
  1261. mov [edx], eax
  1262. cmp eax, 0xffffffff
  1263. je decode_operand_ret_false
  1264. ;; Search for the closed bracket
  1265. mov ebx, esi
  1266. add ebx, 1
  1267. push SQ_CLOSED
  1268. push ebx
  1269. call find_char
  1270. add esp, 8
  1271. cmp eax, 0xffffffff
  1272. je decode_operand_ret_false
  1273. ;; Check that the following character is a terminator
  1274. mov ecx, ebx
  1275. add ecx, eax
  1276. cmp BYTE [ecx+1], 0
  1277. jne decode_operand_ret_false
  1278. ;; Overwrite the closed bracket with a terminator and recognized the
  1279. ;; displacement
  1280. mov BYTE [ecx], 0
  1281. push 0
  1282. mov eax, DWORD [ebp+20]
  1283. push eax
  1284. push ebx
  1285. call decode_number_or_symbol
  1286. add esp, 12
  1287. jmp decode_operand_ret
  1288. decode_operand_direct:
  1289. ;; Direct operand: save this fact in the caller space
  1290. mov edx, [ebp+12]
  1291. mov DWORD [edx], 1
  1292. ;; No prefix should have been found in this case
  1293. cmp ecx, 0
  1294. jne decode_operand_ret_false
  1295. ;; Try to recognized the operand as a 32 bits register
  1296. push ebx
  1297. call decode_reg32
  1298. add esp, 4
  1299. cmp eax, 0xffffffff
  1300. je decode_operand_8bit
  1301. ;; Save the register in the caller space
  1302. mov edx, [ebp+16]
  1303. mov [edx], eax
  1304. ;; Save the detected size in the caller space
  1305. mov edx, [ebp+24]
  1306. mov DWORD [edx], 0
  1307. mov edx, [ebp+28]
  1308. mov DWORD [edx], 1
  1309. jmp decode_operand_ret_true
  1310. decode_operand_8bit:
  1311. ;; Try to recognize the operand as a 8 bits register
  1312. push ebx
  1313. call decode_reg8
  1314. add esp, 4
  1315. cmp eax, 0xffffffff
  1316. je decode_operand_ret_false
  1317. ;; Save the register in the caller space
  1318. mov edx, [ebp+16]
  1319. mov [edx], eax
  1320. ;; Save the detected size in the caller space
  1321. mov edx, [ebp+24]
  1322. mov DWORD [edx], 1
  1323. mov edx, [ebp+28]
  1324. mov DWORD [edx], 0
  1325. jmp decode_operand_ret_true
  1326. decode_operand_ret_true:
  1327. mov eax, 1
  1328. jmp decode_operand_ret
  1329. decode_operand_ret_false:
  1330. mov eax, 0
  1331. jmp decode_operand_ret
  1332. decode_operand_ret:
  1333. pop esi
  1334. pop ebx
  1335. pop ebp
  1336. ret
  1337. global process_bss_line
  1338. process_bss_line:
  1339. ;; Check if the opcode is resb
  1340. mov edx, [esp+4]
  1341. push str_resb
  1342. push edx
  1343. call strcmp
  1344. add esp, 8
  1345. cmp eax, 0
  1346. je process_bss_line_resb
  1347. ;; Check is the opcode is resd
  1348. mov edx, [esp+4]
  1349. push str_resd
  1350. push edx
  1351. call strcmp
  1352. add esp, 8
  1353. cmp eax, 0
  1354. je process_bss_line_resd
  1355. mov eax, 0
  1356. ret
  1357. process_bss_line_resb:
  1358. ;; Save the argument before we mess up with the stack
  1359. mov edx, [esp+8]
  1360. ;; Push 0 to allocate a local variable and take its address
  1361. push 0
  1362. mov ecx, esp
  1363. ;; Call decode_number_or_symbol
  1364. push 1
  1365. push ecx
  1366. push edx
  1367. call decode_number_or_symbol
  1368. add esp, 12
  1369. ;; Deallocate the temporary variable and save it in ecx
  1370. pop ecx
  1371. cmp eax, 0
  1372. je platform_panic
  1373. process_bss_line_resb_loop:
  1374. ;; Loop ecx times calling emit(0) at each loop
  1375. cmp ecx, 0
  1376. je process_bss_line_ret
  1377. sub ecx, 1
  1378. push ecx
  1379. push 0
  1380. call emit
  1381. add esp, 4
  1382. pop ecx
  1383. jmp process_bss_line_resb_loop
  1384. ;; Everything as above, but with emit32 instead of emit
  1385. process_bss_line_resd:
  1386. mov edx, [esp+8]
  1387. push 0
  1388. mov ecx, esp
  1389. push 1
  1390. push ecx
  1391. push edx
  1392. call decode_number_or_symbol
  1393. add esp, 12
  1394. pop ecx
  1395. cmp eax, 0
  1396. je platform_panic
  1397. process_bss_line_resd_loop:
  1398. cmp ecx, 0
  1399. je process_bss_line_ret
  1400. sub ecx, 1
  1401. push ecx
  1402. push 0
  1403. call emit32
  1404. add esp, 4
  1405. pop ecx
  1406. jmp process_bss_line_resd_loop
  1407. process_bss_line_ret:
  1408. mov eax, 1
  1409. ret
  1410. global process_data_line
  1411. process_data_line:
  1412. ;; Check if the opcode is db
  1413. mov edx, [esp+4]
  1414. push str_db
  1415. push edx
  1416. call strcmp
  1417. add esp, 8
  1418. cmp eax, 0
  1419. je process_data_line_db
  1420. ;; Check is the opcode is dd
  1421. mov edx, [esp+4]
  1422. push str_dd
  1423. push edx
  1424. call strcmp
  1425. add esp, 8
  1426. cmp eax, 0
  1427. je process_data_line_dd
  1428. mov eax, 0
  1429. ret
  1430. process_data_line_db:
  1431. ;; If data begin with an apex, treat it as a string
  1432. mov edx, [esp+8]
  1433. cmp BYTE [edx], APEX
  1434. je process_data_line_string
  1435. ;; If not, treat it as a single 8 bits value
  1436. mov eax, 0
  1437. jmp process_data_line_value
  1438. process_data_line_dd:
  1439. ;; Assume data is a single 32 bits value
  1440. mov edx, [esp+8]
  1441. mov eax, 1
  1442. jmp process_data_line_value
  1443. process_data_line_value:
  1444. ;; Like process_bss_line_resb, but with just one emit at the end
  1445. ;; (and decode_number_or_symbol is permitted to fail in stage 0)
  1446. push eax
  1447. push 0
  1448. mov ecx, esp
  1449. push 0
  1450. push ecx
  1451. push edx
  1452. call decode_number_or_symbol
  1453. add esp, 12
  1454. pop ecx
  1455. cmp eax, 0
  1456. je platform_panic
  1457. ;; We used eax to remember if data is 8 or 32 bits; call emit or
  1458. ;; emit32 accordingly
  1459. pop eax
  1460. cmp eax, 0
  1461. jne process_data_line_emit32
  1462. push ecx
  1463. call emit
  1464. add esp, 4
  1465. jmp process_data_line_ret
  1466. process_data_line_emit32:
  1467. push ecx
  1468. call emit32
  1469. add esp, 4
  1470. jmp process_data_line_ret
  1471. process_data_line_string:
  1472. ;; Compute string length
  1473. push edx
  1474. push edx
  1475. call strlen
  1476. add esp, 4
  1477. pop edx
  1478. ;; Check that data has at least length 2 (the two apices)
  1479. cmp eax, 2
  1480. jnae platform_panic
  1481. ;; Check that data has an apex at the end
  1482. mov ecx, edx
  1483. add ecx, eax
  1484. sub ecx, 1
  1485. cmp BYTE [ecx], APEX
  1486. jne platform_panic
  1487. ;; Consume the first apex and overwrite the last with a terminator
  1488. mov BYTE [ecx], 0
  1489. add edx, 1
  1490. ;; Emit all the bytes
  1491. process_data_line_dd_loop:
  1492. cmp BYTE [edx], 0
  1493. je process_data_line_ret
  1494. push edx
  1495. mov ecx, 0
  1496. mov cl, BYTE [edx]
  1497. push ecx
  1498. call emit
  1499. add esp, 4
  1500. pop edx
  1501. add edx, 1
  1502. jmp process_data_line_dd_loop
  1503. process_data_line_ret:
  1504. mov eax, 1
  1505. ret
  1506. global emit_modrm
  1507. emit_modrm:
  1508. ;; Check that input do not overlap when being shifted in place
  1509. mov eax, 0x3
  1510. and eax, [esp+4]
  1511. cmp eax, [esp+4]
  1512. jne platform_panic
  1513. mov eax, 0x7
  1514. and eax, [esp+8]
  1515. cmp eax, [esp+8]
  1516. jne platform_panic
  1517. mov eax, 0x7
  1518. and eax, [esp+12]
  1519. cmp eax, [esp+12]
  1520. jne platform_panic
  1521. ;; Only support a direct register, or an indirect register + disp32
  1522. cmp BYTE [esp+4], 0
  1523. je platform_panic
  1524. cmp BYTE [esp+4], 1
  1525. je platform_panic
  1526. ;; Assemble the first byte
  1527. mov eax, 0
  1528. mov al, BYTE [esp+4]
  1529. mov edx, 8
  1530. mul edx
  1531. add al, BYTE [esp+8]
  1532. mov edx, 8
  1533. mul edx
  1534. add al, BYTE [esp+12]
  1535. ;; Emit the first byte
  1536. push eax
  1537. call emit
  1538. add esp, 4
  1539. ;; In the particular case of ESP used as indirect base, a SIB is
  1540. ;; needed
  1541. cmp BYTE [esp+4], 2
  1542. jne emit_modrm_ret
  1543. cmp BYTE [esp+12], 4
  1544. jne emit_modrm_ret
  1545. push 0x24
  1546. call emit
  1547. add esp, 4
  1548. emit_modrm_ret:
  1549. ret
  1550. global emit_helper
  1551. emit_helper:
  1552. push ebp
  1553. mov ebp, esp
  1554. ;; Check the opcode is valid and call first emit
  1555. mov ecx, [ebp+8]
  1556. mov edx, 0
  1557. mov dl, cl
  1558. cmp cl, 0xf0
  1559. je platform_panic
  1560. push edx
  1561. call emit
  1562. add esp, 4
  1563. ;; Perhaps call second emit
  1564. mov ecx, [ebp+8]
  1565. and ecx, 0xff0000
  1566. cmp ecx, 0
  1567. je emit_helper_modrm
  1568. mov ecx, [ebp+8]
  1569. mov edx, 0
  1570. mov dl, ch
  1571. push edx
  1572. call emit
  1573. add esp, 4
  1574. emit_helper_modrm:
  1575. ;; Perhaps call emit_modrm
  1576. mov eax, [ebp+20]
  1577. cmp eax, 0xffffffff
  1578. je emit_helper_disp
  1579. push eax
  1580. mov edx, [ebp+16]
  1581. cmp edx, 0xffffffff
  1582. jne emit_helper_modrm3
  1583. mov ecx, [ebp+8]
  1584. mov edx, 0
  1585. mov dl, ch
  1586. emit_helper_modrm3:
  1587. push edx
  1588. mov ecx, 2
  1589. cmp DWORD [ebp+12], 0
  1590. je emit_helper_modrm2
  1591. mov ecx, 3
  1592. emit_helper_modrm2:
  1593. push ecx
  1594. call emit_modrm
  1595. add esp, 12
  1596. emit_helper_disp:
  1597. ;; Perhaps call emit32
  1598. cmp DWORD [ebp+12], 0
  1599. jne emit_helper_end
  1600. mov edx, [ebp+24]
  1601. push edx
  1602. call emit32
  1603. add esp, 4
  1604. emit_helper_end:
  1605. pop ebp
  1606. ret
  1607. global process_jmp_like
  1608. process_jmp_like:
  1609. push ebp
  1610. mov ebp, esp
  1611. ;; Allocate space for 5 variables:
  1612. ;; [ebp-4], which is [ebp+0xfffffffc]: is_direct
  1613. ;; [ebp-8], which is [ebp+0xfffffff8]: reg
  1614. ;; [ebp-12], whch is [ebp+0xfffffff4]: disp
  1615. ;; [ebp-16], which is [ebp+0xfffffff0]: is8
  1616. ;; [ebp-20], which is [ebp+0xffffffec]: is32
  1617. sub esp, 20
  1618. ;; Call decode_operand
  1619. mov eax, ebp
  1620. sub eax, 20
  1621. push eax
  1622. mov eax, ebp
  1623. sub eax, 16
  1624. push eax
  1625. mov eax, ebp
  1626. sub eax, 12
  1627. push eax
  1628. mov eax, ebp
  1629. sub eax, 8
  1630. push eax
  1631. mov eax, ebp
  1632. sub eax, 4
  1633. push eax
  1634. mov eax, [ebp+12]
  1635. push eax
  1636. call decode_operand
  1637. add esp, 24
  1638. cmp eax, 0
  1639. jne process_jmp_like_rm32
  1640. jmp process_jmp_like_rel32
  1641. process_jmp_like_rm32:
  1642. ;; Check the operand is not 8 bits
  1643. cmp DWORD [ebp+0xfffffff0], 0
  1644. jne platform_panic
  1645. ;; Get the opcode data
  1646. mov eax, [ebp+8]
  1647. mov edx, 4
  1648. mul edx
  1649. add eax, rm32_opcode
  1650. mov ecx, [eax]
  1651. ;; Call emit_helper
  1652. mov edx, [ebp+0xfffffff4]
  1653. push edx
  1654. mov edx, [ebp+0xfffffff8]
  1655. push edx
  1656. push 0xffffffff
  1657. mov edx, [ebp+0xfffffffc]
  1658. push edx
  1659. push ecx
  1660. call emit_helper
  1661. add esp, 20
  1662. jmp process_jmp_like_end
  1663. process_jmp_like_rel32:
  1664. ;; Get the opcode data
  1665. mov eax, [ebp+8]
  1666. mov edx, 4
  1667. mul edx
  1668. add eax, imm32_opcode
  1669. mov ecx, [eax]
  1670. ;; Call emit_helper
  1671. push 0
  1672. push 0xffffffff
  1673. push 0xffffffff
  1674. push 1
  1675. push ecx
  1676. call emit_helper
  1677. add esp, 20
  1678. ;; Call decode_number_or_symbol
  1679. push 0
  1680. mov edx, esp
  1681. push 0
  1682. push edx
  1683. mov edx, [ebp+12]
  1684. push edx
  1685. call decode_number_or_symbol
  1686. add esp, 12
  1687. ;; Check for success
  1688. cmp eax, 0
  1689. je platform_panic
  1690. ;; Store the value in edx and make it relative
  1691. pop edx
  1692. mov ecx, current_loc
  1693. sub edx, [ecx]
  1694. sub edx, 4
  1695. ;; Call emit32
  1696. push edx
  1697. call emit32
  1698. add esp, 4
  1699. jmp process_jmp_like_end
  1700. process_jmp_like_end:
  1701. add esp, 20
  1702. pop ebp
  1703. ret
  1704. global process_push_like
  1705. process_push_like:
  1706. push ebp
  1707. mov ebp, esp
  1708. ;; Allocate space for 5 variables:
  1709. ;; [ebp-4], which is [ebp+0xfffffffc]: is_direct
  1710. ;; [ebp-8], which is [ebp+0xfffffff8]: reg
  1711. ;; [ebp-12], whch is [ebp+0xfffffff4]: disp
  1712. ;; [ebp-16], which is [ebp+0xfffffff0]: is8
  1713. ;; [ebp-20], which is [ebp+0xffffffec]: is32
  1714. sub esp, 20
  1715. ;; Check if the operation is a bit shift
  1716. cmp DWORD [ebp+8], OP_SHL
  1717. je process_push_like_shift
  1718. cmp DWORD [ebp+8], OP_SHR
  1719. je process_push_like_shift
  1720. cmp DWORD [ebp+8], OP_SAL
  1721. je process_push_like_shift
  1722. cmp DWORD [ebp+8], OP_SAR
  1723. je process_push_like_shift
  1724. jmp process_push_like_decode
  1725. process_push_like_shift:
  1726. ;; Find the comma
  1727. push COMMA
  1728. mov edx, [ebp+12]
  1729. push edx
  1730. call find_char
  1731. add esp, 8
  1732. cmp eax, 0xffffffff
  1733. je platform_panic
  1734. ;; Substitute the comma with a terminator
  1735. mov ecx, [ebp+12]
  1736. add ecx, eax
  1737. mov BYTE [ecx], 0
  1738. ;; Trim second operand
  1739. add ecx, 1
  1740. push ecx
  1741. push ecx
  1742. call trimstr
  1743. add esp, 4
  1744. pop ecx
  1745. ;; Check that second operand is cl
  1746. push ecx
  1747. push reg_cl
  1748. call strcmp
  1749. add esp, 8
  1750. cmp eax, 0
  1751. jne platform_panic
  1752. process_push_like_decode:
  1753. ;; Call decode_operand
  1754. mov eax, ebp
  1755. sub eax, 20
  1756. push eax
  1757. mov eax, ebp
  1758. sub eax, 16
  1759. push eax
  1760. mov eax, ebp
  1761. sub eax, 12
  1762. push eax
  1763. mov eax, ebp
  1764. sub eax, 8
  1765. push eax
  1766. mov eax, ebp
  1767. sub eax, 4
  1768. push eax
  1769. mov eax, [ebp+12]
  1770. push eax
  1771. call decode_operand
  1772. add esp, 24
  1773. cmp eax, 0
  1774. jne process_push_like_rm32
  1775. jmp process_push_like_imm32
  1776. process_push_like_rm32:
  1777. ;; Check the operand is not 8 bits
  1778. cmp DWORD [ebp+0xfffffff0], 0
  1779. jne platform_panic
  1780. ;; Get the opcode data
  1781. mov eax, [ebp+8]
  1782. mov edx, 4
  1783. mul edx
  1784. add eax, rm32_opcode
  1785. mov ecx, [eax]
  1786. ;; Call emit_helper
  1787. mov edx, [ebp+0xfffffff4]
  1788. push edx
  1789. mov edx, [ebp+0xfffffff8]
  1790. push edx
  1791. push 0xffffffff
  1792. mov edx, [ebp+0xfffffffc]
  1793. push edx
  1794. push ecx
  1795. call emit_helper
  1796. add esp, 20
  1797. jmp process_push_like_end
  1798. process_push_like_imm32:
  1799. ;; Check that the operation is push
  1800. cmp DWORD [ebp+8], OP_PUSH
  1801. jne platform_panic
  1802. ;; Emit the operand
  1803. push 0x68
  1804. call emit
  1805. add esp, 4
  1806. ;; Call decode_number_or_symbol
  1807. push 0
  1808. mov edx, esp
  1809. push 0
  1810. push edx
  1811. mov edx, [ebp+12]
  1812. push edx
  1813. call decode_number_or_symbol
  1814. add esp, 12
  1815. cmp eax, 0
  1816. je platform_panic
  1817. ;; Call emit32
  1818. pop edx
  1819. push edx
  1820. call emit32
  1821. add esp, 4
  1822. jmp process_push_like_end
  1823. process_push_like_end:
  1824. add esp, 20
  1825. pop ebp
  1826. ret
  1827. global process_add_like
  1828. process_add_like:
  1829. push ebp
  1830. mov ebp, esp
  1831. ;; Allocate a lot of local variables
  1832. ;; [ebp-4], which is [ebp+0xfffffffc]: dest_is_direct
  1833. ;; [ebp-8], which is [ebp+0xfffffff8]: dest_reg
  1834. ;; [ebp-12], whch is [ebp+0xfffffff4]: dest_disp
  1835. ;; [ebp-16], which is [ebp+0xfffffff0]: dest_is8
  1836. ;; [ebp-20], which is [ebp+0xffffffec]: dest_is32
  1837. ;; [ebp-24], which is [ebp+0xffffffe8]: src_is_direct
  1838. ;; [ebp-28], which is [ebp+0xffffffe4]: src_reg
  1839. ;; [ebp-32], which is [ebp+0xffffffe0]: src_disp
  1840. ;; [ebp-36], which is [ebp+0xffffffdc]: src_is8
  1841. ;; [ebp-40], which is [ebo+0xffffffd8]: src_is32
  1842. sub esp, 40
  1843. ;; Find the comma
  1844. push COMMA
  1845. mov edx, [ebp+12]
  1846. push edx
  1847. call find_char
  1848. add esp, 8
  1849. cmp eax, 0xffffffff
  1850. je platform_panic
  1851. ;; Substitute the comma with a terminator
  1852. mov ecx, [ebp+12]
  1853. add ecx, eax
  1854. mov BYTE [ecx], 0
  1855. ;; Push following position on the stack
  1856. add ecx, 1
  1857. push ecx
  1858. ;; Call decode_operand for destination
  1859. mov ecx, ebp
  1860. sub ecx, 20
  1861. push ecx
  1862. mov ecx, ebp
  1863. sub ecx, 16
  1864. push ecx
  1865. mov ecx, ebp
  1866. sub ecx, 12
  1867. push ecx
  1868. mov ecx, ebp
  1869. sub ecx, 8
  1870. push ecx
  1871. mov ecx, ebp
  1872. sub ecx, 4
  1873. push ecx
  1874. mov ecx, [ebp+12]
  1875. push ecx
  1876. call decode_operand
  1877. add esp, 24
  1878. ;; Panic if decoding failed
  1879. cmp eax, 0
  1880. je platform_panic
  1881. ;; Call decode_operand for source
  1882. pop edx
  1883. push edx
  1884. mov ecx, ebp
  1885. sub ecx, 40
  1886. push ecx
  1887. mov ecx, ebp
  1888. sub ecx, 36
  1889. push ecx
  1890. mov ecx, ebp
  1891. sub ecx, 32
  1892. push ecx
  1893. mov ecx, ebp
  1894. sub ecx, 28
  1895. push ecx
  1896. mov ecx, ebp
  1897. sub ecx, 24
  1898. push ecx
  1899. push edx
  1900. call decode_operand
  1901. add esp, 24
  1902. pop edx
  1903. cmp eax, 0
  1904. je process_add_like_imm
  1905. ;; Decide whether this is an 8 or 32 bits operation
  1906. mov dl, [ebp+0xfffffff0]
  1907. or dl, [ebp+0xffffffdc]
  1908. mov dh, [ebp+0xffffffec]
  1909. or dh, [ebp+0xffffffd8]
  1910. ;; Check that the situation is consistent
  1911. mov al, dl
  1912. or al, dh
  1913. cmp al, 0
  1914. je platform_panic
  1915. mov al, dl
  1916. and al, dh
  1917. cmp al, 0
  1918. jne platform_panic
  1919. ;; Split depending on whether destination is direct or not
  1920. mov ecx, [ebp+0xfffffffc]
  1921. cmp ecx, 0
  1922. jne process_add_like_dest_direct
  1923. jmp process_add_like_dest_indirect
  1924. process_add_like_dest_direct:
  1925. ;; Split depending on 8 or 32 bits operation
  1926. cmp dl, 0
  1927. jne process_add_like_dest_direct_8
  1928. jmp process_add_like_dest_direct_32
  1929. process_add_like_dest_direct_8:
  1930. ;; Retrieve opcode_data
  1931. mov eax, [ebp+8]
  1932. mov edx, 4
  1933. mul edx
  1934. add eax, r8rm8_opcode
  1935. mov ecx, [eax]
  1936. ;; Call emit_helper
  1937. mov eax, [ebp+0xffffffe0]
  1938. push eax
  1939. mov eax, [ebp+0xffffffe4]
  1940. push eax
  1941. mov eax, [ebp+0xfffffff8]
  1942. push eax
  1943. mov eax, [ebp+0xffffffe8]
  1944. push eax
  1945. push ecx
  1946. call emit_helper
  1947. add esp, 20
  1948. jmp process_add_like_end
  1949. process_add_like_dest_direct_32:
  1950. ;; Retrieve opcode_data
  1951. mov eax, [ebp+8]
  1952. mov edx, 4
  1953. mul edx
  1954. add eax, r32rm32_opcode
  1955. mov ecx, [eax]
  1956. ;; Call emit_helper
  1957. mov eax, [ebp+0xffffffe0]
  1958. push eax
  1959. mov eax, [ebp+0xffffffe4]
  1960. push eax
  1961. mov eax, [ebp+0xfffffff8]
  1962. push eax
  1963. mov eax, [ebp+0xffffffe8]
  1964. push eax
  1965. push ecx
  1966. call emit_helper
  1967. add esp, 20
  1968. jmp process_add_like_end
  1969. process_add_like_dest_indirect:
  1970. ;; Check that source is direct
  1971. cmp DWORD [ebp+0xffffffe8], 0
  1972. je platform_panic
  1973. ;; Split depending on 8 or 32 bits operation
  1974. cmp dl, 0
  1975. jne process_add_like_dest_indirect_8
  1976. jmp process_add_like_dest_indirect_32
  1977. process_add_like_dest_indirect_8:
  1978. ;; Retrieve opcode_data
  1979. mov eax, [ebp+8]
  1980. mov edx, 4
  1981. mul edx
  1982. add eax, rm8r8_opcode
  1983. mov ecx, [eax]
  1984. ;; Call emit_helper
  1985. mov eax, [ebp+0xfffffff4]
  1986. push eax
  1987. mov eax, [ebp+0xfffffff8]
  1988. push eax
  1989. mov eax, [ebp+0xffffffe4]
  1990. push eax
  1991. push 0
  1992. push ecx
  1993. call emit_helper
  1994. add esp, 20
  1995. jmp process_add_like_end
  1996. process_add_like_dest_indirect_32:
  1997. ;; Retrieve opcode_data
  1998. mov eax, [ebp+8]
  1999. mov edx, 4
  2000. mul edx
  2001. add eax, rm32r32_opcode
  2002. mov ecx, [eax]
  2003. ;; Call emit_helper
  2004. mov eax, [ebp+0xfffffff4]
  2005. push eax
  2006. mov eax, [ebp+0xfffffff8]
  2007. push eax
  2008. mov eax, [ebp+0xffffffe4]
  2009. push eax
  2010. push 0
  2011. push ecx
  2012. call emit_helper
  2013. add esp, 20
  2014. jmp process_add_like_end
  2015. process_add_like_imm:
  2016. ;; Check that we know the operation size
  2017. mov eax, [ebp+0xfffffff0]
  2018. or eax, [ebp+0xffffffec]
  2019. cmp eax, 0
  2020. je platform_panic
  2021. ;; Call decode_number_or_symbol
  2022. push 0
  2023. mov ecx, esp
  2024. push 0
  2025. push ecx
  2026. push edx
  2027. call decode_number_or_symbol
  2028. add esp, 12
  2029. pop edx
  2030. ;; Check it did work
  2031. cmp eax, 0
  2032. je platform_panic
  2033. cmp DWORD [ebp+0xfffffff0], 0
  2034. je process_add_like_imm_32
  2035. jmp process_add_like_imm_8
  2036. process_add_like_imm_8:
  2037. push edx
  2038. ;; Retrieve opcode_data
  2039. mov eax, [ebp+8]
  2040. mov edx, 4
  2041. mul edx
  2042. add eax, rm8imm8_opcode
  2043. mov ecx, [eax]
  2044. ;; Call emit_helper
  2045. mov eax, [ebp+0xfffffff4]
  2046. push eax
  2047. mov eax, [ebp+0xfffffff8]
  2048. push eax
  2049. push 0xffffffff
  2050. mov eax, [ebp+0xfffffffc]
  2051. push eax
  2052. push ecx
  2053. call emit_helper
  2054. add esp, 20
  2055. ;; Call emit
  2056. pop edx
  2057. push edx
  2058. call emit
  2059. add esp, 4
  2060. jmp process_add_like_end
  2061. process_add_like_imm_32:
  2062. push edx
  2063. ;; Retrieve opcode_data
  2064. mov eax, [ebp+8]
  2065. mov edx, 4
  2066. mul edx
  2067. add eax, rm32imm32_opcode
  2068. mov ecx, [eax]
  2069. ;; Call emit_helper
  2070. mov eax, [ebp+0xfffffff4]
  2071. push eax
  2072. mov eax, [ebp+0xfffffff8]
  2073. push eax
  2074. push 0xffffffff
  2075. mov eax, [ebp+0xfffffffc]
  2076. push eax
  2077. push ecx
  2078. call emit_helper
  2079. add esp, 20
  2080. ;; Call emit
  2081. pop edx
  2082. push edx
  2083. call emit32
  2084. add esp, 4
  2085. jmp process_add_like_end
  2086. process_add_like_end:
  2087. add esp, 40
  2088. pop ebp
  2089. ret
  2090. global process_int
  2091. process_int:
  2092. ;; Check the operation is actually an int
  2093. cmp DWORD [esp+4], OP_INT
  2094. jne platform_panic
  2095. ;; Call decode_number_or_symbol
  2096. push 0
  2097. mov edx, esp
  2098. push 0
  2099. push edx
  2100. mov edx, [esp+8]
  2101. push edx
  2102. call decode_number_or_symbol
  2103. add esp, 12
  2104. pop edx
  2105. ;; Check result
  2106. cmp eax, 0
  2107. je platform_panic
  2108. ;; Check the interrupt number is smaller than 0x100
  2109. cmp edx, 0x100
  2110. jnb platform_panic
  2111. ;; Call emit twice
  2112. push edx
  2113. push 0xcd
  2114. call emit
  2115. add esp, 4
  2116. call emit
  2117. add esp, 4
  2118. ret
  2119. global process_ret_like
  2120. process_ret_like:
  2121. ;; Get the opcode data
  2122. mov eax, [esp+4]
  2123. mov edx, 4
  2124. mul edx
  2125. add eax, empty_opcode
  2126. mov ecx, [eax]
  2127. ;; Check that data is empty
  2128. mov edx, [esp+8]
  2129. cmp BYTE [edx], 0
  2130. jne platform_panic
  2131. ;; Call emit_helper
  2132. push 0
  2133. push 0xffffffff
  2134. push 0xffffffff
  2135. push 1
  2136. push ecx
  2137. call emit_helper
  2138. add esp, 20
  2139. ret
  2140. global process_hlt
  2141. process_hlt:
  2142. ;; Check the operation is actually a ret
  2143. cmp DWORD [esp+4], OP_HLT
  2144. jne platform_panic
  2145. ;; Check that data is empty
  2146. mov edx, [esp+8]
  2147. cmp BYTE [edx], 0
  2148. jne platform_panic
  2149. ;; Call emit
  2150. push 0xf4
  2151. call emit
  2152. add esp, 4
  2153. ret
  2154. global process_in_like
  2155. process_in_like:
  2156. ;; Check the operation is valid
  2157. cmp DWORD [esp+4], OP_IN
  2158. je process_in_like_find_comma
  2159. cmp DWORD [esp+4], OP_OUT
  2160. je process_in_like_find_comma
  2161. call platform_panic
  2162. process_in_like_find_comma:
  2163. ;; Search the comma and panic if it is not there
  2164. mov eax, [esp+8]
  2165. push COMMA
  2166. push eax
  2167. call find_char
  2168. add esp, 8
  2169. cmp eax, 0xffffffff
  2170. je platform_panic
  2171. ;; Substitute the comma with a terminator
  2172. mov edx, [esp+8]
  2173. mov ecx, edx
  2174. add edx, eax
  2175. mov BYTE [edx], 0
  2176. add edx, 1
  2177. mov eax, ecx
  2178. ;; Decide which operation to use
  2179. cmp DWORD [esp+4], OP_IN
  2180. je process_in_like_in
  2181. jmp process_in_like_out
  2182. process_in_like_in:
  2183. ;; Leave the port operand in edx, the register operand in eax and
  2184. ;; the opcode in ecx
  2185. mov ecx, 0xec
  2186. jmp process_in_like_trim
  2187. process_in_like_out:
  2188. ;; Same as above
  2189. mov ecx, eax
  2190. mov eax, edx
  2191. mov edx, ecx
  2192. mov ecx, 0xee
  2193. jmp process_in_like_trim
  2194. process_in_like_trim:
  2195. ;; Trim both operands
  2196. push eax
  2197. push ecx
  2198. push edx
  2199. push eax
  2200. call trimstr
  2201. add esp, 4
  2202. pop edx
  2203. push edx
  2204. push edx
  2205. call trimstr
  2206. add esp, 4
  2207. pop edx
  2208. pop ecx
  2209. pop eax
  2210. ;; Check that the port operand is dx
  2211. push eax
  2212. push ecx
  2213. push reg_dx
  2214. push edx
  2215. call strcmp
  2216. add esp, 8
  2217. cmp eax, 0
  2218. jne platform_panic
  2219. pop ecx
  2220. pop eax
  2221. ;; Select depending on the register operand
  2222. push eax
  2223. push ecx
  2224. push reg_al
  2225. push eax
  2226. call strcmp
  2227. add esp, 8
  2228. cmp eax, 0
  2229. pop ecx
  2230. pop eax
  2231. je process_in_like_al
  2232. push eax
  2233. push ecx
  2234. push reg_ax
  2235. push eax
  2236. call strcmp
  2237. add esp, 8
  2238. cmp eax, 0
  2239. pop ecx
  2240. pop eax
  2241. je process_in_like_ax
  2242. push eax
  2243. push ecx
  2244. push reg_eax
  2245. push eax
  2246. call strcmp
  2247. add esp, 8
  2248. cmp eax, 0
  2249. pop ecx
  2250. pop eax
  2251. je process_in_like_eax
  2252. ;; Nothing matched, panic!
  2253. call platform_panic
  2254. process_in_like_al:
  2255. ;; Emit the opcode
  2256. push ecx
  2257. call emit
  2258. add esp, 4
  2259. jmp process_in_like_ret
  2260. process_in_like_ax:
  2261. ;; Emit the opcode
  2262. add ecx, 1
  2263. push ecx
  2264. push 0x66
  2265. call emit
  2266. add esp, 4
  2267. call emit
  2268. add esp, 4
  2269. jmp process_in_like_ret
  2270. process_in_like_eax:
  2271. add ecx, 1
  2272. push ecx
  2273. call emit
  2274. add esp, 4
  2275. jmp process_in_like_ret
  2276. process_in_like_ret:
  2277. ret
  2278. global process_text_line
  2279. process_text_line:
  2280. push ebp
  2281. mov ebp, esp
  2282. push esi
  2283. push edi
  2284. ;; Init esi for storing the current name and edi for counting
  2285. mov esi, opcode_names
  2286. mov edi, 0
  2287. process_text_line_loop:
  2288. ;; Check for termination: we did not find any match
  2289. mov eax, 0
  2290. cmp BYTE [esi], 0
  2291. je process_text_line_end
  2292. ;; Check for termination: we found a match
  2293. mov ecx, [ebp+8]
  2294. push ecx
  2295. push esi
  2296. call strcmp
  2297. add esp, 8
  2298. cmp eax, 0
  2299. je process_text_line_match
  2300. ;; Consume the string and increment the index
  2301. push esi
  2302. call strlen
  2303. add esp, 4
  2304. add esi, eax
  2305. add esi, 1
  2306. add edi, 1
  2307. jmp process_text_line_loop
  2308. process_text_line_match:
  2309. ;; Select the opcode function
  2310. mov eax, 4
  2311. mul edi
  2312. add eax, opcode_funcs
  2313. ;; Call the opcode function
  2314. mov edx, [ebp+12]
  2315. push edx
  2316. push edi
  2317. call [eax]
  2318. add esp, 8
  2319. mov eax, 1
  2320. jmp process_text_line_end
  2321. process_text_line_end:
  2322. pop edi
  2323. pop esi
  2324. pop ebp
  2325. ret
  2326. global process_directive_line
  2327. process_directive_line:
  2328. ;; Ignore section, org, bits, global and align
  2329. mov eax, [esp+4]
  2330. push str_section
  2331. push eax
  2332. call strcmp
  2333. add esp, 8
  2334. cmp eax, 0
  2335. je process_directive_line_ret_true
  2336. mov eax, [esp+4]
  2337. push str_org
  2338. push eax
  2339. call strcmp
  2340. add esp, 8
  2341. cmp eax, 0
  2342. je process_directive_line_ret_true
  2343. mov eax, [esp+4]
  2344. push str_bits
  2345. push eax
  2346. call strcmp
  2347. add esp, 8
  2348. cmp eax, 0
  2349. je process_directive_line_ret_true
  2350. mov eax, [esp+4]
  2351. push str_global
  2352. push eax
  2353. call strcmp
  2354. add esp, 8
  2355. cmp eax, 0
  2356. je process_directive_line_ret_true
  2357. mov eax, [esp+4]
  2358. push str_align
  2359. push eax
  2360. call strcmp
  2361. add esp, 8
  2362. cmp eax, 0
  2363. je process_directive_line_align
  2364. ;; Recognize extern
  2365. mov eax, [esp+4]
  2366. push str_extern
  2367. push eax
  2368. call strcmp
  2369. add esp, 8
  2370. cmp eax, 0
  2371. je process_directive_line_extern
  2372. ;; Return false for everything else
  2373. mov eax, 0
  2374. ret
  2375. process_directive_line_align:
  2376. ;; Call decode_number_or_symbol
  2377. mov eax, [esp+8]
  2378. push 0
  2379. mov ecx, esp
  2380. push 1
  2381. push ecx
  2382. push eax
  2383. call decode_number_or_symbol
  2384. add esp, 12
  2385. pop ecx
  2386. ;; Panic if it failed
  2387. cmp eax, 0
  2388. je platform_panic
  2389. ;; Compute the number of bytes to skip
  2390. mov edx, current_loc
  2391. mov eax, [edx]
  2392. mov edx, 0
  2393. div ecx
  2394. cmp edx, 0
  2395. je process_directive_line_ret_true
  2396. sub ecx, edx
  2397. ;; Skip them
  2398. process_directive_line_align_loop:
  2399. cmp ecx, 0
  2400. je process_directive_line_ret_true
  2401. push ecx
  2402. push 0
  2403. call emit
  2404. add esp, 4
  2405. pop ecx
  2406. sub ecx, 1
  2407. jmp process_directive_line_align_loop
  2408. process_directive_line_extern:
  2409. ;; Add a mock symbol
  2410. mov eax, [esp+8]
  2411. push 0xffffffff
  2412. push 0
  2413. push eax
  2414. call add_symbol_wrapper
  2415. add esp, 12
  2416. jmp process_directive_line_ret_true
  2417. process_directive_line_ret_true:
  2418. mov eax, 1
  2419. ret
  2420. global process_equ_line
  2421. process_equ_line:
  2422. ;; Find the space in data
  2423. mov eax, [esp+8]
  2424. push SPACE
  2425. push eax
  2426. call find_char
  2427. add esp, 8
  2428. ;; Fail if there is not one
  2429. cmp eax, 0xffffffff
  2430. je process_equ_line_ret_false
  2431. ;; Substitute it with a terminator and save the following position
  2432. mov edx, [esp+8]
  2433. add eax, edx
  2434. mov BYTE [eax], 0
  2435. mov ecx, eax
  2436. add eax, 1
  2437. push eax
  2438. ;; Check we are dealing with an equ line
  2439. push str_equ
  2440. push edx
  2441. call strcmp
  2442. add esp, 8
  2443. pop edx
  2444. ;; Fail if we are not
  2445. cmp eax, 0
  2446. jne process_equ_line_ret_false
  2447. ;; Call trimstr
  2448. push edx
  2449. push edx
  2450. call trimstr
  2451. add esp, 4
  2452. pop edx
  2453. ;; Call decode_number_or_symbol
  2454. push 0
  2455. mov ecx, esp
  2456. push 0
  2457. push ecx
  2458. push edx
  2459. call decode_number_or_symbol
  2460. add esp, 12
  2461. ;; Panic if it did not work
  2462. cmp eax, 0
  2463. je platform_panic
  2464. ;; Create a symbol if it did work
  2465. pop edx
  2466. mov eax, [esp+4]
  2467. push 0xffffffff
  2468. push edx
  2469. push eax
  2470. call add_symbol_wrapper
  2471. add esp, 12
  2472. ;; Return true
  2473. mov eax, 1
  2474. ret
  2475. process_equ_line_ret_false:
  2476. mov eax, 0
  2477. ret
  2478. global process_line
  2479. process_line:
  2480. ;; Find first space
  2481. mov eax, [esp+4]
  2482. push SPACE
  2483. push eax
  2484. call find_char
  2485. add esp, 8
  2486. ;; Select on whether we found it or not
  2487. cmp eax, 0xffffffff
  2488. je process_line_without_space
  2489. jmp process_line_with_space
  2490. process_line_with_space:
  2491. ;; Substitute the space with a terminator; leave opcode in edx and
  2492. ;; data in eax
  2493. mov edx, [esp+4]
  2494. add eax, edx
  2495. mov BYTE [eax], 0
  2496. add eax, 1
  2497. jmp process_line_process
  2498. process_line_without_space:
  2499. ;; Leave opcode in edx and set data (in eax) to an empty string
  2500. mov edx, [esp+4]
  2501. mov eax, str_empty
  2502. jmp process_line_process
  2503. process_line_process:
  2504. ;; Call all line processing functions
  2505. push eax
  2506. push edx
  2507. push eax
  2508. push edx
  2509. call process_directive_line
  2510. add esp, 8
  2511. cmp eax, 0
  2512. pop edx
  2513. pop eax
  2514. jne process_line_end
  2515. push eax
  2516. push edx
  2517. push eax
  2518. push edx
  2519. call process_bss_line
  2520. add esp, 8
  2521. cmp eax, 0
  2522. pop edx
  2523. pop eax
  2524. jne process_line_end
  2525. push eax
  2526. push edx
  2527. push eax
  2528. push edx
  2529. call process_text_line
  2530. add esp, 8
  2531. cmp eax, 0
  2532. pop edx
  2533. pop eax
  2534. jne process_line_end
  2535. push eax
  2536. push edx
  2537. push eax
  2538. push edx
  2539. call process_data_line
  2540. add esp, 8
  2541. cmp eax, 0
  2542. pop edx
  2543. pop eax
  2544. jne process_line_end
  2545. push eax
  2546. push edx
  2547. push eax
  2548. push edx
  2549. call process_equ_line
  2550. add esp, 8
  2551. cmp eax, 0
  2552. pop edx
  2553. pop eax
  2554. jne process_line_end
  2555. ;; Nothing matched, panic
  2556. call platform_panic
  2557. process_line_end:
  2558. ret
  2559. global init_assembler
  2560. init_assembler:
  2561. ;; Allocate input buffer
  2562. push INPUT_BUF_LEN
  2563. call platform_allocate
  2564. add esp, 4
  2565. mov ecx, input_buf_ptr
  2566. mov [ecx], eax
  2567. ret
  2568. global assemble
  2569. assemble:
  2570. push ebp
  2571. mov ebp, esp
  2572. push esi
  2573. push edi
  2574. push ebx
  2575. ;; Set fd for emit
  2576. mov eax, emit_fd
  2577. mov ecx, [ebp+12]
  2578. mov [eax], ecx
  2579. ;; Reset stage
  2580. mov eax, stage
  2581. mov DWORD [eax], 0
  2582. assemble_stage_loop:
  2583. ;; Check for termination
  2584. mov eax, stage
  2585. cmp DWORD [eax], 2
  2586. je assemble_end
  2587. ;; Call platform_reset_file
  2588. mov eax, [ebp+8]
  2589. push eax
  2590. call platform_reset_file
  2591. add esp, 4
  2592. ;; Reset line number (in esi) and current_loc
  2593. mov esi, 0
  2594. mov eax, current_loc
  2595. mov ecx, [ebp+16]
  2596. mov [eax], ecx
  2597. assemble_parse_loop:
  2598. ;; Call readline and store in ebx if we found the EOF
  2599. push INPUT_BUF_LEN
  2600. mov eax, input_buf_ptr
  2601. mov eax, [eax]
  2602. push eax
  2603. mov eax, [ebp+8]
  2604. push eax
  2605. call readline
  2606. add esp, 12
  2607. mov ebx, eax
  2608. ;; Log the line
  2609. ;; push str_decoding_line
  2610. ;; push 2
  2611. ;; call platform_log
  2612. ;; add esp, 8
  2613. ;; mov eax, input_buf_ptr
  2614. ;; mov eax, [eax]
  2615. ;; push eax
  2616. ;; push 2
  2617. ;; call platform_log
  2618. ;; add esp, 8
  2619. ;; push str_newline
  2620. ;; push 2
  2621. ;; call platform_log
  2622. ;; add esp, 8
  2623. ;; Find the first semicolon
  2624. push SEMICOLON
  2625. mov eax, input_buf_ptr
  2626. mov eax, [eax]
  2627. push eax
  2628. call find_char
  2629. add esp, 8
  2630. ;; If found, substitute it with a terminator
  2631. cmp eax, 0xffffffff
  2632. je assemble_parse_trim
  2633. mov ecx, input_buf_ptr
  2634. add eax, [ecx]
  2635. mov BYTE [eax], 0
  2636. assemble_parse_trim:
  2637. ;; Call trimstr
  2638. mov eax, input_buf_ptr
  2639. mov eax, [eax]
  2640. push eax
  2641. call trimstr
  2642. add esp, 4
  2643. ;; Compute line length and store it in edi
  2644. mov eax, input_buf_ptr
  2645. mov eax, [eax]
  2646. push eax
  2647. call strlen
  2648. add esp, 4
  2649. mov edi, eax
  2650. ;; If the line is not empty, pass to parsing it
  2651. cmp edi, 0
  2652. jne assemble_parse_detect_symbol
  2653. ;; If it is empty and we have finished, break
  2654. cmp ebx, 0
  2655. jne assemble_break_parse_loop
  2656. ;; If it is empty and we have not finished, continue
  2657. jmp assemble_continue_parse_loop
  2658. assemble_parse_detect_symbol:
  2659. ;; Detect if this line is a symbol declaration
  2660. mov eax, input_buf_ptr
  2661. mov eax, [eax]
  2662. add eax, edi
  2663. sub eax, 1
  2664. cmp BYTE [eax], COLON
  2665. jne assemble_parse_process
  2666. ;; Substitute the colon with a terminator
  2667. mov BYTE [eax], 0
  2668. ;; Call add_symbol_wrapper
  2669. push 0xffffffff
  2670. mov edx, current_loc
  2671. mov eax, [edx]
  2672. push eax
  2673. mov eax, input_buf_ptr
  2674. mov eax, [eax]
  2675. push eax
  2676. call add_symbol_wrapper
  2677. add esp, 12
  2678. jmp assemble_continue_parse_loop
  2679. assemble_parse_process:
  2680. ;; Call process_line
  2681. mov eax, input_buf_ptr
  2682. mov eax, [eax]
  2683. push eax
  2684. call process_line
  2685. add esp, 4
  2686. jmp assemble_continue_parse_loop
  2687. assemble_continue_parse_loop:
  2688. ;; Increment line number and restart parse loop
  2689. add esi, 1
  2690. jmp assemble_parse_loop
  2691. assemble_break_parse_loop:
  2692. ;; Increment stage
  2693. mov eax, stage
  2694. add DWORD [eax], 1
  2695. jmp assemble_stage_loop
  2696. assemble_end:
  2697. ;; Print processed line number
  2698. push str_ass_finished1
  2699. push 2
  2700. call platform_log
  2701. add esp, 8
  2702. push esi
  2703. call itoa
  2704. add esp, 4
  2705. push eax
  2706. push 2
  2707. call platform_log
  2708. add esp, 8
  2709. push str_ass_finished2
  2710. push 2
  2711. call platform_log
  2712. add esp, 8
  2713. ;; Print symbol number
  2714. push str_symb_num1
  2715. push 2
  2716. call platform_log
  2717. add esp, 8
  2718. mov ecx, symbol_num
  2719. mov eax, [ecx]
  2720. push eax
  2721. call itoa
  2722. add esp, 4
  2723. push eax
  2724. push 2
  2725. call platform_log
  2726. add esp, 8
  2727. push str_symb_num2
  2728. push 2
  2729. call platform_log
  2730. add esp, 8
  2731. pop ebx
  2732. pop edi
  2733. pop esi
  2734. pop ebp
  2735. ret