Tải bản đầy đủ - 0 (trang)
2 Mixing HLA and MASM/Gas Code in the Same Program

2 Mixing HLA and MASM/Gas Code in the Same Program

Tải bản đầy đủ - 0trang

andthe#emitstatement.The#asm..#endasmsequencecopiesall

textbetweenthesetwoclausesdirectlytotheassemblyoutputfile,e.g.,

#asm

moveax,0;MASM/GassyntaxforMOV(0,EAX);

addeax,ebx;"""ADD(ebx,eax);

#endasm

The#asm..#endasmsequenceishowyouinjectin-line(MASMorGas)

assemblycodeintoyourHLAprograms.Forthemostpartthereisvery

littleneedtousethisfeature,butinafewinstancesitisinvaluable.Note,

whenusingGas,thatHLAspecifiesthe".intel_syntax"directive,soyou

shoulduseIntelsyntaxwhensupplyingGascodebetween#asmand

#endasm.

Forexample,ifyou'rewritingstructuredexceptionhandlingcodeunder

Windows,you'llneedtoaccessthedoublewordataddressFS:[0](offset

zerointhesegmentpointedatbythe80x86'sFSsegmentregister).You

candropintoMASMforastatementortwotohandlememoryaccesses

asfollows:

#asm

movebx,fs:[0];LoadsprocesspointerintoEBX

#endasm

Attheendofthisinstructionsequence,EBXwillcontainthepointertothe

processinformationstructurethatWindowsmaintains.

HLAblindlycopiesalltextbetweenthe#asmand#endasmclauses

directlytotheassemblyoutputfile.HLAdoesnotcheckthesyntaxofthis

codeorotherwiseverifyitscorrectness.Ifyouintroduceanerrorwithin

thissectionofyourprogram,theassemblerwillreporttheerrorwhen

HLAassemblesyourcodebycallingMASMorGas.

The#emitstatementalsowritestextdirectlytotheassemblyoutputfile.

However,thisstatementdoesnotsimplycopythetextfromyoursource



filetotheoutputfile;instead,thisstatementcopiesthevalueofa

(constant)stringexpressiontotheoutputfile.Thesyntaxforthis

statementis

#emit(string_expression);

Thisstatementevaluatestheexpressionandverifiesthatit'sastring

expression.Thenitcopiesthestringdatatotheoutputfile.Likethe

#asm/#endasmstatement,the#emitstatementdoesnotcheckthe

syntaxoftheMASM/Gasstatementitwritestotheassemblyfile.Ifthere

isasyntaxerror,MASMorGaswillcatchitlateronwhentheassembler

processestheoutputfile.

Oneadvantageofthe#emitstatementisthatitletsyouconstruct

MASMorGasstatementsunder(compiletime)programcontrol.Youcan

writeanHLAcompiletimeprogramthatgeneratesasequenceofstrings

andemitsthemtotheassemblyfileviathe#emitstatement.The

compiletimeprogramhasaccesstotheHLAsymboltable;thismeans

thatyoucanextracttheidentifiersthatHLAemitstotheassemblyfileand

usethesedirectly,eveniftheyaren'texternalobjects.

WhenHLAcompilesyourprogramsintoassemblylanguage,itdoesnot

usethesamesymbolsintheassemblylanguageoutputfilethatyouuse

intheHLAsourcefiles.Thereareseveraltechnicalreasonsforthis,but

thebottomlineisthis:YoucannoteasilyreferenceyourHLAidentifiersin

yourin-lineassemblycode.Theonlyexceptiontothisruleisexternal

identifiers.HLAexternalidentifiersusethesamenameintheassembly

fileasintheHLAsourcefile.Therefore,youcanrefertoexternalobjects

withinyourin-lineassemblysequencesorinthestringsyououtputvia

#emit.

The@staticnamecompiletimefunctionreturnsthenamethatHLA

usestorefertomoststaticobjectsinyourprogram.Theprogramin

Listing15-1demonstratesasimpleuseofthiscompiletimefunctionto

obtaintheassemblynameofanHLAprocedure.

Listing15-1:Usingthe@StaticNameCompileTimeFunction.

programemitDemo;



#include("stdlib.hhf")

proceduremyProc;

beginmyProc;

stdout.put("InsideMyProc"nl);

endmyProc;

beginemitDemo;

?stmt:string:="call"+@StaticName(myProc);

#emit(stmt);

endemitDemo;



Thisexamplecreatesastringvalue(stmt)thatcontainssomethinglike

"call?741_myProc"andemitsthisassemblyinstructiondirectlytothe

sourcefile("?741_myProc"istypicalofthetypeofnamemanglingthat

HLAdoestostaticnamesitwritestotheoutputfile).Ifyoucompileand

runthisprogram,itshoulddisplay"InsideMyProc"andthenquit.Ifyou

lookattheassemblyfilethatHLAemits,youwillseethatithasgiventhe

myProcprocedurethesamenameitappendstothecallinstruction.[1]

The@StaticNamefunctionisonlyvalidforstaticsymbols.Thisincludes

static,readonly,andstoragevariables,andprocedures.Itdoes

notincludevarobjects,constants,macros,ormethods.

Youcanaccessvarvariablesbyusingthe[EBP+offset]addressing

mode,specifyingtheoffsetofthedesiredlocalvariable.Youcanusethe

@offsetcompiletimefunctiontoobtaintheoffsetofavarobjectora

parameter.Listing15-2demonstrateshowtodothis:

Listing15-2:Usingthe@OffsetCompileTimeFunction.



programoffsetDemo;

#include("stdlib.hhf")

var

i:int32;

beginoffsetDemo;



mov(-255,i);

?stmt:="moveax,[ebp+("+string(@offset(i))+")]";

#print("Emitting'",stmt,"'")

#emit(stmt);

stdout.put("eax=",(typeint32eax),nl);

endoffsetDemo;



Thisexampleemitsthestatement"moveax,[ebp+(-8)]"totheassembly

languagesourcefile.Itturnsoutthat-8istheoffsetoftheivariablein

theoffsetDemoprogram'sactivationrecord.

Ofcourse,theexamplesof#emituptothispointhavebeensomewhat

ridiculousbecauseyoucanachievethesameresultsbyusingHLA

statements.Oneveryusefulpurposeforthe#emitstatement,however,

istocreatesomeinstructionsthatHLAdoesnotsupport.Forexample,at

onetimeHLAdidnotsupportthelesinstructionbecauseyoucan'treally

useitundermost32-bitoperatingsystems.[2]However,ifyoufounda

needforthisinstruction,youcouldeasilywriteamacrotoemitthis

instructionandappropriateoperandstotheassemblysourcefile.Using

the#emitstatementgivesyoutheabilitytoreferenceHLAobjects,

somethingyoucannotdowiththe#asm..#endasmsequence.



15.2.2LinkingMASM/Gas-AssembledModuleswithHLA

Modules

AlthoughyoucandosomeinterestingthingswithHLA'sin-lineassembly

statements,you'llprobablyneverusethem.Further,futureversionsof



HLAmaynotevensupportthesestatements,soyoushouldavoidthem

asmuchaspossibleevenifyouseeaneedforthem.Ofcourse,HLA

doesmostofthestuffyou'dwanttodowiththe#asm/#endasmand

#emitstatementsanyway,sothereisverylittlereasontousethemat

all.Ifyou'regoingtocombineMASM/Gas(orotherassembler)codeand

HLAcodetogetherinaprogram,mostofthetimethiswilloccurbecause

you'vegotamoduleorlibraryroutinewritteninsomeotherassembly

languageandyouwouldliketotakeadvantageofthatcodeinyourHLA

programs.Ratherthanconverttheotherassembler'scodetoHLA,the

easysolutionistosimplyassemblethatothercodetoanobjectfileand

linkitwithyourHLAprograms.

Onceyou'vecompiledorassembledasourcefiletoanobjectfile,the

routinesinthatmodulearecallablefromalmostanymachinecodethat

canhandletheroutines'callingsequences.Ifyouhaveanobjectfilethat

containsasqrtfunction,forexample,itdoesn'tmatterwhetheryou

compiledthatfunctionwithHLA,MASM,TASM,NASM,Gas,orevena

highlevellanguage;ifit'sobjectcodeanditexportsthepropersymbols,

youcancallitfromyourHLAprogram.

CompilingamoduleinMASMorGasandlinkingthatwithyourHLA

programislittledifferentthanlinkingotherHLAmoduleswithyourmain

HLAprogram.Intheassemblysourcefile,youwillhavetoexportsome

symbols(usingthePUBLICdirectiveinMASMorthe.GLOBALdirective

inGas),andinyourHLAprogramyouhavetotellHLAthatthose

symbolsappearinaseparatemodule(usingthe@externaloption).

Becausethetwomodulesarewritteninassemblylanguage,thereisvery

littlelanguage-imposedstructureonthecallingsequenceandparameter

passingmechanisms.Ifyou'recallingafunctionwritteninMASMorGas

fromyourHLAprogram,thenallyou'vegottodoistomakesurethat

yourHLAprogrampassesparametersinthesamelocationswherethe

MASM/Gasfunctionisexpectingthem.

Abouttheonlyissueyou'vegottodealwithisthecaseofidentifiersin

thetwoprograms.Bydefault,GasiscasesensitiveandMASMiscase

insensitive.HLA,ontheotherhand,enforcescaseneutrality(which,

essentially,meansthatitiscasesensitive).Ifyou'reusingMASM,there



isaMASMcommandlineoption("/Cp")thattellsMASMtopreservecase

inallpublicsymbols.It'sarealgoodideatousethisoptionwhen

assemblingmodulesyou'regoingtolinkwithHLAsothatMASMdoesn't

messwiththecaseofyouridentifiersduringassembly.

Ofcourse,becauseMASMandGasprocesssymbolsinacase-sensitive

manner,it'spossibletocreatetwoseparateidentifiersthatarethesame

exceptforalphabeticcase.HLAenforcescaseneutralitysoitwon'tlet

you(directly)createtwodifferentidentifiersthatdifferonlyincase.In

general,thisissuchabadprogrammingpracticethatonewouldhope

youneverencounterit(andGodforbidyouactuallydothisyourself).

However,ifyouinheritsomeMASMorGascodewrittenbyaChacker,

it'squitepossiblethecodeusesthistechnique.Thewayaroundthis

problemistousetwoseparateidentifiersinyourHLAprogramanduse

theextendedformofthe@externaldirectivetoprovidetheexternal

names.Forexample,supposethatinMASMyouhavethefollowing

declarations:

publicAVariable

publicavariable

.

.

.

.data

AVariabledword?

avariablebyte?

Ifyouassemblethiscodewiththe"/Cp"or"/Cx"(totalcasesensitivity)

commandlineoptions,MASMwillemitthesetwoexternalsymbolsfor

usebyothermodules.Ofcourse,wereyoutoattempttodefinevariables

bythesetwonamesinanHLAprogram,HLAwouldcomplainaboutthe

duplicate-symboldefinition.However,youcanconnecttwodifferentHLA

variablestothesetwoidentifiersusingcodelikethefollowing:

static

AVariable:dword;external("AVariable");

AnotherVar:byte;external("avariable");

HLAdoesnotcheckthestringsyousupplyasparameterstothe



@externalclause.Therefore,youcansupplytwonamesthatarethe

sameexceptforcase,andHLAwillnotcomplain.NotethatwhenHLA

callsMASMtoassembleitsoutputfile,HLAspecifiesthe"/Cp"option

thattellsMASMtopreservecaseinpublicandglobalsymbols.Of

course,youwouldusethissametechniqueinGasiftheGas

programmerhasexportedtwosymbolsthatareidenticalexceptforcase.

TheprogramsinListings15-3and15-4,respectively,demonstratehow

tocallaMASMsubroutinefromanHLAmainprogram:

Listing15-3:MainHLAProgramtoLinkwithaMASMProgram.



//TocompilethismoduleandtheattendantMASMfile,usethe

//commandline:

//

//ml-cmasmupper.masm

//hlamasmdemo1.hlamasmupper.obj

programMasmDemo1;

#include("stdlib.hhf")



//Thefollowingexternaldeclarationdefinesafunctiont

//iswritteninMASMtoconvertthecharacterinALfrom

//lowercasetouppercase.



proceduremasmUpperCase(c:charinal);@external("masmU

static

s:string:="HelloWorld!";

beginMasmDemo1;

stdout.put("Stringconvertedtouppercase:'");

mov(s,edi);

while(mov([edi],al)<>#0)do

masmUpperCase(al);



stdout.putc(al);

inc(edi);

endwhile;

stdout.put("'"nl);

endMasmDemo1;



Listing15-4:CallingaMASMProcedurefromanHLAProgram:

MASMModule.

;MASMsourcefiletoaccompanytheMasmDemo1.HLAsource

;file.Thiscodecompilestoanobjectmodulethat

;getslinkedwithanHLAmainprogram.Thefunction

;belowconvertsthecharacterinALtouppercaseifit

;isalowercasecharacter.

.586

.modelflat,pascal

.code

publicmasmUpperCase

masmUpperCaseprocnear32

.ifal>='a'&&al<='z'

andal,5fh

.endif

ret

masmUpperCaseendp

end



ItisalsopossibletocallanHLAprocedurefromaMASMorGasprogram

(thisshouldbeobviousbecauseHLAcompilesitssourcecodetoan

assemblysourcefileandthatassemblysourcefilecancallHLA

proceduressuchasthosefoundintheHLAStandardLibrary).Thereare

afewrestrictionswhencallingHLAcodefromsomeotherlanguage.First



ofall,youcan'teasilyuseHLA'sexceptionhandlingfacilitiesinthe

modulesyoucallfromotherlanguages(includingMASMorGas).The

HLAmainprograminitializestheexceptionhandlingsystem.This

initializationisprobablynotdonebyyournon-HLAassemblyprograms.

Further,theHLAmainprogramexportsacoupleofimportantsymbols

neededbytheexceptionhandlingsubsystem;again,it'sunlikelyyour

non-HLAmainassemblyprogramprovidesthesepublicsymbols.Until

yougettothepointyoucanwritecodeinMASMorGastoproperlyset

uptheHLAexceptionhandlingsystem,youshouldnotexecuteanycode

thatusesthetry..endtry,raise,oranyotherexceptionhandling

statements.

Caution AlargepercentageoftheHLAStandardLibraryroutines

includeexceptionhandlingstatementsorcallotherroutines

thatuseexceptionhandlingstatements.Unlessyou'veset

uptheHLAexceptionhandlingsubsystemproperly,you

shouldnotcallanyHLAStandardLibraryroutinesfromnonHLAprograms.

Otherthantheissueofexceptionhandling,callingHLAproceduresfrom

standardassemblycodeisreallyeasy.Allyou'vegottodoisputan

@externalprototypeintheHLAcodetomakethesymbolyouwishto

accesspublicandthenincludeanEXTERN(orEXTERNDEF)statement

intheMASM/Gassourcefiletoprovidethelinkage.Thenjustcompilethe

twosourcefilesandlinkthemtogether.

AbouttheonlyissueyouneedconcernyourselfwithwhencallingHLA

proceduresfromassemblyistheparameterpassingmechanism.Of

course,ifyoupassallyourparametersinregisters(thebestplace),then

communicationbetweenthetwolanguagesistrivial.Justloadthe

registerswiththeappropriateparametersinyourMASM/Gascodeand

calltheHLAprocedure.InsidetheHLAprocedure,theparametervalues

willbesittingintheappropriateregisters(sortoftheconverseofwhat

happenedinListing15-4).

Ifyoudecidetopassparametersonthestack,notethatHLAnormally

usesthePascallanguage-callingmodel.Therefore,youpushparameters

onthestackintheordertheyappearinaparameterlist(fromleftto



right),anditisthecalledprocedure'sresponsibilitytoremovethe

parametersfromthestack.NotethatyoucanspecifythePascalcalling

conventionforusewithMASM'sINVOKEstatementusingthe".model"

directive.Forexample:

.586

.modelflat,pascal

.

.

.

Ofcourse,ifyoumanuallypushtheparametersonthestackyourself,

thenthespecificlanguagemodeldoesn'treallymatter.Gasusers,of

course,don'thavetheINVOKEstatement,sotheyhavetomanually

pushtheparametersthemselvesanyway.

ThissectionisnotgoingtoattempttogointogorydetailsaboutMASMor

Gassyntax.Presumably,youalreadyknowthatsyntaxifyou'rewanting

tocombineHLAwithMASMorGascode.Analternativeistoreadacopy

oftheDOS/16-biteditionofthistext(availableontheaccompanyingCDROM)thatusestheMASMassembler.ThattextdescribesMASMsyntax

inmuchgreaterdetail,albeitfroma16-bitperspective.Finally,this

sectionisn'tgoingtogointoanyfurtherdetailbecause,quitefrankly,the

needtocallMASMorGascodefromHLA(orviceversa)justisn'tthat

great.Afterall,mostofthestuffyoucandowithMASMandGascanbe

donedirectlyinHLAsotherereallyislittleneedtospendmuchmore

timeonthissubject.Bettertomoveontomoreimportantquestions,such

as,"HowdoyoucallHLAroutinesfromCorPascal?"

[1]HLAmayassignadifferentnamethan"?741_myProc"whenyou

compiletheprogram.TheexactsymbolHLAchoosesvariesfromversion

toversionoftheassembler(itdependsonthenumberofsymbols

definedpriortothedefinitionofmyProc.Inthisexample,therewere741

staticsymbolsdefinedintheHLAStandardLibrarybeforethedefinition

ofmyProc.

[2]SupportwasaddedforthisinstructioninHLA1.33;we'llpretendfor



thesakeofexamplethatHLAstilldoesnotsupportthisinstruction.



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

2 Mixing HLA and MASM/Gas Code in the Same Program

Tải bản đầy đủ ngay(0 tr)

×