diff options
-rw-r--r-- | License | 119 | ||||
-rw-r--r-- | Mkfiles/Makefile.dl | 2 | ||||
-rw-r--r-- | doc/internal.doc | 291 | ||||
-rw-r--r-- | doc/nasmdoc.src | 2 | ||||
-rw-r--r-- | insns.dat | 32 | ||||
-rw-r--r-- | misc/Doxyfile | 752 | ||||
-rw-r--r-- | misc/c16.mac | 49 | ||||
-rw-r--r-- | misc/c32.mac | 28 | ||||
-rw-r--r-- | misc/exebin2.mac | 114 | ||||
-rw-r--r-- | misc/findleak.pl | 41 | ||||
-rw-r--r-- | misc/findleak.txt | 59 | ||||
-rw-r--r-- | misc/hints.txt | 26 | ||||
-rw-r--r-- | misc/myC32.mac | 122 | ||||
-rw-r--r-- | misc/nasmstab | 296 | ||||
-rw-r--r-- | misc/proc32.ash | 441 | ||||
-rw-r--r-- | nasm.h | 2 | ||||
-rw-r--r-- | preproc.c | 2 | ||||
-rw-r--r-- | test/changed.asm | 383 |
18 files changed, 2737 insertions, 24 deletions
@@ -0,0 +1,119 @@ + +Terms and Conditions for the use of the Netwide Assembler +========================================================= + +Can I have the gist without reading the legalese? +------------------------------------------------- + +Basically, NASM is free. You can't charge for it. You can copy it as +much as you like. You can incorporate it, or bits of it, into other +free programs if you want. (But we want to know about it if you do, +and we want to be mentioned in the credits.) We may well allow you +to incorporate it into commercial software too, but we'll probably +demand some money for it, and we'll certainly demand to be given +credit. And in extreme cases (although I can't immediately think of +a reason we might actually want to do this) we may refuse to let you +do it at all. + +NASM LICENCE AGREEMENT +====================== + +By "the Software" this licence refers to the complete contents of +the NASM archive, excluding this licence document itself, and +excluding the contents of the `test' directory. The Netwide +Disassembler, NDISASM, is specifically included under this licence. + +I. The Software is freely redistributable; anyone may copy the +Software, or parts of the Software, and give away as many copies as +they like to anyone, as long as this licence document is kept with +the Software. Charging a fee for the Software is prohibited, +although a fee may be charged for the act of transferring a copy, +and you can offer warranty protection and charge a fee for that. + +II. The Software, or parts thereof, may be incorporated into other +freely redistributable software (by which we mean software that may +be obtained free of charge) without requiring permission from the +authors, as long as due credit is given to the authors of the +Software in the resulting work, as long as the authors are informed +of this action if possible, and as long as those parts of the +Software that are used remain under this licence. + +III. Modified forms of the Software may be created and distributed +as long as the authors are informed of this action if possible, as +long as the resulting work remains under this licence, as long as +the modified form of the Software is distributed with documentation +which still gives credit to the original authors of the Software, +and as long as the modified form of the Software is distributed with +a clear statement that it is not the original form of the Software +in the form that it was distributed by the authors. + +IV. The Software, or parts thereof, may be incorporated into other +software which is not freely redistributable (i.e. software for +which a fee is charged), as long as permission is granted from the +authors of the Software. The authors reserve the right to grant this +permission only for a fee, which may at our option take the form of +royalty payments. The authors also reserve the right to refuse to +grant permission if they deem it necessary. For further information +about who exactly the authors are, see clause XI below. + +V. The Software may be incorporated, in its original archive form, +into software collections or archives which are not freely +redistributable, as long as it is clearly stated that the Software +itself remains freely redistributable and remains under this licence +and no other. Such collections are deemed not to fall under article +IV of this licence. + +VI. Object files or programs generated by the Software as output do +not fall under this licence at all, and may be placed under any +licence the author wishes. The authors explicitly lay no claim to, +and assert no rights over, any programs written by other people and +assembled into object form by the Software. + +VII. You may not copy, modify or distribute the Software except +under the terms given in this licence document. You may not +sublicense the Software or in any way place it under any other +licence than this one. Since you have not signed this licence, you +are not of course required to accept it; however, no other licence +applies to the Software, and nothing else grants you any permission +to copy, modify, sublicense or distribute the Software in any way. +These actions are therefore prohibited if you do not accept this +licence. + +VIII. There is no warranty for the Software, to the extent permitted +by applicable law. The authors provide the Software "as is" without +warranty of any kind, either expressed or implied, including but not +limited to the implied warranties of merchantability and fitness for +a particular purpose. The entire risk as to the quality and +performance of the Software is with you. Should the Software prove +defective, you assume the cost of all necessary servicing, repair or +correction. + +IX. In no event, unless required by applicable law or agreed to in +writing, will any of the authors be liable to you for damages, +including any general, special, incidental or consequential damages, +arising out of the use or the inability to use the Software, +including but not limited to loss of data or data being rendered +inaccurate or a failure of the Software to operate with any other +programs, even if you have been advised of the possibility of such +damages. + +X. In addition to what this Licence otherwise provides, the Software +may be distributed in such a way as to be compliant with the GNU +General Public Licence, as published by the Free Software Foundation, +Cambridge, MA, USA; version 2, or, at your option, any later version; +incorporated herein by reference. You must include a copy of this +Licence with such distribution. Furthermore, patches sent to the +authors for the purpose of inclusion in the official release version +are considered cleared for release under the full terms of this +Licence. + +XI. The authors of NASM are the original authors (Simon Tatham and +Julian Hall) and all those who the original authors feel have +contributed significantly to the overall project. If you wish to +contact the authors, Julian Hall (jules@earthcorp.com) should be your +first port of call. + +XII. Should any part of this agreement be deemed unenforcable, it is +intended that the remainder of the agreement be held in force. + +END OF LICENCE AGREEMENT diff --git a/Mkfiles/Makefile.dl b/Mkfiles/Makefile.dl index db53e57..aadc7bc 100644 --- a/Mkfiles/Makefile.dl +++ b/Mkfiles/Makefile.dl @@ -1,5 +1,3 @@ -# Makefile for the Netwide Assembler under 16-bit DOS -# # The Netwide Assembler is copyright (C) 1996 Simon Tatham and # Julian Hall. All rights reserved. The software is # redistributable under the licence given in the file "Licence" diff --git a/doc/internal.doc b/doc/internal.doc new file mode 100644 index 0000000..8a73aa1 --- /dev/null +++ b/doc/internal.doc @@ -0,0 +1,291 @@ +Internals of the Netwide Assembler +================================== + +The Netwide Assembler is intended to be a modular, re-usable x86 +assembler, which can be embedded in other programs, for example as +the back end to a compiler. + +The assembler is composed of modules. The interfaces between them +look like: + + +--- preproc.c ----+ + | | + +---- parser.c ----+ + | | | + | float.c | + | | + +--- assemble.c ---+ + | | | + nasm.c ---+ insnsa.c +--- nasmlib.c + | | + +--- listing.c ----+ + | | + +---- labels.c ----+ + | | + +--- outform.c ----+ + | | + +----- *out.c -----+ + +In other words, each of `preproc.c', `parser.c', `assemble.c', +`labels.c', `listing.c', `outform.c' and each of the output format +modules `*out.c' are independent modules, which do not directly +inter-communicate except through the main program. + +The Netwide *Disassembler* is not intended to be particularly +portable or reusable or anything, however. So I won't bother +documenting it here. :-) + +nasmlib.c +--------- + +This is a library module; it contains simple library routines which +may be referenced by all other modules. Among these are a set of +wrappers around the standard `malloc' routines, which will report a +fatal error if they run out of memory, rather than returning NULL. + +preproc.c +--------- + +This contains a macro preprocessor, which takes a file name as input +and returns a sequence of preprocessed source lines. The only symbol +exported from the module is `nasmpp', which is a data structure of +type `Preproc', declared in nasm.h. This structure contains pointers +to all the functions designed to be callable from outside the +module. + +parser.c +-------- + +This contains a source-line parser. It parses `canonical' assembly +source lines, containing some combination of the `label', `opcode', +`operand' and `comment' fields: it does not process directives or +macros. It exports two functions: `parse_line' and `cleanup_insn'. + +`parse_line' is the main parser function: you pass it a source line +in ASCII text form, and it returns you an `insn' structure +containing all the details of the instruction on that line. The +parameters it requires are: + +- The location (segment, offset) where the instruction on this line + will eventually be placed. This is necessary in order to evaluate + expressions containing the Here token, `$'. + +- A function which can be called to retrieve the value of any + symbols the source line references. + +- Which pass the assembler is on: an undefined symbol only causes an + error condition on pass two. + +- The source line to be parsed. + +- A structure to fill with the results of the parse. + +- A function which can be called to report errors. + +Some instructions (DB, DW, DD for example) can require an arbitrary +amount of storage, and so some of the members of the resulting +`insn' structure will be dynamically allocated. The other function +exported by `parser.c' is `cleanup_insn', which can be called to +deallocate any dynamic storage associated with the results of a +parse. + +names.c +------- + +This doesn't count as a module - it defines a few arrays which are +shared between NASM and NDISASM, so it's a separate file which is +#included by both parser.c and disasm.c. + +float.c +------- + +This is essentially a library module: it exports one function, +`float_const', which converts an ASCII representation of a +floating-point number into an x86-compatible binary representation, +without using any built-in floating-point arithmetic (so it will run +on any platform, portably). It calls nothing, and is called only by +`parser.c'. Note that the function `float_const' must be passed an +error reporting routine. + +assemble.c +---------- + +This module contains the code generator: it translates `insn' +structures as returned from the parser module into actual generated +code which can be placed in an output file. It exports two +functions, `assemble' and `insn_size'. + +`insn_size' is designed to be called on pass one of assembly: it +takes an `insn' structure as input, and returns the amount of space +that would be taken up if the instruction described in the structure +were to be converted to real machine code. `insn_size' also requires +to be told the location (as a segment/offset pair) where the +instruction would be assembled, the mode of assembly (16/32 bit +default), and a function it can call to report errors. + +`assemble' is designed to be called on pass two: it takes all the +parameters that `insn_size' does, but has an extra parameter which +is an output driver. `assemble' actually converts the input +instruction into machine code, and outputs the machine code by means +of calling the `output' function of the driver. + +insnsa.c +-------- + +This is another library module: it exports one very big array of +instruction translations. It has to be a separate module so that DOS +compilers, with less memory to spare than typical Unix ones, can +cope with it. + +labels.c +-------- + +This module contains a label manager. It exports six functions: + +`init_labels' should be called before any other function in the +module. `cleanup_labels' may be called after all other use of the +module has finished, to deallocate storage. + +`define_label' is called to define new labels: you pass it the name +of the label to be defined, and the (segment,offset) pair giving the +value of the label. It is also passed an error-reporting function, +and an output driver structure (so that it can call the output +driver's label-definition function). `define_label' mentally +prepends the name of the most recently defined non-local label to +any label beginning with a period. + +`define_label_stub' is designed to be called in pass two, once all +the labels have already been defined: it does nothing except to +update the "most-recently-defined-non-local-label" status, so that +references to local labels in pass two will work correctly. + +`declare_as_global' is used to declare that a label should be +global. It must be called _before_ the label in question is defined. + +Finally, `lookup_label' attempts to translate a label name into a +(segment,offset) pair. It returns non-zero on success. + +The label manager module is (theoretically :) restartable: after +calling `cleanup_labels', you can call `init_labels' again, and +start a new assembly with a new set of symbols. + +listing.c +--------- + +This file contains the listing file generator. The interface to the +module is through the one symbol it exports, `nasmlist', which is a +structure containing six function pointers. The calling semantics of +these functions isn't terribly well thought out, as yet, but it +works (just about) so it's going to get left alone for now... + +outform.c +--------- + +This small module contains a set of routines to manage a list of +output formats, and select one given a keyword. It contains three +small routines: `ofmt_register' which registers an output driver as +part of the managed list, `ofmt_list' which lists the available +drivers on stdout, and `ofmt_find' which tries to find the driver +corresponding to a given name. + +The output modules +------------------ + +Each of the output modules, `outbin.o', `outelf.o' and so on, +exports only one symbol, which is an output driver data structure +containing pointers to all the functions needed to produce output +files of the appropriate type. + +The exception to this is `outcoff.o', which exports _two_ output +driver structures, since COFF and Win32 object file formats are very +similar and most of the code is shared between them. + +nasm.c +------ + +This is the main program: it calls all the functions in the above +modules, and puts them together to form a working assembler. We +hope. :-) + +Segment Mechanism +----------------- + +In NASM, the term `segment' is used to separate the different +sections/segments/groups of which an object file is composed. +Essentially, every address NASM is capable of understanding is +expressed as an offset from the beginning of some segment. + +The defining property of a segment is that if two symbols are +declared in the same segment, then the distance between them is +fixed at assembly time. Hence every externally-declared variable +must be declared in its own segment, since none of the locations of +these are known, and so no distances may be computed at assembly +time. + +The special segment value NO_SEG (-1) is used to denote an absolute +value, e.g. a constant whose value does not depend on relocation, +such as the _size_ of a data object. + +Apart from NO_SEG, segment indices all have their least significant +bit clear, if they refer to actual in-memory segments. For each +segment of this type, there is an auxiliary segment value, defined +to be the same number but with the LSB set, which denotes the +segment-base value of that segment, for object formats which support +it (Microsoft .OBJ, for example). + +Hence, if `textsym' is declared in a code segment with index 2, then +referencing `SEG textsym' would return zero offset from +segment-index 3. Or, in object formats which don't understand such +references, it would return an error instead. + +The next twist is SEG_ABS. Some symbols may be declared with a +segment value of SEG_ABS plus a 16-bit constant: this indicates that +they are far-absolute symbols, such as the BIOS keyboard buffer +under MS-DOS, which always resides at 0040h:001Eh. Far-absolutes are +handled with care in the parser, since they are supposed to evaluate +simply to their offset part within expressions, but applying SEG to +one should yield its segment part. A far-absolute should never find +its way _out_ of the parser, unless it is enclosed in a WRT clause, +in which case Microsoft 16-bit object formats will want to know +about it. + +Porting Issues +-------------- + +We have tried to write NASM in portable ANSI C: we do not assume +little-endianness or any hardware characteristics (in order that +NASM should work as a cross-assembler for x86 platforms, even when +run on other, stranger machines). + +Assumptions we _have_ made are: + +- We assume that `short' is at least 16 bits, and `long' at least + 32. This really _shouldn't_ be a problem, since Kernighan and + Ritchie tell us we are entitled to do so. + +- We rely on having more than 6 characters of significance on + externally linked symbols in the NASM sources. This may get fixed + at some point. We haven't yet come across a linker brain-dead + enough to get it wrong anyway. + +- We assume that `fopen' using the mode "wb" can be used to write + binary data files. This may be wrong on systems like VMS, with a + strange file system. Though why you'd want to run NASM on VMS is + beyond me anyway. + +That's it. Subject to those caveats, NASM should be completely +portable. If not, we _really_ want to know about it. + +Porting Non-Issues +------------------ + +The following is _not_ a portability problem, although it looks like +one. + +- When compiling with some versions of DJGPP, you may get errors + such as `warning: ANSI C forbids braced-groups within + expressions'. This isn't NASM's fault - the problem seems to be + that DJGPP's definitions of the <ctype.h> macros include a + GNU-specific C extension. So when compiling using -ansi and + -pedantic, DJGPP complains about its own header files. It isn't a + problem anyway, since it still generates correct code. diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src index 2a550e4..d588df7 100644 --- a/doc/nasmdoc.src +++ b/doc/nasmdoc.src @@ -7203,7 +7203,7 @@ This is a larger and more unwieldy version of \c{CMPXCHG}: it compares the 64-bit (eight-byte) value stored at \c{[mem]} with the value in \c{EDX:EAX}. If they are equal, it sets the zero flag and stores \c{ECX:EBX} into the memory area. If they are unequal, it -clears the zero flag and stores the memory contents into \c{EDX:EAX}. +clears the zero flag and leaves the memory area untouched. \c{CMPXCHG8B} can be used with the \c{LOCK} prefix, to allow atomic execution. This is useful in multi-processor and multi-tasking @@ -139,9 +139,9 @@ CALL imm|far \322\1\x9A\34\37 8086,ND CALL imm16 \320\1\xE8\64 8086 CALL imm16|near \320\1\xE8\64 8086 CALL imm16|far \320\1\x9A\34\37 8086,ND -CALL imm32 \321\1\xE8\64 386 -CALL imm32|near \321\1\xE8\64 386 -CALL imm32|far \321\1\x9A\34\37 386,ND +CALL imm32 \321\1\xE8\64 8086 +CALL imm32|near \321\1\xE8\64 8086 +CALL imm32|far \321\1\x9A\34\37 8086,ND CALL imm:imm \322\1\x9A\35\30 8086 CALL imm16:imm \320\1\x9A\31\30 8086 CALL imm:imm16 \320\1\x9A\31\30 8086 @@ -486,9 +486,9 @@ JMP imm|far \322\1\xEA\34\37 8086,ND JMP imm16 \320\1\xE9\64 8086 JMP imm16|near \320\1\xE9\64 8086,ND JMP imm16|far \320\1\xEA\34\37 8086,ND -JMP imm32 \321\1\xE9\64 386 -JMP imm32|near \321\1\xE9\64 386,ND -JMP imm32|far \321\1\xEA\34\37 386,ND +JMP imm32 \321\1\xE9\64 8086 +JMP imm32|near \321\1\xE9\64 8086,ND +JMP imm32|far \321\1\xEA\34\37 8086,ND JMP imm:imm \322\1\xEA\35\30 8086 JMP imm16:imm \320\1\xEA\31\30 8086 JMP imm:imm16 \320\1\xEA\31\30 8086 @@ -508,15 +508,15 @@ JMP mem32 \321\300\1\xFF\204 386 LAHF void \1\x9F 8086 LAR reg16,mem \320\301\2\x0F\x02\110 286,PROT,SM LAR reg16,reg16 \320\301\2\x0F\x02\110 286,PROT -LAR reg32,mem \321\301\2\x0F\x02\110 386,PROT,SM -LAR reg32,reg32 \321\301\2\x0F\x02\110 386,PROT +LAR reg32,mem \321\301\2\x0F\x02\110 286,PROT,SM +LAR reg32,reg32 \321\301\2\x0F\x02\110 286,PROT LDS reg16,mem \320\301\1\xC5\110 8086 -LDS reg32,mem \321\301\1\xC5\110 386 +LDS reg32,mem \321\301\1\xC5\110 8086 LEA reg16,mem \320\301\1\x8D\110 8086 -LEA reg32,mem \321\301\1\x8D\110 386 +LEA reg32,mem \321\301\1\x8D\110 8086 LEAVE void \1\xC9 186 LES reg16,mem \320\301\1\xC4\110 8086 -LES reg32,mem \321\301\1\xC4\110 386 +LES reg32,mem \321\301\1\xC4\110 8086 LFS reg16,mem \320\301\2\x0F\xB4\110 386 LFS reg32,mem \321\301\2\x0F\xB4\110 386 LGDT mem \300\2\x0F\x01\202 286,PRIV @@ -551,8 +551,8 @@ LOOPZ imm,reg_cx \310\1\xE1\50 8086 LOOPZ imm,reg_ecx \311\1\xE1\50 386 LSL reg16,mem \320\301\2\x0F\x03\110 286,PROT,SM LSL reg16,reg16 \320\301\2\x0F\x03\110 286,PROT -LSL reg32,mem \321\301\2\x0F\x03\110 386,PROT,SM -LSL reg32,reg32 \321\301\2\x0F\x03\110 386,PROT +LSL reg32,mem \321\301\2\x0F\x03\110 286,PROT,SM +LSL reg32,reg32 \321\301\2\x0F\x03\110 286,PROT LSS reg16,mem \320\301\2\x0F\xB2\110 386 LSS reg32,mem \321\301\2\x0F\xB2\110 386 LTR mem \300\1\x0F\17\203 286,PROT,PRIV @@ -564,14 +564,14 @@ MOV mem,reg_fsgs \300\1\x8C\101 386,SM MOV reg16,reg_cs \320\300\1\x8C\201 8086 MOV reg16,reg_dess \320\300\1\x8C\101 8086 MOV reg16,reg_fsgs \320\300\1\x8C\101 386 -MOV reg32,reg_cs \321\300\1\x8C\201 386 -MOV reg32,reg_dess \321\300\1\x8C\101 386 +MOV reg32,reg_cs \321\300\1\x8C\201 8086 +MOV reg32,reg_dess \321\300\1\x8C\101 8086 MOV reg32,reg_fsgs \321\300\1\x8C\101 386 MOV reg_dess,mem \301\1\x8E\110 8086,SM MOV reg_fsgs,mem \301\1\x8E\110 386,SM MOV reg_dess,reg16 \301\1\x8E\110 8086 MOV reg_fsgs,reg16 \301\1\x8E\110 386 -MOV reg_dess,reg32 \301\1\x8E\110 386 +MOV reg_dess,reg32 \301\1\x8E\110 8086 MOV reg_fsgs,reg32 \301\1\x8E\110 386 MOV reg_al,mem_offs \301\1\xA0\35 8086,SM MOV reg_ax,mem_offs \301\320\1\xA1\35 8086,SM diff --git a/misc/Doxyfile b/misc/Doxyfile new file mode 100644 index 0000000..1bb1cc3 --- /dev/null +++ b/misc/Doxyfile @@ -0,0 +1,752 @@ +# Doxyfile 1.2.5 + +# This file describes the settings to be used by doxygen for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "NASM - the Netwide Assembler" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.98 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doxy + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese, +# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian, +# Polish, Portuguese and Slovene. + +OUTPUT_LANGUAGE = English + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these class will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +STRIP_FROM_PATH = + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a class diagram (in Html and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. + +CLASS_DIAGRAMS = YES + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower case letters. If set to YES upper case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are adviced to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# The ENABLE_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consist of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +FILE_PATTERNS = *.c *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse. + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript and frames is required (for instance Netscape 4.0+ +# or Internet explorer 4.0+). + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = YES + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using a WORD or other. +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = YES + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tagfiles. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to +# YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other +# documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to +# YES then doxygen will generate a graph for each documented header file showing +# the documented files that directly or indirectly include this file + +INCLUDED_BY_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = /usr/local/bin/ + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/misc/c16.mac b/misc/c16.mac index 86e6bf9..50b5d5e 100644 --- a/misc/c16.mac +++ b/misc/c16.mac @@ -1,37 +1,82 @@ ; NASM macro set to make interfacing to 16-bit programs easier -*- nasm -*- + + %imacro proc 1 ; begin a procedure definition + %push proc + global %1 + %1: push bp + mov bp,sp + %ifdef FARCODE PASCAL ; arguments may start at bp+4 or bp+6 + %assign %$arg 6 + +%define %$firstarg 6 + %else + %assign %$arg 4 + +%define %$firstarg 4 + %endif + %define %$procname %1 + %endmacro + + %imacro arg 0-1 2 ; used with the argument name as a label - equ %$arg + +%00 equ %$arg + + ; we could possibly be adding some + + ; debug information at this point...? + %assign %$arg %1+%$arg + %endmacro + + %imacro endproc 0 + %ifnctx proc + %error Mismatched `endproc'/`proc' + %else + mov sp,bp + pop bp + %ifdef PASCAL - retf %$arg + + retf %$arg - %$firstarg + %elifdef FARCODE + retf + %else + retn + %endif + __end_%$procname: ; useful for calculating function size + %pop + %endif + %endmacro + diff --git a/misc/c32.mac b/misc/c32.mac index a59acfd..f0c116b 100644 --- a/misc/c32.mac +++ b/misc/c32.mac @@ -1,26 +1,52 @@ ; NASM macro set to make interfacing to 32-bit programs easier -*- nasm -*- + + %imacro proc 1 ; begin a procedure definition + %push proc + global %1 + %1: push ebp + mov ebp,esp + %assign %$arg 8 + %define %$procname %1 + %endmacro + + %imacro arg 0-1 4 ; used with the argument name as a label - equ %$arg + +%00 equ %$arg + %assign %$arg %1+%$arg + %endmacro + + %imacro endproc 0 + %ifnctx proc + %error Mismatched `endproc'/`proc' + %else + leave + ret + __end_%$procname: ; useful for calculating function size + %pop + %endif + %endmacro + diff --git a/misc/exebin2.mac b/misc/exebin2.mac new file mode 100644 index 0000000..89c6889 --- /dev/null +++ b/misc/exebin2.mac @@ -0,0 +1,114 @@ +; -*- nasm -*- + +; NASM macro file to allow the `bin' output format to generate + +; simple .EXE files by constructing the EXE header by hand. + +; Adapted from a contribution by Yann Guidon <whygee_corp@hol.fr> + + + +%define EXE_stack_size EXE_realstacksize + + + +%macro EXE_begin 0 + + ORG 0E0h + + section .text + + + +header_start: + + db 4Dh,5Ah ; EXE file signature + + dw EXE_allocsize % 512 + + dw (EXE_allocsize + 511) / 512 + + dw 0 ; relocation information: none + + dw (header_end-header_start)/16 ; header size in paragraphs + + dw (EXE_absssize + EXE_realstacksize) / 16 ; min extra mem + + dw (EXE_absssize + EXE_realstacksize) / 16 ; max extra mem + + dw -10h ; Initial SS (before fixup) + + dw EXE_endbss + EXE_realstacksize ; Initial SP (1K DPMI+1K STACK) + + dw 0 ; (no) Checksum + + dw 100h ; Initial IP - start just after the header + + dw -10h ; Initial CS (before fixup) + + dw 0 ; file offset to relocation table: none + + dw 0 ; (no overlay) + + align 16,db 0 + +header_end: + + + +EXE_startcode: + + section .data + +EXE_startdata: + + section .bss + +EXE_startbss: + +%endmacro + + + +%macro EXE_stack 1 + +EXE_realstacksize equ %1 + +%define EXE_stack_size EXE_bogusstacksize ; defeat EQU in EXE_end + +%endmacro + + + +%macro EXE_end 0 + + section .text + +EXE_endcode: + + section .data + +EXE_enddata: + + section .bss + + alignb 4 + +EXE_endbss: + + + +EXE_acodesize equ (EXE_endcode-EXE_startcode+3) & (~3) + +EXE_datasize equ EXE_enddata-EXE_startdata + +EXE_absssize equ (EXE_endbss-EXE_startbss+3) & (~3) + +EXE_allocsize equ EXE_acodesize + EXE_datasize + + + +EXE_stack_size equ 0x800 ; default if nothing else was used + +%endmacro + diff --git a/misc/findleak.pl b/misc/findleak.pl new file mode 100644 index 0000000..727628b --- /dev/null +++ b/misc/findleak.pl @@ -0,0 +1,41 @@ +#!/usr/bin/perl +my %mem = {}; +my %alloc = {}; +while(<>) +{ + if (/realloc\((0x[0-9a-f]+).*\).*returns \((0x[0-9a-f]+)/) + { + $mem{$1}--; + if ($mem{$1} != 0) { + print "free before alloc! $_"; + } + if ($mem{$2} != 0) { + print "memory leak! $_"; + } + $mem{$2}++; + $alloc{$2} = $_; + } + elsif (/free\((0x[0-9a-f]+)/) + { + $mem{$1}--; + if ($mem{$1} != 0) { + print "free before alloc! $_"; + } + } + elsif (m/returns (0x[0-9a-f]+)/) + { + if ($mem{$1} != 0) { + print "memory leak! $_"; + } + $mem{$1}++; + $alloc{$1} = $_; + } +} +foreach $goo (sort keys %mem) +{ + if ($mem{$goo}) + { + print "$mem{$goo} $alloc{$goo}"; + } +} +# From: Ed Beroset <beroset@mindspring.com> diff --git a/misc/findleak.txt b/misc/findleak.txt new file mode 100644 index 0000000..8a1cfdc --- /dev/null +++ b/misc/findleak.txt @@ -0,0 +1,59 @@ +Subject: [nasm-devel] tool to help find memory leaks +Date: Fri, 02 Nov 2001 22:08:01 -0500 +From: Ed Beroset <beroset@mindspring.com> +Reply-To: nasm-devel@yahoogroups.com +To: nasm-devel@yahoogroups.com + +Here's a little Perl script I wrote a while ago to help track down memory +leaks in nasm. First, compile nasm with LOGALLOC defined (see +nasmlib.c). That creates a log file of all allocs and frees. This Perl +script reads that file and tells you which source code lines caused a leak +(or a free of unallocated memory). There are many leaks, almost all of +them in the preprocessor. + +-+--- findleak.pl begins +#!/usr/bin/perl +my %mem = {}; +my %alloc = {}; +while(<>) +{ + if (/realloc\((0x[0-9a-f]+).*\).*returns \((0x[0-9a-f]+)/) + { + $mem{$1}--; + if ($mem{$1} != 0) { + print "free before alloc! $_"; + } + if ($mem{$2} != 0) { + print "memory leak! $_"; + } + $mem{$2}++; + $alloc{$2} = $_; + } + elsif (/free\((0x[0-9a-f]+)/) + { + $mem{$1}--; + if ($mem{$1} != 0) { + print "free before alloc! $_"; + } + } + elsif (m/returns (0x[0-9a-f]+)/) + { + if ($mem{$1} != 0) { + print "memory leak! $_"; + } + $mem{$1}++; + $alloc{$1} = $_; + } +} +foreach $goo (sort keys %mem) +{ + if ($mem{$goo}) + { + print "$mem{$goo} $alloc{$goo}"; + } +} +-+--- findleak.pl ends + + + +Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/ diff --git a/misc/hints.txt b/misc/hints.txt new file mode 100644 index 0000000..576e1cf --- /dev/null +++ b/misc/hints.txt @@ -0,0 +1,26 @@ +Subject: Re: [nasm-devel] P4 insns +Date: Sat, 05 May 2001 11:39:36 -0500 +From: Kyle Markley <kmarkley@seffera.net> +Reply-To: nasm-devel@yahoogroups.com +To: nasm-devel@yahoogroups.com + +berkus wrote: +> +> Use The Source, NASM! +> +> Do we have the P4 'probable branch taken' (3e) and 'probable branch +> not taken' (2e) prefixes opcodes? + +They're just segment override prefixes: 2e is CS, 3e is DS. You can just +say +"cs jnz foo" for a not-taken hint, "ds jnz foo" for a taken hint. + +Maybe it would be nice to have a more suggestive name, but you could just +%define one. + +--- +Kyle Markley + + + +Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/ diff --git a/misc/myC32.mac b/misc/myC32.mac new file mode 100644 index 0000000..2088e85 --- /dev/null +++ b/misc/myC32.mac @@ -0,0 +1,122 @@ +; NASM macro set to make interfacing to 32-bit programs easier +; Also cool little macros to make NASM emulate some MASM things. +; +; Originally included in NASM. Modifications by Peter Johnson, 1999. +; +; $Id$ + +%imacro proc 1 ; begin a procedure definition +%push proc + global %1 +%1: push ebp + mov ebp, esp +%assign %$arg 8 +;%assign %$argnum 0 +%define %$procname %1 +%endmacro + +%imacro arg 0-1 4 ; used with the argument name as a label +%00 equ %$arg +;%assign %$argnum %$argnum+1 +;.arg%$argnum equ %1 +%assign %$arg %1+%$arg +%endmacro + +%imacro endproc 0 +%ifnctx proc +%error Mismatched `endproc'/`proc' +%else +; mov esp, ebp +; pop ebp +%ifdef LEGACY_ENDPROC + ret +%endif +;__end_%$procname: ; useful for calculating function size +; global %{$procname}_arglen +;%{$procname}_arglen equ %$arg-8 +;%assign %$i 1 +;%rep %$argnum +; global %{$procname}_arg%$i +;%{$procname}_arg%$i equ %{$procname}.arg%$i +;%assign %$i %$i+1 +;%endrep +%pop +%endif +%endmacro + +; redefine ret instructions for in-proc cases +%imacro ret 0-1 +%ifnctx proc + ret %1 +%else + mov esp, ebp + pop ebp + ret %1 +%endif +%endmacro + +%imacro retf 0-1 +%ifnctx proc + retf %1 +%else + mov esp, ebp + pop ebp + retf %1 +%endif +%endmacro + +%imacro retn 0-1 +%ifnctx proc + retn %1 +%else + mov esp, ebp + pop ebp + retn %1 +%endif +%endmacro + +; invoke calls a C function +; defaults to word (16 bit) size parameters +%macro invoke 1-* +%rotate -1 +;%define invoketype word +%rep (%0-1) +; %ifidni %1,dword +; %define invoketype dword +; %elifidni %1,word +; %define invoketype word +; %elifidni %1,byte +; %define invoketype byte +; %else + %ifidni %1, cs + o16 push %1 + %elifidni %1, ds + o16 push %1 + %elifidni %1, es + o16 push %1 + %elifidni %1, fs + o16 push %1 + %elifidni %1, gs + o16 push %1 + %elifidni %1, word cs + o16 push %1 + %elifidni %1, word ds + o16 push %1 + %elifidni %1, word es + o16 push %1 + %elifidni %1, word fs + o16 push %1 + %elifidni %1, word gs + o16 push %1 + %else + push %1 + %endif +; %endif + %rotate -1 +%endrep +call %1 +%if (%0!=1) + add esp, byte %{1}_arglen +%endif +%endmacro + diff --git a/misc/nasmstab b/misc/nasmstab new file mode 100644 index 0000000..d61d88a --- /dev/null +++ b/misc/nasmstab @@ -0,0 +1,296 @@ +#!/usr/bin/perl + +sub StabLine ($ $ $ $ $ $) { + local ($comment,$n_strx,$type,$other,$desc,$value) = @_; + print $comment; + print "","dd",$n_strx; + print "","db",$type; + print "","db",$other; + print "","dw",$desc; + print "","dd","0" . $value . "h"; +} + +sub RStabLine ($ $ $ $ $) { + local ($comment,$offset,$info,$type,$symbol) = @_; + print $comment; + print "","dd",$offset; + print "","db",$type; + print "","db",$symbol; + print "","dw",$info; +} + +#this sub exists because i've no idea how to print non-ascii numbers in perl + +sub OutBin ( $ $ ) { + local ($offset, $shnum) = @_; + seek(FINAL,$offset,0); + if ( $shnum == 2 ) { printf FINAL "\x02" } ; + if ( $shnum == 3 ) { printf FINAL "\x03" } ; + if ( $shnum == 4 ) { printf FINAL "\x04" } ; + if ( $shnum == 5 ) { printf FINAL "\x05" } ; + if ( $shnum == 6 ) { printf FINAL "\x06" } ; + if ( $shnum == 7 ) { printf FINAL "\x07" } ; + if ( $shnum == 8 ) { printf FINAL "\x08" } ; + if ( $shnum == 9 ) { printf FINAL "\x09" } ; + if ( $shnum == 10 ) { printf FINAL "\x0a" } ; + if ( $shnum == 11 ) { printf FINAL "\x0b" } ; + if ( $shnum == 12 ) { printf FINAL "\x0c" } ; + if ( $shnum == 13 ) { printf FINAL "\x0d" } ; + if ( $shnum == 14 ) { printf FINAL "\x0e" } ; + if ( $shnum == 15 ) { printf FINAL "\x0f" } ; +} + +sub DispHelp () { + $\="\n"; + print "Usage:"; + print "\t-f,--input-file"; + print "\t\tThe input file name (only required option)"; + print "\t-o,--output-file"; + print "\t\tThe output file name (if not specified, *.asm becomes *.o"; + print "\t\tand anything else becomes a.out)"; + print "\t-l,--list-file"; + print "\t\tThe listing file's name (default: trailing .asm is +removed"; + print "\t\tif there and .lst is appended)"; + print "\t-s,--second-asm-file"; + print "\t\tThe second asm file's name (default: trailing .asm is"; + print "\t\tremoved if there and .nasm is appended)"; + print "\n"; + exit ; +} + +if ( $ARGV[0] eq "" ) { $ARGV[0] = "-h" }; + +$i = 0; +$filename = ""; +$outname = ""; + +while ( $ARGV[$i] ne "" ) { + $_ = $ARGV[$i]; + if ( m/^-/ ) { + if ( m/^-f$/ ) { $filename = $ARGV[++$i] }; + if ( m/^-o$/ ) { $outname = $ARGV[++$i] }; + if ( m/^-l$/ ) { $listname = $ARGV[++$i] }; + if ( m/^-s$/ ) { $asmname = $ARGV[++$i] }; + if ( m/^-h$/ ) { DispHelp }; + } elsif ( m/^--\w+/ ) { + if ( m/^--input-file$/ ) { $filename = $ARGV[++$i] }; + if ( m/^--output-file$/ ) { $outname = $ARGV[++$i] }; + if ( m/^--list-file$/ ) { $listname = $ARGV[++$i] }; + if ( m/^--second-asm-file$/ ) { $asmname = $ARGV[++$i] }; + if ( m/^--help/ ) { DispHelp }; + } elsif ( m/^--$/ ) { + while ( $ARGV[++$i] ) { + $NasmOptions .= " "; + $NasmOptions .= $_; + }; + } else { + DispHelp() + }; + $i++; +}; + +if ( $filename eq "" ) { DispHelp() }; + +if ( $outname eq "" ) { + $outname = $filename; + $outname =~ s/\.asm/.o/; + if ( $outname eq $filename ) { $outname = "a.out" }; +}; + +if ( $listname eq "" ) { + $listname = $filename; + $listname =~ s/\.asm//; + $listname .= ".lst"; +}; + +if ( $asmname eq "" ) { + $asmname = $filename; + $asmname =~ s/\.asm//; + $asmname .= ".nasm"; +}; + +$err = `nasm -f elf ${filename} -l ${listname} -o ${outname} `; + +if ( $err ) { die "\n$err\n"}; + +open(LISTFILE,"${listname}") or die "\n $0: Could not reopen list file!\n"; +open(ASMFILE,">${asmname}") or die "\n $0: Could not open asm file!\n"; + +select ASMFILE; + +open(OLDASM,$filename) or die "\n$0: Cannot open file $filename\n"; + +while ( $x = <OLDASM> ) { + print $x; +} + +@stab = ("n_desc", "value"); +@rel_stab = ("offset"); +$i = 0; +$current_section = ""; +$has_text = 'FALSE'; +$midst_of_macro = 'FALSE'; +$line_dec = 0 ; + +while ( $x = <LISTFILE> ) { + if ( $x =~ m/[^;]*%include/ ) { + $x = <LISTFILE>; + while ( $x =~ m/\s+\d+\s+\<\d+\>\s+/ ) { + $x = <LISTFILE>; + $line_dec++; + } + } + if ( $current_section eq ".text" ) { + if ( $x =~ m/^\s+(\S+)\s+(\S+)\s+(\S+)\s+[^<]+$/ ) { + $stab[$i++] = $1-$line_dec; #linenum + $stab[$i++] = $2; #offset + $count++; + if ( $3 =~ m/-/ ) { + $x = <LISTFILE>; + $line_dec++; + } + $midst_of_macro = 'FALSE'; + } elsif ( $x =~ m/^\s+(\S+)\s+(\S+)\s+(\S+)\s+<\d+>/ ) { + if ( $midst_of_macro eq 'TRUE' ) { + $stab[$i] = $stab[$i-2]; #same linenum + $line_dec++; + } else { + $stab[$i] = $1 - ++$line_dec; + $midst_of_macro = 'TRUE'; + } + $count++; + $i++; + $stab[$i++] = $2; + if ( $3 =~ m/-/ ) { + $x = <LISTFILE>; + $line_dec++; + } + + } + $has_text = 'TRUE'; + } elsif ( $x =~ m/\s+\S+\s+\S+\s+\S+\s+<\d+>/ ) { # is it a macro? + $line_dec++; + } + if ( $x =~ s/(section|segment)\s+([^\s]+)/$2/ ) { + $current_section = $2; + } +}; + +close LISTFILE; + +unless ( $has_text eq "TRUE" ) { + $err = `nasm -f elf ${asmname} -o ${outname}`; + print STDERR $err; + exit; +} + +#Write Stab section +$, = "\t"; #output field separator +$\ = "\n"; #output record separator + +print "section .stab noalloc"; +StabLine(";header",1,0,0,$count+1,length($filename)*2+3); +StabLine(";so",length($asmname)+2,"064h",0,0,0); + +$offset = 12; +$i = 0; +$j = 0; +$rel_stab[$j++] = $offset + 8; + +while ( $stab[$i] ) { + StabLine(";N_SLINE" . " " . ( ($i+2) / 2 ), 0, "044h", 0, + $stab[$i++], $stab[$i++]); + $offset += 12; + $rel_stab[$j++] = $offset + 8; +} + +#Write .rel.stab section +print "\n\nsection .rel.stab noalloc"; + +open (READELF,"readelf -s ${outname} |") or die "\n$0: Could not run readelf\n"; + +while ( $x = <READELF> ) { + if ( $x =~ m/\s+(\d+):\s+00000000\s+\d+\s+SECTION\s+\w+\s+\w+\s+1\s+/){ $textsymnum = $1; + }; +}; +close READELF; + +$i = 0; + +while ( $rel_stab[$i] ne "" ) { + RStabLine(";relocation for N_SLINE " . ($i), $rel_stab[$i], 0, 1, $textsymnum); + $i++; +} ; + +#Write .stabstr section + +print "\n\nsection .stabstr noalloc"; + +print "","db","0"; +print "","db",'"' . $asmname . '"'; +print "","db","0"; +print "","db",'"' . $asmname . '"' ; +print "","db","0"; + +close ASMFILE; + +$err = `nasm -f elf ${asmname} -o ${outname}`; + +if ( $err ) { die "\n$err\n" } ; + +open (READELF,"readelf -h -S ${outname} |") or die "\n$0: Could not run readelf\n"; + + +while ( $x = <READELF> ) { + if ( $x =~ m/Start\s+of\s+section\s+headers:\s+(\d+)\s+/ ) { + $shoff = $1; + } + if ( $x =~ m/Size\s+of\s+section\s+headers:\s+(\d+)\s+/ ) { + $shentsize = $1; + } + if ( $x =~ m/\[\s*(\d+)\]\s+.rel.stab\s+/ ) { + $relnum = $1; + } + if ( $x =~ m/\[\s*(\d+)\]\s+.stab\s+/ ) { + $stabnum = $1; + } + if ( $x =~ m/\[\s*(\d+)\]\s+.stabstr\s+/ ) { + $stabstrnum = $1; + } + if ( $x =~ m/\[\s*(\d+)\]\s+.symtab\s+/ ) { + $symtabnum = $1; + } +} +close READELF; + +sysopen (FINAL,"${outname}",2,0) or die "\n$0: Could not open ${outname}"; +$, = ""; #output field separator +$\ = ""; #output record separator + +#set .rel.stab->type to rel +OutBin($shoff + ($shentsize * $relnum) + 4,9); + +#set .rel.stab->link to .symtab +OutBin($shoff + ($shentsize * $relnum) + 24,$symtabnum); + +#set .rel.stab->info to .stab +OutBin($shoff + ($shentsize * $relnum) + 28,$stabnum); + +#set .rel.stab->entsize to 8 +OutBin($shoff + ($shentsize * $relnum) + 36,8); + +#set .stab->link to .stabstr +OutBin($shoff + ($shentsize * $stabnum) + 24,$stabstrnum); + +#set .stab->entsize to 12 +OutBin($shoff + ($shentsize * $stabnum) + 36,12); + +#set .stabstr->type to strtab +OutBin($shoff + ($shentsize * $stabstrnum) + 4,3); + +close FINAL; + +#Date: 17 Mar 2002 15:51:20 -0800 +#From: kitsred@hotmail.com (kired) +#Newsgroups: alt.lang.asm diff --git a/misc/proc32.ash b/misc/proc32.ash new file mode 100644 index 0000000..f513b73 --- /dev/null +++ b/misc/proc32.ash @@ -0,0 +1,441 @@ +;--------=========xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=========-------- +; +; Copyright (C) 1999 by Andrew Zabolotny +; Miscelaneous NASM macros that makes use of new preprocessor features +; +; This library is free software; you can redistribute it and/or +; modify it under the terms of the GNU Library General Public +; License as published by the Free Software Foundation; either +; version 2 of the License, or (at your option) any later version. +; +; This library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; Library General Public License for more details. +; +; You should have received a copy of the GNU Library General Public +; License along with this library; if not, write to the Free +; Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +; +;--------=========xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=========-------- + +; The macros in this file provides support for writing 32-bit C-callable +; NASM routines. For a short description of every macros see the +; corresponding comment before every one. Simple usage example: +; +; proc sin,1 +; targ %$angle +; fld %$angle +; fsin +; endproc sin + +%ifndef __PROC32_ASH__ +%define __PROC32_ASH__ + +[WARNING -macro-selfref] + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Mangle a name to be compatible with the C compiler +; Arguments: +; The name +; Example: +; cname (my_func) +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%ifdef EXTERNC_UNDERSCORE + %define cname(x) _ %+ x +%else + %define cname(x) x +%endif + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Import an external C procedure definition +; Arguments: +; The name of external C procedure +; Example: +; cextern printf +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro cextern 1 + %xdefine %1 cname(%1) + %ifidni __OUTPUT_FORMAT__,obj + extern %1:wrt FLAT + %else + extern %1 + %endif +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Export an C procedure definition +; Arguments: +; The name of C procedure +; Example: +; cglobal my_printf +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro cglobal 1 + %xdefine %1 cname(%1) + global %1 +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Misc macros to deal with PIC shared libraries +; Comment: +; Note that we have a different syntax for working with and without +; PIC shared libraries. In a PIC environment we should load first +; the address of the variable into a register and then work through +; that address, i.e: mov eax,myvar; mov [eax],1 +; In a non-PIC environment we should directly write: mov myvar,1 +; Example: +; extvar myvar +; GetGOT +; %ifdef PIC +; mov ebx,myvar ; get offset of myvar into ebx +; %else +; lea ebx,myvar +; %endif +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%ifdef PIC + cextern _GLOBAL_OFFSET_TABLE_ + %macro GetGOT 0 + %ifdef .$proc.stkofs + %assign .$proc.stkofs .$proc.stkofs+4 + %endif + call %$Get_GOT + %$Get_GOT: + pop ebx + add ebx,_GLOBAL_OFFSET_TABLE_ + $$ - %$Get_GOT wrt ..gotpc + %endmacro + %macro extvar 1 + cextern %1 + %xdefine %1 [ebx+%1 wrt ..got] + %endmacro +%else + %define GetGOT + %macro extvar 1 + cextern %1 + %endmacro +%endif + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Begin a procedure definition +; For performance reasons we don't use stack frame pointer EBP, +; instead we're using the [esp+xx] addressing. Because of this +; you should be careful when you work with stack pointer. +; The push/pop instructions are macros that are defined to +; deal correctly with these issues. +; Arguments: +; First argument - the procedure name +; Second optional argument - the number of bytes for local variables +; The following arguments could specify the registers that should be +; pushed at beginning of procedure and popped before exiting +; Example: +; proc MyTestProc +; proc MyTestProc,4,ebx,esi,edi +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro proc 1-3+ 0 + cglobal %1 + %push %1 + align 16 +%1: + %xdefine %$proc.name %1 + ; total size of local arguments + %assign %$proc.locsize (%2+3) & 0xFFFC + ; offset from esp to argument + %assign %$proc.argofs 4+%$proc.locsize + ; additional offset to args (tracks push/pops) + %assign .$proc.stkofs 0 + ; offset from esp to local arguments + %assign %$proc.locofs 0 + ; Now push the registers that we should save + %define %$proc.save %3 + %if %$proc.locsize != 0 + sub esp,%$proc.locsize + %endif + push %$proc.save +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Declare an argument passed on stack +; This macro defines two additional macros: +; first (with the name given by first argument) - [esp+xx] +; second (with a underscore appended to first argument) - esp+xx +; Arguments: +; First argument defines the procedure argument name +; Second optional parameter defines the size of the argument +; Default value is 4 (a double word) +; Example: +; arg .my_float +; arg .my_double,8 +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro arg 1-2 4 + %ifndef %$proc.argofs + %error "`arg' not in a proc context" + %else + ; Trick: temporary undefine .$proc.stkofs so that it won't be expanded + %assign %%. .$proc.stkofs + %undef .$proc.stkofs + %xdefine %{1}_ esp+%$proc.argofs+.$proc.stkofs + %xdefine %1 [esp+%$proc.argofs+.$proc.stkofs] + %assign .$proc.stkofs %%. + %assign %$proc.argofs %2+%$proc.argofs + %endif +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Declare an local variable +; first (with the name given by first argument) - [esp+xx] +; second (with a slash prefixing the first argument) - esp+xx +; Arguments: +; First argument defines the procedure argument name +; Second optional parameter defines the size of the argument +; Default value is 4 (a double word) +; Example: +; loc .int_value +; loc .double_value,8 +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro loc 1-2 4 + %ifndef %$proc.locofs + %error "`loc' not in a proc context" + %elif %$proc.locofs + %2 > %$proc.locsize + %error "local stack space exceeded" + %else + %assign %%. .$proc.stkofs + %undef .$proc.stkofs + %xdefine %{1}_ esp+%$proc.locofs+.$proc.stkofs + %xdefine %1 [esp+%$proc.locofs+.$proc.stkofs] + %assign .$proc.stkofs %%. + %assign %$proc.locofs %$proc.locofs+%2 + %endif +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Get the type of given size into context-local variable %$type +; Arguments: +; Size of type we want (1,2,4,8 or 10) +; Example: +; type 4 ; gives "dword" +; type 10 ; gives "tword" +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro type 1 + %if %1 = 1 + %define %$type byte + %elif %1 = 2 + %define %$type word + %elif %1 = 4 + %define %$type dword + %elif %1 = 8 + %define %$type qword + %elif %1 = 10 + %define %$type tword + %else + %define %$. %1 + %error "unknown type for argument size %$." + %endif +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Same as `arg' but prepends "word", "dword" etc (typed arg) +; first (with the name given by first argument) - dword [esp+xx] +; second (with a slash prefixing the first argument) - esp+xx +; Arguments: +; Same as for `arg' +; Example: +; targ .my_float ; .my_float is now "dword [esp+xxx]" +; targ .my_double,8 ; .my_double is now "qword [esp+xxx]" +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro targ 1-2 4 + %ifndef %$proc.argofs + %error "`targ' not in a proc context" + %else + arg %1,%2 + type %2 + %assign %%. .$proc.stkofs + %undef .$proc.stkofs + %xdefine %1 %$type %1 + %assign .$proc.stkofs %%. + %endif +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Same as `loc' but prepends "word", "dword" etc (typed loc) +; first (with the name given by first argument) - dword [esp+xx] +; second (with a slash prefixing the first argument) - esp+xx +; Arguments: +; Same as for `loc' +; Example: +; tloc int_value +; tloc double_value,8 +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro tloc 1-2 4 + %ifndef %$proc.locofs + %error "`tloc' not in a proc context" + %else + loc %1,%2 + type %2 + %assign %%. .$proc.stkofs + %undef .$proc.stkofs + %xdefine %1 %$type %1 + %assign .$proc.stkofs %%. + %endif +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Finish a procedure +; Gives an error if proc/endproc pairs mismatch +; Defines an label called __end_(procedure name) +; which is useful for calculating function size +; Arguments: +; (optional) The name of procedure +; Example: +; endproc MyTestProc +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%push tmp ; trick: define a dummy context to avoid error in next line +%macro endproc 0-1 %$proc.name + %ifndef %$proc.argofs + %error "`endproc' not in a proc context" + %elifnidn %$proc.name,%1 + %define %$. %1 + %error "endproc names mismatch: expected `%$proc.name'" + %error "but got `%$.' instead" + %elif %$proc.locofs < %$proc.locsize + %error "unused local space declared (used %$proc.locofs, requested %$proc.locsize)" + %else +%$exit: + ; Now pop the registers that we should restore on exit + pop %$proc.save + %if %$proc.locsize != 0 + add esp,%$proc.locsize + %endif + ret +__end_%1: + %pop + %endif +%endmacro +%pop + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; A replacement for "push" for use within procedures +; Arguments: +; any number of registers which will be push'ed successively +; Example: +; push eax,ebx,ecx,edx +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro push 0-* +; dummy comment to avoid problems with "push" on the same line with a label + %rep %0 + push %1 + %rotate 1 + %assign .$proc.stkofs .$proc.stkofs+4 + %endrep +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; A replacement for "pop" for use within procedures +; Arguments: +; any number of registers which will be pop'ed in reverse order +; Example: +; pop eax,ebx,ecx,edx +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro pop 0-* +; dummy comment to avoid problems with "pop" on the same line with a label + %rep %0 + %rotate -1 + pop %1 + %assign .$proc.stkofs .$proc.stkofs-4 + %endrep +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Replacements for "pushfd" and "popfd" that takes care of esp +; Example: +; pushfd +; popfd +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro pushfd 0 + pushfd + %assign .$proc.stkofs .$proc.stkofs+4 +%endmacro +%macro popfd 0 + popfd + %assign .$proc.stkofs .$proc.stkofs-4 +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Exit from current procedure (optionally on given condition) +; Arguments: +; Either none or a condition code +; Example: +; exit +; exit nz +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro exit 0-1 mp + j%1 near %$exit +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; start an conditional branch +; Arguments: +; A condition code +; second (optional) argument - "short" (by default - "near") +; Example: +; if nz +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro if 1-2 near +; dummy comment to avoid problems with "if" on the same line with a label + %push if + j%-1 %2 %$elseif +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; define the "else" branch of a conditional statement +; Arguments: +; optionaly: "short" if jmp to endif is less than 128 bytes away +; Example: +; else +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro else 0-1 + %ifnctx if + %error "`else' without matching `if'" + %else + jmp %1 %$endif +%$elseif: + %define %$elseif_defined + %endif +%endmacro + +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +; Summary: +; Finish am conditional statement +; Arguments: +; none +; Example: +; endif +;-----======xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx======----- +%macro endif 0 + %ifnctx if + %error "`endif' without matching `if'" + %else + %ifndef %$elseif_defined +%$elseif: + %endif +%$endif: + %pop + %endif +%endmacro + +%endif ; __PROC32_ASH__ @@ -13,7 +13,7 @@ #define NASM_MAJOR_VER 0 #define NASM_MINOR_VER 98 -#define NASM_VER "0.98.25" +#define NASM_VER "0.98.25alt" #ifndef NULL #define NULL 0 @@ -722,7 +722,7 @@ read_line(void) return NULL; } - src_set_linnum(src_get_linnum() + istk->lineinc + continued_count); + src_set_linnum(src_get_linnum() + istk->lineinc + (continued_count * istk->lineinc)); /* * Play safe: remove CRs as well as LFs, if any of either are diff --git a/test/changed.asm b/test/changed.asm new file mode 100644 index 0000000..29818d1 --- /dev/null +++ b/test/changed.asm @@ -0,0 +1,383 @@ +;This file demonstrates many of the differences between NASM version X and NASM +;version 0.97 +; +; changed.asm is copyright (C) 1998 John S. Fine +; +; It may be redistributed under the same conditions as NASM as described in +; Licence file in the NASM archive +;_________________________________ +; +; nasm changed.asm -l changed.lst +; +; When assembled without any -d switches, it includes examples which: +; Work correctly in version X +; and Work incorrectly and/or display warnings in version 0.97 +; and Do not prevent the generation of output in version 0.97 +; +; Not all the differences can be seen in the .lst file. I suggest that you use +; "ndisasm changes" to examine the code actually generated. +;_________________________________ +; +; nasm changed.asm -l changed.lst -doldmsg +; +; When assembled with -doldmsg, it adds examples which: +; Work correctly in version X +; and Generate error messages in version 0.97 and do not generate output +;_________________________________ +; +; nasm changed.asm -l changed.lst -doldcrash +; +; When assembled with -doldcrash, it adds examples which: +; Work correctly in version X +; and Cause NASM to crash in version 0.97 +;_________________________________ +; +; nasm changed.asm -l changed.lst -dnewmsg +; +; When assembled with -dnewmsg, it adds examples which: +; Generate error messages in version X +; and Generate wrong output without warning or error message in version 0.97 +;----------------------------------------------------------------------------- + +; Please note that I have reported the name of the person who made the +; correction based on very limited information. In several cases, I am sure I +; will identify the wrong author. Please send me any corrections; I don't +; intend to insult or exclude anyone. + +;----------------------------------------------------------------------------- +; Bug fixed by Simon in assemble() +; +; The following generated "call next" / "call next-1" instead of +; two copies of "call next" +; + times 2 a16 call next +next: + +;----------------------------------------------------------------------------- +; Bug fixed by John in parse_line() (and other routines) +; +; This used to jmp to prior.1, when it should be here.1 +; +prior: +.1: +here: jmp .1 +.1: + +;----------------------------------------------------------------------------- +; Bug fixed by John in assemble() +; +; Strings used in dq and dt were not zero filled correctly +; + dq 'b' + + +;----------------------------------------------------------------------------- +; Bug fixed by Simon in isn_names[] +; +; Was not recognised as an instruction +; + int01 ; Instead of INT1 + +;----------------------------------------------------------------------------- +; Bug fixed by Jim Hague in ??? +; +; Forward references were instruction level rather than per operand +; + shr word [forwardref],1 +forwardref: + +;----------------------------------------------------------------------------- +; Bug fixed by John in preproc.c +; +; It used to silently discard id characters appended to a multi-line +; macro parameter (such as the x in %1x below). +; +%macro xxx 1 +%1: nop +%{1}x: jmp %1x +%endmacro +xxx yyy + +;----------------------------------------------------------------------------- +; Bug added by John in preproc.c 0.98-J4, removed by John in 0.98-J5 +; +; Tested here to make sure it stays removed +; +%macro TestElse 1 +%if %1=0 +%elif %1=1 +nop +%endif +%endmacro +TestElse 1 + +%ifdef oldmsg +;*************************************************************** +; +; The following examples will generate error messages in 0.97 and will generate +; correct output in the new version. + +;----------------------------------------------------------------------------- +; Bug fixed by Simon in isns.dat +; +; The optional "near" was not permitted on JMP and CALL +; + jmp near here + +;----------------------------------------------------------------------------- +; Feature added by Simon in stdscan() +; +; You can now use the numeric value of strings in %assign +; +%assign xxx 'ABCD' + dd xxx + +;----------------------------------------------------------------------------- +; Feature added by John in add_vectors() +; +; Stranger address expressions are now supported as long as they resolve to +; something valid. +; + mov ax, [eax + ebx + ecx - eax] + +;----------------------------------------------------------------------------- +; Bug fixed by Simon in ??? +; +; The EQU directive affected local labels in a way that was inconsistent +; between passes +; +.local: +neither equ $ + jmp .local + +;----------------------------------------------------------------------------- +; Feature added by Jules in parse_line +; +; You can override a size specifier +; +%define arg1 dword [bp+4] + cmp word arg1, 2 + +;----------------------------------------------------------------------------- +; Bug fixed by John in preproc.c +; +; You could not use a label on the same line with a macro invocation, if the +; macro definition began with a preprocessor directive. +; + struc mytype +.long resd 1 + endstruc + +lbl istruc mytype + at mytype.long, dd 'ABCD' + iend + +;----------------------------------------------------------------------------- +; Warning removed by John in preproc.c +; +; In order to allow macros that extend the definition of instructions, I +; disabled the warning on a multi-line macro referencing itself. +; +%endif ;NASM 0.97 doesn't handle %0 etc. inside false %if +%macro push 1-* ; +%rep %0 ; +push %1 ; +%rotate 1 ; +%endrep ; +%endmacro ; +%ifdef oldmsg ; + + push ax,bx + +;----------------------------------------------------------------------------- +; Warning removed by John in preproc.c +; +; To support other types of macros that extend the definition of instructions, +; I disabled the warning on a multi-line macro called with the wrong number of +; parameters. PUSH and POP can be extended equally well by either method, but +; other intruction extensions may need one method or the other, so I made both +; work. +; +; Note that neither of these warnings was really needed, because a later stage +; of NASM would almost always give an adequate error message if the macro use +; really was wrong. +; +%endif +%macro pop 2-* +%rep %0 +pop %1 +%rotate 1 +%endrep +%endmacro +%ifdef oldmsg + + pop ax,bx +%endif + + +%ifdef newmsg ;*************************************************************** + +;----------------------------------------------------------------------------- +; Bug fixed by John in parse_line() (and other routines) +; +; This invalid code used to assemble without errors +; +myself equ myself+1 + jmp myself + +;----------------------------------------------------------------------------- +; Change made by John in preproc.c +; +; In 0.97, an id that appears as a label on a macro invocation was always +; prepended to the first line of the macro expansion. That caused several +; bugs, but also could be used in tricks like the arg macro in c16.mac and +; c32.mac. +; +; In version X, an id that appears as a label on a macro invocation will +; normally be defined as a label for the address at which the macro is +; invoked, regardless of whether the first line of the macro expansion is +; something that can take a label. The new token %00 may be used for any +; of the situations in which the old prepend behavior was doing something +; tricky but useful. %00 can also be used more than once and in places +; other than the start of the expansion. +; +%endif +%assign arg_off 0 + +%imacro arg 0-1 2 ;arg defined the old way + equ arg_off +%assign arg_off %1+arg_off +%endmacro + +%ifdef newmsg +arg_example arg +%endif + +%imacro arg2 0-1 2 ;arg defined the new way +%00 equ arg_off +%assign arg_off %1+arg_off +%endmacro + +%ifdef oldmsg +arg_example2 arg2 + +;----------------------------------------------------------------------------- +; Change made by Jules and John in INSNS.DAT +; +; Various instruction in which the size of an immediate is built-in to the +; instruction set, now allow you to redundantly specify that size as long +; as you specify it correctly +; + AAD byte 5 + AAM byte 5 + BT bx, byte 3 + BTC cx, byte 4 + BTR dx, byte 5 + BTS si, byte 6 + IN eax, byte 0x40 + INT byte 21h + OUT byte 70h, ax + RET word 2 + RETN word 2 + RETF word 4 + +; note "ENTER" has not been changed yet. + +;----------------------------------------------------------------------------- +; Enhancement by hpa in insns.dat et al +; +; Simplified adding new instructions, and added some missing instructions +; + int03 ; Instead of INT3 + ud1 ; No documented mnemonic for this one + ud2 + sysenter + sysexit + syscall + sysret + fxsave [ebx] + fxrstor [es:ebx+esi*4+0x3000] + +;----------------------------------------------------------------------------- +; Enhancement by hpa in insns.dat et al +; +; Actually make SSE work, and use the -p option to ndisasm to select +; one of several aliased opcodes +; + sqrtps xmm0,[ebx+10] ; SSE opcode + paddsiw mm0,[ebx+10] ; Cyrix opcode with the same byte seq. + +;----------------------------------------------------------------------------- +; Enhancement by hpa in preproc.c +; +; Support %undef to remoce a single-line macro +; +%define TEST_ME 42 +%ifndef TEST_ME +%error "TEST_ME not defined after %define" +%endif + +%undef TEST_ME +%ifdef TEST_ME +%error "TEST_ME defined after %undef" +%endif + +;----------------------------------------------------------------------------- +; Bug fix by hpa in insns.dat +; +; PSHUFW and PINSRW weren't handling the implicit sizes correctly; all of +; the entries below are (or should be) legal +; + pshufw mm2, mm1, 3 + pshufw mm3,[ebx],2 + pshufw mm7,[0+edi*8],1 + + pshufw mm2, mm1, byte 3 + pshufw mm3,[ebx],byte 2 + pshufw mm7,[0+edi*8],byte 1 + + pshufw mm2, mm1, 3 + pshufw mm3, qword [ebx], 2 + pshufw mm7, qword [0+edi*8], 1 + + pshufw mm2, mm1, byte 3 + pshufw mm3, qword [ebx], byte 2 + pshufw mm7, qword [0+edi*8], byte 1 + + pinsrw mm1, [esi], 1 + pinsrw mm1, word [esi], 1 + pinsrw mm1, [esi], byte 1 + pinsrw mm1, word [esi], byte 1 + + +%endif ; oldmsg + +%ifdef oldcrash ;************************************************************* + +This_label_is_256_characters_long__There_used_to_be_a_bug_in_stdscan_which_made_it_crash_when_it_did_a_keyword_search_on_any_label_longer_than_255_characters__Now_anything_longer_than_MAX_KEYWORD_is_always_a_symbol__It_will_not_even_try_a_keyword_search___ + +;----------------------------------------------------------------------------- +; Bug fixed by John in preproc.c +; +; Builds of NASM that prohibit dereferencing a NULL pointer used to crash if a +; macro that started with a blank line was invoked with a label +; +%macro empty_macro 0 + +%endm + +emlabel empty_macro + jmp emlabel + +;----------------------------------------------------------------------------- +; Enhancement by Conan Brink in preproc.c +; +; Allow %rep to be nested +; +%rep 4 +%rep 5 + nop +%endrep +%endrep + +%endif |