home *** CD-ROM | disk | FTP | other *** search
/ Really Useful CD 1 / ReallyUsefulCD1.iso / extras / progutils / _moddis / docs / manual < prev   
Encoding:
Text File  |  1991-11-18  |  29.5 KB  |  636 lines

  1. >Manual
  2.  
  3.  
  4. DIRECTORY STRUCTURE
  5. ===================
  6.  
  7.     !Boot              Obey    Boot file
  8.     !Help              Text    Help file
  9.     !Run               Obey    Run file
  10.     !Sprites           Sprite  Sprite file
  11.     Checker            BASIC   Checks the validity of a re-assembled module
  12.     Docs.Changes12     Text    Major changes between versions 1 and 2
  13.     Docs.Changes23     Text    Major changes between versions 2 and 3
  14.     Dosc.Copyright     Text    Copyright details
  15.     Docs.GetStarted    Text    How to start quickly without reading the manual
  16.     Docs.Manual        Text    This manual
  17.     Externals.Default  BASIC   Library containing default external procedures
  18.     Flop               BASIC   Library containing floating-point macros
  19.     ModDis304          BASIC   The main program
  20.     Modules.           Dir     Newly-assembled modules are saved here
  21.     Originals.         Dir     The module to be disassembled should be put here
  22.     Scripts.           Dir     User responses are stored here
  23.     Sources.           Dir     Disassembled modules are stored here
  24.  
  25.  
  26. PROGRAM DESCRIPTION
  27. ===================
  28. This is version 3.04 of ModDis, and replaces those versions previously
  29. published (0.E, 0.F 1.04 and 2.01). It has various bug fixes and
  30. enhancements not available in previous versions. If you already have version
  31. 2.01, see the file Changes23 for details of important changes. If you don't
  32. want to read this manual yet try reading GetStarted and following its
  33. instructions.
  34.  
  35. ModDis a semi-intelligent module disassembler. It will read a relocatable
  36. module file from the Originals directory and attempt to disassemble it into
  37. a form suitable for the BASIC assembler. If successful, the Source file is
  38. stored in the Sources directory, under the same filename as the module. If,
  39. as is likely, the program cannot resolve the disassembly unaided, it will
  40. prompt the user for help, hence the "semi-intelligent" description. These
  41. responses will be stored in a Script file in the Scripts directory and can
  42. be played back later to re-create the disassembly. The validity of the
  43. disassembly can be tested by re-assembling, which makes a new version in the
  44. Modules directory. The BASIC program Checker can then be used to do a
  45. byte-by-byte comparison of the original and new versions.
  46.  
  47. I had already disassembled several modules by hand, and, while it is
  48. relatively easy, it becomes quite tedious as the module size increases. This
  49. program started as a quick utility to do some of the mechanical
  50. "donkey-work" aspects of disassembly, but has grown out of all proportion to
  51. its original aims. I have successfully disassembled all of the RISC OS 2
  52. modules, and there are usually only a handful of errors to sort out in the
  53. output assembler listing (see the Problems section for details). You should
  54. be warned, however, that some of the larger RISC OS modules can produce
  55. thousands of lines of assembler listing.
  56.  
  57. There are more enhancements in the pipeline, but it will probably be some
  58. time before they become available.
  59.  
  60.  
  61. IN USE
  62. ======
  63. Start by storing the module you want to disassemble in the Originals
  64. directory inside the ModDis app. Then double-click on !ModDis. There are 6
  65. logical variables which control the disassembly and which the user can
  66. change, located in PROCinit, around line 12300. All are TRUE by default,
  67. and the program can normally be run with these defaults.
  68.  
  69. debug%        If TRUE debugging information is displayed in cyan while
  70.               the program is running. This is useful for keeping an eye
  71.               on where the program has got to.
  72. flop%         If TRUE floating point instructions are recognised and
  73.               disassembled using the FNflop macro, otherwise floating
  74.               point instructions are rejected as coprocessor instructions.
  75. verbose%      If TRUE full output is enabled while Script files are being
  76.               replayed. This displays the full prompts and responses.If you
  77.               are re-creating a particularly large Source file from its
  78.               Script you may like to set verbose% to FALSE to speed up the
  79.               process.
  80. guessalign%   If TRUE alignment-byte guessing is enabled
  81. guessbratab%  If TRUE branch-table guessing is enabled
  82. guessldrstr%  If TRUE load/store double guessing is enabled
  83.  
  84.  
  85. HOW THE PROGRAM WORKS
  86. =====================
  87. The program identifies the "type" of each byte of the module, according to
  88. the following scheme:
  89.  
  90. type      description
  91. -4        'Acorn'-format compressed string. This is expanded as an EQUS
  92.           directive until a null-byte is encountered, provided the null-byte
  93.           is not preceded by an ASCII 27 byte.
  94. -3        Padded string, ie a string padded with zeros up to a fixed length.
  95.           The program prompts the user for the length of the string and
  96.           expands it as an EQUS directive. It is also useful for dealing
  97.           with 4-byte strings with no terminator, eg "TASK".
  98. -2        Carriage-return-terminated string. This is expanded as an EQUS
  99.           directive until a carriage-return is encountered,
  100. -1        Zero-terminated string. This is expanded as an EQUS directive
  101.           until a null-byte is encountered.
  102.  0        Don't know. All bytes have this value when the program starts, and
  103.           none should have it when the program ends.
  104.  1        A byte of data. Expanded as EQUB.
  105.  2        A word (2 bytes of data). Expanded as EQUW.
  106.  3        Address, ie a 4-byte number pointing to another point in the
  107.           module. It is expanded as EQUD followed by a label.
  108.  4        A double word (4 bytes of data). It is expanded as EQUD.
  109.  5        ARM code
  110.  6        Alignment bytes, 1, 2 or 3 bytes to bring us to a word boundary.
  111.           It is expanded as an ALIGN directive.
  112.  7        External. See below
  113.  
  114. These last four types should normally never be encountered by the user. They
  115. are used internally by the program whenever LDF or STF instructions are
  116. found.
  117.  
  118.  8        Floating-point, standard precision (4 bytes). Expanded as FNequfs.
  119.  9        Floating-point, double precision (8 bytes). Expanded as FNequfd.
  120. 10        Floating-point, extended precision (12 bytes). Expanded as FNequfe.
  121. 11        Floating-point, packed decimal (12 bytes). Expanded as FNequfp.
  122.  
  123. The first pass through the module is made armed with the entry points, eg
  124. initialisation code, finalisation code, etc. At this stage, ModDis is just
  125. setting the "type" of each byte it comes across, code, data or whatever. If
  126. it finds code, it follows it, and investigates branches and subroutine calls
  127. recursively, asking the user for help with identifying what it has found,
  128. where necessary. The program is smart enough to spot when the code ends, so
  129. it doesn't "fall off" into following data. It also recognises such things as
  130. SWI "OS_Exit", the zero-terminated string which always follows SWI
  131. "OS_WriteS",  and stuff like that.
  132.  
  133. After investigating all the entry points, it does one sequential pass
  134. through the module, searching for any bytes whose type has not yet been
  135. identified, and asking the user what they are.
  136.  
  137. Once all the types have been sorted out, the disassembly proper starts. If
  138. parts of the module are marked as data, they are expanded with EQU
  139. directives. The code is disassembled with calls to the Debugger module, but
  140. the following enhancements are made to its output:
  141.  
  142. 1. Labels are placed at all necessary points, as .xABCD where ABCD is the
  143.    offset in hex from the module start.
  144. 2. Wherever possible, sensible label names are constructed, eg SWI tables,
  145.    Keyword code, etc.
  146. 3. Branches are expanded to refer to labels.
  147. 4. Subroutines are identified by sABCD, rather than xABCD
  148. 5. PC-relative addressing is expanded as the ADR macro.
  149. 6. SWI names are enclosed in quotes.
  150. 7. The 2 instructions making up a 'long ADR' are recognised and represented
  151.    by a macro, FNadrl, to aid readability.
  152. 8. Floating-point instructions, if enabled, are expanded as the FNflop
  153.    macro.
  154.  
  155.  
  156. THE "What's this?" PROMPT
  157. =========================
  158. During the first pass through the module, the program will ask for help if
  159. it finds a reference to another part of the module, asking whether this
  160. reference is code to be disassembled, or data, in which case it wants to
  161. know what kind of data it is. The display looks like this:
  162.  
  163. [                 ]        This is the line currently being disassembled
  164. [    Block of     ]        and the three following, to show the context.
  165. [   yellow text   ]
  166. [                 ]
  167.                   
  168. [                 ]
  169. [    Block of     ]        A few lines preceding the reference
  170. [    white text   ]
  171. [                 ]
  172.  
  173. [     RED LINE    ]        The address being referred to
  174.  
  175. [                 ]
  176. [      More       ]        A few lines after the reference
  177. [    white text   ]
  178. [                 ]
  179.  
  180. What's this?               The prompt
  181.  
  182. The program expects a numeric response in the range -4 to 7.
  183.  
  184. It should be easy to tell if it's a string. Most strings are zero-terminated
  185. (type -1), but OS_CLI strings may be CR-terminated (-2). RISC OS menu labels
  186. are usually padded with zeros to 12 bytes; if you reply -3 you will be asked
  187. for the length of the padded string. 'Acorn'-format strings contain ASCII 27
  188. to indicate compressed dictionary entries; although zero-terminated they may
  189. also contain ASCII 0 immediately after ASCII 27.
  190.  
  191. Try to avoid replying 0 (don't know) if at all possible, because you'll have
  192. to answer sooner or later, and this may be your best oppertunity. There are
  193. however, two occasions when it is useful to answer 0. One is when the offset
  194. in question is obviously something like the module's title string, help
  195. string, or some other known entry point which is going to be recognised by
  196. the program later on. If you identify this offset now, it may not be fully
  197. followed-up by the program later. The other case is when the offset is
  198. pointing to the middle of an instruction, somewhere where a label cannnot be
  199. placed. See 'Odd labels' in the Problems section for more details.
  200.  
  201. Byte, word and address (1,2,3) are fairly rare. Make sure that the reference
  202. is word-aligned before replying 4 or 5 (double or code); if you get this
  203. wrong the program will keep re-prompting you until you give a valid
  204. response. It is unlikely that a reference will be made to alignment bytes
  205. (6). See the External section below for details of type 7.
  206.  
  207.  
  208. THE "bytes of unknown type" PROMPT
  209. ==================================
  210. This prompt will occur during the final sequential pass through the module.
  211. The display looks like this:
  212.  
  213. [                 ]
  214. [    Block of     ]                A few lines preceding the address
  215. [    white text   ]
  216. [                 ]
  217.  
  218. [     RED LINE    ]                The address being referred to
  219.  
  220. [                 ]
  221. [      More       ]                A few lines after the address
  222. [    white text   ]
  223. [                 ]
  224.  
  225. n byte(s) at ABC of unknown type   The prompt
  226.  
  227. This is your last chance to work out unresolved byte types. Note that if
  228. n is 69, this means that there is a block of more than 68 bytes whose types
  229. are unknown. The allowed responses are the similar to those above, with the
  230. following changes:
  231.  
  232. You must NOT reply "don't know" (0) at this prompt. If you answer 1,2,3 or 4
  233. (byte, word, address, double) the program will ask you how many of these
  234. items there are. If you answer 5 (code), you may get some more "What's
  235. this?" type prompts as the program re-enters its recursive code-following
  236. phase, but it will eventually return to where it left off. Alignment bytes
  237. (6) are easily recognised as 1, 2 or 3 zeros at the end of a string,
  238. bringing it to a word boundary. See the External section below for details
  239. of type 7.
  240.  
  241. If you can see by inspection that the block of bytes contains more than one
  242. "type", simply reply with the type number of whatever comes first, and the
  243. program will re-prompt you for the remainder.
  244.                                             
  245.  
  246. WHEN IT'S FINISHED
  247. ==================
  248. Once the program has finished, the Source file will be left in the Sources
  249. directory. Although it has a BASIC filetype, it is still in text format and
  250. the lines are terminated by carriage-return and linefeed characters. Before
  251. using it you should load it into an editor such as Edit or Twin (to help
  252. Twin users, the !Boot file programs the F8 key to do this) and remove the
  253. carriage returns. If you have Twin you can then load it into BASIC by simply
  254. exiting to BASIC , otherwise you should use the command
  255.     *BASIC -load <filename>
  256. If the Source file is very large you may find that this latter method
  257. doesn't work (there seems to be a problem with BASIC V). In this case you
  258. could add the line
  259.     AUTO 1,1
  260. at the start of the Source file, go to the BASIC prompt and type
  261.     *Exec <filename>
  262. pressing Escape when the loading stops.
  263.  
  264.  
  265. CHECKER
  266. =======
  267. To verify that the disassembly worked, you can re-assemble the module; the
  268. new version is stored in directory Modules. The program Checker does a
  269. byte-by-byte comparison of the original and new module, reporting on any
  270. differences it finds, as a disassembled instruction from each version. Any
  271. differences should be unimportant, as outlined in the Problems section below.
  272.  
  273.  
  274. FLOATING POINT MNEMONICS
  275. ========================
  276. The program will now disassemble floating-point instructions using a macro
  277. FNflop. This is accessed by a LIBRARY call which is built into every source
  278. file generated by ModDis. Also enabled are assembler directives FNequfs,
  279. FNequfd, FNequfe and FNequfp which store floating-point numbers to single,
  280. double, extended precision and packed decimal respectively. These directives
  281. are used by the program in response to LDF and STF instructions.
  282.  
  283.  
  284. THE EXTERNAL TYPE (7)
  285. =====================
  286. Rather than making the program general enough to cope with anything, I have
  287. allowed for the heading "none of the above" by creating type 7. If your
  288. module contains something weird, you can tell the program to cope with it,
  289. by writing your own PROCexternal, which marks the weird block as type 7, and
  290. PROCdisexternal, which copes with the disassembly of the block. These
  291. procedures should be put in a file in the Externals directory and the Script
  292. file should be edited to tell the program the name of the new External
  293. file. (See the section on Script file format below).
  294.  
  295. The default file (Externals.Default) consists of two empty procedures,
  296. namely:
  297.  
  298.     DEFPROCdisexternal
  299.     ENDPROC
  300.  
  301.     DEFPROCexternal
  302.     ENDPROC
  303.  
  304. PROCexternal is called once before the analysis of the module begins.
  305. PROCdisexternal is called during the final phase when the assembly listing
  306. is being spooled to file whenever a type 7 (external) is encountered. For
  307. example, if,say, a Sprite file of length &100 bytes is embedded in a module
  308. at offset &1234 then the user might create the following External file:
  309.  
  310.     DEFPROCdisexternal
  311.     PRINT"]"
  312.     PRINT"OSCLI""Load SpriteFile ""+STR$~(O%)"
  313.     PRINT"O%+=&100"
  314.     PRINT"P%+=&100"
  315.     PRINT"[OPT pass%"
  316.     offset%+=&100
  317.     ENDPROC
  318.  
  319.     DEFPROCexternal
  320.     FORoffset%=&1234TO&1333
  321.       type%(offset%)=7
  322.     NEXT
  323.     ENDPROC
  324.  
  325. In PROCexternal all the bytes corresponding to the Sprite file are set to
  326. type 7 (external) at the start of the program. When the disassembly proper
  327. comes across the first type 7 byte it calls PROCdisexternal. This prints the
  328. appropriate messages to exit the assembler, load the Sprite file at the
  329. assembler pointer O%, increment both O% and P% and re-enter the assembler.
  330. Finally it increments the ModDis pointer offset%.
  331.  
  332. Another good use for PROCexternal is if you know that the module contains a
  333. large block of, say, zero-terminated strings. rather than identifying each
  334. one individually at run time, you could put something like this in
  335. PROCexternal:
  336.     FOR offset%=&1234 TO &2468
  337.       type%(offset%)=-1
  338.     NEXT
  339. This will mark the block en-masse before the program proper starts.
  340.  
  341.  
  342. SCRIPT FILE FORMAT
  343. ==================
  344. The Script file format is a series of blocks like this:
  345.  
  346. begin keyword
  347. ...
  348. ...
  349. ...
  350. end
  351.  
  352. A line starting with the word "begin" marks the beginning of a block and a
  353. line consisting only of the word "end" marks the end. There can be any
  354. number of lines between the begin and end, although most blocks use only
  355. one. The order of the blocks is not important, except that the responses
  356. block must come last. The keywords currently recognised are as follows:
  357.  
  358.     KEYWORD      MEANING
  359.  
  360.     version      The version number of ModDis used to produce the script file.
  361.                  eg ModDis 3.04. This information is placed in the Script
  362.                  file by ModDis when it's created, and is used to make sure
  363.                  that the Script file is compatible with the version of the
  364.                  program in use.
  365.  
  366.     module       The name and version number of the module eg
  367.                      SpriteUtils  1.04 (22 Jul 1988)
  368.                  This is placed in the Script file by ModDis when it's
  369.                  created and is used to make sure that the Script file
  370.                  refers to the same module.
  371.  
  372.     nonreturn    The number of subroutines which modify their return address
  373.                  in some way, followed by the offsets of these subroutines.
  374.                  In most cases this will simply be a single zero. It is
  375.                  intended to cope with things like this:
  376.                      BL   s1234
  377.                      EQUS "Hello world"
  378.                      ....
  379.                  where the subroutine at offset 1234 does not return to
  380.                  execute the following instruction. To cope with this, the
  381.                  user would enter 1,1234 in the nonreturn block, meaning one
  382.                  subroutine at offset &1234. Note that ModDis does not
  383.                  automatically recognise these cases - it's up to you to spot
  384.                  them and modify the Script file manually to cope with them.
  385.  
  386.     external     The name of the BASIC file in the Externals directory which
  387.                  contains the external procedures used for this module. The
  388.                  default is "Default", which uses a file with empty
  389.                  procedures. If you want to use the external facility you
  390.                  should write your own external routines, store them in a file
  391.                  in the Externals directory and edit this block to contain
  392.                  the name of your External file.
  393.  
  394.     responses    The user responses, written as 3 numbers separated by
  395.                  commas. They consist of the offset in hex, the type of data
  396.                  at this offset and the number of items. For example,
  397.                  1240,-1,1 would mean one zero-terminated string at offset
  398.                  &1240. At present the responses block must be the last one
  399.                  in the Script file, and is not terminated by an "end". This
  400.                  may change in the future .
  401.  
  402. If you try to run this version with a Script file from version 2 it will
  403. display an error message and stop, but will write a file called "Header"
  404. into the current directory. You can simply paste this header into your old
  405. Script file to bring it up to version 3 standard. (Note: A few people have
  406. pre-release copies of version 3. If you are one of these, you should delete
  407. the first 2 lines of the Script file before adding the new header)
  408.  
  409.  
  410. TYPE GUESSING
  411. =============
  412. Version 3 of ModDis includes "guessing" for the first time. If it
  413. encounters some bytes of unknown type and there is no entry in the Script
  414. file the program applies some simple rules to try to establish what their
  415. type is before asking the user for help. At the moment there are three types
  416. of guessing:
  417.  
  418.     Alignment bytes    If the program is not on a word boundary, and all the
  419.                        bytes to the word boundary are zero then it guesses
  420.                        that these are alignment bytes. This action is
  421.                        controlled by the variable guessalign% - it takes
  422.                        place if the variable is TRUE
  423.  
  424.     Branch tables      If the program is on a word boundary and both this
  425.                        instruction and the previous one are unconditional
  426.                        branches then it guesses that this is part if a
  427.                        branch table. This action is controlled by the
  428.                        variable guessbratab% - it takes place if the
  429.                        variable is TRUE.
  430.  
  431.     Load/store word    If the program is at a load/store register
  432.                        instruction, then the location loaded from/stored to
  433.                        is guessed to be a double. This action is controlled
  434.                        by the variable guessldrstr% - it takes place if the
  435.                        variable is TRUE.
  436.  
  437. These three types of guessing were chosen initially because they were easy
  438. to implement and because they give very good results in practice. In most
  439. cases the amount of user interaction (and hence the size of the Script file)
  440. is reduced by about 30% and in extreme cases by as much as 60%. In the case
  441. of some very short modules guessing allows disassembly to be completed with
  442. no user intervention at all. The branch table guessing is particularly
  443. welcome since the old recognition routines never worked particularly well,
  444. and it was very tedious to be forced to single-step through a long table
  445. when it was perfectly obvious what it was.
  446.  
  447. There is, however, a penalty to be paid in that the guesses may sometimes
  448. not be what you would have chosen. For instance, it is common for certain
  449. strings (like TASK) to be stored as a double, but if it is accessed by an
  450. LDR then guessing will disassemble it as a double rather than a string.
  451. Also, guessing alignment bytes will only work if the original programmer has
  452. taken the trouble to initialise his workspace to zeros when the original
  453. module was assembled. If there are any garbage bytes showing through
  454. guessing will fail to recognise them alignment bytes.
  455.  
  456. Note that the program always checks the Script file first before resorting
  457. to guessing, so if you find that it's guessing wrong in one particular case
  458. you can manually add this one case to the Script file and leave guessing
  459. enabled for the rest of the module. If you find the program is guessing
  460. consistently wrong you should disable guessing and carry on as normal.
  461.  
  462.  
  463. CONFLICTS
  464. =========
  465. Conflicts can arise if the program identifies a byte as one type and then
  466. finds it was already marked as another. In these circumstances, the program
  467. offers the prompt "[A]dvance, [R]etreat, [S]top ?" when a conflict arises.
  468. Pressing "A" means go ahead and overwrite the old type with the new one. "R"
  469. means back off and leave things as they are while "S" means stop the program
  470. while you figure out what's happening.
  471.  
  472.  
  473. SYSTEM VARIABLES
  474. ================
  475. ModDis now stores the current filename in a system variable called
  476. ModDis$File. When prompted for a filename you can just press Return and
  477. ModDis will look up the system variable and use it as a filename. This
  478. system variable is also used by the Checker program if you don't give it a
  479. filename. The idea is that if you need to exit ModDis to edit the Script
  480. file manually, you can restart easily. Obviously the system variable is
  481. created the first time ModDis is run and is lost if the computer is reset
  482. so you must supply a filename at least once at the start of the ModDis
  483. session.
  484.  
  485.  
  486. COMMENTS
  487. ========
  488. Comments can now be placed in the Script file, but only in the responses
  489. block at the moment. Putting a ! as the first character on a line will cause
  490. that line to be ignored by the program. I only added this feature so that I
  491. could experiment with removing certain responses from the Script file to see
  492. if the guessing routines could cope without them, so it will probably be of
  493. limited use to the user.
  494.  
  495.  
  496. PROBLEMS
  497. ========
  498. This is a list of known problem areas with ModDis. In most cases the
  499. problems are obscure, or difficult to correct in the program, but easy to
  500. spot and fix in the final assembler listing.
  501.  
  502. Immediate constants
  503. -------------------
  504. An immediate constant is expressed as an 8-bit value with a 4-bit rotation
  505. applied to it. This means that there can be more than one way of expressing
  506. a constant, eg #1 can be represented as #1 with 0 rotation, #4 with a
  507. rotation of 2, etc. The BASIC assembler hides this process from the
  508. programmer, who merely supplies the required constant and lets the assembler
  509. figure out how to represent it. If the original module has #1 stored as
  510. 4>>2, the disassembler will convert this to #1, and the BASIC assembler will
  511. reassemble it as 1>>0. This is functionally identical, but a byte-by-byte
  512. comparison of the two modules will show a difference.
  513.  
  514. Another related problem is that the program sometimes fails to expand the
  515. constant at all, giving something like MOV R0,#0,24, ie 0 rotated by 24,
  516. which is still 0. This format, which the program generates through the
  517. debugger module, is not valid for the BASIC assembler and should be replaced
  518. by MOV R0,#0. Some of these are detected and translated by this version
  519. of the program, but it's not foolproof, and some still slip through. This
  520. problem is caused by a bug in the Debugger module. To solve it permanently,
  521. you need to modify the Debugger module itself, changing offset &920 from
  522. &1A000028  to &FA000028, effectively changing a BNE to a BNV. In months of use
  523. I have found this modification seems to have no drawbacks and I would
  524. recommend that you store a modified copy of the Debugger module in the
  525. ModDis directory and make the !Boot file load it automatically.
  526.  
  527.  
  528. The ADR directive
  529. -----------------
  530. ADR Rn,#address is converted by the assembler into either SUB Rn,PC,#offset
  531. or ADD Rn,PC,#offset, depending on whether the address comes before or after
  532. the current PC value. A problem arises in that ADD Rn,PC,#0 is functionally
  533. identical to SUB Rn,PC,#0. The BASIC assembler always chooses the former, so
  534. if the latter occurs in a module it will be converted from SUB to ADD
  535. leading to an apparent difference between the modules when compared
  536. byte-by-byte. It should have no effect on running the module.
  537.  
  538.  
  539. SWI branch table
  540. ----------------
  541. The program attempts to match the SWI names to the SWI branch table, but it
  542. sometimes fails to identify the branch table as belonging to the SWI
  543. routine. In this case it substitutes labels of the type xABCD, so the
  544. assembly is still syntactically correct (and logically) correct. I think
  545. this is one of those things you're going to have to live with.
  546.  
  547.  
  548. Embedded text
  549. -------------
  550. Something that cropped up in the NetPrint module was like this:
  551.           BL    s1234
  552.           EQUS  "A message"
  553.           More code...
  554. where the subroutine at s1234 adjusts the return address to skip the string.
  555. While ModDis recognises this if used with SWI "OS_WriteS", it cannot check
  556. for a user routine which does the same. ModDis will try to interpret the
  557. string as code, and there are two possible outcomes. Either it will succeed,
  558. and "drop through" into some following code, in which case you will never
  559. suspect anything untoward has happened unless you examine the Source file
  560. carefully, or it will find that the string disassembles as an undefined or
  561. coprocessor instruction, in which case it will print a warning message. In
  562. the latter case you can note the offset of the offending subroutine and edit
  563. the Script file to take account of it (See the section on Script file
  564. format).
  565.  
  566.  
  567. Odd labels
  568. ----------
  569. Sometimes a reference is made to, for example, the byte BEFORE a block of
  570. data, the pointer being incremented before use. Something like:
  571.           ADR   xF6F
  572.           ........
  573.           MOV   PC,R14
  574. .xF70     EQUS  "...."
  575. It is not possible to place a label at &F6F, since it lies in the middle of
  576. an instruction. Instead, you should manually substitute something like this:
  577.           ADR   xF70-1
  578. This sort of thing is usually fairly easy to spot.
  579.  
  580.  
  581. ALIGN
  582. -----
  583. When assembling a module, the ALIGN directive is used to move to a word
  584. boundary, simply incrementing the pointer by 1, 2 or 3. The bytes "skipped"
  585. like this are not explicitly set to zero, and will contain whatever was
  586. there at the time the module was originally compiled. When recompiling after
  587. running ModDis, these 'skipped" bytes may well have different values, and the
  588. Checker program will detect this, but since they play no part in the module,
  589. they are unimportant.
  590.  
  591.  
  592. Weirdos
  593. -------
  594. I have come across some code which looked like this:
  595.     BICEQ PC,R14,#&10000000
  596.     ORRNE PC,R14,#&10000000
  597.     EQUS "...."
  598. Now it's obvious that the program is returning from a subroutine with the
  599. overfow flag either set or clear, depending on the state of the zero flag.
  600. Unfortunately, the program sees both of these as *conditional* end-of-codes
  601. and assumes that there is more code following, and goes blundering on into
  602. the string. I can't see any obvious simple way to cope with this, and I wish
  603. the author had used
  604.     BICEQ PC,R14,#&10000000
  605.     ORR   PC,R14,#&10000000
  606.     EQUS "...."
  607. instead, in which case ModDis would have had no trouble with it.
  608.  
  609.  
  610. THE END
  611. =======
  612. My thanks to those users who reported bugs in the previous versions of
  613. ModDis, and to those who made suggestions on improving it, especially Ralph
  614. Corderoy who converted the program to a RISC-OS compliant application and
  615. made many improvements to the code (not all of which I have included yet -
  616. patience Ralph :-)). If you have any problems or (constructive) comments
  617. about ModDis, please get in touch with me. If you have any ideas for
  618. improving it, or if you extend it yourself, I'd be very glad to hear from
  619. you. I'd also be interested in comparing notes with anyone else out there
  620. who has written an ARM disassembler (anybody from BASS there? I can't find
  621. a copy of !Dissi anywhere).
  622.  
  623. Lorcan Mongey
  624. 56 Salisbury Court
  625. Dublin Road
  626. Belfast BT7 1DD
  627. Tel: 0232 234386
  628.  
  629. I can also be reached at the following BBS:
  630.  
  631. BBS                    Telephone      Username         Number
  632. ---                    ---------      --------         ------
  633. CIX                    081 390 1244   lorcan@cix.compulink.co.uk  
  634. The World of Cryton    0749 670030    lorcan           #237
  635. Arcade                 081 654 2212   lorcan           #417
  636.