1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118 |
- ;; This file is part of asmc, a bootstrapping OS with minimal seed
- ;; Copyright (C) 2018 Giovanni Mascellani <gio@debian.org>
- ;; https://gitlab.com/giomasce/asmc
- ;; This program is free software: you can redistribute it and/or modify
- ;; it under the terms of the GNU General Public License as published by
- ;; the Free Software Foundation, either version 3 of the License, or
- ;; (at your option) any later version.
- ;; This program is distributed in the hope that it will be useful,
- ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;; GNU General Public License for more details.
- ;; You should have received a copy of the GNU General Public License
- ;; along with this program. If not, see <https://www.gnu.org/licenses/>.
- OP_PUSH equ 0
- OP_POP equ 1
- OP_ADD equ 2
- OP_SUB equ 3
- OP_MOV equ 4
- OP_CMP equ 5
- OP_AND equ 6
- OP_OR equ 7
- OP_JMP equ 8
- OP_CALL equ 9
- OP_JE equ 10
- OP_JNE equ 11
- OP_JA equ 12
- OP_JNA equ 13
- OP_JAE equ 14
- OP_JNAE equ 15
- OP_JB equ 16
- OP_JNB equ 17
- OP_JBE equ 18
- OP_JNBE equ 19
- OP_JG equ 20
- OP_JNG equ 21
- OP_JGE equ 22
- OP_JNGE equ 23
- OP_JL equ 24
- OP_JNL equ 25
- OP_JLE equ 26
- OP_JNLE equ 27
- OP_MUL equ 28
- OP_IMUL equ 29
- OP_INT equ 30
- OP_RET equ 31
- OP_IN equ 32
- OP_OUT equ 33
- OP_DIV equ 34
- OP_IDIV equ 35
- OP_NEG equ 36
- OP_NOT equ 37
- OP_XOR equ 38
- OP_TEST equ 39
- OP_HLT equ 40
- OP_RDPMC equ 41
- OP_RDMSR equ 42
- OP_WRMSR equ 43
- OP_CPUID equ 44
- OP_SHL equ 45
- OP_SHR equ 46
- OP_SAL equ 47
- OP_SAR equ 48
- section .data
- opcode_names:
- db 'push'
- db 0
- db 'pop'
- db 0
- db 'add'
- db 0
- db 'sub'
- db 0
- db 'mov'
- db 0
- db 'cmp'
- db 0
- db 'and'
- db 0
- db 'or'
- db 0
- db 'jmp'
- db 0
- db 'call'
- db 0
- db 'je'
- db 0
- db 'jne'
- db 0
- db 'ja'
- db 0
- db 'jna'
- db 0
- db 'jae'
- db 0
- db 'jnae'
- db 0
- db 'jb'
- db 0
- db 'jnb'
- db 0
- db 'jbe'
- db 0
- db 'jnbe'
- db 0
- db 'jg'
- db 0
- db 'jng'
- db 0
- db 'jge'
- db 0
- db 'jnge'
- db 0
- db 'jl'
- db 0
- db 'jnl'
- db 0
- db 'jle'
- db 0
- db 'jnle'
- db 0
- db 'mul'
- db 0
- db 'imul'
- db 0
- db 'int'
- db 0
- db 'ret'
- db 0
- db 'in'
- db 0
- db 'out'
- db 0
- db 'div'
- db 0
- db 'idiv'
- db 0
- db 'neg'
- db 0
- db 'not'
- db 0
- db 'xor'
- db 0
- db 'test'
- db 0
- db 'hlt'
- db 0
- db 'rdpmc'
- db 0
- db 'rdmsr'
- db 0
- db 'wrmsr'
- db 0
- db 'cpuid'
- db 0
- db 'shl'
- db 0
- db 'shr'
- db 0
- db 'sal'
- db 0
- db 'sar'
- db 0
- db 0
- opcode_funcs:
- dd process_push_like ; OP_PUSH
- dd process_push_like ; OP_POP
- dd process_add_like ; OP_ADD
- dd process_add_like ; OP_SUB
- dd process_add_like ; OP_MOV
- dd process_add_like ; OP_CMP
- dd process_add_like ; OP_AND
- dd process_add_like ; OP_OR
- dd process_jmp_like ; OP_JMP
- dd process_jmp_like ; OP_CALL
- dd process_jmp_like ; OP_JE
- dd process_jmp_like ; OP_JNE
- dd process_jmp_like ; OP_JA
- dd process_jmp_like ; OP_JNA
- dd process_jmp_like ; OP_JAE
- dd process_jmp_like ; OP_JNAE
- dd process_jmp_like ; OP_JB
- dd process_jmp_like ; OP_JNB
- dd process_jmp_like ; OP_JBE
- dd process_jmp_like ; OP_JNBE
- dd process_jmp_like ; OP_JG
- dd process_jmp_like ; OP_JNG
- dd process_jmp_like ; OP_JGE
- dd process_jmp_like ; OP_JNGE
- dd process_jmp_like ; OP_JL
- dd process_jmp_like ; OP_JNL
- dd process_jmp_like ; OP_JLE
- dd process_jmp_like ; OP_JNLE
- dd process_jmp_like ; OP_MUL
- dd process_jmp_like ; OP_IMUL
- dd process_int ; OP_INT
- dd process_ret_like ; OP_RET
- dd process_in_like ; OP_IN
- dd process_in_like ; OP_OUT
- dd process_jmp_like ; OP_DIV
- dd process_jmp_like ; OP_IDIV
- dd process_jmp_like ; OP_NEG
- dd process_jmp_like ; OP_NOT
- dd process_add_like ; OP_XOR
- dd process_add_like ; OP_TEST
- dd process_hlt ; OP_HLT
- dd process_ret_like ; OP_RDPMC
- dd process_ret_like ; OP_RDMSR
- dd process_ret_like ; OP_WRMSR
- dd process_ret_like ; OP_CPUID
- dd process_push_like ; OP_SHL
- dd process_push_like ; OP_SHR
- dd process_push_like ; OP_SAL
- dd process_push_like ; OP_SAR
- empty_opcode:
- dd 0xf0 ; OP_PUSH
- dd 0xf0 ; OP_POP
- dd 0xf0 ; OP_ADD
- dd 0xf0 ; OP_SUB
- dd 0xf0 ; OP_MOV
- dd 0xf0 ; OP_CMP
- dd 0xf0 ; OP_AND
- dd 0xf0 ; OP_OR
- dd 0xf0 ; OP_JMP
- dd 0xf0 ; OP_CALL
- dd 0xf0 ; OP_JE
- dd 0xf0 ; OP_JNE
- dd 0xf0 ; OP_JA
- dd 0xf0 ; OP_JNA
- dd 0xf0 ; OP_JAE
- dd 0xf0 ; OP_JNAE
- dd 0xf0 ; OP_JB
- dd 0xf0 ; OP_JNB
- dd 0xf0 ; OP_JBE
- dd 0xf0 ; OP_JNBE
- dd 0xf0 ; OP_JG
- dd 0xf0 ; OP_JNG
- dd 0xf0 ; OP_JGE
- dd 0xf0 ; OP_JNGE
- dd 0xf0 ; OP_JL
- dd 0xf0 ; OP_JNL
- dd 0xf0 ; OP_JLE
- dd 0xf0 ; OP_JNLE
- dd 0xf0 ; OP_MUL
- dd 0xf0 ; OP_IMUL
- dd 0xf0 ; OP_INT
- dd 0xc3 ; OP_RET
- dd 0xf0 ; OP_IN
- dd 0xf0 ; OP_OUT
- dd 0xf0 ; OP_DIV
- dd 0xf0 ; OP_IDIV
- dd 0xf0 ; OP_NEG
- dd 0xf0 ; OP_NOT
- dd 0xf0 ; OP_XOR
- dd 0xf0 ; OP_TEST
- dd 0xf0 ; OP_HLT
- dd 0x1330f ; OP_RDPMC
- dd 0x1320f ; OP_RDMSR
- dd 0x1300f ; OP_WRMSR
- dd 0x1a20f ; OP_CPUID
- dd 0xf0 ; OP_SHL
- dd 0xf0 ; OP_SHR
- dd 0xf0 ; OP_SAL
- dd 0xf0 ; OP_SAR
- rm32_opcode:
- dd 0x06ff ; OP_PUSH
- dd 0x008f ; OP_POP
- dd 0xf0 ; OP_ADD
- dd 0xf0 ; OP_SUB
- dd 0xf0 ; OP_MOV
- dd 0xf0 ; OP_CMP
- dd 0xf0 ; OP_AND
- dd 0xf0 ; OP_OR
- dd 0x04ff ; OP_JMP
- dd 0x02ff ; OP_CALL
- dd 0xf0 ; OP_JE
- dd 0xf0 ; OP_JNE
- dd 0xf0 ; OP_JA
- dd 0xf0 ; OP_JNA
- dd 0xf0 ; OP_JAE
- dd 0xf0 ; OP_JNAE
- dd 0xf0 ; OP_JB
- dd 0xf0 ; OP_JNB
- dd 0xf0 ; OP_JBE
- dd 0xf0 ; OP_JNBE
- dd 0xf0 ; OP_JG
- dd 0xf0 ; OP_JNG
- dd 0xf0 ; OP_JGE
- dd 0xf0 ; OP_JNGE
- dd 0xf0 ; OP_JL
- dd 0xf0 ; OP_JNL
- dd 0xf0 ; OP_JLE
- dd 0xf0 ; OP_JNLE
- dd 0x04f7 ; OP_MUL
- dd 0x05f7 ; OP_IMUL
- dd 0xf0 ; OP_INT
- dd 0xf0 ; OP_RET
- dd 0xf0 ; OP_IN
- dd 0xf0 ; OP_OUT
- dd 0x06f7 ; OP_DIV
- dd 0x07f7 ; OP_IDIV
- dd 0x03f7 ; OP_NEG
- dd 0x02f7 ; OP_NOT
- dd 0xf0 ; OP_XOR
- dd 0xf0 ; OP_TEST
- dd 0xf0 ; OP_HLT
- dd 0xf0 ; OP_RDPMC
- dd 0xf0 ; OP_RDMSR
- dd 0xf0 ; OP_WRMSR
- dd 0xf0 ; OP_CPUID
- dd 0x04d3 ; OP_SHL
- dd 0x05d3 ; OP_SHR
- dd 0x04d3 ; OP_SAL
- dd 0x07d3 ; OP_SAR
- imm32_opcode:
- dd 0xf0 ; OP_PUSH
- dd 0xf0 ; OP_POP
- dd 0xf0 ; OP_ADD
- dd 0xf0 ; OP_SUB
- dd 0xf0 ; OP_MOV
- dd 0xf0 ; OP_CMP
- dd 0xf0 ; OP_AND
- dd 0xf0 ; OP_OR
- dd 0xe9 ; OP_JMP
- dd 0xe8 ; OP_CALL
- dd 0x1840f ; OP_JE
- dd 0x1850f ; OP_JNE
- dd 0x1870f ; OP_JA
- dd 0x1860f ; OP_JNA
- dd 0x1830f ; OP_JAE
- dd 0x1820f ; OP_JNAE
- dd 0x1820f ; OP_JB
- dd 0x1830f ; OP_JNB
- dd 0x1860f ; OP_JBE
- dd 0x1870f ; OP_JNBE
- dd 0x18f0f ; OP_JG
- dd 0x18e0f ; OP_JNG
- dd 0x18d0f ; OP_JGE
- dd 0x18c0f ; OP_JNGE
- dd 0x18c0f ; OP_JL
- dd 0x18d0f ; OP_JNL
- dd 0x18e0f ; OP_JLE
- dd 0x18f0f ; OP_JNLE
- dd 0xf0 ; OP_MUL
- dd 0xf0 ; OP_IMUL
- dd 0xf0 ; OP_INT
- dd 0xf0 ; OP_RET
- dd 0xf0 ; OP_IN
- dd 0xf0 ; OP_OUT
- dd 0xf0 ; OP_DIV
- dd 0xf0 ; OP_IDIV
- dd 0xf0 ; OP_NEG
- dd 0xf0 ; OP_NOT
- dd 0xf0 ; OP_XOR
- dd 0xf0 ; OP_TEST
- dd 0xf0 ; OP_HLT
- dd 0xf0 ; OP_RDPMC
- dd 0xf0 ; OP_RDMSR
- dd 0xf0 ; OP_WRMSR
- dd 0xf0 ; OP_CPUID
- dd 0xf0 ; OP_SHL
- dd 0xf0 ; OP_SHR
- dd 0xf0 ; OP_SAL
- dd 0xf0 ; OP_SAR
- r8rm8_opcode:
- dd 0xf0 ; OP_PUSH
- dd 0xf0 ; OP_POP
- dd 0x02 ; OP_ADD
- dd 0x2a ; OP_SUB
- dd 0x8a ; OP_MOV
- dd 0x3a ; OP_CMP
- dd 0x22 ; OP_AND
- dd 0x0a ; OP_OR
- dd 0xf0 ; OP_JMP
- dd 0xf0 ; OP_CALL
- dd 0xf0 ; OP_JE
- dd 0xf0 ; OP_JNE
- dd 0xf0 ; OP_JA
- dd 0xf0 ; OP_JNA
- dd 0xf0 ; OP_JAE
- dd 0xf0 ; OP_JNAE
- dd 0xf0 ; OP_JB
- dd 0xf0 ; OP_JNB
- dd 0xf0 ; OP_JBE
- dd 0xf0 ; OP_JNBE
- dd 0xf0 ; OP_JG
- dd 0xf0 ; OP_JNG
- dd 0xf0 ; OP_JGE
- dd 0xf0 ; OP_JNGE
- dd 0xf0 ; OP_JL
- dd 0xf0 ; OP_JNL
- dd 0xf0 ; OP_JLE
- dd 0xf0 ; OP_JNLE
- dd 0xf0 ; OP_MUL
- dd 0xf0 ; OP_IMUL
- dd 0xf0 ; OP_INT
- dd 0xf0 ; OP_RET
- dd 0xf0 ; OP_IN
- dd 0xf0 ; OP_OUT
- dd 0xf0 ; OP_DIV
- dd 0xf0 ; OP_IDIV
- dd 0xf0 ; OP_NEG
- dd 0xf0 ; OP_NOT
- dd 0x32 ; OP_XOR
- dd 0x84 ; OP_TEST
- dd 0xf0 ; OP_HLT
- dd 0xf0 ; OP_RDPMC
- dd 0xf0 ; OP_RDMSR
- dd 0xf0 ; OP_WRMSR
- dd 0xf0 ; OP_CPUID
- dd 0xf0 ; OP_SHL
- dd 0xf0 ; OP_SHR
- dd 0xf0 ; OP_SAL
- dd 0xf0 ; OP_SAR
- r32rm32_opcode:
- dd 0xf0 ; OP_PUSH
- dd 0xf0 ; OP_POP
- dd 0x03 ; OP_ADD
- dd 0x2b ; OP_SUB
- dd 0x8b ; OP_MOV
- dd 0x3b ; OP_CMP
- dd 0x23 ; OP_AND
- dd 0x0b ; OP_OR
- dd 0xf0 ; OP_JMP
- dd 0xf0 ; OP_CALL
- dd 0xf0 ; OP_JE
- dd 0xf0 ; OP_JNE
- dd 0xf0 ; OP_JA
- dd 0xf0 ; OP_JNA
- dd 0xf0 ; OP_JAE
- dd 0xf0 ; OP_JNAE
- dd 0xf0 ; OP_JB
- dd 0xf0 ; OP_JNB
- dd 0xf0 ; OP_JBE
- dd 0xf0 ; OP_JNBE
- dd 0xf0 ; OP_JG
- dd 0xf0 ; OP_JNG
- dd 0xf0 ; OP_JGE
- dd 0xf0 ; OP_JNGE
- dd 0xf0 ; OP_JL
- dd 0xf0 ; OP_JNL
- dd 0xf0 ; OP_JLE
- dd 0xf0 ; OP_JNLE
- dd 0xf0 ; OP_MUL
- dd 0xf0 ; OP_IMUL
- dd 0xf0 ; OP_INT
- dd 0xf0 ; OP_RET
- dd 0xf0 ; OP_IN
- dd 0xf0 ; OP_OUT
- dd 0xf0 ; OP_DIV
- dd 0xf0 ; OP_IDIV
- dd 0xf0 ; OP_NEG
- dd 0xf0 ; OP_NOT
- dd 0x33 ; OP_XOR
- dd 0x85 ; OP_TEST
- dd 0xf0 ; OP_HLT
- dd 0xf0 ; OP_RDPMC
- dd 0xf0 ; OP_RDMSR
- dd 0xf0 ; OP_WRMSR
- dd 0xf0 ; OP_CPUID
- dd 0xf0 ; OP_SHL
- dd 0xf0 ; OP_SHR
- dd 0xf0 ; OP_SAL
- dd 0xf0 ; OP_SAR
- rm8r8_opcode:
- dd 0xf0 ; OP_PUSH
- dd 0xf0 ; OP_POP
- dd 0x00 ; OP_ADD
- dd 0x28 ; OP_SUB
- dd 0x88 ; OP_MOV
- dd 0x38 ; OP_CMP
- dd 0x20 ; OP_AND
- dd 0x08 ; OP_OR
- dd 0xf0 ; OP_JMP
- dd 0xf0 ; OP_CALL
- dd 0xf0 ; OP_JE
- dd 0xf0 ; OP_JNE
- dd 0xf0 ; OP_JA
- dd 0xf0 ; OP_JNA
- dd 0xf0 ; OP_JAE
- dd 0xf0 ; OP_JNAE
- dd 0xf0 ; OP_JB
- dd 0xf0 ; OP_JNB
- dd 0xf0 ; OP_JBE
- dd 0xf0 ; OP_JNBE
- dd 0xf0 ; OP_JG
- dd 0xf0 ; OP_JNG
- dd 0xf0 ; OP_JGE
- dd 0xf0 ; OP_JNGE
- dd 0xf0 ; OP_JL
- dd 0xf0 ; OP_JNL
- dd 0xf0 ; OP_JLE
- dd 0xf0 ; OP_JNLE
- dd 0xf0 ; OP_MUL
- dd 0xf0 ; OP_IMUL
- dd 0xf0 ; OP_INT
- dd 0xf0 ; OP_RET
- dd 0xf0 ; OP_IN
- dd 0xf0 ; OP_OUT
- dd 0xf0 ; OP_DIV
- dd 0xf0 ; OP_IDIV
- dd 0xf0 ; OP_NEG
- dd 0xf0 ; OP_NOT
- dd 0x30 ; OP_XOR
- dd 0x84 ; OP_TEST
- dd 0xf0 ; OP_HLT
- dd 0xf0 ; OP_RDPMC
- dd 0xf0 ; OP_RDMSR
- dd 0xf0 ; OP_WRMSR
- dd 0xf0 ; OP_CPUID
- dd 0xf0 ; OP_SHL
- dd 0xf0 ; OP_SHR
- dd 0xf0 ; OP_SAL
- dd 0xf0 ; OP_SAR
- rm32r32_opcode:
- dd 0xf0 ; OP_PUSH
- dd 0xf0 ; OP_POP
- dd 0x01 ; OP_ADD
- dd 0x29 ; OP_SUB
- dd 0x89 ; OP_MOV
- dd 0x39 ; OP_CMP
- dd 0x21 ; OP_AND
- dd 0x09 ; OP_OR
- dd 0xf0 ; OP_JMP
- dd 0xf0 ; OP_CALL
- dd 0xf0 ; OP_JE
- dd 0xf0 ; OP_JNE
- dd 0xf0 ; OP_JA
- dd 0xf0 ; OP_JNA
- dd 0xf0 ; OP_JAE
- dd 0xf0 ; OP_JNAE
- dd 0xf0 ; OP_JB
- dd 0xf0 ; OP_JNB
- dd 0xf0 ; OP_JBE
- dd 0xf0 ; OP_JNBE
- dd 0xf0 ; OP_JG
- dd 0xf0 ; OP_JNG
- dd 0xf0 ; OP_JGE
- dd 0xf0 ; OP_JNGE
- dd 0xf0 ; OP_JL
- dd 0xf0 ; OP_JNL
- dd 0xf0 ; OP_JLE
- dd 0xf0 ; OP_JNLE
- dd 0xf0 ; OP_MUL
- dd 0xf0 ; OP_IMUL
- dd 0xf0 ; OP_INT
- dd 0xf0 ; OP_RET
- dd 0xf0 ; OP_IN
- dd 0xf0 ; OP_OUT
- dd 0xf0 ; OP_DIV
- dd 0xf0 ; OP_IDIV
- dd 0xf0 ; OP_NEG
- dd 0xf0 ; OP_NOT
- dd 0x31 ; OP_XOR
- dd 0x85 ; OP_TEST
- dd 0xf0 ; OP_HLT
- dd 0xf0 ; OP_RDPMC
- dd 0xf0 ; OP_RDMSR
- dd 0xf0 ; OP_WRMSR
- dd 0xf0 ; OP_CPUID
- dd 0xf0 ; OP_SHL
- dd 0xf0 ; OP_SHR
- dd 0xf0 ; OP_SAL
- dd 0xf0 ; OP_SAR
- rm8imm8_opcode:
- dd 0xf0 ; OP_PUSH
- dd 0xf0 ; OP_POP
- dd 0x0080 ; OP_ADD
- dd 0x0580 ; OP_SUB
- dd 0x00c6 ; OP_MOV
- dd 0x0780 ; OP_CMP
- dd 0x0480 ; OP_AND
- dd 0x0180 ; OP_OR
- dd 0xf0 ; OP_JMP
- dd 0xf0 ; OP_CALL
- dd 0xf0 ; OP_JE
- dd 0xf0 ; OP_JNE
- dd 0xf0 ; OP_JA
- dd 0xf0 ; OP_JNA
- dd 0xf0 ; OP_JAE
- dd 0xf0 ; OP_JNAE
- dd 0xf0 ; OP_JB
- dd 0xf0 ; OP_JNB
- dd 0xf0 ; OP_JBE
- dd 0xf0 ; OP_JNBE
- dd 0xf0 ; OP_JG
- dd 0xf0 ; OP_JNG
- dd 0xf0 ; OP_JGE
- dd 0xf0 ; OP_JNGE
- dd 0xf0 ; OP_JL
- dd 0xf0 ; OP_JNL
- dd 0xf0 ; OP_JLE
- dd 0xf0 ; OP_JNLE
- dd 0xf0 ; OP_MUL
- dd 0xf0 ; OP_IMUL
- dd 0xf0 ; OP_INT
- dd 0xf0 ; OP_RET
- dd 0xf0 ; OP_IN
- dd 0xf0 ; OP_OUT
- dd 0xf0 ; OP_DIV
- dd 0xf0 ; OP_IDIV
- dd 0xf0 ; OP_NEG
- dd 0xf0 ; OP_NOT
- dd 0x0680 ; OP_XOR
- dd 0x00f6 ; OP_TEST
- dd 0xf0 ; OP_HLT
- dd 0xf0 ; OP_RDPMC
- dd 0xf0 ; OP_RDMSR
- dd 0xf0 ; OP_WRMSR
- dd 0xf0 ; OP_CPUID
- dd 0xf0 ; OP_SHL
- dd 0xf0 ; OP_SHR
- dd 0xf0 ; OP_SAL
- dd 0xf0 ; OP_SAR
- rm32imm32_opcode:
- dd 0xf0 ; OP_PUSH
- dd 0xf0 ; OP_POP
- dd 0x0081 ; OP_ADD
- dd 0x0581 ; OP_SUB
- dd 0x00c7 ; OP_MOV
- dd 0x0781 ; OP_CMP
- dd 0x0481 ; OP_AND
- dd 0x0181 ; OP_OR
- dd 0xf0 ; OP_JMP
- dd 0xf0 ; OP_CALL
- dd 0xf0 ; OP_JE
- dd 0xf0 ; OP_JNE
- dd 0xf0 ; OP_JA
- dd 0xf0 ; OP_JNA
- dd 0xf0 ; OP_JAE
- dd 0xf0 ; OP_JNAE
- dd 0xf0 ; OP_JB
- dd 0xf0 ; OP_JNB
- dd 0xf0 ; OP_JBE
- dd 0xf0 ; OP_JNBE
- dd 0xf0 ; OP_JG
- dd 0xf0 ; OP_JNG
- dd 0xf0 ; OP_JGE
- dd 0xf0 ; OP_JNGE
- dd 0xf0 ; OP_JL
- dd 0xf0 ; OP_JNL
- dd 0xf0 ; OP_JLE
- dd 0xf0 ; OP_JNLE
- dd 0xf0 ; OP_MUL
- dd 0xf0 ; OP_IMUL
- dd 0xf0 ; OP_INT
- dd 0xf0 ; OP_RET
- dd 0xf0 ; OP_IN
- dd 0xf0 ; OP_OUT
- dd 0xf0 ; OP_DIV
- dd 0xf0 ; OP_IDIV
- dd 0xf0 ; OP_NEG
- dd 0xf0 ; OP_NOT
- dd 0x0681 ; OP_XOR
- dd 0x00f7 ; OP_TEST
- dd 0xf0 ; OP_HLT
- dd 0xf0 ; OP_RDPMC
- dd 0xf0 ; OP_RDMSR
- dd 0xf0 ; OP_WRMSR
- dd 0xf0 ; OP_CPUID
- dd 0xf0 ; OP_SHL
- dd 0xf0 ; OP_SHR
- dd 0xf0 ; OP_SAL
- dd 0xf0 ; OP_SAR
- reg_eax:
- db 'eax'
- db 0
- reg_ecx:
- db 'ecx'
- db 0
- reg_edx:
- db 'edx'
- db 0
- reg_ebx:
- db 'ebx'
- db 0
- reg_esp:
- db 'esp'
- db 0
- reg_ebp:
- db 'ebp'
- db 0
- reg_esi:
- db 'esi'
- db 0
- reg_edi:
- db 'edi'
- db 0
- reg_al:
- db 'al'
- db 0
- reg_cl:
- db 'cl'
- db 0
- reg_dl:
- db 'dl'
- db 0
- reg_bl:
- db 'bl'
- db 0
- reg_ah:
- db 'ah'
- db 0
- reg_ch:
- db 'ch'
- db 0
- reg_dh:
- db 'dh'
- db 0
- reg_bh:
- db 'bh'
- db 0
- reg_ax:
- db 'ax'
- db 0
- reg_dx:
- db 'dx'
- db 0
- str_BYTE:
- db 'BYTE'
- db 0
- str_DWORD:
- db 'DWORD'
- db 0
- str_resb:
- db 'resb'
- db 0
- str_resd:
- db 'resd'
- db 0
- str_dd:
- db 'dd'
- db 0
- str_db:
- db 'db'
- db 0
- str_section:
- db 'section'
- db 0
- str_org:
- db 'org'
- db 0
- str_bits:
- db 'bits'
- db 0
- str_global:
- db 'global'
- db 0
- str_align:
- db 'align'
- db 0
- str_extern:
- db 'extern'
- db 0
- str_equ:
- db 'equ'
- db 0
- str_decoding_line:
- db 'Decoding line: '
- db 0
- str_empty:
- db 0
- str_ass_finished1:
- db 'Finished assembling a file with '
- db 0
- str_ass_finished2:
- db ' lines!'
- db NEWLINE
- db 0
- str_symb_num1:
- db 'There are now '
- db 0
- str_symb_num2:
- db ' known symbols.'
- db NEWLINE
- db 0
- section .bss
- input_buf_ptr:
- resd 1
- section .text
- global get_input_buf
- get_input_buf:
- mov eax, input_buf_ptr
- mov eax, [eax]
- ret
- global get_opcode_names
- get_opcode_names:
- mov eax, opcode_names
- ret
- global get_opcode_funcs
- get_opcode_funcs:
- mov eax, opcode_funcs
- ret
- global get_rm32_opcode
- get_rm32_opcode:
- mov eax, rm32_opcode
- ret
- global get_imm32_opcode
- get_imm32_opcode:
- mov eax, imm32_opcode
- ret
- global get_rm8r8_opcode
- get_rm8r8_opcode:
- mov eax, rm8r8_opcode
- ret
- global get_rm32r32_opcode
- get_rm32r32_opcode:
- mov eax, rm32r32_opcode
- ret
- global get_r8rm8_opcode
- get_r8rm8_opcode:
- mov eax, r8rm8_opcode
- ret
- global get_r32rm32_opcode
- get_r32rm32_opcode:
- mov eax, r32rm32_opcode
- ret
- global get_rm8imm8_opcode
- get_rm8imm8_opcode:
- mov eax, rm8imm8_opcode
- ret
- global get_rm32imm32_opcode
- get_rm32imm32_opcode:
- mov eax, rm32imm32_opcode
- ret
- global assert
- assert:
- cmp DWORD [esp+4], 0
- jne assert_return
- call platform_panic
- assert_return:
- ret
- global readline
- readline:
- push ebp
- mov ebp, esp
- readline_begin_loop:
- ;; If len is zero, jump to panic
- cmp DWORD [ebp+16], 0
- je platform_panic
- ;; Call platform_read_char
- mov ecx, [ebp+8]
- push ecx
- call platform_read_char
- add esp, 4
- ;; Store the buffer address in edx
- mov edx, [ebp+12]
- ;; Handle newline and eof
- cmp eax, NEWLINE
- je readline_newline_found
- cmp eax, 0xffffffff
- je readline_eof_found
- ;; Copy a byte
- mov [edx], al
- ;; Increment the buffer and decrement the length
- add edx, 1
- mov [ebp+12], edx
- mov ecx, [ebp+16]
- sub ecx, 1
- mov [ebp+16], ecx
- jmp readline_begin_loop
- ;; On newline, store the string terminator and return 0
- readline_newline_found:
- mov BYTE [edx], 0
- mov eax, 0
- jmp readline_ret
- ;; On eof, store the string terminator and return 1
- readline_eof_found:
- mov BYTE [edx], 0
- mov eax, 1
- jmp readline_ret
- readline_ret:
- pop ebp
- ret
- global trimstr
- trimstr:
- ;; Load registers (eax for writing, ecx for reading)
- mov eax, [esp+4]
- mov ecx, eax
- ;; Skip the initial whitespace
- trimstr_skip_initial:
- cmp BYTE [ecx], SPACE
- je trimstr_initial_white
- cmp BYTE [ecx], TAB
- je trimstr_initial_white
- jmp trimstr_copy_loop
- trimstr_initial_white:
- add ecx, 1
- jmp trimstr_skip_initial
- ;; Copy until the string terminator
- trimstr_copy_loop:
- cmp BYTE [ecx], 0
- mov dl, [ecx]
- mov [eax], dl
- je trimstr_trim_end
- add ecx, 1
- add eax, 1
- jmp trimstr_copy_loop
- ;; Replace the final whitespace with terminators
- trimstr_trim_end:
- sub eax, 1
- trimstr_trim_loop2:
- cmp eax, [esp+4]
- jb trimstr_ret
- cmp BYTE [eax], SPACE
- je trimstr_final_white
- cmp BYTE [eax], TAB
- je trimstr_final_white
- jmp trimstr_ret
- trimstr_final_white:
- mov BYTE [eax], 0
- sub eax, 1
- jmp trimstr_trim_loop2
- trimstr_ret:
- ret
- global remove_spaces
- remove_spaces:
- ;; Load registers (eax for writing, ecx for reading)
- mov eax, [esp+4]
- mov ecx, eax
- ;; Main loop
- remove_spaces_loop:
- ;; Copy the byte and, if found terminator, stop
- cmp BYTE [ecx], 0
- mov dl, [ecx]
- mov [eax], dl
- je remove_spaces_ret
- ;; Advance the read pointer; advance the write pointer only if we
- ;; did not found whitespace
- add ecx, 1
- cmp dl, SPACE
- je remove_spaces_loop
- cmp dl, TAB
- je remove_spaces_loop
- add eax, 1
- jmp remove_spaces_loop
- remove_spaces_ret:
- ret
- global isstrpref
- isstrpref:
- ;; Load registers
- mov eax, [esp+4]
- mov ecx, [esp+8]
- isstrpref_loop:
- ;; If the first string is finished, then return 1
- mov dl, [eax]
- cmp dl, 0
- jne isstrpref_after_cmp1
- mov eax, 1
- ret
- isstrpref_after_cmp1:
- ;; If the characters do not match, return 0
- cmp dl, [ecx]
- je isstrpref_after_cmp2
- mov eax, 0
- ret
- isstrpref_after_cmp2:
- ;; Increment both pointers and restart
- add eax, 1
- add ecx, 1
- jmp isstrpref_loop
- global decode_reg32
- decode_reg32:
- ;; Save and load registers
- push ebx
- mov ebx, [esp+8]
- push esi
- ;; Compare the argument with each possible register name
- mov esi, 0
- push reg_eax
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg32_ret
- mov esi, 1
- push reg_ecx
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg32_ret
- mov esi, 2
- push reg_edx
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg32_ret
- mov esi, 3
- push reg_ebx
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg32_ret
- mov esi, 4
- push reg_esp
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg32_ret
- mov esi, 5
- push reg_ebp
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg32_ret
- mov esi, 6
- push reg_esi
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg32_ret
- mov esi, 7
- push reg_edi
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg32_ret
- ;; Return -1 if none matched
- mov esi, 0xffffffff
- decode_reg32_ret:
- mov eax, esi
- pop esi
- pop ebx
- ret
- global decode_reg8
- decode_reg8:
- ;; Save and load registers
- push ebx
- mov ebx, [esp+8]
- push esi
- ;; Compare the argument with each possible register name
- mov esi, 0
- push reg_al
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg8_ret
- mov esi, 1
- push reg_cl
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg8_ret
- mov esi, 2
- push reg_dl
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg8_ret
- mov esi, 3
- push reg_bl
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg8_ret
- mov esi, 4
- push reg_ah
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg8_ret
- mov esi, 5
- push reg_ch
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg8_ret
- mov esi, 6
- push reg_dh
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg8_ret
- mov esi, 7
- push reg_bh
- push ebx
- call strcmp
- add esp, 8
- cmp eax, 0
- je decode_reg8_ret
- ;; Return -1 if none matched
- mov esi, 0xffffffff
- decode_reg8_ret:
- mov eax, esi
- pop esi
- pop ebx
- ret
- global decode_number_or_symbol
- decode_number_or_symbol:
- push ebp
- mov ebp, esp
- ;; Call decode_number
- mov eax, [ebp+12]
- push eax
- mov eax, [ebp+8]
- push eax
- call decode_number
- add esp, 8
- ;; If decode_number succeded, return 1
- cmp eax, 1
- jne decode_number_or_symbol_after_number
- jmp decode_number_or_symbol_ret
- decode_number_or_symbol_after_number:
- ;; Branch to appropriate stage (in particular, if third argument is
- ;; true assume stage 1)
- mov edx, stage
- mov eax, [edx]
- cmp eax, 1
- je decode_number_or_symbol_stage1
- cmp DWORD [ebp+16], 0
- jne decode_number_or_symbol_stage1
- cmp eax, 0
- je decode_number_or_symbol_stage0
- jmp platform_panic
- decode_number_or_symbol_stage0:
- ;; Set the number to placeholder 0 and return 1
- mov eax, [ebp+12]
- mov DWORD [eax], 0
- mov eax, 1
- jmp decode_number_or_symbol_ret
- decode_number_or_symbol_stage1:
- ;; Call find_symbol and return what it returns
- push 0
- push DWORD [ebp+12]
- push DWORD [ebp+8]
- call find_symbol
- add esp, 12
- jmp decode_number_or_symbol_ret
- decode_number_or_symbol_ret:
- pop ebp
- ret
- global decode_operand
- decode_operand:
- push ebp
- mov ebp, esp
- push ebx
- push esi
- ;; Use ebx for the input string
- mov ebx, [ebp+8]
- ;; Call remove_spaces
- push ebx
- call remove_spaces
- add esp, 4
- ;; Use cl and ch to remember if we found 8 or 32 bits code
- mov ecx, 0
- ;; Search for BYTE prefix
- push ecx
- push ebx
- push str_BYTE
- call isstrpref
- add esp, 8
- pop ecx
- cmp eax, 0
- je decode_operand_after_byte_search
- add ebx, 4
- mov cl, 1
- ;; Search for DWORD prefix
- decode_operand_after_byte_search:
- push ecx
- push ebx
- push str_DWORD
- call isstrpref
- add esp, 8
- pop ecx
- cmp eax, 0
- je decode_operand_after_dword_search
- add ebx, 5
- mov ch, 1
- ;; Check that at most one prefix was found
- decode_operand_after_dword_search:
- mov dl, cl
- and dl, ch
- cmp dl, 0
- jne platform_panic
- ;; Check whether the operand is direct or indirect
- cmp BYTE [ebx], SQ_OPEN
- jne decode_operand_direct
- ;; Indirect operand: mark as such and consume character
- mov edx, [ebp+12]
- mov DWORD [edx], 0
- add ebx, 1
- ;; In this branch cl and ch are not used, so we can save them in the
- ;; caller space and then recycle the register
- mov edx, [ebp+24]
- mov DWORD [edx], 0
- mov [edx], cl
- mov edx, [ebp+28]
- mov DWORD [edx], 0
- mov [edx], ch
- ;; Search for the plus
- push PLUS
- push ebx
- call find_char
- add esp, 8
- cmp eax, 0xffffffff
- jne decode_operand_have_plus
- ;; There is no plus, so the displacement is zero
- mov edx, [ebp+20]
- mov DWORD [edx], 0
- ;; Search for the closed bracket
- push SQ_CLOSED
- push ebx
- call find_char
- add esp, 8
- cmp eax, 0xffffffff
- je decode_operand_ret_false
- ;; Check that the following character is a terminator
- mov ecx, ebx
- add ecx, eax
- cmp BYTE [ecx+1], 0
- jne decode_operand_ret_false
- ;; Overwrite the closed bracket with a terminator and recognize the
- ;; register name (which must be a 32 bits register)
- mov BYTE [ecx], 0
- push ebx
- call decode_reg32
- add esp, 4
- ;; Save its value in the caller space and return appropriately
- mov edx, [ebp+16]
- mov [edx], eax
- cmp eax, 0xffffffff
- je decode_operand_ret_false
- jmp decode_operand_ret_true
- decode_operand_have_plus:
- ;; Overwrite the plus with a terminator and recognize the register
- ;; name
- mov esi, ebx
- add esi, eax
- mov BYTE [esi], 0
- push ebx
- call decode_reg32
- add esp, 4
- ;; Save the register in the caller space and return 0 if it failed
- mov edx, [ebp+16]
- mov [edx], eax
- cmp eax, 0xffffffff
- je decode_operand_ret_false
- ;; Search for the closed bracket
- mov ebx, esi
- add ebx, 1
- push SQ_CLOSED
- push ebx
- call find_char
- add esp, 8
- cmp eax, 0xffffffff
- je decode_operand_ret_false
- ;; Check that the following character is a terminator
- mov ecx, ebx
- add ecx, eax
- cmp BYTE [ecx+1], 0
- jne decode_operand_ret_false
- ;; Overwrite the closed bracket with a terminator and recognized the
- ;; displacement
- mov BYTE [ecx], 0
- push 0
- mov eax, DWORD [ebp+20]
- push eax
- push ebx
- call decode_number_or_symbol
- add esp, 12
- jmp decode_operand_ret
- decode_operand_direct:
- ;; Direct operand: save this fact in the caller space
- mov edx, [ebp+12]
- mov DWORD [edx], 1
- ;; No prefix should have been found in this case
- cmp ecx, 0
- jne decode_operand_ret_false
- ;; Try to recognized the operand as a 32 bits register
- push ebx
- call decode_reg32
- add esp, 4
- cmp eax, 0xffffffff
- je decode_operand_8bit
- ;; Save the register in the caller space
- mov edx, [ebp+16]
- mov [edx], eax
- ;; Save the detected size in the caller space
- mov edx, [ebp+24]
- mov DWORD [edx], 0
- mov edx, [ebp+28]
- mov DWORD [edx], 1
- jmp decode_operand_ret_true
- decode_operand_8bit:
- ;; Try to recognize the operand as a 8 bits register
- push ebx
- call decode_reg8
- add esp, 4
- cmp eax, 0xffffffff
- je decode_operand_ret_false
- ;; Save the register in the caller space
- mov edx, [ebp+16]
- mov [edx], eax
- ;; Save the detected size in the caller space
- mov edx, [ebp+24]
- mov DWORD [edx], 1
- mov edx, [ebp+28]
- mov DWORD [edx], 0
- jmp decode_operand_ret_true
- decode_operand_ret_true:
- mov eax, 1
- jmp decode_operand_ret
- decode_operand_ret_false:
- mov eax, 0
- jmp decode_operand_ret
- decode_operand_ret:
- pop esi
- pop ebx
- pop ebp
- ret
- global process_bss_line
- process_bss_line:
- ;; Check if the opcode is resb
- mov edx, [esp+4]
- push str_resb
- push edx
- call strcmp
- add esp, 8
- cmp eax, 0
- je process_bss_line_resb
- ;; Check is the opcode is resd
- mov edx, [esp+4]
- push str_resd
- push edx
- call strcmp
- add esp, 8
- cmp eax, 0
- je process_bss_line_resd
- mov eax, 0
- ret
- process_bss_line_resb:
- ;; Save the argument before we mess up with the stack
- mov edx, [esp+8]
- ;; Push 0 to allocate a local variable and take its address
- push 0
- mov ecx, esp
- ;; Call decode_number_or_symbol
- push 1
- push ecx
- push edx
- call decode_number_or_symbol
- add esp, 12
- ;; Deallocate the temporary variable and save it in ecx
- pop ecx
- cmp eax, 0
- je platform_panic
- process_bss_line_resb_loop:
- ;; Loop ecx times calling emit(0) at each loop
- cmp ecx, 0
- je process_bss_line_ret
- sub ecx, 1
- push ecx
- push 0
- call emit
- add esp, 4
- pop ecx
- jmp process_bss_line_resb_loop
- ;; Everything as above, but with emit32 instead of emit
- process_bss_line_resd:
- mov edx, [esp+8]
- push 0
- mov ecx, esp
- push 1
- push ecx
- push edx
- call decode_number_or_symbol
- add esp, 12
- pop ecx
- cmp eax, 0
- je platform_panic
- process_bss_line_resd_loop:
- cmp ecx, 0
- je process_bss_line_ret
- sub ecx, 1
- push ecx
- push 0
- call emit32
- add esp, 4
- pop ecx
- jmp process_bss_line_resd_loop
- process_bss_line_ret:
- mov eax, 1
- ret
- global process_data_line
- process_data_line:
- ;; Check if the opcode is db
- mov edx, [esp+4]
- push str_db
- push edx
- call strcmp
- add esp, 8
- cmp eax, 0
- je process_data_line_db
- ;; Check is the opcode is dd
- mov edx, [esp+4]
- push str_dd
- push edx
- call strcmp
- add esp, 8
- cmp eax, 0
- je process_data_line_dd
- mov eax, 0
- ret
- process_data_line_db:
- ;; If data begin with an apex, treat it as a string
- mov edx, [esp+8]
- cmp BYTE [edx], APEX
- je process_data_line_string
- ;; If not, treat it as a single 8 bits value
- mov eax, 0
- jmp process_data_line_value
- process_data_line_dd:
- ;; Assume data is a single 32 bits value
- mov edx, [esp+8]
- mov eax, 1
- jmp process_data_line_value
- process_data_line_value:
- ;; Like process_bss_line_resb, but with just one emit at the end
- ;; (and decode_number_or_symbol is permitted to fail in stage 0)
- push eax
- push 0
- mov ecx, esp
- push 0
- push ecx
- push edx
- call decode_number_or_symbol
- add esp, 12
- pop ecx
- cmp eax, 0
- je platform_panic
- ;; We used eax to remember if data is 8 or 32 bits; call emit or
- ;; emit32 accordingly
- pop eax
- cmp eax, 0
- jne process_data_line_emit32
- push ecx
- call emit
- add esp, 4
- jmp process_data_line_ret
- process_data_line_emit32:
- push ecx
- call emit32
- add esp, 4
- jmp process_data_line_ret
- process_data_line_string:
- ;; Compute string length
- push edx
- push edx
- call strlen
- add esp, 4
- pop edx
- ;; Check that data has at least length 2 (the two apices)
- cmp eax, 2
- jnae platform_panic
- ;; Check that data has an apex at the end
- mov ecx, edx
- add ecx, eax
- sub ecx, 1
- cmp BYTE [ecx], APEX
- jne platform_panic
- ;; Consume the first apex and overwrite the last with a terminator
- mov BYTE [ecx], 0
- add edx, 1
- ;; Emit all the bytes
- process_data_line_dd_loop:
- cmp BYTE [edx], 0
- je process_data_line_ret
- push edx
- mov ecx, 0
- mov cl, BYTE [edx]
- push ecx
- call emit
- add esp, 4
- pop edx
- add edx, 1
- jmp process_data_line_dd_loop
- process_data_line_ret:
- mov eax, 1
- ret
- global emit_modrm
- emit_modrm:
- ;; Check that input do not overlap when being shifted in place
- mov eax, 0x3
- and eax, [esp+4]
- cmp eax, [esp+4]
- jne platform_panic
- mov eax, 0x7
- and eax, [esp+8]
- cmp eax, [esp+8]
- jne platform_panic
- mov eax, 0x7
- and eax, [esp+12]
- cmp eax, [esp+12]
- jne platform_panic
- ;; Only support a direct register, or an indirect register + disp32
- cmp BYTE [esp+4], 0
- je platform_panic
- cmp BYTE [esp+4], 1
- je platform_panic
- ;; Assemble the first byte
- mov eax, 0
- mov al, BYTE [esp+4]
- mov edx, 8
- mul edx
- add al, BYTE [esp+8]
- mov edx, 8
- mul edx
- add al, BYTE [esp+12]
- ;; Emit the first byte
- push eax
- call emit
- add esp, 4
- ;; In the particular case of ESP used as indirect base, a SIB is
- ;; needed
- cmp BYTE [esp+4], 2
- jne emit_modrm_ret
- cmp BYTE [esp+12], 4
- jne emit_modrm_ret
- push 0x24
- call emit
- add esp, 4
- emit_modrm_ret:
- ret
- global emit_helper
- emit_helper:
- push ebp
- mov ebp, esp
- ;; Check the opcode is valid and call first emit
- mov ecx, [ebp+8]
- mov edx, 0
- mov dl, cl
- cmp cl, 0xf0
- je platform_panic
- push edx
- call emit
- add esp, 4
- ;; Perhaps call second emit
- mov ecx, [ebp+8]
- and ecx, 0xff0000
- cmp ecx, 0
- je emit_helper_modrm
- mov ecx, [ebp+8]
- mov edx, 0
- mov dl, ch
- push edx
- call emit
- add esp, 4
- emit_helper_modrm:
- ;; Perhaps call emit_modrm
- mov eax, [ebp+20]
- cmp eax, 0xffffffff
- je emit_helper_disp
- push eax
- mov edx, [ebp+16]
- cmp edx, 0xffffffff
- jne emit_helper_modrm3
- mov ecx, [ebp+8]
- mov edx, 0
- mov dl, ch
- emit_helper_modrm3:
- push edx
- mov ecx, 2
- cmp DWORD [ebp+12], 0
- je emit_helper_modrm2
- mov ecx, 3
- emit_helper_modrm2:
- push ecx
- call emit_modrm
- add esp, 12
- emit_helper_disp:
- ;; Perhaps call emit32
- cmp DWORD [ebp+12], 0
- jne emit_helper_end
- mov edx, [ebp+24]
- push edx
- call emit32
- add esp, 4
- emit_helper_end:
- pop ebp
- ret
- global process_jmp_like
- process_jmp_like:
- push ebp
- mov ebp, esp
- ;; Allocate space for 5 variables:
- ;; [ebp-4], which is [ebp+0xfffffffc]: is_direct
- ;; [ebp-8], which is [ebp+0xfffffff8]: reg
- ;; [ebp-12], whch is [ebp+0xfffffff4]: disp
- ;; [ebp-16], which is [ebp+0xfffffff0]: is8
- ;; [ebp-20], which is [ebp+0xffffffec]: is32
- sub esp, 20
- ;; Call decode_operand
- mov eax, ebp
- sub eax, 20
- push eax
- mov eax, ebp
- sub eax, 16
- push eax
- mov eax, ebp
- sub eax, 12
- push eax
- mov eax, ebp
- sub eax, 8
- push eax
- mov eax, ebp
- sub eax, 4
- push eax
- mov eax, [ebp+12]
- push eax
- call decode_operand
- add esp, 24
- cmp eax, 0
- jne process_jmp_like_rm32
- jmp process_jmp_like_rel32
- process_jmp_like_rm32:
- ;; Check the operand is not 8 bits
- cmp DWORD [ebp+0xfffffff0], 0
- jne platform_panic
- ;; Get the opcode data
- mov eax, [ebp+8]
- mov edx, 4
- mul edx
- add eax, rm32_opcode
- mov ecx, [eax]
- ;; Call emit_helper
- mov edx, [ebp+0xfffffff4]
- push edx
- mov edx, [ebp+0xfffffff8]
- push edx
- push 0xffffffff
- mov edx, [ebp+0xfffffffc]
- push edx
- push ecx
- call emit_helper
- add esp, 20
- jmp process_jmp_like_end
- process_jmp_like_rel32:
- ;; Get the opcode data
- mov eax, [ebp+8]
- mov edx, 4
- mul edx
- add eax, imm32_opcode
- mov ecx, [eax]
- ;; Call emit_helper
- push 0
- push 0xffffffff
- push 0xffffffff
- push 1
- push ecx
- call emit_helper
- add esp, 20
- ;; Call decode_number_or_symbol
- push 0
- mov edx, esp
- push 0
- push edx
- mov edx, [ebp+12]
- push edx
- call decode_number_or_symbol
- add esp, 12
- ;; Check for success
- cmp eax, 0
- je platform_panic
- ;; Store the value in edx and make it relative
- pop edx
- mov ecx, current_loc
- sub edx, [ecx]
- sub edx, 4
- ;; Call emit32
- push edx
- call emit32
- add esp, 4
- jmp process_jmp_like_end
- process_jmp_like_end:
- add esp, 20
- pop ebp
- ret
- global process_push_like
- process_push_like:
- push ebp
- mov ebp, esp
- ;; Allocate space for 5 variables:
- ;; [ebp-4], which is [ebp+0xfffffffc]: is_direct
- ;; [ebp-8], which is [ebp+0xfffffff8]: reg
- ;; [ebp-12], whch is [ebp+0xfffffff4]: disp
- ;; [ebp-16], which is [ebp+0xfffffff0]: is8
- ;; [ebp-20], which is [ebp+0xffffffec]: is32
- sub esp, 20
- ;; Check if the operation is a bit shift
- cmp DWORD [ebp+8], OP_SHL
- je process_push_like_shift
- cmp DWORD [ebp+8], OP_SHR
- je process_push_like_shift
- cmp DWORD [ebp+8], OP_SAL
- je process_push_like_shift
- cmp DWORD [ebp+8], OP_SAR
- je process_push_like_shift
- jmp process_push_like_decode
- process_push_like_shift:
- ;; Find the comma
- push COMMA
- mov edx, [ebp+12]
- push edx
- call find_char
- add esp, 8
- cmp eax, 0xffffffff
- je platform_panic
- ;; Substitute the comma with a terminator
- mov ecx, [ebp+12]
- add ecx, eax
- mov BYTE [ecx], 0
- ;; Trim second operand
- add ecx, 1
- push ecx
- push ecx
- call trimstr
- add esp, 4
- pop ecx
- ;; Check that second operand is cl
- push ecx
- push reg_cl
- call strcmp
- add esp, 8
- cmp eax, 0
- jne platform_panic
- process_push_like_decode:
- ;; Call decode_operand
- mov eax, ebp
- sub eax, 20
- push eax
- mov eax, ebp
- sub eax, 16
- push eax
- mov eax, ebp
- sub eax, 12
- push eax
- mov eax, ebp
- sub eax, 8
- push eax
- mov eax, ebp
- sub eax, 4
- push eax
- mov eax, [ebp+12]
- push eax
- call decode_operand
- add esp, 24
- cmp eax, 0
- jne process_push_like_rm32
- jmp process_push_like_imm32
- process_push_like_rm32:
- ;; Check the operand is not 8 bits
- cmp DWORD [ebp+0xfffffff0], 0
- jne platform_panic
- ;; Get the opcode data
- mov eax, [ebp+8]
- mov edx, 4
- mul edx
- add eax, rm32_opcode
- mov ecx, [eax]
- ;; Call emit_helper
- mov edx, [ebp+0xfffffff4]
- push edx
- mov edx, [ebp+0xfffffff8]
- push edx
- push 0xffffffff
- mov edx, [ebp+0xfffffffc]
- push edx
- push ecx
- call emit_helper
- add esp, 20
- jmp process_push_like_end
- process_push_like_imm32:
- ;; Check that the operation is push
- cmp DWORD [ebp+8], OP_PUSH
- jne platform_panic
- ;; Emit the operand
- push 0x68
- call emit
- add esp, 4
- ;; Call decode_number_or_symbol
- push 0
- mov edx, esp
- push 0
- push edx
- mov edx, [ebp+12]
- push edx
- call decode_number_or_symbol
- add esp, 12
- cmp eax, 0
- je platform_panic
- ;; Call emit32
- pop edx
- push edx
- call emit32
- add esp, 4
- jmp process_push_like_end
- process_push_like_end:
- add esp, 20
- pop ebp
- ret
- global process_add_like
- process_add_like:
- push ebp
- mov ebp, esp
- ;; Allocate a lot of local variables
- ;; [ebp-4], which is [ebp+0xfffffffc]: dest_is_direct
- ;; [ebp-8], which is [ebp+0xfffffff8]: dest_reg
- ;; [ebp-12], whch is [ebp+0xfffffff4]: dest_disp
- ;; [ebp-16], which is [ebp+0xfffffff0]: dest_is8
- ;; [ebp-20], which is [ebp+0xffffffec]: dest_is32
- ;; [ebp-24], which is [ebp+0xffffffe8]: src_is_direct
- ;; [ebp-28], which is [ebp+0xffffffe4]: src_reg
- ;; [ebp-32], which is [ebp+0xffffffe0]: src_disp
- ;; [ebp-36], which is [ebp+0xffffffdc]: src_is8
- ;; [ebp-40], which is [ebo+0xffffffd8]: src_is32
- sub esp, 40
- ;; Find the comma
- push COMMA
- mov edx, [ebp+12]
- push edx
- call find_char
- add esp, 8
- cmp eax, 0xffffffff
- je platform_panic
- ;; Substitute the comma with a terminator
- mov ecx, [ebp+12]
- add ecx, eax
- mov BYTE [ecx], 0
- ;; Push following position on the stack
- add ecx, 1
- push ecx
- ;; Call decode_operand for destination
- mov ecx, ebp
- sub ecx, 20
- push ecx
- mov ecx, ebp
- sub ecx, 16
- push ecx
- mov ecx, ebp
- sub ecx, 12
- push ecx
- mov ecx, ebp
- sub ecx, 8
- push ecx
- mov ecx, ebp
- sub ecx, 4
- push ecx
- mov ecx, [ebp+12]
- push ecx
- call decode_operand
- add esp, 24
- ;; Panic if decoding failed
- cmp eax, 0
- je platform_panic
- ;; Call decode_operand for source
- pop edx
- push edx
- mov ecx, ebp
- sub ecx, 40
- push ecx
- mov ecx, ebp
- sub ecx, 36
- push ecx
- mov ecx, ebp
- sub ecx, 32
- push ecx
- mov ecx, ebp
- sub ecx, 28
- push ecx
- mov ecx, ebp
- sub ecx, 24
- push ecx
- push edx
- call decode_operand
- add esp, 24
- pop edx
- cmp eax, 0
- je process_add_like_imm
- ;; Decide whether this is an 8 or 32 bits operation
- mov dl, [ebp+0xfffffff0]
- or dl, [ebp+0xffffffdc]
- mov dh, [ebp+0xffffffec]
- or dh, [ebp+0xffffffd8]
- ;; Check that the situation is consistent
- mov al, dl
- or al, dh
- cmp al, 0
- je platform_panic
- mov al, dl
- and al, dh
- cmp al, 0
- jne platform_panic
- ;; Split depending on whether destination is direct or not
- mov ecx, [ebp+0xfffffffc]
- cmp ecx, 0
- jne process_add_like_dest_direct
- jmp process_add_like_dest_indirect
- process_add_like_dest_direct:
- ;; Split depending on 8 or 32 bits operation
- cmp dl, 0
- jne process_add_like_dest_direct_8
- jmp process_add_like_dest_direct_32
- process_add_like_dest_direct_8:
- ;; Retrieve opcode_data
- mov eax, [ebp+8]
- mov edx, 4
- mul edx
- add eax, r8rm8_opcode
- mov ecx, [eax]
- ;; Call emit_helper
- mov eax, [ebp+0xffffffe0]
- push eax
- mov eax, [ebp+0xffffffe4]
- push eax
- mov eax, [ebp+0xfffffff8]
- push eax
- mov eax, [ebp+0xffffffe8]
- push eax
- push ecx
- call emit_helper
- add esp, 20
- jmp process_add_like_end
- process_add_like_dest_direct_32:
- ;; Retrieve opcode_data
- mov eax, [ebp+8]
- mov edx, 4
- mul edx
- add eax, r32rm32_opcode
- mov ecx, [eax]
- ;; Call emit_helper
- mov eax, [ebp+0xffffffe0]
- push eax
- mov eax, [ebp+0xffffffe4]
- push eax
- mov eax, [ebp+0xfffffff8]
- push eax
- mov eax, [ebp+0xffffffe8]
- push eax
- push ecx
- call emit_helper
- add esp, 20
- jmp process_add_like_end
- process_add_like_dest_indirect:
- ;; Check that source is direct
- cmp DWORD [ebp+0xffffffe8], 0
- je platform_panic
- ;; Split depending on 8 or 32 bits operation
- cmp dl, 0
- jne process_add_like_dest_indirect_8
- jmp process_add_like_dest_indirect_32
- process_add_like_dest_indirect_8:
- ;; Retrieve opcode_data
- mov eax, [ebp+8]
- mov edx, 4
- mul edx
- add eax, rm8r8_opcode
- mov ecx, [eax]
- ;; Call emit_helper
- mov eax, [ebp+0xfffffff4]
- push eax
- mov eax, [ebp+0xfffffff8]
- push eax
- mov eax, [ebp+0xffffffe4]
- push eax
- push 0
- push ecx
- call emit_helper
- add esp, 20
- jmp process_add_like_end
- process_add_like_dest_indirect_32:
- ;; Retrieve opcode_data
- mov eax, [ebp+8]
- mov edx, 4
- mul edx
- add eax, rm32r32_opcode
- mov ecx, [eax]
- ;; Call emit_helper
- mov eax, [ebp+0xfffffff4]
- push eax
- mov eax, [ebp+0xfffffff8]
- push eax
- mov eax, [ebp+0xffffffe4]
- push eax
- push 0
- push ecx
- call emit_helper
- add esp, 20
- jmp process_add_like_end
- process_add_like_imm:
- ;; Check that we know the operation size
- mov eax, [ebp+0xfffffff0]
- or eax, [ebp+0xffffffec]
- cmp eax, 0
- je platform_panic
- ;; Call decode_number_or_symbol
- push 0
- mov ecx, esp
- push 0
- push ecx
- push edx
- call decode_number_or_symbol
- add esp, 12
- pop edx
- ;; Check it did work
- cmp eax, 0
- je platform_panic
- cmp DWORD [ebp+0xfffffff0], 0
- je process_add_like_imm_32
- jmp process_add_like_imm_8
- process_add_like_imm_8:
- push edx
- ;; Retrieve opcode_data
- mov eax, [ebp+8]
- mov edx, 4
- mul edx
- add eax, rm8imm8_opcode
- mov ecx, [eax]
- ;; Call emit_helper
- mov eax, [ebp+0xfffffff4]
- push eax
- mov eax, [ebp+0xfffffff8]
- push eax
- push 0xffffffff
- mov eax, [ebp+0xfffffffc]
- push eax
- push ecx
- call emit_helper
- add esp, 20
- ;; Call emit
- pop edx
- push edx
- call emit
- add esp, 4
- jmp process_add_like_end
- process_add_like_imm_32:
- push edx
- ;; Retrieve opcode_data
- mov eax, [ebp+8]
- mov edx, 4
- mul edx
- add eax, rm32imm32_opcode
- mov ecx, [eax]
- ;; Call emit_helper
- mov eax, [ebp+0xfffffff4]
- push eax
- mov eax, [ebp+0xfffffff8]
- push eax
- push 0xffffffff
- mov eax, [ebp+0xfffffffc]
- push eax
- push ecx
- call emit_helper
- add esp, 20
- ;; Call emit
- pop edx
- push edx
- call emit32
- add esp, 4
- jmp process_add_like_end
- process_add_like_end:
- add esp, 40
- pop ebp
- ret
- global process_int
- process_int:
- ;; Check the operation is actually an int
- cmp DWORD [esp+4], OP_INT
- jne platform_panic
- ;; Call decode_number_or_symbol
- push 0
- mov edx, esp
- push 0
- push edx
- mov edx, [esp+8]
- push edx
- call decode_number_or_symbol
- add esp, 12
- pop edx
- ;; Check result
- cmp eax, 0
- je platform_panic
- ;; Check the interrupt number is smaller than 0x100
- cmp edx, 0x100
- jnb platform_panic
- ;; Call emit twice
- push edx
- push 0xcd
- call emit
- add esp, 4
- call emit
- add esp, 4
- ret
- global process_ret_like
- process_ret_like:
- ;; Get the opcode data
- mov eax, [esp+4]
- mov edx, 4
- mul edx
- add eax, empty_opcode
- mov ecx, [eax]
- ;; Check that data is empty
- mov edx, [esp+8]
- cmp BYTE [edx], 0
- jne platform_panic
- ;; Call emit_helper
- push 0
- push 0xffffffff
- push 0xffffffff
- push 1
- push ecx
- call emit_helper
- add esp, 20
- ret
- global process_hlt
- process_hlt:
- ;; Check the operation is actually a ret
- cmp DWORD [esp+4], OP_HLT
- jne platform_panic
- ;; Check that data is empty
- mov edx, [esp+8]
- cmp BYTE [edx], 0
- jne platform_panic
- ;; Call emit
- push 0xf4
- call emit
- add esp, 4
- ret
- global process_in_like
- process_in_like:
- ;; Check the operation is valid
- cmp DWORD [esp+4], OP_IN
- je process_in_like_find_comma
- cmp DWORD [esp+4], OP_OUT
- je process_in_like_find_comma
- call platform_panic
- process_in_like_find_comma:
- ;; Search the comma and panic if it is not there
- mov eax, [esp+8]
- push COMMA
- push eax
- call find_char
- add esp, 8
- cmp eax, 0xffffffff
- je platform_panic
- ;; Substitute the comma with a terminator
- mov edx, [esp+8]
- mov ecx, edx
- add edx, eax
- mov BYTE [edx], 0
- add edx, 1
- mov eax, ecx
- ;; Decide which operation to use
- cmp DWORD [esp+4], OP_IN
- je process_in_like_in
- jmp process_in_like_out
- process_in_like_in:
- ;; Leave the port operand in edx, the register operand in eax and
- ;; the opcode in ecx
- mov ecx, 0xec
- jmp process_in_like_trim
- process_in_like_out:
- ;; Same as above
- mov ecx, eax
- mov eax, edx
- mov edx, ecx
- mov ecx, 0xee
- jmp process_in_like_trim
- process_in_like_trim:
- ;; Trim both operands
- push eax
- push ecx
- push edx
- push eax
- call trimstr
- add esp, 4
- pop edx
- push edx
- push edx
- call trimstr
- add esp, 4
- pop edx
- pop ecx
- pop eax
- ;; Check that the port operand is dx
- push eax
- push ecx
- push reg_dx
- push edx
- call strcmp
- add esp, 8
- cmp eax, 0
- jne platform_panic
- pop ecx
- pop eax
- ;; Select depending on the register operand
- push eax
- push ecx
- push reg_al
- push eax
- call strcmp
- add esp, 8
- cmp eax, 0
- pop ecx
- pop eax
- je process_in_like_al
- push eax
- push ecx
- push reg_ax
- push eax
- call strcmp
- add esp, 8
- cmp eax, 0
- pop ecx
- pop eax
- je process_in_like_ax
- push eax
- push ecx
- push reg_eax
- push eax
- call strcmp
- add esp, 8
- cmp eax, 0
- pop ecx
- pop eax
- je process_in_like_eax
- ;; Nothing matched, panic!
- call platform_panic
- process_in_like_al:
- ;; Emit the opcode
- push ecx
- call emit
- add esp, 4
- jmp process_in_like_ret
- process_in_like_ax:
- ;; Emit the opcode
- add ecx, 1
- push ecx
- push 0x66
- call emit
- add esp, 4
- call emit
- add esp, 4
- jmp process_in_like_ret
- process_in_like_eax:
- add ecx, 1
- push ecx
- call emit
- add esp, 4
- jmp process_in_like_ret
- process_in_like_ret:
- ret
- global process_text_line
- process_text_line:
- push ebp
- mov ebp, esp
- push esi
- push edi
- ;; Init esi for storing the current name and edi for counting
- mov esi, opcode_names
- mov edi, 0
- process_text_line_loop:
- ;; Check for termination: we did not find any match
- mov eax, 0
- cmp BYTE [esi], 0
- je process_text_line_end
- ;; Check for termination: we found a match
- mov ecx, [ebp+8]
- push ecx
- push esi
- call strcmp
- add esp, 8
- cmp eax, 0
- je process_text_line_match
- ;; Consume the string and increment the index
- push esi
- call strlen
- add esp, 4
- add esi, eax
- add esi, 1
- add edi, 1
- jmp process_text_line_loop
- process_text_line_match:
- ;; Select the opcode function
- mov eax, 4
- mul edi
- add eax, opcode_funcs
- ;; Call the opcode function
- mov edx, [ebp+12]
- push edx
- push edi
- call [eax]
- add esp, 8
- mov eax, 1
- jmp process_text_line_end
- process_text_line_end:
- pop edi
- pop esi
- pop ebp
- ret
- global process_directive_line
- process_directive_line:
- ;; Ignore section, org, bits, global and align
- mov eax, [esp+4]
- push str_section
- push eax
- call strcmp
- add esp, 8
- cmp eax, 0
- je process_directive_line_ret_true
- mov eax, [esp+4]
- push str_org
- push eax
- call strcmp
- add esp, 8
- cmp eax, 0
- je process_directive_line_ret_true
- mov eax, [esp+4]
- push str_bits
- push eax
- call strcmp
- add esp, 8
- cmp eax, 0
- je process_directive_line_ret_true
- mov eax, [esp+4]
- push str_global
- push eax
- call strcmp
- add esp, 8
- cmp eax, 0
- je process_directive_line_ret_true
- mov eax, [esp+4]
- push str_align
- push eax
- call strcmp
- add esp, 8
- cmp eax, 0
- je process_directive_line_align
- ;; Recognize extern
- mov eax, [esp+4]
- push str_extern
- push eax
- call strcmp
- add esp, 8
- cmp eax, 0
- je process_directive_line_extern
- ;; Return false for everything else
- mov eax, 0
- ret
- process_directive_line_align:
- ;; Call decode_number_or_symbol
- mov eax, [esp+8]
- push 0
- mov ecx, esp
- push 1
- push ecx
- push eax
- call decode_number_or_symbol
- add esp, 12
- pop ecx
- ;; Panic if it failed
- cmp eax, 0
- je platform_panic
- ;; Compute the number of bytes to skip
- mov edx, current_loc
- mov eax, [edx]
- mov edx, 0
- div ecx
- cmp edx, 0
- je process_directive_line_ret_true
- sub ecx, edx
- ;; Skip them
- process_directive_line_align_loop:
- cmp ecx, 0
- je process_directive_line_ret_true
- push ecx
- push 0
- call emit
- add esp, 4
- pop ecx
- sub ecx, 1
- jmp process_directive_line_align_loop
- process_directive_line_extern:
- ;; Add a mock symbol
- mov eax, [esp+8]
- push 0xffffffff
- push 0
- push eax
- call add_symbol_wrapper
- add esp, 12
- jmp process_directive_line_ret_true
- process_directive_line_ret_true:
- mov eax, 1
- ret
- global process_equ_line
- process_equ_line:
- ;; Find the space in data
- mov eax, [esp+8]
- push SPACE
- push eax
- call find_char
- add esp, 8
- ;; Fail if there is not one
- cmp eax, 0xffffffff
- je process_equ_line_ret_false
- ;; Substitute it with a terminator and save the following position
- mov edx, [esp+8]
- add eax, edx
- mov BYTE [eax], 0
- mov ecx, eax
- add eax, 1
- push eax
- ;; Check we are dealing with an equ line
- push str_equ
- push edx
- call strcmp
- add esp, 8
- pop edx
- ;; Fail if we are not
- cmp eax, 0
- jne process_equ_line_ret_false
- ;; Call trimstr
- push edx
- push edx
- call trimstr
- add esp, 4
- pop edx
- ;; Call decode_number_or_symbol
- push 0
- mov ecx, esp
- push 0
- push ecx
- push edx
- call decode_number_or_symbol
- add esp, 12
- ;; Panic if it did not work
- cmp eax, 0
- je platform_panic
- ;; Create a symbol if it did work
- pop edx
- mov eax, [esp+4]
- push 0xffffffff
- push edx
- push eax
- call add_symbol_wrapper
- add esp, 12
- ;; Return true
- mov eax, 1
- ret
- process_equ_line_ret_false:
- mov eax, 0
- ret
- global process_line
- process_line:
- ;; Find first space
- mov eax, [esp+4]
- push SPACE
- push eax
- call find_char
- add esp, 8
- ;; Select on whether we found it or not
- cmp eax, 0xffffffff
- je process_line_without_space
- jmp process_line_with_space
- process_line_with_space:
- ;; Substitute the space with a terminator; leave opcode in edx and
- ;; data in eax
- mov edx, [esp+4]
- add eax, edx
- mov BYTE [eax], 0
- add eax, 1
- jmp process_line_process
- process_line_without_space:
- ;; Leave opcode in edx and set data (in eax) to an empty string
- mov edx, [esp+4]
- mov eax, str_empty
- jmp process_line_process
- process_line_process:
- ;; Call all line processing functions
- push eax
- push edx
- push eax
- push edx
- call process_directive_line
- add esp, 8
- cmp eax, 0
- pop edx
- pop eax
- jne process_line_end
- push eax
- push edx
- push eax
- push edx
- call process_bss_line
- add esp, 8
- cmp eax, 0
- pop edx
- pop eax
- jne process_line_end
- push eax
- push edx
- push eax
- push edx
- call process_text_line
- add esp, 8
- cmp eax, 0
- pop edx
- pop eax
- jne process_line_end
- push eax
- push edx
- push eax
- push edx
- call process_data_line
- add esp, 8
- cmp eax, 0
- pop edx
- pop eax
- jne process_line_end
- push eax
- push edx
- push eax
- push edx
- call process_equ_line
- add esp, 8
- cmp eax, 0
- pop edx
- pop eax
- jne process_line_end
- ;; Nothing matched, panic
- call platform_panic
- process_line_end:
- ret
- global init_assembler
- init_assembler:
- ;; Allocate input buffer
- push INPUT_BUF_LEN
- call platform_allocate
- add esp, 4
- mov ecx, input_buf_ptr
- mov [ecx], eax
- ret
- global assemble
- assemble:
- push ebp
- mov ebp, esp
- push esi
- push edi
- push ebx
- ;; Set fd for emit
- mov eax, emit_fd
- mov ecx, [ebp+12]
- mov [eax], ecx
- ;; Reset stage
- mov eax, stage
- mov DWORD [eax], 0
- assemble_stage_loop:
- ;; Check for termination
- mov eax, stage
- cmp DWORD [eax], 2
- je assemble_end
- ;; Call platform_reset_file
- mov eax, [ebp+8]
- push eax
- call platform_reset_file
- add esp, 4
- ;; Reset line number (in esi) and current_loc
- mov esi, 0
- mov eax, current_loc
- mov ecx, [ebp+16]
- mov [eax], ecx
- assemble_parse_loop:
- ;; Call readline and store in ebx if we found the EOF
- push INPUT_BUF_LEN
- mov eax, input_buf_ptr
- mov eax, [eax]
- push eax
- mov eax, [ebp+8]
- push eax
- call readline
- add esp, 12
- mov ebx, eax
- ;; Log the line
- ;; push str_decoding_line
- ;; push 2
- ;; call platform_log
- ;; add esp, 8
- ;; mov eax, input_buf_ptr
- ;; mov eax, [eax]
- ;; push eax
- ;; push 2
- ;; call platform_log
- ;; add esp, 8
- ;; push str_newline
- ;; push 2
- ;; call platform_log
- ;; add esp, 8
- ;; Find the first semicolon
- push SEMICOLON
- mov eax, input_buf_ptr
- mov eax, [eax]
- push eax
- call find_char
- add esp, 8
- ;; If found, substitute it with a terminator
- cmp eax, 0xffffffff
- je assemble_parse_trim
- mov ecx, input_buf_ptr
- add eax, [ecx]
- mov BYTE [eax], 0
- assemble_parse_trim:
- ;; Call trimstr
- mov eax, input_buf_ptr
- mov eax, [eax]
- push eax
- call trimstr
- add esp, 4
- ;; Compute line length and store it in edi
- mov eax, input_buf_ptr
- mov eax, [eax]
- push eax
- call strlen
- add esp, 4
- mov edi, eax
- ;; If the line is not empty, pass to parsing it
- cmp edi, 0
- jne assemble_parse_detect_symbol
- ;; If it is empty and we have finished, break
- cmp ebx, 0
- jne assemble_break_parse_loop
- ;; If it is empty and we have not finished, continue
- jmp assemble_continue_parse_loop
- assemble_parse_detect_symbol:
- ;; Detect if this line is a symbol declaration
- mov eax, input_buf_ptr
- mov eax, [eax]
- add eax, edi
- sub eax, 1
- cmp BYTE [eax], COLON
- jne assemble_parse_process
- ;; Substitute the colon with a terminator
- mov BYTE [eax], 0
- ;; Call add_symbol_wrapper
- push 0xffffffff
- mov edx, current_loc
- mov eax, [edx]
- push eax
- mov eax, input_buf_ptr
- mov eax, [eax]
- push eax
- call add_symbol_wrapper
- add esp, 12
- jmp assemble_continue_parse_loop
- assemble_parse_process:
- ;; Call process_line
- mov eax, input_buf_ptr
- mov eax, [eax]
- push eax
- call process_line
- add esp, 4
- jmp assemble_continue_parse_loop
- assemble_continue_parse_loop:
- ;; Increment line number and restart parse loop
- add esi, 1
- jmp assemble_parse_loop
- assemble_break_parse_loop:
- ;; Increment stage
- mov eax, stage
- add DWORD [eax], 1
- jmp assemble_stage_loop
- assemble_end:
- ;; Print processed line number
- push str_ass_finished1
- push 2
- call platform_log
- add esp, 8
- push esi
- call itoa
- add esp, 4
- push eax
- push 2
- call platform_log
- add esp, 8
- push str_ass_finished2
- push 2
- call platform_log
- add esp, 8
- ;; Print symbol number
- push str_symb_num1
- push 2
- call platform_log
- add esp, 8
- mov ecx, symbol_num
- mov eax, [ecx]
- push eax
- call itoa
- add esp, 4
- push eax
- push 2
- call platform_log
- add esp, 8
- push str_symb_num2
- push 2
- call platform_log
- add esp, 8
- pop ebx
- pop edi
- pop esi
- pop ebp
- ret
|