| About ·
Download ·
What's new ·
Usage ·
Flash virtual machine ·
Assembler syntax ·
Embedding Flasm ·
Optimization techniques ·
__bytecode__ ·
File size difference ·
Huge scripts ·
Quirks, bugs and crashes ·
History ·
Project state ·
Resources ·
Terms of use ·
Enjoy AboutFlasm disassembles your entire SWF including all the timelines and events. Looking at disassembly, you learn how the Flash compiler works, which improves your ActionScript skills. You can also do some optimizations on the disassembled code by hand or adjust the code as you wish. Flasm then applies your changes to the original SWF, replacing original actions.
It's also possible to embed Flasm actions in your ActionScript,
making optimizing of large projects more comfortable.
 
Flasm is not a decompiler. What you get is the human readable representation of SWF bytecodes, not ActionScript source. If you're looking for a decompiler, Flare may suit your needs. However, Flare can't alter the SWF.
 
Page too long? You don't have to read it all. First, make yourself familiar with usage. Then read flash virtual machine topic to understand the concept of registers and stack. Disassemble some of your SWFs, starting with simpler ones, to see the inner workings of the Flash compiler. The rest of this page tries to address questions you may have at this point.
 DownloadMost recent Flasm version is 1.62.
Windows binary:  flasm16win.zipMac OS X binary:  flasm16mac.tgz
 Linux x86 binary:  flasm16linux.tgz
 
There is no installation procedure. Just create a folder named flasmsomewhere and unpack the archive there. To uninstall, delete the folder and you're done. Flasm doesn't touch your system files or registry. 
Third-party distributions and translations
 
FreeBSD port is maintained by Jun Kuriyama, Redhat RPMs are built by Daichi Shinozaki. They may be some versions behind the current and are not tested by me. If something goes wrong, please contact the maintainers. Jaco has translated Flasm manual into Italian.
 
Want to compile from sources?
 
Source code, platform independent: flasm16src.zip
 
You will need gcc or cc compiler with flex,bison,gperf,zlibandzlib-develpackages installed. It should compile well without any changes. Tested on Windows 2000 (Cygwin), Mac OS X, and Linux. For Cygwin, please installmingw,mingw-runtimeandmingw-zlibpackages too. On Windows, MS Visual C++ and other not entirely POSIX compatible compilers will require plenty of changes to the source. Consider Cygwin. What's new in Flasm 1.6 seriesFlasm 1.62
 
Bug fixes, thanks to Petr Ovtchenkov et al. 
Flasm 1.61
 
 
importAssets2tag fixplaceObject2tag fix (Flash 4)Calculate path to the flasm.iniin a more reliable way 
Flasm 1.6
 
 
Flash 8: support for metadata,fileAttributestagsFlash 8: support for placeObject3,importAssets2tags (Wang Zhen)"Update with Flasm and Preview" JSFL action now works in Flash 8 IDEWindows binary includes zlib 1.2.3Fixed: names of register parameters of function2may contain non-English charactersCalling Flasm without a command: flasm foo.flmhas the same effect asflasm -a foo.flm 
Older changes are listed in CHANGES.TXTincluded in distribution. UsageFlasm is a command line tool. To use it, you have to open DOS window first (Windows). On Mac OS X, open terminal window:Applications/Utilities/Terminal. Then go to the Flasm folder withcd c:\Flasm(Windows)  orcd /flasm(Mac/Linux), assuming you saved it here. To execute Flasm, simply type inflasm(Windows) or./flasm(Mac/Linux). Called without arguments, Flasm will show you the list of possible commands described below.
flasm command filename 
command
 -dDisassemble SWF file to the console
 -aAssemble Flasm project
 -uUpdate SWF file, replace Flasm macros
 -bAssemble actions to__bytecode__()instruction or byte sequence
 -zCompress SWF with zlib
 -xDecompress SWF
 
-d foo.swfDisassemble
 foo.swfto the console. To see action offsets in disassembly setshowoffsetandhexoffsetoptions inflasm.ini. 
-d foo.swf > foo.flmDisassemble
 foo.swf, redirect the output tofoo.flm. Calling Flasm without a command on a.swffile has the same effect. 
-a foo.flmAssemble
 foo.flmand update the SWF defined inside. Calling Flasm without a command on a.flmfile has the same effect.The backup of original SWF is created with
 .$wfextension. 
-u foo.swfDisassemble
 foo.swfto the temporary file.Execute Flasm macros embedded in SWF.
 Make trivial optimizations automatically: remove double nots, replace
 0.0with0, rebuild constant pools, clear register arguments.Create
 .$wfbackup, update the original SWF. 
It's a good idea to update the final version of SWF with flasm -u.
Don't expect the SWF to be noticeably faster, it will just make it a bit smaller. 
-b foo.txtproduce
 __bytecode__instruction or byte sequence, depending onboutputsetting inflasm.ini. Takes as input a simple
action list without anymovieorframedeclarations. Output is sent to console. Redirect it to file if you wish:flasm -b foo.txt > foo.asWhenboutputis set to1, Flasm produces binary output — probably of use for inserting raw action chunks into swf files build by other tools on server. 
-x foo.swfDecompress
 foo.swf, create.$wfbackup. 
-z foo.swfCompress
 foo.swf, create.$wfbackup.
Source SWF doesn't have to be Flash MX file. However, only Flash MX and later players
will be able to play the resulting compressed file. 
Flasm settings are read from the configuration file flasm.ini. Available options are commented inflasm.iniand explained at appropriate places in the documentation.flasm.iniis searched for in the working directory and, if not found, in the directory where the Flasm binary resides. 
All errors and warnings go to the console. If you want to log them in a file instead, uncomment logtooption inflasm.iniand enter the desired log file name there. Setlogmodeoption to0(default) to append new messages to the log file. Iflogmodeis set to1the log file will be overwritten each time you run Flasm. 
If you like Flasm and use it often, you may want to add it to Windows right-click context menu for SWF files.
The explanation is for Windows 2000, but it should work with minor changes for any Windows version.Start Windows Explorer. Select
 View, Folder Options,click theFile Typestab, and chooseFlash player movie(or similar) type, which stands for SWF file extension. ClickEditbutton, then clickNewbutton. In theActionfield enterDisassemble. Click theBrowsebutton, navigate to the Flasm's folder, and double-click onflasm.exe. No parameters are needed. ClickOK, Close,andCloseagain. Now right click on any SWF and chooseDisassemble. The disassembly ofsomename.swfwill be stored in filesomename.flmin SWF's folder.
Further automating is possible, addingflasm -ufor updating SWFs orflasm -afor assembling flm files. 
If you don't want to do that, look at WinFlasm — simple windows GUI wrapper for Flasm. Note WinFlasm is old and does not support all Flasm commands.
 Flash virtual machine
StackConstant pool
 Global registers
 Local registers
 
Every ActionScript statement is compiled by Flash into a couple of
simple bytecode actions. For example, a=b*b;is transformed into 
constants 'a', 'b'push 'a', 'b'
 getVariable
 push 'b'
 getVariable
 multiply
 setVariable
 
The bytecodes are stored in SWF in binary form. They are interpreted by the virtual machine
of the Flash Player. The code above is the visual representation of the bytecodes, created by Flasm.
 
I'll call actions inside of a frame or event action blocks.
Flash executes action blocks one after another, so the execution flow inside of a block is never interrupted, neither by event nor by gotoAndPlay()or similar actions. Real parallel execution would be nicer? I'm sure it would dramatically affect player stability, which is great now, considering all things going on in a complex movie. 
Stack
 
Flash virtual machine is stack based, you can not refer to the particular memory location.
The stack is a place in memory where data can be stored so that the
last entered (pushed) value will be extracted (popped) first from the stack.
Every command reads (and pops) operands from stack and pushes the result (if any) onto the stack.
 
The stack may contain elements of arbitrary type — integers, strings, floats and some others.
If needed, type conversion happens during execution — like in ActionScript.
Often there's no difference between the string '10', integer10or double10.0. 
Further stack explanation by Robert Penner:
 If you're familiar with Array.pushandArray.pop, those commands are similar to stack manipulations. The stack is like an array of values, except you can only access the value on top, push another value onto the top, or swap the top two values.For instance, to add two numbers, you have to push both of them onto the stack, then call
 add. Theaddcommand will pop the top two values off the stack, add them together, and push the value onto the stack. 
The popaction leads to no errors if the stack is empty. The specialUNDEFvalue is popped then, that corresponds to the ActionScript'sundefined. 
These two actions give you additional functionality for stack handling: dupandswap.dupduplicates the value on top of the stack,swapswaps the two topmost values. Currently Flash doesn't usedupandswapvery often as you'll see in disassembly, but they are of great importance for optimization. 
Every ActionScript statement, regardless of its complexity, leaves the stack empty after execution. In Flash IDE you don't see the bytecodes and don't have to worry about it.
Making changes to bytecodes with Flasm, however, you should always count what's on stack.
Improper stack manipulation often doesn't lead to any errors in Flash player.
You will not see the 10.000 dead stack entries your loop produced, but the execution will slow down and the SWF probably runs out of memory at some point.
 
The stack was global in Flash 5. If the value was pushed in frame 1, frame 5 could trace it successfully. It was accessible in movie clips too. With Flash MX the situation changed: Flash Players 6 and 7 flush stack contents after every action block.
 
Constant pool
 
At the beginning of every action block where variables, methods or strings are used more than once, Flash creates so called constant pool. In fact, if at least one variable is used twice, the pool is created for all strings in the block.
Here is an example:
 
constants 'bottom', 'paused', 'aliensleft', 'fire' 
Constant pool can hold up to 65535 strings (in theory). These can be addressed later in your actions with 1 byte (first 256 strings in the pool)
or 2 byte (the rest of the pool) reference. Commonly no more than 256 strings are stored, so you rarely meet 2 byte references in SWF. Practically the number of strings is limited by overall size of constantsaction, which can't exceed 65535 bytes like any other action. 
Flasm disassembler abstracts constant references away by default. They are showed as strings. To see actual references in disassembly, set literalconstantsoption inflasm.inito0. The difference between strings and constant pool members will be obvious then. 
Writing push c:1after the aboveconstantsdefinition means push second constant from the pool (counting from 0). Writingpush 'paused'will in turn have the same effect, because Flasm finds the constant in the pool automatically and substitutes string with reference during assembly. 
If no previous constant pool declaration is found in the same action block, however, the string 'paused'will be pushed as is. The difference is in code size only, not in execution speed — naturally, the string'paused'takes five bytes more than one-byte reference. Don't forget to add your strings to the constant pool. 
In update mode (flasm -u foo.swf) Flasm rebuilds all constants, removing empty strings and those referenced only once. 
The constant pool defined at the start of the frame is valid for every function in this frame. I've never seen constants defined in functions in disassembly. Every event has its own constant pool though.
 
Although Flash itself never redefines constant pool in the middle of the action block, theoretically you're allowed to do this. Flasm disassembler versions < 1.52 couldn't really deal with multiple constant pools. Flasm 1.52 will show constant references in c:xxform. To always show strings (resembles Flasm < 1.52 behavior, may be inaccurate) setliteralconstantsto2. 
Global registers
 
Flash virtual machine has 4 global registers that are addressed r:0, r:1, r:2, r:3.
Accessing variables is much slower than accessing registers, so you should store your most
used variables there. Flash versions before MX 2004 only usedr:0, so there was enough room for optimization. Flash MX 2004's compiler, however, may substitute local variables with other registers — a very good reason to use local variables in ActionScript. 
To store something in a register, you should first put this something onto the stack and then execute
setRegistercommand: 
push 'paused'getVariable
 setRegister r:1
 
Now the value of variable pausedis stored inr:1.
Instead of asking forpausednext time, usepush r:1.Note: Unlike most other commands,
 setRegisterdoes not pop the top value from stack! If you don't need the value stored in register to be on stack, you should manuallypopit. 
The value of global register, defined in a particular frame on _root,
is available to all functions in this frame. If some function is defined or movie clip happens here, it can access or overwrite the register too. It looks like after theshowFrametag occurs in SWF, registers disappear. Generally you don't know what happens to the global register. Of course, calling function A from the middle of function B should leave registers untouched. Flash MX 2004's compiler takes care of it — at the start of the function registers are saved on stack, at the end original values are restored. You should pay some attention here, too. 
Local registers
 
Inside of function2(Flash Player 6.0.65 and above), and only there, up to 255 local registers exist — fromr:0tor:254. Why not 256? In thefunction2header, the number of local registers used in this function is stored in a byte. At the start offunction2the place for local registers is allocated somewhere in memory. The highest possible value for a byte is 255. 
Generally, you don't have to care about the number of allocated registers — Flasm calculates this number automatically, and it's not shown in disassembly. Please take consequent registers numbers — using r:1andr:254only forces Flasm and Flash Player to allocate 255 registers, which may have impact on memory. 
Since local registers are addressed by the same bytecodes as global registers — setRegisterandpush r:something,function2has no access to the global registers. Even more confusing is the scope — imagine you haveframe A,function2 Binside ofA, andfunction Cinside ofB. Nowfunction2 Bnicely has its own set of registers, and is totally unaware of global registers. That's OK. Butfunction Cwill share four global registers withframe A! 
Besides of all that, local registers function just like global ones. There's no speed difference, too. To summarize: in SWF7 there are still four global registers everywhere outside function2, but anyfunction2may allocate a set of 255 local registers. Assembler syntaxData types and pushControl flow
 Button events
 Play head control
 setTarget/setTargetExpr
 function2
 try/catch/finally
 protect/enableDebugger
 scriptLimits
 Unknown actions
 
For details on SWF file format, read Macromedia's description and Alexis' SWF Reference. Macromedia has updated the docs for Flash 7 file format in November 2003. For historical reasons Flasm has its own names for some actions, slightly different from Macromedia's names. Important differences and abstractions are described here. If in doubt, look into action.hfrom Flasm's source distribution. 
Every Flasm project must start with movie 'moviename.swf'.
Themoviename.swfis the name of your SWF origin.
Don't forget to include the file name in quotes. At assembling time Flasm
first looks here and then tries to overwrite the file. The backup of target SWF is created
with.$wfextension.
If update fails for whatever reason, however, the original file will not be destroyed and no backup will be created. 
If compressedattribute is found just after movie name
(movie 'moviename.swf' compressed), SWF will be compressed after assembling. Original SWF may be compressed or not,compressedkeyword decides about compression of updated SWF. 
Flasm is case insensitive (excluding string values that may be case sensitive).
If you must use a single quote in your strings, escape it like this: 'it\'s beautiful'.
Alternatively you can include string in double quotes:"it's beautiful". 
Comments look exactly like in ActionScript:
 // calculating distanceor multi-line comment:
 
 /* calculatingdistance */
 
Flasm implements #includemacro.#include 'loop.flm'will be substituted with the contents ofloop.flm.
Nested and multiple includes are allowed too:foo.flmincludesroutine.flm, which includesloop.flmandcalc.flm.
Maximum nesting depth is 10. 
I introduced some extra constructs in order to match the SWF structure. These serve as containers for Flash actions: frame,defineButton,defineMovieClip,initMovieClip,movie,on,onClipEvent,placeMovieClip. 
Other supported tags:
enableDebugger,enableDebugger2,exportAssets,fileAttributes.importAssets,importAssets2,metadata,protect,scriptLimits. 
Please don't alter the SWF structure!
It means don't delete, replace or add action block containers! Well, you may add or delete an extra event without causing any damage. But if you remove a frame or change the movie clip id, Flasm will be no more able to find the pendant to it and any subsequent statements at assembling time.
 
Data types and push
 
Well, pushis the core action in SWF and we'll go a bit more into detail here.
Since you can push all kinds of values onto the stack, thepushaction has
an internal type attribute in SWF. While you don't see and can't access the push type from within Flasm,
Flasm decides what type to use based on how your data is formatted. 
 
| Push type | Number of bytes | What it means | Example |  | 0 | string length + 1  | string | push 'Hello' |  | 1 | 4 | float | push Y_PROPERTY |  | 2 | 0 | null | push NULL |  | 3 | 0 | undefined | push UNDEF |  | 4 | 1 | register | push r:2 |  | 5 | 1 | boolean | push TRUE |  | 6 | 8 | double | push 3.1415926 |  | 7 | 4 | integer | push 25 |  | 8 | 1 | constant (0-255) | push 'Hello' |  | 9 | 2 | constant (256-65534) | push 'Hello' |  
Strings must be included in single or double quotes and may contain escape characters: \b, \f, \n, \r, \tand\\.
No line break is allowed inside of a string.
If Flasm foundspush 'Hello'statement, it first looks into the constant pool
for the current action block. If the string is defined there, 1- or 2-byte reference is pushed (push type8or9);
if not, the string itself (type0). 
Integers are recognized in decimal and hexadecimal notation (0xF0F0).
Doubles are decimal:-3.1415926. The notation9.4e-10is supported too. In addition, constants_NAN,POSITIVE_INFINITYandNEGATIVE_INFINITYare defined
as double values. 
0.0is considered double;0is an integer.
Flash compiler itself always stores0as double0.0. In update mode Flasm will automatically replace all0.0occurrences with0, saving 4 bytes per each replace. 
Push type 1is only used by Flash to store property values. Flash 4 stored all number values as strings (push type0), Flash 5+ utilizes push type7for integers and push type6for floats. 
However, Flash is not the only program creating SWFs. I know now of at least one third-party program (3D-Flash Animator),
which uses type 1for actually storing numbers. So while Flasm will disassemble type1to property constant if
possible, all values that couldn't be resolved to any constant will be shown as floats:-3.1415926for100.0f. You can use this notation in your Flasm projects too, saving 4 bytes
per number. Any floating point value which ends withfwill be treated as
single-precision float and stored with push type1(beware of limited precision). The constants_NANF,POSITIVE_INFINITYFandNEGATIVE_INFINITYFare defined too. 
One pushstatement can handle multiple values of different types:push 'Hello', 3.141, XSCALE_PROPERTY. It's not just a shortcut
in Flasm for 3 singlepushactions, but a shorter and faster way. 
Control flow
 
Jumps inside of the action block are implemented with branchandbranchIfTrueactions. Every high level ActionScript construct likeif (..) then .. else ..orwhile (..) do ..is converted to somebranch/branchIfTruepattern.branchsimply jumps to the specified label. For example, the translation ofif .. then .. elseconstruct always has abranchafter itsthenpart, which skips theelsepart and jumps forward to the end ofif. Backward jumps are allowed too, loops always contain them.branchIfTruetakes the condition from stack. 
Internally relative numerical branch offsets are stored in SWF after every branch instruction. During disassembling Flasm creates unique label for every offset with the name label1 .. labelN, which hides the branch offset from your eyes and makes the disassembly more readable. The syntax isbranch label4orbranchIfTrue label6. Somewhere in the same action block the label (identifier followed by colon) must be present. You are by no means forced to use identifiers likelabel5:. Choose meaningful names (LoopStart:,SearchComplete:etc.) instead. 
Let's take an example: the really fast countdown loop, which can't be made with Flash (and can't be decompiled to any valid ActionScript).
 
push 0,1,2,3,4,5,6,7,8,9,10loopstart:
 dup
 trace
 branchIfTrue loopstart
 
First 10 values are pushed onto the stack. Note the last pushed value (10)
will be on top of the stack. We have to duplicate the value in loop withdup,
because we need it two times:tracepops the first value,branchIfTruegets the second as loop condition.
SincebranchIfTrueconverts condition to boolean,
loop executes until0is found, which evaluates to false and stops the loop. 
Button events
 
Every single button event oncontains one or multiple of the following: 
 
| idleToOverUp | overUpToIdle | overUpToOverDown |  | overDownToOverUp | overDownToOutDown | outDownToOverDown |  | outDownToIdle | idleToOverDown | overDownToIdle |  | keyPress |  |  |  
There's no one-to-one relation of ActionScript button events and events stored in SWF. Some ActionScript events actually set multiple SWF events. That's why the names are different.
 
keyPressis used in the formkeyPress 'char'orkeyPpress const,
for examplekeyPress 'a'orkeyPress _SPACE.
All constants correspond to those in Flash authoring:_BACKSPACE,_DELETE,_DOWN,_END,_ENTER,_ESCAPE,_HOME,_INSERT,_LEFT,_PAGEDOWN,_PAGEUP,_RIGHT,_SPACE,_TAB,_UP. 
You are free to change button event conditions in Flasm code.
 
Play head control
 
The SWF file format describes three actions for this task: gotoFrame(frame number as operand),gotoFrame2(takes the frame number from stack) andgotoLabel(frame label as operand).
While Flasm'sgotoFrameandgotoLabelactions are named exactly like their SWF format pendants,gotoFrame2action is not present.
For your conveniencegotoFrame2is showed asgotoAndPlay/gotoAndStop.
In SWFgotoFrame2is a sole action with a byte flag for play/stop. 
Additionally, if you have multiple scenes, Flash puts yet another argument here — the total number of frames in all scenes before the one you're jumping to.
These frames will be skipped by Flash player — in other words, added to the expression on stack.
This allows for using gotoAndPlay/gotoAndStopwith
a frame number inside of current scene instead of absolute frame number which starts from the beginning
of SWF. Remember, scenes do not exist in SWF. In this case Flasm will show you something likegotoAndStop skip 10. Note you're in trouble if your expression
represents label string instead of integer frame number. Flash player doesn't care and will add
frames to skip here too — and play head jumps to the false frame. Try using_root.gotoAndStop().
Here movie clip method will be used instead of single instruction. It does no corrections and will
work properly for labels. 
Higher Flash versions tend to use gotoAndPlay/gotoAndStopmethods of the movie clip object (passing them as strings) to control movie clips. 
gotoLabelis rarely seen in disassembly, because Flash
replaces it with frame-based actions exporting SWF.
Only if Flash can't resolve the frame number (the label is not on the same timeline),gotoLabelwill be left as is.
Labels, however, are still present in SWF and may be accessed from javascript
or whatever hosts the SWF, even if jumps to these labels were eliminated. 
setTarget and setTargetExpr
 
setTargetaction corresponds totellTargetin ActionScript.
If target is an expression,setTargetExpris used, which pops the target string from stack.
Flasm shows it like 
 
| setTarget '/defender'gotoFrame 1
 play
 end
 | or | setTargetExprgotoFrame 1
 play
 end
 |  
The endstatement does not exist in bytecode; Flash usessetTarget ''to mark the end of “targeted” statements. 
 
| setTarget '/defender'gotoFrame 1
 play
 setTarget ''
 | or | setTargetExprgotoFrame 1
 play
 setTarget ''
 |  
Since every setTargetis handled by Flash this way, I decided to make it look more readable. Nesting ofsetTargetblocks is not allowed. 
function2
 
Flash MX 2004 introduced new function2bytecode, which works in Flash Player 6.0.65 and above.function2is an extended version offunction.
In disassembly, it looks like this: 
function2 test (r:3='arg1', 'arg2', r:4='arg3') (r:1='this', r:2='_root') 
In first parenthesis function arguments are shown.
These arguments may be stored in local registers.
Each function2has its own set of local registers.
If register is absent, the corresponding argument isn't stored in register and behaves just like normal function argument. If register is present, the corresponding argument is stored there beforefunction2executes. 
You can't access arguments stored in registers by name (with getVariable), only byr:something(somethingbeing numerical or literal, see below).
That means their names are effectively useless in SWF. Ifclearregisterargsis set to1inflasm.ini,flasm -uwill remove these names from SWF, making it a bit smaller and forcing decompilers to name argumentsarg1, arg2, ...,because actual parameter names will be lost. To the best of my knowledge
it doesn't affect code execution in any way. 
Second parenthesis contains “automatic” parameters. Their values are calculated and stored in local registers before function executes, like function arguments. Currently (in SWF7) there are six possible values:
'this','arguments','super','_root','_parent'and'_global'.
Internally in SWF the corresponding bits in an unsigned integer
value are set to indicate the presence of such value. For the
sake of understandability Flasm shows them in literal form, however
you can't add your own particular value here or affect register
allocation. Registers are allocated by Flash Player in the above
order, i.e the value of'this'goes tor:1, the value of'arguments'tor:2etc. If'this'is absent,'arguments'goes tor:1.
If you accidentally tell Flasm to store automatic values in wrong registers, Flasm will report an error. 
So the use of local registers in function2is threefold: arguments, “automatic” values and local variables are stored there. 
If literalregistersflag is set to1inflasm.ini, Flasm will disassemblefunction2like this: 
function2 isSpace (r:1='char')push r:char
 ...
 end // of function isSpace
 
instead of 
 
function2 isSpace (r:1='char')push r:1
 ...
 end // of function isSpace
 
I.e. all function2arguments and automatic values like'this'will be shown with their literal names afterr:. Of course, you're free to write
your own code using literal registers.r:charin the example above means exactly the same asr:1,
and you may use numerical and literal notations together without any problems.
However, you can't name other registers (local variables or like). 
You can safely store your own values in local registers, Flasm automatically adjusts the number of registers to allocate for any function2. This number, although stored in SWF, is invisible in disassembly. A small side-effect: for whatever reason Flash compiler often allocates more registers than needed. Flasm will allocate the minimal possible number. 
An edge case: this,argumentsandsuperautomatic parameters will be suppressed by Flash player if they don't appear in second parenthesis. They will neither be stored in registers nor accessible by name inside offunction2. Normally, you don't care: if you need one of these, allocate a register for it. In the very special case where you don't want to do it, but still want to access the parameter by name, you can list it without register given. Listing'_root','_parent'and'_global'makes no difference. They are always available by name anyway. Nice, what? 
The try/catch/finally block
 
There is a new try-catch-finallyconstruct in Flash MX 2004. In SWF allcatchblocks are merged into one, and exception condition checking is done with
normal control flow there. In disassembly, the variable that holds the actual exception will be shown aftertrykeyword, notcatch. Like this: 
try 'e'push 'x'
 getVariable
 throw
 branch label1
 catch
 push 5
 trace
 label1:
 end // of try
 
 
Alternatively, condition may be held in a register: try r:2ortry r:something(literal register). Data type exceptions, for example, are always transferred through register, usuallyr:0. Other registers are used if error variable is declared local inside oftryblock (thanks to Alex Bradley for finding this out), or given as parameter tofunction2that contains thetry/catch/finallyblock. 
The throwaction stores condition in a variable or register given after thetrykeyword automatically, you don't have to do it explicitly.
The condition is then available at the start ofcatchblock. 
protect, enableDebugger and enableDebugger2 tags
 
protectwas meant by Macromedia as a hint for authoring program, saying that the author of particular SWF doesn't wish it to be opened in Flash IDE.protectis not actually protecting anything, any program that deals with SWF can simply ignore it. In Flasm,protectwill be shown, and can be added/deleted. You can place it anywhere in SWF, albeit usual location is somewhere near to the beginning. Noteprotectis not an action,
so it has to be outside of action blocks. Passwords are encoded by Flash compiler into a 28 characters long string, consisting of these parts (Paul Cannon): 
The Flasm will show the encoded string, but not the password.$1$at the start does signify an encryption scheme; it's the traditional way to
indicate a crypt-MD5 password. Everything between the second and third$is the salt, and everything after the last$is the hashed password, in a sort of base-64 representation. 
enableDebuggeris another attempt to secure the content of SWF. Always protected by password (Flasm will show the encoded string), this tag gives you the ability to “remote debug” the SWF. If you don't know the password, debugger will not let you in. If you delete the password, debugger will not let you in. But if you changeenableDebuggerparameter to'$1$.e$7cXTDev5MooPv3voVnOMX1', empty password will be accepted. 
To say it clear one more time: above tags, including encrypted passwords, give you no protection and can be safely deleted or altered.
 
Flash MX allows debugging on source code level, so there is a new tag enableDebugger2, which is used instead ofenableDebugger. It makes no difference at all. However, Flasm will not show another tag (63) or contents of external file used by debugger, don't know anything about their format. 
scriptLimits tag
 
Introduced with Flash Player 7, scriptLimits tag gives you control about the maximum recursion depth and the maximum time before the famous "Script causes the movie to run slowly.." message appears. So far I know, these settings can not be changed in Flash IDE. The following syntax is used:
 
scriptLimits recursion 2000 timeout 10 
While increasing recursion depth (256 by default) is surely useful in some situations, you may actually want to decrease the time-out for ActionScript for testing purposes. Instead of standard 15 or 20 seconds, setting the value to 1 or 2 will immediately show you where the bottlenecks are.
 
Unknown actions support
 
Flasm 1.6 knows every Flash action, including Flash 8 actions. Only subset of possible bytecodes, however, is currently used by Flash. Part of bytecodes space is reserved for third-party applications. For example, Apple's QuickTime added tag 0xAAfor QuickTime actions. Flasm is able to disassemble/assemble actions it doesn't know. The disassembly line looks like 
swfAction 0x02 // Unknown action! 
If the action has additional data, hexdatapart is present: 
swfAction 0xAA hexdata 0x43,0x12,0x18 // Unknown action! 
The data is shown as comma separated list of hex bytes.
If you define your own actions for some proprietary application, there is no need to include tag length in hexdatafield — the length is calculated and added automatically ifhexdatakeyword is found.
Don't forget, only bytecodes >0x80may have additional data. Embedding Flasm code in ActionScript
If invoked with -ucommand (flasm -u foo.swf), Flasm processes macros embedded in your ActionScript and updates the SWF with Flasm statements.
It's not unlike embedding assembler in C or Pascal. The syntax is a bit special to let Flash compile scripts without errors — you have to include Flasm statements in quotes. An example: 
"push 'Hello world!'""push myTextField"
 "setVariable"
 
The above has the same effect as myTextField = "Hello world!";ActionScript statement. Semicolons are not required, but will do no harm.
Flasm code strings are allowed everywhere in your scripts, so don't worry about the
right placement. Any restrictions? Sure. Don't define frames or movie clips in embedded Flasm. If you embed, you are already inside of some frame or event definition. Make sure the stack is empty after your embedded code executes. It's not a restriction, but you probably don't want to cause memory leaks. 
All Flasm actions behave as expected, there is only one important difference to consider — if you use constantsdeclaration in embedded scripts, Flasm will add them to the main pool in the action block instead of redefining it. The same goes forconstantsinside of any included file. Using#includeas part of the embedded string, please take care of slashes. Use normal slashes and not backslashes in file path. Latter will be escaped,
if not deleted by Flash. 
While Flasm works just fine with compression enabled in Flash MX, update process will require two additional steps: decompressing and compressing.
If your computer is slow, you may consider disabling compression in Flash publish settings. You can always compress SWF with flasm -zas last step before distribution. 
Testing embedded actions from within Flash IDE
 
Of course you can export the SWF, update it with Flasm, and check for errors then. Testing directly from Flash IDE would be nicer. Since Flash IDE has no post processing interface, it's rather tricky.
 
Flash 8 and Flash MX 2004
 
I've written a dll and a JSFL script which manages to preview your SWF in internal player. Here we go.
 
All Flasm messages and errors should go to the output window now. You may also use trace statements in Flasm code. Please note JSFL isn't that stable. Flash 8/MX 2004 may crash or run out of memory occasionally. This has nothing to do with my particular JSFL code or dll.Copy flasmhelper.dllfromhelperdirectory of Flasm distribution toExternal Librariesdirectory inside of your Flash configuration folder.On windows 2000 and XP Flash 8 configuration is located here:
 C:\Documents and Settings\username\Local Settings\Application Data\Macromedia\Flash 8\en\Configuration. The path will vary for non-English Windows and/or Flash.Copy Update with Flasm and Preview.jsfltoCommandsdirectory inside Flash configuration folder.Edit the first line of JSFL script and adjust path to the Flasm executable.
Start Flash 8/MX 2004. "Update with Flasm and Preview" should be now available under
"Commands". If you wish, associate a shortcut with it.
You are all set. Execute the command to preview embedded Flasm actions. You have to write some first :) If unsure, re-read previous section.
 
The dll is reasonably secure in the sense it will execute only a program called flasm.exe, nocommand.comor such. It should be enough to prevent simple abusing it from malicious JSFL scripts. The dll is tested under Windows 2000 and XP. Please tell me if it works for you on Windows 98/ME — or if it doesn't. 
It shouldn't be too hard to port the library to Mac. To a pity, I don't own a Mac and can't do it myself. If you have interest in porting, drop me a line, I'll make the source available on request. To make sure you have all the prerequisites, try compiling the Mac sample from Macromedia.
 
Flash 5 or MX
 
There was no JSFL. Sven König has found a way, and I've implemented it in Flasm. We'll make Flash believe Flasm is a browser.
While proper installation requires some tweaking, it will work like a charm once you got it.
I'll describe the procedure for Windows, but something similar should work on Mac too.
 
Flash will compile the SWF, look for browser shortcut, check the name (
 Copy flasm.exeandflasm.iniinto theBrowsersubdirectory of Flash.For Flash 5, the
 Browsersubdirectory is inside of your Flash install folder.Flash MX, stores settings elsewhere. If
 Browsersubdirectory does not exist, create it.Windows 2000 or XP:
 C:\Documents and Settings\username\Application Data\Macromedia\Flash MX\Configuration\BrowserWindows 98 or ME:
 C:\Windows\Application Data\Macromedia\Flash MX\Configuration\BrowserWindows NT:
 [Windows directory]\profiles\[username]\Application Data\Macromedia\Flash MX\Configuration\BrowserMac OS X:
 Hard Drive/Users/Library/Application Support/Macromedia/FlashMX/Configuration/BrowserEmbedding on Mac is untested, please drop me a line if you get it to work.
Rename flasm.exetoiexplore.exeCreate shortcut to your new iexplore.exein the same subdirectory. Don't worry, it doesn't affect
the real browser.Open flasm.iniin a text editor.
Changeflaplayerandflabrowservalues to contain your Flash player and internet browser path, respectively.
Long file names are not supported in dos, you should first discover what the corresponding short names look like:"C:\PROGRA~1\INTERN~1\IEXPLORE.EXE"or similar.
Even if you're on Win 2000, please use short names.
Set the value offlatestto “flaplayer”
if you want to test your files in player, and to “flabrowser”,
if you'll test in browser. You can changeflatestvalue later while testing without restarting machine or Flash.
or Flash IDE.Done. Now open your file in Flash, insert Flasm code, make sure HTMLand “Use Default Names”
boxes are checked in Flash publish settings, and pressF12(Publish Preview).
 iexplore.exe) is ok, give the HTML file name to Flasm. After calculating the real SWF name Flasm will update the SWF and invoke browser or player to show it.
The DOS box appears for the short time, but will only stay open if there are error messages to report.
I guess (based on my experience) the most popular error would be “Could not start: c:\...\...\foo.exe”,
because the path inflaplayerorflabrowseris wrong.
Correct it and try again.
Doesn't work? Have you tried it with Flash MX 2004 by chance? MX 2004 doesn't seem to support default browser mechanism any more, use the first dll/JSFL method.
 
Sometimes Flash just doesn't start Flasm. Enter something in actions window.
Or uncheck HTML in export settings, publish, check it again, publish. Or
delete iexplore shortcut from browser directory, publish, restore shortcut.
#includemay fail in Flash IDE if you haven't exported
the SWF to the right location before. Check publish settings. 
In Resources you'll find links to the small debugger by Pavils Jurjans and profiler by Ben Schleimer.
 Optimization techniquesMeasurementActionScript optimizations
 Flasm optimizations
 Double nots
 Thanks
 
Huge bitmaps, not optimized vectors, false frame rates, animating many movie clips at the same time, loading large XML files, dealing with tons of editable text, streaming high quality sound, or simply viewing SWF on mac — in 95% of all cases, bad SWF performance has nothing to do with ActionScript.
Flasm, although being “yet another cool tool”, is no solution for above problems.
Optimizing with Flasm makes sense for games, 3D engines, path finding, actually converting large amounts of data — computing things in general. Flash MX 2004 and Flash 8 made things much better here, too — at least for newer Flash Players.
 
If you're unsure where is the bottle neck: slow drawing or slow calculating, there is
a simple trick: make the player or browser window very small and switch aliasing off in the Flash Player. If performance increases significantly, you probably should optimize your graphics or movie clip structure first.
 
Measurement
 
Don't try to optimize every single line of your code — you'll just make it unreadable,
probably omit some important places, and nobody will ever notice 10.000 hours of your hard work. The key to any optimization is measurement. Bottle necks are very hard to guess. I used to have plenty of tips here, well tested for Flash 5 and Flash 4, but it just can't work this way because of the current diversity of possible environments. Now we have Flash Player 8, 7, 6, 5 and (still) 4  out there, stand-alone applications, mobile devices, not to mention Windows, Mac and Linux. These all are entirely different species. It means only some general strategies still work everywhere, and you have to measure your particular application on your target environment yourself. But how?
 
Optimize and test for your target environment. Tests in Flash IDE are very rough estimates at best.
 
You should differentiate between ActionScript code in FLA and compiled code in SWF. For example, if “Omit Trace Actions” is checked during publishing, traces simply do not make it into SWF. They do not exist there. The same goes for commented code.#included files are in effect exactly the same as inlined code, since they are first included, then compiled — nothing to test here, too. There are no classes in SWF — just functions. Flash compiler optimizes library function calls with constant arguments too.
Calls likef = Math.sin(0.25)orf = Math.max(3,5)are never saved in SWF, the calculated values go here. Neither willifparts with condition that always evaluates tofalsebe stored. Some local variables are stored in registers by the compiler, which makes a huge difference. And so on. Before you test, take a look at disassembly. 
Compiled bytecodes for Flash Player 7 are, err, context-dependant. Code inside of function2 benefits from local registers. The same code in a frame will not.
 
In a standard procedural programming language, most of the program time is spent in loops and functions or methods called from those loops. In Flash, frame loops and often or parallel called events should be investigated too.
 
Ben Schleimer's Flasm Profiler (or is it Flash Profiler?) and David Chang's ASProf are attempts to solve the main problem — what to optimize. I don't know how good they work, because I've not used them in a real-world project yet — they are relatively new. The profiler basically tells you execution times and number of calls for every function.
 
After you've found what's critical, find better algorithm first, or change your approach in general. Although you could improve the code in small, optimization should be the last resort.
 
Do all tests in a defined computer state — fresh booted, no virus scans or internet connection in background, all other programs closed. Don't move or resize widows during the test, don't do anything. Don't move your mouse, and let your mouse stay over flash movie. It does make a huge difference. That's not voodoo — OS manages your mouse, and Flash isn't the only running process. 
 
Think about graphics. A script is never interrupted, so it's relatively easy to measure. If, however, you start to measure in the first frame, and end in tenth, you measure everything in between and simply don't know what you measure. The result largely depends on player's mood and takes generally much longer, making your ActionScript test irrelevant. Network requests, gotoAndPlayactions and many other things related to screen refresh are executed asynchronously. Get them out of measured code parts. 
Beware of loop overhead. Short test times are not reliable, since the loop itself takes most of the time. Calculate time for an empty loop, function, etc. and subtract it from your results. Use big loops, so that remaining times are bigger then, say, 1000 ms. Computers aren't that exact in ms. Generally, try to isolate the code in question from anything else and measure  that code only. Of course, try to get other factors out of consideration first — network bandwidth, graphics etc. Otherwise you results can't be compared because of hidden overhead.
 
Mac Flash Player is slow compared to PC. Test on Macs early.
 
Don't execute different tests together. If you try to compare optimization 1 with optimization 2, give them the same environment. One run — one test. If you put both tests in the same frame, you start to deal with caching.
  
ActionScript optimizations
 
Flash Player 7 and 8 are much faster with ActionScript. Because of player improvements, and because of compiler improvements in Flash MX 2004/Flash 8. The latter are only noticeable if you compile for Flash Player 6 or higher though. If that's your target audience, you mostly can do now without Flasm optimizations, because the compiler will use registers anyway. You will still be able to achieve better performance with Flasm, but your first step should be getting Flash 8 IDE for critical applications.
 
I used to elaborate on so called “deprecated Flash 4 actions” here, which are much faster in Flash Player 5 or 6. The worst example: myMC.gotoAndStop()was 25 times slower thantellTarget("myMC") gotoAndStop(). In Flash Player 7 they finally don't seem to make a real difference. To insist on recommending them, I would have to re-do the whole testing, including mobile devices, so to hell with them. 
Action blocks are always executed from the start to the end, no event or gotoAndPlay()will interrupt execution of other code. That's the reason why any largeforloop will hang the player, no screen updates are made. 
Define local variables in functions with varkeyword. Local variables are
faster, generally a good practice, and may be replaced with registers automatically, if compiled with Flash MX 2004/Flash 8. 
evalis something special compared to, say,thisor any other ActionScript keyword. In fact,evalis kind of macro — it doesn't have a bytecode, but simply writes its argument onto the stack — at compile time. No doubt it's faster than any method call. Starting with Flash MX, you're no longer allowed to useevalon the left side of assignment. Usesetinstead. 
Unfortunately, identifier length still matters, even in Flash 8, so choose short names for variables. This can be extended to built-in functions too. Creating the function t = Math.tanand substituting allMath.tanoccurrences withtwill serve 2 purposes: no additional lookup is made for objectMath, then for methodtan; and the name itself is shorter. It works only for Flash 5+ methods and functions; Flash 4 functions will slow down.
Of course, names of local variables don't matter if they are stored in registers. 
The old trick with replacing b = a*4tob = a«2(shift) makes no speed difference in ActionScript. 
Flash tries to precalculate constant parts of your expressions. The calculation order results from operator precedence. As Robert Penner noticed, rad = Math.PI/180will actually store calculated value in SWF, whilerad = c*Math.PI/180will not. Conclusion: explicitly set the precedence to enable precalculation (rad = c*(Math.PI/180)in this case). 
forandwhileloops show no speed difference.
It depends on how you write them. The most optimized ActionScript examples of both, looping down to0, produce the same bytecode:for(var i = 10; i--;) {}andi = 10; while (i--) {}The third part of theforloop, absent in my example, is actually in the body of loop, so you can't compare it with a normalwhile. 
Avoid multiple parallel hitTest()functions in events — often seen in games.
If the player is killed after any touch with an enemy, and you have 100 duplicated enemy clips,
don't include any code in the enemy clipenterFrameevent.
Create the new movie clip and insert the enemy clip here. Then duplicate inside of this parent clip.
Now you can check with only onehitTest()if the collision
takes place. If you need to, use some custom math then to calculate what enemy was hit. Since most of the time no collision occurs, you'll make a really big improvement in fps. 
I mostly do not say “3.45 times slower”, because comparisons are very context dependant, exact values will vary. My “slower” just means “noticeably slower, no situation ever makes it faster”.
 
The list is by no means complete, and will never be. Technology may render some points incorrect, again. Please make your own tests.
 
Flasm optimizations
 
After you're done in ActionScript, and the code is still slow, you can start to optimize with Flasm.
Basically only two meaningful low-level features are not accessible from ActionScript and therefore subject of Flasm work: stack and registers.
 
Let's optimize a simple loop using stack. Our ActionScript is
 
for (var n=0; n<1000; n++) {someFunction(n);
 }
 
Flash compiles this loop to the following bytecodes:
 
 
| 
constants 'n', 'someFunction'    push 'n', 0.0
 varEquals
 label1:
 push 'n'
 getVariable
 push 1000
 lessThan
 not
 branchIfTrue label2
 
 push 'n'
 getVariable
 push 1, 'someFunction'
 callFunction
 pop
 
 push 'n', 'n'
 getVariable
 increment
 setVariable
 branch label1
 label2:
 | 
// Store all variables in constant pool// Push the string 'n' and starting 0 onto the stack
 // Initialize loop counter: n = 0
 // Start of the loop
 
 // Get the value of 'n' again
 // Push loop bound
 // Evaluate boolean condition: “n < 1000?”
 // Invert: now “n >= 1000?”
 // If “true” is on stack, go to the end of the loop
 
 // Loop body
 // Get the value of 'n' again
 // Push the number of args (1) and function name
 // function call is made with n as argument
 // Pop the possible function result away — it's unused
 
 // Push 'n' two times
 // Evaluate 'n' again
 // n+1 on stack now
 // n = n+1
 // jump to the loop start — unconditional
 // end of the loop — addressed with branchIfTrue above
 |  
What we immediately see, the nvariable is evaluated many times here.getVariableaction is slow compared to stack operations, and thenis only used as local counter.
Why not discardn, keep the counter on stack and use it over and over,
thus eliminating allgetVariablecalls?
We also don't need the constant pool declaration, sincenwill disappear,
andsomeFunctionname will be only used once.
The number of jumps can be reduces to one, too. We know we have to callsomeFunction(0),
so there is no need to check for the condition on the top of the loop.
Look at optimized version: 
 
| 
push 0loopStart:
 dup
 
 push 1, 'someFunction'
 callFunction
 pop
 
 increment
 dup
 push 1000
 lessThan
 branchIfTrue loopStart
 pop
 | 
// No need for double 0.0, integer 0 will do it// Choosing meaningful name
 // dup the counter — our function will eat it up
 
 // Push the number of args (1) and function name
 // function call is made with n as argument
 // Pop the possible function result away — it's unused
 // Now the counter is on top of the stack again
 // Increment it
 // Dup the counter — condition evaluation will eat it up
 // Push loop bound
 // Condition evaluation: counter < 1000?
 // Jump to the loop start, counter is on top
 // Should remove counter from stack after the loop
 |  
We can go even further. If our function, say, fills an array with some calculated values, it makes no difference
to do it from 0to999or from999“down to”0. We can eliminatelessThanaction in this case, becausebranchIfTrueis kind enough to convert0to false, and all other numbers to true for us. 
 | 
push 1000loopStart:
 decrement
 dup
 push 1, 'someFunction'
 callFunction
 pop
 dup
 branchIfTrue loopStart
 pop
 | 
 
We moved decrementto the top of the loop, because otherwisebranchIfTruewould immediately exit loop if
the counter value is0and not let us executesomeFunction(0). 
As you see, we end with a pretty clear loop version, which will be much faster than
the original Flash. How much, depends on what someFunction()does. As the next step you would go there and optimize it. 
The best way to learn how to use registers is to compile the same code in Flash MX 2004 for Flash 5, Flash 6, Flash 7, and look at the disassembly. Flash 5 version will use r:0only, Flash 6 will utilize all four global registers, and Flash 7/8 will add localfunction2registers. 
Now if your target is Flash 5, you'll see from Flash 6' code what can be done. For higher targets, the room for further optimization is smaller. But there are still many places where the code could be improved — basically by eliminating useless pops,pushes andbranches. 
pushstatements may push multiple values, not just one. Try to merge singlepushes into one. That's way faster. You'll have to slightly re-arrange the code to do that. 
Registers are faster than variables, but still slower than stack.
Why not keep all the values on stack so they go to the top just in the moment you need them?
The problem is, if you're doing this with 2 or more variables, your algorithm may want
to access them in a different order than they're stored. 
If some value is only required, say, at the start and at the end of your routine — no problem,
it happily lives somewhere at the bottom, waiting for its time coming, and lets you work
with other values on top. But for often needed values it doesn't work.
While we have swapaction to exchange two top values on stack,
we can't directly access the third. Even if you find some illusionistic approach to access
many variables, you'll just slow the execution with big amounts ofswapcommands. 
Double nots
 
In certain cases Flash writes double nots in your code.
Consider ActionScript codeif (a<=b) { ... } else { ... }Two
inversions are created here by Flash compiler: 
push 'b'// a>b?getVariable
 push 'a'
 getVariable
 lessThan
 
not// now inverted: a<=b?
 
not// prepare for branch to the else condition: again a>b?
 
branchIfTrue elseCondition
 
As you see, Flash is not very flexible compiling your statements and does not change the order of operands in expression or use another pattern for ifstatement.
It doesn't really make sense. The only purpose here could be an attempt to force type conversion to boolean. The next action you always see in the code, however,
isbranchIfTrue. And this action does type conversion itself.So Flasm will automatically remove those
 nots in update mode. 
Thanks
 
My very special thanks go to the people on flashcoders list, whose ideas helped me to
the better understanding of optimization and flowed into above examples:
 
Rasheed Abdal-Aziz, Ralf Bokelberg, Robin Debreuil, Zeh Fernando, Gary Fixler, Branden Hall, Dave Hayden, Damien Morton, Amos Olson, Robert Penner, Casper Schuirink.
 __bytecode__
__bytecode__function, first mentioned (1. post, 2. post) by Robin Debreuil is a way to inject bytecodes directly into swf without using Flasm (compare embedding). It takes a string filled with hexadecimal numbers as parameter. Since__bytecode__is evaluated at compile time, it is not possible to give it a variable parameter. While it's convenient to not rely on Flasm updating the swf,__bytecode__also offers an excellent way to shoot yourself in the foot. No checks are made by compiler here. You better make sure values are correct. Well, using Flasm in-bmode to produce__bytecode__parameter (or any other tool) at least guarantees proper instruction layout. Some caveats remain though. 
__bytecode__is a function and as such returns a value.
So singlepopaction is added by Flash IDE if the result is unused. You may also assign the return value to variable, then it will be something else thanpop. Normally, an extrapopis harmless. 
There are possible complications here with constant pools. Defining your own inside of __bytecode__will disable the pool automatically produced by compiler. Not defining makes the swf bigger. Define your own pool when needed and let__bytecode__reside in a place where there is no other ActionScript — don't mix. File size difference
After assembling Flasm source or updating SWF with Flasm you'll often see your SWF having few less bytes even if you haven't changed anything in the bytecode. Besides of trivial optimizations Flasm does in update mode, there is one more reason for it. Flash may save block lengthes in the SWF as 2 or 6 byte records. 6 bytes are only needed if the block is larger than 62 bytes. Flash, however, often uses 6 bytes where 2 bytes will do. Although Flasm does this too in certain cases, most blocks are optimized during assembling. So I get 400 less bytes on the file of 90kB length without optimizing anything. I don't know of any disadvantages, enjoy this unexpected Flasm bonus. Side note: ironically, there are places where long lengthes are required because of Flash player bugs, but Flasm is aware of this and will let them untouched.
 Huge scripts
While it's good practice to keep scripts smaller than 64k (compiled) per frame, it's possible to get larger. But the sole action record — constants, push, functionand other is limited to 64k because of 2 bytes length field size. 
Since Flash attempts to create the constant pool for all variables and methods, and never creates multiple constant pools, what does it do in such cases? Flash 5 compiler would silently write an overflowed value to the length field without errors or warnings. Later Flash versions are smarter: they would put so many strings as possible into constant pool, other strings just remain in place. Flash MX 2004 will even warn you about classes being too big. However, the compiler doesn't check other places where overflow may occur. Function length (ActionScript 1), for example, isn't verified and will be broken for very big functions.
 
If you try to execute this kind of SWF, Flash player crashes or actions are omitted. Disassembly will be incomplete and/or wrong. In most cases, Flasm will show an error message.
 Quirks, bugs and crashesFlasm may not be able to disassemble protected SWFs. The protection is usually achieved by inserting some kind of junk into SWF. Generally, such SWFs work in Flash Player, but break the SWF file format spec. Flasm, however, aims to support the spec, not to mimic essentially undefined behavior of some particular Flash Player version. What's my point here? Don't ask me to disassemble something you've downloaded somewhere. Neither will I tune Flasm to overcome any protections. They are not even interesting, and easy to fix with a hex editor.
Windows version of Flasm can't open unicode file names. It seems to be a Cygwin limitation.
 
When saving flm files in Windows Notepad/Editor, choose ANSI as encoding. In UTF-8 mode Notepad inserts so called byte order mark (BOM) at the start of the file, which irritates Flasm (and many other programs). If you work with UTF-8, please choose another editor, most of them don't add the BOM.
 
You can't compile something like function 0123ä()in Flash because of  parser limitations, the SWF format doesn't impose any restrictions on function names. Since Flasm deals with SWF directly, it should support such names, too. When assembling an SWF, you have to manually place quotes around problematic function names. Note: some of these (unicode names, for example, or Flasm keywords) are perfectly ok with Flash IDE, but interfere with Flasm parser. 
An edge case: nested tellTargetsdon't work if one of them is inside of a function. 
Don't know of any other bugs at the moment. If you find a nontrivial bug, fell free to send me your file. Please try to produce a minimal sample where the bug still occurs. The relevant part of source code or FLA is also welcome.
 
To make it clear: provided the SWF is valid, it must run properly after disassembling and assembling back without changes. The update mode must work too. There are absolutely no voodoo behaviors or unsupported features in Flasm. If you encounter problems, there must be a serious bug in my implementation and your report is highly appreciated.
 History
Dave Hayden released Flasm in cooperation with Damien Morton in April 2001.
The first version was able to disassemble the main timeline of the SWF and assemble to the first frame only. Flasm was quite useful already. I was very excited to discover Flasm back then, and soon started to play with source code. I've expanded Flasm's functionality and fixed some bugs. Dave then started the project on sourceforge.net. From 2002 until now I'm the only person developing and maintaining Flasm. Recently, Wang Zhen from Genable Labs has greatly contributed to Flasm 1.6.
 Project state
After five years of development Flasm is stable enough to be used in real-life projects and to my best knowledge fully supports all quirks of SWF format. I'm happy that during these time Flasm's source code has helped to develop some third-party software. My special thanks go to all the people who reported problems and suggested improvements. Now I'm busy with other projects and will not be able to implement exciting new features. Please send me your bug reports though, bug fixes will continue to happen.
 
It's unlikely I'll ever add support for Flash 9. As you may know, Flash Player 9 contains the new virtual machine, which is nothing like the old one. I see it as a natural end of Flasm's life cycle — supporting that would in fact mean writing another Flasm from scratch.
 Resources
This page can always be found at http://www.nowrap.de/flasm.html. The mirror at flasm.sourceforge.net is updated from time to time.
 
The source is available here or may be downloaded from SourceForge's CVS. Project page is http://sourceforge.net/projects/flasm.
 
Take a look at my another project: Flare, the free ActionScript decompiler.
 
On the original Flasm page resides the first version and the useful explanation of Flash 5 bytecodes by Dave.
 
Compare tree animations made by Amos Olson: standard ActionScript version and the optimized one.
 
Look at path finding swf made with Flasm by Casper Schuirink.
Here is the source.
 
MTASC, an open source ActionScript II compiler.
 
ActionScript problems are discussed on the highly frequented flashcoders mailing list,
maintained by Branden Hall.
 
Alexis' SWF Reference
 
Macromedia's SWF File Format description
 
At the prototype site you'll find some Flash functions redefined for speed or flexibility, and also many new and useful ones. Often it's better to start Flasm optimizing from one of them.
 
Extendflash mailing list deals mostly with JSAPI, which allows customizing Flash MX 2004 and Flash 8 IDEs. Some posts about SWF internals.
 
KineticFusion by Kinesis Software converts your complete SWF to XML and back. Pricey.
 
Ben Schleimer's Flasm Profiler shows you what to optimize in the first place.
 
Pavils Jurjans has written the little debugger for Flasm,
useful while embedding Flasm code in ActionScript. The debugger shows stack and register contents. 
 
Jon Bott's has written an obfuscator, based on Flasm.
 
For people who don't like to work with command line, and don't like to register Flasm as SWF handler in Windows Explorer either,
there is a WinFlasm by Sharriff Aina,
simple Windows interface to Flasm.
 
Albert Chosky has created Flasm  1.32 syntax files for EditPlus.
 
The older Flasm syntax file for UltraEdit, submitted by anonymous Russian flasmer.
 Terms of use
Copyright © 2001  Opaque Industries,  © 2002-2007  Igor Kogan,  © 2005  Wang ZhenAll rights reserved.
 
Flasm is completely free. It's provided “as is” and without any warranties. Please read the license included in the distribution for details.
 
Macromedia and Flash are registered trademarks of Adobe Systems Inc.
Adobe does not sponsor, affiliate, or endorse this product.
 EnjoyIgor Kogan
 
 
| Last significant update:  15 Juni 2007 |  | 
 |