From 4cf1748e6829f80be251b8d7d274738009f934cf Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 30 Apr 2002 21:01:38 +0000 Subject: [PATCH] NASM 0.98.11 --- AUTHORS | 2 +- Doxyfile | 752 +++++++++++++++++++++++++++++ assemble.c | 6 +- disasm.c | 12 +- doc/nasmdoc.src | 11 +- insns.dat | 139 +++--- macros.c | 16 + macros.pl | 3 +- misc/exasm.zip | Bin 6058 -> 491 bytes nasm.c | 10 +- nasm.h | 9 +- ndisasm.c | 16 +- ndisasm.doc | 2 +- parser.c | 9 +- rdoff/Makefile.in | 170 +++---- rdoff/ldrdf.c | 1378 ++--------------------------------------------------- rdoff/rdflib.c | 1 + rdoff/rdfload.c | 1 + rdoff/rdoff.h | 305 +++++------- test/bintest.asm | 90 ++-- 20 files changed, 1161 insertions(+), 1771 deletions(-) create mode 100644 Doxyfile diff --git a/AUTHORS b/AUTHORS index fb10957..b6764d7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -40,7 +40,7 @@ D: New Athlon instructions D: Makefile.vc fix N: John Coffman -E: johninsd@users.sourceforge.net +E: johninsd@san.rr.com D: added Jcc optimizations; CPU level checks D: bug fixes, compilation fixes diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..1bb1cc3 --- /dev/null +++ b/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 , where +# is the value of the INPUT_FILTER tag, and 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/assemble.c b/assemble.c index 8058979..39ffd46 100644 --- a/assemble.c +++ b/assemble.c @@ -152,7 +152,7 @@ static int jmp_match (long segment, long offset, int bits, if (c != 0370) return 0; - if (ins->oprs[0].opflags & OPFLAG_FORWARD) return (! pass0); /*1;*/ /* match a forward reference */ + if (ins->oprs[0].opflags & OPFLAG_FORWARD) return (!pass0); /* match a forward reference */ isize = calcsize (segment, offset, bits, ins, code); if (ins->oprs[0].segment != segment) return 0; @@ -546,7 +546,7 @@ static int is_sbyte (insn *ins, int op, int size) int ret; ret = !(ins->forw_ref && ins->oprs[op].opflags ) && /* dead in the water on forward reference or External */ - !(ins->oprs[op].type & (BITS16|BITS32)) && /* John Coffman's 3/24/01 patch - fbk - 10/16/01 */ + (optimizing || !(ins->oprs[op].type & (BITS16|BITS32))) && ins->oprs[op].wrt==NO_SEG && ins->oprs[op].segment==NO_SEG; v = ins->oprs[op].offset; @@ -791,7 +791,7 @@ static void gencode (long segment, long offset, int bits, data = ins->oprs[c-034].offset; size = ((ins->oprs[c-034].addr_size ? ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4); - if (size==16 && (data < -65536L || data > 65535L)) + if (size==2 && (data < -65536L || data > 65535L)) errfunc (ERR_WARNING, "word value exceeds bounds"); out (offset, segment, &data, OUT_ADDRESS+size, ins->oprs[c-034].segment, ins->oprs[c-034].wrt); diff --git a/disasm.c b/disasm.c index e7e634e..9184686 100644 --- a/disasm.c +++ b/disasm.c @@ -377,13 +377,23 @@ static int matches (struct itemplate *t, unsigned char *data, int asize, ins->oprs[c-070].offset |= (((long) *data++) << 24); ins->oprs[c-070].segment |= SEG_32BIT | SEG_RELATIVE; } - if (c >= 0100 && c <= 0177) { + if (c >= 0100 && c < 0130) { int modrm = *data++; ins->oprs[c & 07].basereg = (modrm >> 3) & 07; ins->oprs[c & 07].segment |= SEG_RMREG; data = do_ea (data, modrm, asize, segsize, &ins->oprs[(c >> 3) & 07]); } + if (c >= 0130 && c <= 0132) { + ins->oprs[c-0130].offset = *data++; + ins->oprs[c-0130].offset |= (*data++ << 8); + } + if (c >= 0140 && c <= 0142) { + ins->oprs[c-0140].offset = *data++; + ins->oprs[c-0140].offset |= (*data++ << 8); + ins->oprs[c-0140].offset |= (((long) *data++) << 16); + ins->oprs[c-0140].offset |= (((long) *data++) << 24); + } if (c >= 0200 && c <= 0277) { int modrm = *data++; if (((modrm >> 3) & 07) != (c & 07)) diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src index f91861b..66825ed 100644 --- a/doc/nasmdoc.src +++ b/doc/nasmdoc.src @@ -5810,7 +5810,8 @@ form of the instruction. \c ADDPS xmmreg,xmmreg ; 0f 58 /r [KATMAI,SSE] \c{ADDPS} performs addition on each of four packed SP FP -number items dst(0-31):=dst(0-31)+src(0-31), ..(63-32), etc. +number items dst(0-31):=dst(0-31)+src(0-31) +, ..(63-32), etc. \H{insADDSS} \i\c{ADDSS}: Scalar Single FP ADD @@ -6219,13 +6220,17 @@ first unequal or equal byte is found. EQ, LT, LE, UNORD, NEQ, NLT, NLE, ORD -\H{insCMPUNORDPS} \i\c{CMPUNORDPS}: Packed Single FP Compare (CMPPS) +\H{insCMPUNORDPS} \i\c{CMPUNORDPS}: Packed Single FP Compare + + (CMPPS) \c CMPUNORDPS xmmreg,memory ; ?? [KATMAI,SSE] \c CMPUNORDPS xmmreg,xmmreg ; ?? [KATMAI,SSE] -\H{insCMPUNORDSS} \i\c{CMPUNORDSS}: Scalar Single FP Compare (CMPSS) +\H{insCMPUNORDSS} \i\c{CMPUNORDSS}: Scalar Single FP Compare + + (CMPSS) \c CMPUNORDSS xmmreg,memory ; ?? [KATMAI,SSE] \c CMPUNORDSS xmmreg,xmmreg ; ?? [KATMAI,SSE] diff --git a/insns.dat b/insns.dat index e167a77..c34fa0e 100644 --- a/insns.dat +++ b/insns.dat @@ -37,14 +37,15 @@ ADC rm16,imm8 \320\300\1\x83\202\15 8086 ADC rm32,imm8 \321\300\1\x83\202\15 386 ADC reg_al,imm \1\x14\21 8086,SM ADC reg_ax,imm \320\1\x15\31 8086,SM -ADC reg_eax,sbyte \321\1\x83\202\15 386,ND -ADC reg_eax,imm \321\1\x15\41 386,SM +ADC reg_eax,sbyte \321\1\x83\202\15 386,SM,ND +ADC reg_eax,sbig \321\1\x15\41 386,SM,ND +ADC reg_eax,imm32 \321\1\x15\41 386 ADC rm8,imm \300\1\x80\202\21 8086,SM -ADC rm16,imm \320\300\134\1\x81\202\131 8086,SM,ND -ADC rm32,imm \321\300\144\1\x81\202\141 386,SM,ND +ADC rm16,imm \320\300\134\1\x81\202\131 8086,SM +ADC rm32,imm \321\300\144\1\x81\202\141 386,SM ADC mem,imm8 \300\1\x80\202\21 8086,SM -ADC mem,imm16 \320\300\134\1\x81\202\131 8086,SM,ND -ADC mem,imm32 \321\300\144\1\x81\202\141 386,SM,ND +ADC mem,imm16 \320\300\134\1\x81\202\131 8086,SM +ADC mem,imm32 \321\300\144\1\x81\202\141 386,SM ADD mem,reg8 \300\17\101 8086,SM ADD reg8,reg8 \300\17\101 8086 ADD mem,reg16 \320\300\1\x01\101 8086,SM @@ -61,14 +62,15 @@ ADD rm16,imm8 \320\300\1\x83\200\15 8086 ADD rm32,imm8 \321\300\1\x83\200\15 386 ADD reg_al,imm \1\x04\21 8086,SM ADD reg_ax,imm \320\1\x05\31 8086,SM -ADD reg_eax,sbyte \321\1\x83\200\15 386,ND -ADD reg_eax,imm \321\1\x05\41 386,SM +ADD reg_eax,sbyte \321\1\x83\200\15 386,SM,ND +ADD reg_eax,sbig \321\1\x05\41 386,SM,ND +ADD reg_eax,imm32 \321\1\x05\41 386 ADD rm8,imm \300\1\x80\200\21 8086,SM -ADD rm16,imm \320\300\134\1\x81\200\131 8086,SM,ND -ADD rm32,imm \321\300\144\1\x81\200\141 386,SM,ND +ADD rm16,imm \320\300\134\1\x81\200\131 8086,SM +ADD rm32,imm \321\300\144\1\x81\200\141 386,SM ADD mem,imm8 \300\1\x80\200\21 8086,SM -ADD mem,imm16 \320\300\134\1\x81\200\131 8086,SM,ND -ADD mem,imm32 \321\300\144\1\x81\200\141 386,SM,ND +ADD mem,imm16 \320\300\134\1\x81\200\131 8086,SM +ADD mem,imm32 \321\300\144\1\x81\200\141 386,SM AND mem,reg8 \300\1\x20\101 8086,SM AND reg8,reg8 \300\1\x20\101 8086 AND mem,reg16 \320\300\1\x21\101 8086,SM @@ -85,14 +87,15 @@ AND rm16,imm8 \320\300\1\x83\204\15 8086 AND rm32,imm8 \321\300\1\x83\204\15 386 AND reg_al,imm \1\x24\21 8086,SM AND reg_ax,imm \320\1\x25\31 8086,SM -AND reg_eax,sbyte \321\1\x83\204\15 386,ND -AND reg_eax,imm \321\1\x25\41 386,SM +AND reg_eax,sbyte \321\1\x83\204\15 386,SM,ND +AND reg_eax,sbig \321\1\x25\41 386,SM,ND +AND reg_eax,imm32 \321\1\x25\41 386 AND rm8,imm \300\1\x80\204\21 8086,SM -AND rm16,imm \320\300\134\1\x81\204\131 8086,SM,ND -AND rm32,imm \321\300\144\1\x81\204\141 386,SM,ND +AND rm16,imm \320\300\134\1\x81\204\131 8086,SM +AND rm32,imm \321\300\144\1\x81\204\141 386,SM AND mem,imm8 \300\1\x80\204\21 8086,SM -AND mem,imm16 \320\300\134\1\x81\204\131 8086,SM,ND -AND mem,imm32 \321\300\144\1\x81\204\141 386,SM,ND +AND mem,imm16 \320\300\134\1\x81\204\131 8086,SM +AND mem,imm32 \321\300\144\1\x81\204\141 386,SM ARPL mem,reg16 \300\1\x63\101 286,PROT,SM ARPL reg16,reg16 \300\1\x63\101 286,PROT BOUND reg16,mem \320\301\1\x62\110 186 @@ -178,14 +181,15 @@ CMP rm16,imm8 \320\300\1\x83\207\15 8086 CMP rm32,imm8 \321\300\1\x83\207\15 386 CMP reg_al,imm \1\x3C\21 8086,SM CMP reg_ax,imm \320\1\x3D\31 8086,SM -CMP reg_eax,sbyte \321\1\x83\207\15 386,ND -CMP reg_eax,imm \321\1\x3D\41 386,SM +CMP reg_eax,sbyte \321\1\x83\207\15 386,SM,ND +CMP reg_eax,sbig \321\1\x3D\41 386,SM,ND +CMP reg_eax,imm32 \321\1\x3D\41 386 CMP rm8,imm \300\1\x80\207\21 8086,SM -CMP rm16,imm \320\300\134\1\x81\207\131 8086,SM,ND -CMP rm32,imm \321\300\144\1\x81\207\141 386,SM,ND +CMP rm16,imm \320\300\134\1\x81\207\131 8086,SM +CMP rm32,imm \321\300\144\1\x81\207\141 386,SM CMP mem,imm8 \300\1\x80\207\21 8086,SM -CMP mem,imm16 \320\300\134\1\x81\207\131 8086,SM,ND -CMP mem,imm32 \321\300\144\1\x81\207\141 386,SM,ND +CMP mem,imm16 \320\300\134\1\x81\207\131 8086,SM +CMP mem,imm32 \321\300\144\1\x81\207\141 386,SM CMPSB void \332\1\xA6 8086 CMPSD void \332\321\1\xA7 386 CMPSW void \332\320\1\xA7 8086 @@ -423,17 +427,29 @@ IMUL reg16,reg16 \320\2\x0F\xAF\110 386 IMUL reg32,mem \321\301\2\x0F\xAF\110 386,SM IMUL reg32,reg32 \321\2\x0F\xAF\110 386 IMUL reg16,mem,imm8 \320\301\1\x6B\110\16 186,SM -IMUL reg16,reg16,imm8 \320\301\1\x6B\110\16 186 -IMUL reg16,mem,imm \320\301\135\1\x69\110\132 186,SM -IMUL reg16,reg16,imm \320\135\1\x69\110\132 186,SM +IMUL reg16,mem,sbyte \320\301\1\x6B\110\16 186,SM,ND +IMUL reg16,mem,imm16 \320\301\1\x69\110\32 186,SM +IMUL reg16,mem,imm \320\301\135\1\x69\110\132 186,SM,ND +IMUL reg16,reg16,imm8 \320\1\x6B\110\16 186 +IMUL reg16,reg16,sbyte \320\1\x6B\110\16 186,SM,ND +IMUL reg16,reg16,imm16 \320\1\x69\110\32 186 +IMUL reg16,reg16,imm \320\135\1\x69\110\132 186,SM,ND IMUL reg32,mem,imm8 \321\301\1\x6B\110\16 386,SM +IMUL reg32,mem,sbyte \321\301\1\x6B\110\16 386,SM,ND +IMUL reg32,mem,imm32 \321\301\1\x69\110\42 386,SM +IMUL reg32,mem,imm \321\301\145\1\x69\110\142 386,SM,ND IMUL reg32,reg32,imm8 \321\1\x6B\110\16 386 -IMUL reg32,mem,imm \321\301\145\1\x69\110\142 386,SM -IMUL reg32,reg32,imm \321\145\1\x69\110\142 386,SM +IMUL reg32,reg32,sbyte \321\1\x6B\110\16 386,SM,ND +IMUL reg32,reg32,imm32 \321\1\x69\110\42 386 +IMUL reg32,reg32,imm \321\145\1\x69\110\142 386,SM,ND IMUL reg16,imm8 \320\1\x6B\100\15 186 -IMUL reg16,imm \320\134\1\x69\100\131 186,SM +IMUL reg16,sbyte \320\1\x6B\100\15 186,SM,ND +IMUL reg16,imm16 \320\1\x69\100\31 186 +IMUL reg16,imm \320\134\1\x69\100\131 186,SM,ND IMUL reg32,imm8 \321\1\x6B\100\15 386 -IMUL reg32,imm \321\144\1\x69\100\141 386,SM +IMUL reg32,sbyte \321\1\x6B\100\15 386,SM,ND +IMUL reg32,imm32 \321\1\x69\100\41 386 +IMUL reg32,imm \321\144\1\x69\100\141 386,SM,ND IN reg_al,imm \1\xE4\25 8086,SB IN reg_ax,imm \320\1\xE5\25 8086,SB IN reg_eax,imm \321\1\xE5\25 386,SB @@ -542,9 +558,9 @@ LSS reg32,mem \321\301\2\x0F\xB2\110 386 LTR mem \300\1\x0F\17\203 286,PROT,PRIV LTR mem16 \300\1\x0F\17\203 286,PROT,PRIV LTR reg16 \300\1\x0F\17\203 286,PROT,PRIV -MOV mem,reg_cs \300\1\x8C\201 8086,SM -MOV mem,reg_dess \300\1\x8C\101 8086,SM -MOV mem,reg_fsgs \300\1\x8C\101 386,SM +MOV mem,reg_cs \300\1\x8C\201 8086,SM +MOV mem,reg_dess \300\1\x8C\101 8086,SM +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 @@ -637,14 +653,15 @@ OR rm16,imm8 \320\300\1\x83\201\15 8086 OR rm32,imm8 \321\300\1\x83\201\15 386 OR reg_al,imm \1\x0C\21 8086,SM OR reg_ax,imm \320\1\x0D\31 8086,SM -OR reg_eax,sbyte \321\1\x83\201\15 386,ND -OR reg_eax,imm \321\1\x0D\41 386,SM +OR reg_eax,sbyte \321\1\x83\201\15 386,SM,ND +OR reg_eax,sbig \321\1\x0D\41 386,SM,ND +OR reg_eax,imm32 \321\1\x0D\41 386 OR rm8,imm \300\1\x80\201\21 8086,SM -OR rm16,imm \320\300\134\1\x81\201\131 8086,SM,ND -OR rm32,imm \321\300\144\1\x81\201\141 386,SM,ND +OR rm16,imm \320\300\134\1\x81\201\131 8086,SM +OR rm32,imm \321\300\144\1\x81\201\141 386,SM OR mem,imm8 \300\1\x80\201\21 8086,SM -OR mem,imm16 \320\300\134\1\x81\201\131 8086,SM,ND -OR mem,imm32 \321\300\144\1\x81\201\141 386,SM,ND +OR mem,imm16 \320\300\134\1\x81\201\131 8086,SM +OR mem,imm32 \321\300\144\1\x81\201\141 386,SM OUT imm,reg_al \1\xE6\24 8086,SB OUT imm,reg_ax \320\1\xE7\24 8086,SB OUT imm,reg_eax \321\1\xE7\24 386,SB @@ -826,9 +843,10 @@ PUSH rm32 \321\300\1\xFF\206 386 PUSH reg_fsgs \1\x0F\7 386 PUSH reg_sreg \6 8086 PUSH imm8 \1\x6A\14 186 -PUSH sbyte \1\x6A\14 186,ND PUSH imm16 \320\133\1\x68\130 186 PUSH imm32 \321\143\1\x68\140 386 +PUSH sbyte \1\x6A\14 186,ND +PUSH imm \1\x68\34 186,ND PUSHA void \322\1\x60 186 PUSHAD void \321\1\x60 386 PUSHAW void \320\1\x60 186 @@ -928,14 +946,15 @@ SBB rm16,imm8 \320\300\1\x83\203\15 8086 SBB rm32,imm8 \321\300\1\x83\203\15 8086 SBB reg_al,imm \1\x1C\21 8086,SM SBB reg_ax,imm \320\1\x1D\31 8086,SM -SBB reg_eax,sbyte \321\1\x83\203\15 386,ND -SBB reg_eax,imm \321\1\x1D\41 386,SM +SBB reg_eax,sbyte \321\1\x83\203\15 386,SM,ND +SBB reg_eax,sbig \321\1\x1D\41 386,SM,ND +SBB reg_eax,imm32 \321\1\x1D\41 386 SBB rm8,imm \300\1\x80\203\21 8086,SM -SBB rm16,imm \320\300\134\1\x81\203\131 8086,SM,ND -SBB rm32,imm \321\300\144\1\x81\203\141 386,SM,ND +SBB rm16,imm \320\300\134\1\x81\203\131 8086,SM +SBB rm32,imm \321\300\144\1\x81\203\141 386,SM SBB mem,imm8 \300\1\x80\203\21 8086,SM -SBB mem,imm16 \320\300\134\1\x81\203\131 8086,SM,ND -SBB mem,imm32 \321\300\144\1\x81\203\141 386,SM,ND +SBB mem,imm16 \320\300\134\1\x81\203\131 8086,SM +SBB mem,imm32 \321\300\144\1\x81\203\141 386,SM SCASB void \332\1\xAE 8086 SCASD void \332\321\1\xAF 386 SCASW void \332\320\1\xAF 8086 @@ -1010,14 +1029,15 @@ SUB rm16,imm8 \320\300\1\x83\205\15 8086 SUB rm32,imm8 \321\300\1\x83\205\15 386 SUB reg_al,imm \1\x2C\21 8086,SM SUB reg_ax,imm \320\1\x2D\31 8086,SM -SUB reg_eax,sbyte \321\1\x83\205\15 386,ND -SUB reg_eax,imm \321\1\x2D\41 386,SM +SUB reg_eax,sbyte \321\1\x83\205\15 386,SM,ND +SUB reg_eax,sbig \321\1\x2D\41 386,SM,ND +SUB reg_eax,imm32 \321\1\x2D\41 386 SUB rm8,imm \300\1\x80\205\21 8086,SM -SUB rm16,imm \320\300\134\1\x81\205\131 8086,SM,ND -SUB rm32,imm \321\300\144\1\x81\205\141 386,SM,ND +SUB rm16,imm \320\300\134\1\x81\205\131 8086,SM +SUB rm32,imm \321\300\144\1\x81\205\141 386,SM SUB mem,imm8 \300\1\x80\205\21 8086,SM -SUB mem,imm16 \320\300\134\1\x81\205\131 8086,SM,ND -SUB mem,imm32 \321\300\144\1\x81\205\141 386,SM,ND +SUB mem,imm16 \320\300\134\1\x81\205\131 8086,SM +SUB mem,imm32 \321\300\144\1\x81\205\141 386,SM SVDC mem80,reg_sreg \300\2\x0F\x78\101 486,CYRIX,SMM SVLDT mem80 \300\2\x0F\x7A\200 486,CYRIX,SMM SVTS mem80 \300\2\x0F\x7C\200 486,CYRIX,SMM @@ -1112,14 +1132,15 @@ XOR rm16,imm8 \320\300\1\x83\206\15 8086 XOR rm32,imm8 \321\300\1\x83\206\15 386 XOR reg_al,imm \1\x34\21 8086,SM XOR reg_ax,imm \320\1\x35\31 8086,SM -XOR reg_eax,sbyte \321\1\x83\206\15 386,ND -XOR reg_eax,imm \321\1\x35\41 386,SM +XOR reg_eax,sbyte \321\1\x83\206\15 386,SM,ND +XOR reg_eax,sbig \321\1\x35\41 386,SM,ND +XOR reg_eax,imm32 \321\1\x35\41 386 XOR rm8,imm \300\1\x80\206\21 8086,SM -XOR rm16,imm \320\300\134\1\x81\206\131 8086,SM,ND -XOR rm32,imm \321\300\144\1\x81\206\141 386,SM,ND +XOR rm16,imm \320\300\134\1\x81\206\131 8086,SM +XOR rm32,imm \321\300\144\1\x81\206\141 386,SM XOR mem,imm8 \300\1\x80\206\21 8086,SM -XOR mem,imm16 \320\300\134\1\x81\206\131 8086,SM,ND -XOR mem,imm32 \321\300\144\1\x81\206\141 386,SM,ND +XOR mem,imm16 \320\300\134\1\x81\206\131 8086,SM +XOR mem,imm32 \321\300\144\1\x81\206\141 386,SM CMOVcc reg16,mem \320\301\1\x0F\330\x40\110 P6,SM CMOVcc reg16,reg16 \320\301\1\x0F\330\x40\110 P6 CMOVcc reg32,mem \321\301\1\x0F\330\x40\110 P6,SM diff --git a/macros.c b/macros.c index ed70a75..38a7e0f 100644 --- a/macros.c +++ b/macros.c @@ -1,6 +1,12 @@ /* This file auto-generated from standard.mac by macros.pl - don't edit it */ static char *stdmac[] = { + "%idefine IDEAL", + "%idefine JUMPS", + "%idefine P386", + "%idefine P486", + "%idefine P586", + "%idefine END", "%define __NASM_MAJOR__ 0", "%define __NASM_MINOR__ 98", "%define __FILE__", @@ -57,6 +63,12 @@ static char *stdmac[] = { "%imacro bits 1+.nolist", "[bits %1]", "%endmacro", + "%imacro use16 0.nolist", + "[bits 16]", + "%endmacro", + "%imacro use32 0.nolist", + "[bits 32]", + "%endmacro", "%imacro global 1-*.nolist", "%rep %0", "[global %1]", @@ -69,5 +81,9 @@ static char *stdmac[] = { "%rotate 1", "%endrep", "%endmacro", + "%imacro cpu 1+.nolist", + "[cpu %1]", + "%endmacro", NULL }; +#define TASM_MACRO_COUNT 6 diff --git a/macros.pl b/macros.pl index e1d9ed0..ecf0595 100644 --- a/macros.pl +++ b/macros.pl @@ -6,7 +6,8 @@ # Julian Hall. All rights reserved. The software is # redistributable under the licence given in the file "Licence" # distributed in the NASM archive. -use strict; + +# use strict; # if your PERL's got it my $fname; my $line = 0; diff --git a/misc/exasm.zip b/misc/exasm.zip index b4e9e58a0845696f5ba7f15b4d381d8899df3641..e8130182cd7dd1393bd74504e130a99179491bd6 100644 GIT binary patch delta 7 OcmZ3b|C)KjYeoPLQ3GTE literal 6058 zcmZ{obySpV)b@uIWRM!Vk!I+W9=c;dB&1VXKtfWw2N*&m6p#)HY3T+*KxvSYkQ}<@ zo8x!Ri|<;#&wa0XV$E;wCz&y`N2gXN!!JfgR7y=6qd*wU65)N=UZ0hQ7kr1I}29g9;n3-OEk6swB&$o zE!yqfQ=M$>Y#nFTMMa)Vga5VEk25xf$6Rt3<=UbGh;EoKdw%{e0sQ?#-1$BjRnOum#e_=OAzIs zQLDW0O|`-KVXz1n?H6S`s0UNlGfKI;^#O}-6N8`PUI?vw59eDpd&hT`!vbQuBiRA6d(XR)aL?V{@WP9CMt z%cN|{T+`P^8oj|(_+#y1)`$89F)vruOT8QpbyB^m+qI#7uRiBs9dj^W zCm~wY#8_Ka;39>q{Gs^F(4Tor7Hw$rXD)?=vcHTV-yFL~uzO-7{mop# zEt03CGYKV%WT}?81HX6{s9I7C&lwREbXfNeg@7nA+bcf)7!=LeswE_dt~vzmyvy6Q z2o4(7FpKW59m`2$;9@Hs=a`g)jeN|;bEV9oy151R4E&5K>j!p<$^A= zpmOPZu4nLXEYwNi?|Ioo!O{8XJme)nE?IboEg4@ZkXJVTsf`yrXJCmxl($Vj}Y=ohZx&+L0$i(2Mgl5j$ zY?GXVx4LHmtmQP5AGjA)y%ScKYuDqc#y{k{8<)arDvZW-M3;@HAU%%ot+4=_!7Vu1 z?qNTUq={Ze4?!tDtup0aiVYbN*G$+pj1-<_4^wdSY!o|+9C|n#J8VVs+(%AmQ$XZN z@eWrX6Wp}Hz|22!#zehv${ zBe9sgK&S3c=7j2szQ$nVo;9uqgtnpH7%%3Q&}5-~^r18K`~j4{O(pmOcz8W0pwe(- zr}$$9E;fEz9X!UWAy6jRbV{HkjYcfE;wWD++Bs(r!ErGTeA`buucA}1o=_~sI5k?J zkEiA7R5%Em%+vLkd6Xhi(z$tFb$4d_AuuDOP(4hikJRrnL!0qb(^^aA&z|$E2gA?vR>$4yCxP`gBn$t*WpFTD9^E+r< zywM9Vz5F6(n)zkX=PXd`f9j-%7$?d$Pr&pcvOc~*0RV82X9Z<7c~fOME;(gG^#n0z zG+vd4;p@CiE!r6N6Ow6ha=njB?~3FzcFU9LWjS;) z9*5;g4C{Owqc#`X^2%yrjBAmhdY1i*n1U}OFEKRw;5NSlpgNDACFOY$aYkLQZZzwZ zRAk>}o~^+%!go5K*z`*1G|UerYnhVe^Vb9JWSWt_`YFXG5866t|7DZC`}lI(BC2J_ zesbp?h9z``qi?BT0zqbDDE1_`QpX=d=n%60d|9+aEG1eM)OZK!1+vZJ$h=SaXl=12Z$QUp4jjav^Sm=z9GjHY!b#j@s^j@XHtRkd zT@aajLM~BbuRv<9hx$h#;lMc+;U(NiXG=f{C8+09>g$ebd>Zr3QTPcH979@!{dG*k zctfX8kHAh3ww3}8%|Tfhi_kGo;+g`Mlekf`F?JB&t_rJt-Kk?K`kJ$M@#X{K;?n#E ze`As8=MHA^6XVkY_U}K}q$oHOM5vBWV#!Idv_5^N%bIVn_jO6Z*Mad@Jyt>Noz7^3U{=hPiF6^kKV_Lq{CfV1c6wth>_LIIzm_%%G!xM31 z!s4YYeg(l^#re48mu~Ia#I->-dNg2AR1y4nX<{oCuN#;n#`#KHBkV~uZjlM0hU zuq<90!G+iL?#siYvpPMm#L`Idc#ZE)v~iK%b6}34^TAj}vDaKI7`$o=O{?PL^=4nDic=LwW*NegWRuJYUXy!A8+MLkHbt@+ zsyw0&?bP0A@%+@nh@_c@z>sf)A(l7}!h75nc^SJ4P+>{%nFsF46gMO*Fw8L+Hi7Hd zqUX|dQb7Trw54R8+P0<}dAW4iZy3m0`*Pe9bJ|uk_4-jMY5uxuU$!2ElyK9;+NvokEJ|I0!4&LC7 z7HZmwa;fKai-jMGlInJM>u67`eHWZ3RP1MakG=*H<;o`ULqz$smmP97&);}N&}M$5 z8vS+}31W}UP0&V(i?PczjO{FX9E@e@`pPID_{yyCM^a?!&A_ ztsf=EX###1x11N2&SUx{R<&?+T0v-K-WahBYz7W z;G}NNUL_GXI@~+=EK6G9-Gh5dN5TwpX<6tb-zgX+KAYjkp(>v6Ri0*H34voel5pSR zo|fMGWG;cxQ}p=({}Sr$E@Su00~pFJ?OUMaLFNVHdaQ`KpJ;p-UJiUoi(^Gl==n>M zssIvqF@tX>R=gRG+N8-3+wr8vsgoYb1RGqAQ-6=*{(2kx3-3&&Q|{Y0S9(MDi`=iO zaYq}`q!~&noC0_wqOcv718hmRlR{BjnI;#G>tE815t^`dgR0$xh}q4C9^kAqyUZzS zjw;rP3KIEgTX>v@sdt>k-p+yZqM)Il-C${QVdjsQJ{L8jA-Zpz%}ciQfSEke)--k zxXrWTE9}>^@AJSCb_$@aGqy7_L5d7mSW5itQvOYXt%tqtv#psrqkaN6XicAPYyAgf z+MfP$A2I&bQpR-o#^LsGiZ)2PU8NmB=Z)GQE+g%7@rZXK3p2f!10^e{*&)dBSS(V| z$*LRkYS|dGDjC3e?QxIp8kMd~#XlVP$cG+Kt3MD)EcETe38t-DVidv0_um;FK2fkc z!zhj=^MD*|@5UusB-E1~b7H=Vfh=1jG>{2!VJ5~v)+`bl$viy6Yc)ym1bAlJ1#m3K zMyo3=3=FEk<%ro?X)mXcl~Oto?Ud&^dCN&?Yuh!?b8ai2Ia0pu5r7g|Q5m*wawygq z9k_l&8f+A*D{k9=iZfDOCKj5MKe}Hzo}VCgALTnMy5km9DW*8vM7pJqH5W~AF3a!v`$UYZ=0e z?G_fgsy1md>mpLPLVWE!8mGI2u%edWsM6=es0^j}pf2JL?Ik)K03{gRqo!qiQu`CR z{$VV3=P)9kA&FrrEINoE*3j{jC>R`d{GJYdrxibeB{V3G05#f$zI`Sv2*i!vP>lcW zn60w}x>|^}tup+Up$se-6kS>O4V}Gn3wke~%K;&*!1oYDNzAKct4~-LwqZg^_LNwN z&yqPJ{pT~M&mj2?4Oz2#fl4EaX--_Avxl~@kheUQQI8!r7KI`2td1|AXQgEf8mOh` z0UQfOwXqq)rcu+6$ah~~hWgwZ(B?ulqa7|TnGA&8-Y#xRnoOP{W<+9OI=&joyW7GH z*=UVT2=8{q_5CCD4R^>YAK1lG7c;1^w13J^XYewZrx+0 zIs26tI*i}obOdRA79kg44PD?HbtcCqxRg=AF8Y#TYIH46@)kecUB)U=`ibZwUO&%5 zikrOAV};OD@vn}ZR-Z6}5Yq|;;uTobaUH3#@zkw!;`cM=X68rM_r7(o1=sBm(MVVW zClTb5^j%8cQP4NHk0^OB<+iD1Bc!SvGX&Tz|Gvan?Wfy1o_@SpLXsV_96-RII)W&uecZ>!{@@ zepcx_EwMx6iPt=|SKYkB_20>MOd@8_z~f7{ySP3~9EWpk`vv$#~BgRifH(;81{9F&J_!E9J% zQI%}vk!6nWE6rKf5_E>VtQFQ~VOJXru-OW0CoLV^5`CXJGCZ9j`*EW02unuqfO0C? z9`L+Zk#%-_RlYu=qX#y;$SC+U=hmNqgNZ}KNo8AMxUzZqvK9XR-8sxFf0Y~}VKUzK z9dIX!ummT{JtB@0X{3$OLKfBgNNJ$*5IJ>uE?s@yti)ktNyQJ{$876*=X(ffOqX_X zqIbdzlb)G%Fp`&2Fl0HMdr}8yenm5j<&n5CmrngK>j~a&ZUS#YYDWdr6E}?L#N9%2 z^L{}I!B`Q|9F%frLwJSVR6CShTxBt?zb5KK?K0NE5l;$!n94n_o(O`zR5V%3*lUi#pVX8 zbLXpn|7pM*a>~80$!a-urj=*2)3d>hc zOzK-)3T{7%s#EA@FT-qKto?G?%B$Pc7*Aa`89&IfT3Xj|OK_ic(NaZ01p)r=!7Ng2 zb+n*OBz=4tOJJ7g>P z5A~nJ{geEgH@hQek>>a}`L9#^ll+^Nxg*zb|0DmuvH6qyTVA^(2?_rt|IKoLl7Gts scO(_jzvRDJ;ZO2!;c`cEBme2U;L%dW_-FVIz(%ecWO$_!|8w{M0NPTG-~a#s diff --git a/nasm.c b/nasm.c index cd7f714..c3575cd 100644 --- a/nasm.c +++ b/nasm.c @@ -51,7 +51,7 @@ static struct ofmt *ofmt = NULL; static FILE *error_file; /* Where to write error messages */ static FILE *ofile = NULL; -static int optimizing = 0; /* number of optimization passes to take */ +int optimizing = 0; /* number of optimization passes to take */ static int sb, cmd_sb = 16; /* by default */ static unsigned long cmd_cpu = IF_PLEVEL; /* highest level by default */ static unsigned long cpu = IF_PLEVEL; /* passed to insn_size & assemble.c */ @@ -429,15 +429,15 @@ static int process_arg (char *p, char *q) " or nasm -r for version info (obsolete)\n" " or nasm -v for version info (preferred)\n\n" " -t Assemble in SciTech TASM compatible mode\n" - " -g Generate debug information in selected format.\n" - " -e preprocess only (writes output to stdout by default)\n" + " -g Generate debug information in selected format.\n"); + printf(" -e preprocess only (writes output to stdout by default)\n" " -a don't preprocess (assemble only)\n" " -M generate Makefile dependencies on stdout\n\n" " -E redirect error messages to file\n" " -s redirect error messages to stdout\n\n" " -F format select a debugging format\n\n" - " -I adds a pathname to the include file path\n" - " -O optimize branch offsets (-O0 disables, default)\n" + " -I adds a pathname to the include file path\n"); + printf(" -O optimize branch offsets (-O0 disables, default)\n" " -P pre-includes a file\n" " -D[=] pre-defines a macro\n" " -U undefines a macro\n" diff --git a/nasm.h b/nasm.h index d4079dc..55d8a8f 100644 --- a/nasm.h +++ b/nasm.h @@ -13,7 +13,7 @@ #define NASM_MAJOR_VER 0 #define NASM_MINOR_VER 98 -#define NASM_VER "0.98.09" +#define NASM_VER "0.98.11" #ifndef NULL #define NULL 0 @@ -426,8 +426,10 @@ enum { /* special type of immediate operand */ #define ONENESS 0x00800000L /* so UNITY == IMMEDIATE | ONENESS */ #define UNITY 0x00802000L /* for shift/rotate instructions */ -#define BYTENESS 0x80000000L /* so SBYTE == IMMEDIATE | BYTENESS */ -#define SBYTE 0x80002000L /* for op r16/32,immediate instrs. */ +#define BYTENESS 0x40000000L /* so SBYTE == IMMEDIATE | BYTENESS */ +#define SBYTE 0x40002000L /* for op r16/32,immediate instrs. */ +#define BIGNESS 0x80000000L /* so SBIG == IMMEDIATE | BIGNESS */ +#define SBIG 0x80002000L /* for eax immediate instrs. */ /* * Next, the codes returned from the parser, for registers and @@ -867,5 +869,6 @@ extern int tasm_compatible_mode; */ extern int pass0; /* this is globally known */ +extern int optimizing; #endif diff --git a/ndisasm.c b/ndisasm.c index 354ea3c..227dde7 100644 --- a/ndisasm.c +++ b/ndisasm.c @@ -27,7 +27,7 @@ static const char *help = " -u sets USE32 (32-bit mode)\n" " -b 16 or -b 32 sets number of bits too\n" " -h displays this text\n" -" -r displays the version number\n" +" -r or -v displays the version number\n" " -e skips bytes of header\n" " -k avoids disassembling bytes from position \n" " -p selects the preferred vendor instruction set (intel, amd, cyrix, idt)\n"; @@ -42,7 +42,8 @@ int main(int argc, char **argv) char *pname = *argv; char *filename = NULL; unsigned long nextsync, synclen, initskip = 0L; - int lenread, lendis; + int lenread; + long lendis; int autosync = FALSE; int bits = 16; int eof = FALSE; @@ -68,7 +69,8 @@ int main(int argc, char **argv) fprintf(stderr, help); return 0; case 'r': - fprintf(stderr, "NDISASM version " NASM_VER "\n"); + case 'v': + fprintf(stderr, "NDISASM version %s compiled " __DATE__ "\n", NASM_VER); return 0; case 'u': /* USE32 */ bits = 32; @@ -181,6 +183,10 @@ int main(int argc, char **argv) } p = ""; /* force to next argument */ break; + default: /*bf*/ + fprintf(stderr, "%s: unrecognised option `-%c'\n", + pname, *p); + return 1; } } else if (!filename) { filename = p; @@ -227,7 +233,7 @@ int main(int argc, char **argv) } else lenread = 0; p += lenread; - if (offset == nextsync) { + if ((unsigned long)offset == nextsync) { if (synclen) { printf("%08lX skipping 0x%lX bytes\n", offset, synclen); offset += synclen; @@ -239,7 +245,7 @@ int main(int argc, char **argv) while (p > q && (p - q >= INSN_MAX || lenread == 0)) { lendis = disasm (q, outbuf, bits, offset, autosync, prefer); if (!lendis || lendis > (p - q) || - lendis > nextsync-offset) + (unsigned long)lendis > nextsync-offset) lendis = eatbyte (q, outbuf); output_ins (offset, q, lendis, outbuf); q += lendis; diff --git a/ndisasm.doc b/ndisasm.doc index 76367f5..5b5374a 100644 --- a/ndisasm.doc +++ b/ndisasm.doc @@ -174,7 +174,7 @@ Bugs and Improvements ===================== There are no known bugs. However, any you find, with patches if -possible, should be sent to or +possible, should be sent to or , and we'll try to fix them. Feel free to send contributions and new features as well. diff --git a/parser.c b/parser.c index 00dfcad..d802f05 100644 --- a/parser.c +++ b/parser.c @@ -686,9 +686,12 @@ insn *parse_line (int pass, char *buffer, insn *result, if (is_simple(value)) { if (reloc_value(value)==1) result->oprs[operand].type |= UNITY; - if (reloc_value(value) >= -128 && - reloc_value(value) <= 127) - result->oprs[operand].type |= SBYTE; + if (optimizing) { + if (reloc_value(value) >= -128 && + reloc_value(value) <= 127) + result->oprs[operand].type |= SBYTE; + else result->oprs[operand].type |= SBIG; + } } } else /* it's a register */ diff --git a/rdoff/Makefile.in b/rdoff/Makefile.in index 5ea14a0..38620d7 100644 --- a/rdoff/Makefile.in +++ b/rdoff/Makefile.in @@ -1,84 +1,86 @@ -# $Id$ -# -# Auto-configuring Makefile for RDOFF object file utils; part of the -# Netwide Assembler -# -# 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" -# distributed in the NASM archive. - -top_srcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ -bindir = @bindir@ -mandir = @mandir@ - -CC = @CC@ -CFLAGS = @CFLAGS@ @GCCFLAGS@ -I$(srcdir) -I$(top_srcdir) -LDFLAGS = @LDFLAGS@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ -LN_S = @LN_S@ - -LDRDFLIBS = rdoff.o nasmlib.o symtab.o collectn.o rdlib.o segtab.o hash.o -RDXLIBS = rdoff.o rdfload.o symtab.o collectn.o hash.o - -.c.o: - $(CC) -c $(CFLAGS) $< - -all: rdfdump ldrdf rdx rdflib rdf2bin rdf2com rdf2ihx - -rdfdump: rdfdump.o - $(CC) $(LDFLAGS) -o rdfdump rdfdump.o -ldrdf: ldrdf.o $(LDRDFLIBS) - $(CC) $(LDFLAGS) -o ldrdf ldrdf.o $(LDRDFLIBS) -rdx: rdx.o $(RDXLIBS) - $(CC) $(LDFLAGS) -o rdx rdx.o $(RDXLIBS) -rdflib: rdflib.o - $(CC) $(LDFLAGS) -o rdflib rdflib.o -rdf2bin: rdf2bin.o $(RDXLIBS) nasmlib.o - $(CC) $(LDFLAGS) -o rdf2bin rdf2bin.o $(RDXLIBS) nasmlib.o -rdf2com: - rm -f rdf2com && $(LN_S) rdf2bin rdf2com -rdf2ihx: rdf2ihx.o $(RDXLIBS) nasmlib.o - $(CC) $(LDFLAGS) -o rdf2ihx rdf2ihx.o $(RDXLIBS) nasmlib.o - -rdf2ihx.o: rdf2ihx.c -rdf2bin.o: rdf2bin.c -rdfdump.o: rdfdump.c -rdoff.o: rdoff.c rdoff.h -ldrdf.o: ldrdf.c rdoff.h $(top_srcdir)/nasmlib.h symtab.h collectn.h rdlib.h -symtab.o: symtab.c symtab.h -collectn.o: collectn.c collectn.h -rdx.o: rdx.c rdoff.h rdfload.h symtab.h -rdfload.o: rdfload.c rdfload.h rdoff.h collectn.h symtab.h -rdlib.o: rdlib.c rdlib.h -rdflib.o: rdflib.c -segtab.o: segtab.c - -nasmlib.o: $(top_srcdir)/nasmlib.c -## $(CC) -c $(CFLAGS) $(top_srcdir)/nasmlib.c - cd $(top_srcdir);make nasmlib.o - cp $(top_srcdir)/nasmlib.o $(srcdir) - -clean: - rm -f *.o rdfdump ldrdf rdx rdflib rdf2bin rdf2com rdf2ihx - -spotless: clean - rm -f Makefile - -distclean: spotless - -install: rdfdump ldrdf rdx rdflib rdf2bin rdf2com rdf2ihx - $(INSTALL_PROGRAM) rdfdump $(INSTALLROOT)$(bindir)/rdfdump - $(INSTALL_PROGRAM) ldrdf $(INSTALLROOT)$(bindir)/ldrdf - $(INSTALL_PROGRAM) rdx $(INSTALLROOT)$(bindir)/rdx - $(INSTALL_PROGRAM) rdflib $(INSTALLROOT)$(bindir)/rdflib - $(INSTALL_PROGRAM) rdf2bin $(INSTALLROOT)$(bindir)/rdf2bin - $(INSTALL_PROGRAM) rdf2ihx $(INSTALLROOT)$(bindir)/rdf2ihx - cd $(INSTALLROOT)$(bindir) && rm -f rdf2com && $(LN_S) rdf2bin rdf2com +*************** +*** 1,4 **** +- # $Id$ + # + # Auto-configuring Makefile for RDOFF object file utils; part of the + # Netwide Assembler +--- 1,4 ---- ++ # $Id$ + # + # Auto-configuring Makefile for RDOFF object file utils; part of the + # Netwide Assembler +*************** +*** 31,37 **** + .c.o: + $(CC) -c $(CFLAGS) $< + +- all: rdfdump ldrdf rdx rdflib rdf2bin rdf2com + + rdfdump: rdfdump.o + $(CC) $(LDFLAGS) -o rdfdump rdfdump.o +--- 31,37 ---- + .c.o: + $(CC) -c $(CFLAGS) $< + ++ all: rdfdump ldrdf rdx rdflib rdf2bin rdf2com rdf2ihx + + rdfdump: rdfdump.o + $(CC) $(LDFLAGS) -o rdfdump rdfdump.o +*************** +*** 45,51 **** + $(CC) $(LDFLAGS) -o rdf2bin rdf2bin.o $(RDXLIBS) nasmlib.o + rdf2com: + rm -f rdf2com && $(LN_S) rdf2bin rdf2com + + rdf2bin.o: rdf2bin.c + rdfdump.o: rdfdump.c + rdoff.o: rdoff.c rdoff.h +--- 45,54 ---- + $(CC) $(LDFLAGS) -o rdf2bin rdf2bin.o $(RDXLIBS) nasmlib.o + rdf2com: + rm -f rdf2com && $(LN_S) rdf2bin rdf2com ++ rdf2ihx: rdf2ihx.o $(RDXLIBS) nasmlib.o ++ $(CC) $(LDFLAGS) -o rdf2ihx rdf2ihx.o $(RDXLIBS) nasmlib.o + ++ rdf2ihx.o: rdf2ihx.c + rdf2bin.o: rdf2bin.c + rdfdump.o: rdfdump.c + rdoff.o: rdoff.c rdoff.h +*************** +*** 62,78 **** + $(CC) -c $(CFLAGS) $(top_srcdir)/nasmlib.c + + clean: +- rm -f *.o rdfdump ldrdf rdx rdflib rdf2bin rdf2com + + spotless: clean + rm -f Makefile + + distclean: spotless + +- install: rdfdump ldrdf rdx rdflib rdf2bin rdf2com + $(INSTALL_PROGRAM) rdfdump $(INSTALLROOT)$(bindir)/rdfdump + $(INSTALL_PROGRAM) ldrdf $(INSTALLROOT)$(bindir)/ldrdf + $(INSTALL_PROGRAM) rdx $(INSTALLROOT)$(bindir)/rdx + $(INSTALL_PROGRAM) rdflib $(INSTALLROOT)$(bindir)/rdflib + $(INSTALL_PROGRAM) rdf2bin $(INSTALLROOT)$(bindir)/rdf2bin + cd $(INSTALLROOT)$(bindir) && rm -f rdf2com && $(LN_S) rdf2bin rdf2com +--- 65,82 ---- + $(CC) -c $(CFLAGS) $(top_srcdir)/nasmlib.c + + clean: ++ rm -f *.o rdfdump ldrdf rdx rdflib rdf2bin rdf2com rdf2ihx + + spotless: clean + rm -f Makefile + + distclean: spotless + ++ install: rdfdump ldrdf rdx rdflib rdf2bin rdf2com rdf2ihx + $(INSTALL_PROGRAM) rdfdump $(INSTALLROOT)$(bindir)/rdfdump + $(INSTALL_PROGRAM) ldrdf $(INSTALLROOT)$(bindir)/ldrdf + $(INSTALL_PROGRAM) rdx $(INSTALLROOT)$(bindir)/rdx + $(INSTALL_PROGRAM) rdflib $(INSTALLROOT)$(bindir)/rdflib + $(INSTALL_PROGRAM) rdf2bin $(INSTALLROOT)$(bindir)/rdf2bin ++ $(INSTALL_PROGRAM) rdf2ihx $(INSTALLROOT)$(bindir)/rdf2ihx + cd $(INSTALLROOT)$(bindir) && rm -f rdf2com && $(LN_S) rdf2bin rdf2com diff --git a/rdoff/ldrdf.c b/rdoff/ldrdf.c index 3d9d749..d9aac2f 100644 --- a/rdoff/ldrdf.c +++ b/rdoff/ldrdf.c @@ -1,1347 +1,31 @@ -/* ldrdf.c RDOFF Object File linker/loader main program - * - * 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" - * distributed in the NASM archive. - */ - -/* - * TODO: actually get this new version working! - * - finish off write_output() - appears to be done - * - implement library searching - appears to be done - * - maybe we only want to do one pass, for performance reasons? - * this makes things a little harder, but unix 'ld' copes... - * - implement command line options - appears to be done - * - improve symbol table implementation - done, thanks to Graeme Defty - * - keep a cache of symbol names in each library module so - * we don't have to constantly recheck the file - * - general performance improvements - * - * BUGS & LIMITATIONS: this program doesn't support multiple code, data - * or bss segments, therefore for 16 bit programs whose code, data or BSS - * segment exceeds 64K in size, it will not work. This program probably - * wont work if compiled by a 16 bit compiler. Try DJGPP if you're running - * under DOS. '#define STINGY_MEMORY' may help a little. - */ - -#include -#include -#include - -#include "multboot.h" -#include "rdoff.h" -#include "symtab.h" -#include "collectn.h" -#include "rdlib.h" -#include "segtab.h" - -#define LDRDF_VERSION "1.02" - -#define RDF_MAXSEGS 64 -/* #define STINGY_MEMORY */ - -/* ======================================================================= - * Types & macros that are private to this program - */ - -struct segment_infonode { - int dest_seg; /* output segment to be placed into, -1 to - skip linking this segment */ - long reloc; /* segment's relocation factor */ -}; - - -struct modulenode { - rdffile f; /* the RDOFF file structure */ - struct segment_infonode seginfo[RDF_MAXSEGS]; /* what are we doing - with each segment? */ - void * header; - char * name; - struct modulenode * next; - long bss_reloc; -}; - -#include "ldsegs.h" - -#define newstr(str) strcpy(malloc(strlen(str) + 1),str) -#define newstrcat(s1,s2) strcat(strcpy(malloc(strlen(s1)+strlen(s2)+1),s1),s2) - -/* ========================================================================== - * Function prototypes of private utility functions - */ - -void processmodule(const char * filename, struct modulenode * mod); -int allocnewseg(int16 type,int16 reserved); -int findsegment(int16 type,int16 reserved); -void symtab_add(const char * symbol, int segment, long offset); -int symtab_get(const char * symbol, int * segment, long * offset); - -/* ========================================================================= - * Global data structures. - */ - -/* a linked list of modules that will be included in the output */ -struct modulenode * modules = NULL; -struct modulenode * lastmodule = NULL; - -/* a linked list of libraries to be searched for unresolved imported symbols */ -struct librarynode * libraries = NULL; -struct librarynode * lastlib = NULL; - -/* the symbol table */ -void * symtab = NULL; - -/* objects search path */ -char * objpath = NULL; - -/* libraries search path */ -char * libpath = NULL; - -/* error file */ -static FILE * error_file; - -#ifdef _MULTBOOT_H - -/* loading address for multiboot header */ -unsigned MBHloadAddr; - -/* - * Tiny code that moves RDF loader to its working memory region: - * mov esi,SOURCE_ADDR ; BE xx xx xx xx - * mov edi,DEST_ADDR ; BF xx xx xx xx - * mov esp,edi ; 89 FC - * push edi ; 57 - * mov ecx,RDFLDR_LENGTH/4 ; B9 xx xx xx xx - * cld ; FC - * rep movsd ; F3 A5 - * ret ; C3 - */ - -#define RDFLDR_LENGTH 4096 /* Loader will be moved to unused */ -#define RDFLDR_DESTLOC 0xBF000 /* video page */ - -unsigned char RDFloaderMover[]={ - 0xBE, 0, 0, 0, 0, 0xBF, 0, 0xF0, 0xB, 0, - 0x89, 0xFC, 0x57, - 0xB9, 0, 4, 0, 0, - 0xFC, 0xF3, 0xA5, 0xC3 -}; - -#endif - -/* the header of the output file, built up stage by stage */ -rdf_headerbuf * newheader = NULL; - -/* The current state of segment allocation, including information about - * which output segment numbers have been allocated, and their types and - * amount of data which has already been allocated inside them. - */ -struct SegmentHeaderRec outputseg[RDF_MAXSEGS]; -int nsegs = 0; -long bss_length; - -/* global options which affect how the program behaves */ -struct ldrdfoptions { - int verbose; - int align; - int warnUnresolved; - int errorUnresolved; - int strip; - int respfile; - int stderr_redir; - int objpath; - int libpath; - int addMBheader; -} options; - -int errorcount = 0; /* determines main program exit status */ - -/* ========================================================================= - * Utility functions - */ - - -/* - * initsegments() - * - * sets up segments 0, 1, and 2, the initial code data and bss segments - */ - -void initsegments() -{ - nsegs = 3; - outputseg[0].type = 1; - outputseg[0].number = 0; - outputseg[0].reserved = 0; - outputseg[0].length = 0; - outputseg[1].type = 2; - outputseg[1].number = 1; - outputseg[1].reserved = 0; - outputseg[1].length = 0; - outputseg[2].type = 0xFFFF; /* reserved segment type */ - outputseg[2].number = 2; - outputseg[2].reserved = 0; - outputseg[2].length = 0; - bss_length = 0; -} - -/* - * loadmodule - * - * Determine the characteristics of a module, and decide what to do with - * each segment it contains (including determining destination segments and - * relocation factors for segments that are kept). - */ - -void loadmodule(const char * filename) -{ - if (options.verbose) - printf("loading `%s'\n", filename); - - /* allocate a new module entry on the end of the modules list */ - if (!modules) - { - modules = malloc (sizeof(*modules)); - lastmodule = modules; - } - else - { - lastmodule->next = malloc (sizeof(*modules)); - lastmodule = lastmodule->next; - } - - if ( ! lastmodule) - { - fprintf(stderr, "ldrdf: out of memory\n"); - exit(1); - } - - /* open the file using 'rdfopen', which returns nonzero on error */ - - if (rdfopen(&lastmodule->f, filename) != 0) - { - rdfperror("ldrdf", filename); - exit(1); - } - - /* - * store information about the module, and determine what segments - * it contains, and what we should do with them (determine relocation - * factor if we decide to keep them) - */ - - lastmodule->header = NULL; - lastmodule->name = strdup(filename); - lastmodule->next = NULL; - - processmodule(filename, lastmodule); -} - -/* - * processmodule() - * - * step through each segment, determine what exactly we're doing with - * it, and if we intend to keep it, determine (a) which segment to - * put it in and (b) whereabouts in that segment it will end up. - * (b) is fairly easy, cos we're now keeping track of how big each segment - * in our output file is... - */ - -void processmodule(const char * filename, struct modulenode * mod) -{ - struct segconfig sconf; - int seg, outseg; - void * header; - rdfheaderrec * hr; - long bssamount = 0; - - for (seg = 0; seg < mod->f.nsegs; seg++) - { - /* - * get the segment configuration for this type from the segment - * table. getsegconfig() is a macro, defined in ldsegs.h. - */ - getsegconfig(sconf, mod->f.seg[seg].type); - - if (options.verbose > 1) { - printf ("%s %04x [%04x:%10s] ", filename, mod->f.seg[seg].number, - mod->f.seg[seg].type, sconf.typedesc); - } - /* - * sconf->dowhat tells us what to do with a segment of this type. - */ - switch (sconf.dowhat) { - case SEG_IGNORE: - /* - * Set destination segment to -1, to indicate that this segment - * should be ignored for the purpose of output, ie it is left - * out of the linked executable. - */ - mod->seginfo[seg].dest_seg = -1; - if (options.verbose > 1) printf("IGNORED\n"); - break; - - case SEG_NEWSEG: - /* - * The configuration tells us to create a new segment for - * each occurrence of this segment type. - */ - outseg = allocnewseg(sconf.mergetype, - mod->f.seg[seg].reserved); - mod->seginfo[seg].dest_seg = outseg; - mod->seginfo[seg].reloc = 0; - outputseg[outseg].length = mod->f.seg[seg].length; - if (options.verbose > 1) - printf ("=> %04x:%08lx (+%04lx)\n", outseg, - mod->seginfo[seg].reloc, - mod->f.seg[seg].length); - break; - - case SEG_MERGE: - /* - * The configuration tells us to merge the segment with - * a previously existing segment of type 'sconf.mergetype', - * if one exists. Otherwise a new segment is created. - * This is handled transparently by 'findsegment()'. - */ - outseg = findsegment(sconf.mergetype, - mod->f.seg[seg].reserved); - mod->seginfo[seg].dest_seg = outseg; - - /* - * We need to add alignment to these segments. - */ - if (outputseg[outseg].length % options.align != 0) - outputseg[outseg].length += - options.align - (outputseg[outseg].length % options.align); - - mod->seginfo[seg].reloc = outputseg[outseg].length; - outputseg[outseg].length += mod->f.seg[seg].length; - - if (options.verbose > 1) - printf ("=> %04x:%08lx (+%04lx)\n", outseg, - mod->seginfo[seg].reloc, - mod->f.seg[seg].length); - } - - } - - /* - * extract symbols from the header, and dump them into the - * symbol table - */ - header = malloc(mod->f.header_len); - if (!header) { - fprintf(stderr, "ldrdf: not enough memory\n"); - exit(1); - } - if (rdfloadseg(&mod->f, RDOFF_HEADER, header)) { - rdfperror("ldrdf", filename); - exit(1); - } - - while ((hr = rdfgetheaderrec (&mod->f))) - { - switch(hr->type) { - case 2: /* imported symbol - define with seg = -1 */ - case 7: - symtab_add(hr->i.label, -1, 0); - break; - - case 3: /* exported symbol */ - { - int destseg; - long destreloc; - - if (hr->e.segment == 2) - { - destreloc = bss_length; - if (destreloc % options.align != 0) - destreloc += options.align - (destreloc % options.align); - destseg = 2; - } - else - { - if ((destseg = mod->seginfo[(int)hr->e.segment].dest_seg) == -1) - continue; - destreloc = mod->seginfo[(int)hr->e.segment].reloc; - } - symtab_add(hr->e.label, destseg, destreloc + hr->e.offset); - break; - } - - case 5: /* BSS reservation */ - /* - * first, amalgamate all BSS reservations in this module - * into one, because we allow this in the output format. - */ - bssamount += hr->b.amount; - break; - } - } - - if (bssamount != 0) - { - /* - * handle the BSS segment - first pad the existing bss length - * to the correct alignment, then store the length in bss_reloc - * for this module. Then add this module's BSS length onto - * bss_length. - */ - if (bss_length % options.align != 0) - bss_length += options.align - (bss_length % options.align); - - mod->bss_reloc = bss_length; - if (options.verbose > 1) { - printf ("%s 0002 [ BSS] => 0002:%08lx (+%04lx)\n", - filename, bss_length, bssamount); - } - bss_length += bssamount; - } - -#ifdef STINGY_MEMORY - /* - * we free the header buffer here, to save memory later. - * this isn't efficient, but probably halves the memory usage - * of this program... - */ - mod->f.header_loc = NULL; - free(header); - -#endif - -} - - -/* - * Look in list for module by its name. - */ -int lookformodule(const char *name) - { - struct modulenode *curr=modules; - - while(curr) { - if (!strcmp(name,curr->name)) return 1; - curr = curr->next; - } - return 0; - } - - -/* - * allocnewseg() - * findsegment() - * - * These functions manipulate the array of output segments, and are used - * by processmodule(). allocnewseg() allocates a segment in the array, - * initialising it to be empty. findsegment() first scans the array for - * a segment of the type requested, and if one isn't found allocates a - * new one. - */ -int allocnewseg(int16 type,int16 reserved) -{ - outputseg[nsegs].type = type; - outputseg[nsegs].number = nsegs; - outputseg[nsegs].reserved = reserved; - outputseg[nsegs].length = 0; - outputseg[nsegs].offset = 0; - outputseg[nsegs].data = NULL; - - return nsegs++; -} - -int findsegment(int16 type,int16 reserved) -{ - int i; - - for (i = 0; i < nsegs; i++) - if (outputseg[i].type == type) return i; - - return allocnewseg(type,reserved); -} - -/* - * symtab_add() - * - * inserts a symbol into the global symbol table, which associates symbol - * names either with addresses, or a marker that the symbol hasn't been - * resolved yet, or possibly that the symbol has been defined as - * contained in a dynamic [load time/run time] linked library. - * - * segment = -1 => not yet defined - * segment = -2 => defined as dll symbol - * - * If the symbol is already defined, and the new segment >= 0, then - * if the original segment was < 0 the symbol is redefined, otherwise - * a duplicate symbol warning is issued. If new segment == -1, this - * routine won't change a previously existing symbol. It will change - * to segment = -2 only if the segment was previously < 0. - */ - -void symtab_add(const char * symbol, int segment, long offset) -{ - symtabEnt * ste; - - ste = symtabFind(symtab, symbol); - if (ste) - { - if (ste->segment >= 0) { - /* - * symbol previously defined - */ - if (segment < 0) return; - fprintf (error_file, "warning: `%s' redefined\n", symbol); - return; - } - - /* - * somebody wanted the symbol, and put an undefined symbol - * marker into the table - */ - if (segment == -1) return; - /* - * we have more information now - update the symbol's entry - */ - ste->segment = segment; - ste->offset = offset; - ste->flags = 0; - return; - } - /* - * this is the first declaration of this symbol - */ - ste = malloc(sizeof(symtabEnt)); - if (!ste) { - fprintf(stderr, "ldrdf: out of memory\n"); - exit(1); - } - ste->name = strdup(symbol); - ste->segment = segment; - ste->offset = offset; - ste->flags = 0; - symtabInsert(symtab, ste); -} - -/* - * symtab_get() - * - * Retrieves the values associated with a symbol. Undefined symbols - * are assumed to have -1:0 associated. Returns 1 if the symbol was - * successfully located. - */ - -int symtab_get(const char * symbol, int * segment, long * offset) -{ - symtabEnt * ste = symtabFind(symtab, symbol); - if (!ste) { - *segment = -1; - *offset = 0; - return 0; - } - else - { - *segment = ste->segment; - *offset = ste->offset; - return 1; - } -} - -/* - * add_library() - * - * checks that a library can be opened and is in the correct format, - * then adds it to the linked list of libraries. - */ - -void add_library(const char * name) -{ - if (rdl_verify(name)) { - rdl_perror("ldrdf", name); - errorcount++; - return; - } - if (! libraries) - { - lastlib = libraries = malloc(sizeof(*libraries)); - if (! libraries) { - fprintf(stderr, "ldrdf: out of memory\n"); - exit(1); - } - } - else - { - lastlib->next = malloc(sizeof(*libraries)); - if (!lastlib->next) { - fprintf(stderr, "ldrdf: out of memory\n"); - exit(1); - } - lastlib = lastlib->next; - } - lastlib->next = NULL; - if (rdl_open(lastlib, name)) { - rdl_perror("ldrdf", name); - errorcount++; - return; - } -} - -/* - * search_libraries() - * - * scans through the list of libraries, attempting to match symbols - * defined in library modules against symbols that are referenced but - * not defined (segment = -1 in the symbol table) - * - * returns 1 if any extra library modules are included, indicating that - * another pass through the library list should be made (possibly). - */ - -int search_libraries() -{ - struct librarynode * cur; - rdffile f; - int i; - void * header; - int segment; - long offset; - int doneanything = 0, pass = 1, keepfile; - rdfheaderrec * hr; - - cur = libraries; - - while (cur) - { - if (options.verbose > 2) - printf("scanning library `%s', pass %d...\n", cur->name, pass); - - for (i = 0; rdl_openmodule(cur, i, &f) == 0; i++) - { - if (pass == 2 && lookformodule(f.name)) continue; - - if (options.verbose > 3) - printf(" looking in module `%s'\n", f.name); - - header = malloc(f.header_len); - if (!header) { - fprintf(stderr, "ldrdf: not enough memory\n"); - exit(1); - } - if (rdfloadseg(&f, RDOFF_HEADER, header)) { - rdfperror("ldrdf", f.name); - errorcount++; - return 0; - } - - keepfile = 0; - - while ((hr = rdfgetheaderrec (&f))) - { - /* we're only interested in exports, so skip others: */ - if (hr->type != 3) continue; - - /* - * Find the symbol in the symbol table. If the symbol isn't - * defined, we aren't interested, so go on to the next. - * If it is defined as anything but -1, we're also not - * interested. But if it is defined as -1, insert this - * module into the list of modules to use, and go - * immediately on to the next module... - */ - if (! symtab_get(hr->e.label, &segment, &offset) - || segment != -1) - { - continue; - } - - doneanything = 1; - keepfile = 1; - - /* - * as there are undefined symbols, we can assume that - * there are modules on the module list by the time - * we get here. - */ - lastmodule->next = malloc(sizeof(*lastmodule->next)); - if (!lastmodule->next) { - fprintf(stderr, "ldrdf: not enough memory\n"); - exit(1); - } - lastmodule = lastmodule->next; - memcpy(&lastmodule->f, &f, sizeof(f)); - lastmodule->name = strdup(f.name); - lastmodule->next = NULL; - processmodule(f.name, lastmodule); - break; - } - if (!keepfile) - { - free(f.name); - f.name = NULL; - f.fp = NULL; - } - } - if (rdl_error != 0 && rdl_error != RDL_ENOTFOUND) - rdl_perror("ldrdf", cur->name); - - cur = cur->next; - if (cur == NULL && pass == 1) { - cur = libraries; - pass++; - } - } - - return doneanything; -} - -/* - * write_output() - * - * this takes the linked list of modules, and walks through it, merging - * all the modules into a single output module, and then writes this to a - * file. - */ -void write_output(const char * filename) -{ - FILE * f; - rdf_headerbuf * rdfheader; - struct modulenode * cur; - int i, availableseg, seg, localseg, isrelative; - void * header; - rdfheaderrec * hr, newrec; - symtabEnt * se; - segtab segs; - long offset; - byte * data; - - if ((f = fopen(filename, "wb"))==NULL) { - fprintf(stderr, "ldrdf: couldn't open %s for output\n", filename); - exit(1); - } - if ((rdfheader=rdfnewheader())==NULL) { - fprintf(stderr, "ldrdf: out of memory\n"); - exit(1); - } - - /* - * Add multiboot header if appropriate option is specified. - * Multiboot record *MUST* be the first record in output file. - */ - if (options.addMBheader) { - if (options.verbose) - puts("\nadding multiboot header record"); - - hr = (rdfheaderrec *) malloc(sizeof(struct MultiBootHdrRec)); - hr->mbh.type = 9; - hr->mbh.reclen = sizeof(struct tMultiBootHeader)+RDFLDRMOVER_SIZE; - - hr->mbh.mb.Magic = MB_MAGIC; - hr->mbh.mb.Flags = MB_FL_KLUDGE; - hr->mbh.mb.Checksum = ~(MB_MAGIC+MB_FL_KLUDGE-1); - hr->mbh.mb.HeaderAddr = MBHloadAddr+16; - hr->mbh.mb.LoadAddr = MBHloadAddr; - hr->mbh.mb.Entry = MBHloadAddr+16+sizeof(struct tMultiBootHeader); - - memcpy(hr->mbh.mover,RDFloaderMover,RDFLDRMOVER_SIZE); - - rdfaddheader(rdfheader,hr); - free(hr); - } - - if (options.verbose) - printf ("\nbuilding output module (%d segments)\n", nsegs); - - /* - * Allocate the memory for the segments. We may be better off - * building the output module one segment at a time when running - * under 16 bit DOS, but that would be a slower way of doing this. - * And you could always use DJGPP... - */ - for (i = 0; i < nsegs; i++) - { - outputseg[i].data=NULL; - if(!outputseg[i].length) continue; - outputseg[i].data = malloc(outputseg[i].length); - if (!outputseg[i].data) { - fprintf(stderr, "ldrdf: out of memory\n"); - exit(1); - } - } - - /* - * initialise availableseg, used to allocate segment numbers for - * imported and exported labels... - */ - availableseg = nsegs; - - /* - * Step through the modules, performing required actions on each one - */ - for (cur = modules; cur; cur=cur->next) - { - /* - * Read the actual segment contents into the correct places in - * the newly allocated segments - */ - - for (i = 0; i < cur->f.nsegs; i++) - { - int dest = cur->seginfo[i].dest_seg; - - if (dest == -1) continue; - if (rdfloadseg(&cur->f, i, - outputseg[dest].data + cur->seginfo[i].reloc)) - { - rdfperror("ldrdf", cur->name); - exit(1); - } - } - - /* - * Perform fixups, and add new header records where required - */ - - header = malloc(cur->f.header_len); - if (!header) { - fprintf(stderr, "ldrdf: out of memory\n"); - exit(1); - } - - if (cur->f.header_loc) - rdfheaderrewind(&cur->f); - else - if (rdfloadseg(&cur->f, RDOFF_HEADER, header)) - { - rdfperror("ldrdf", cur->name); - exit(1); - } - - /* - * we need to create a local segment number -> location - * table for the segments in this module. - */ - init_seglocations(&segs); - for (i = 0; i < cur->f.nsegs; i++) - { - add_seglocation(&segs, cur->f.seg[i].number, - cur->seginfo[i].dest_seg, cur->seginfo[i].reloc); - } - /* - * and the BSS segment (doh!) - */ - add_seglocation (&segs, 2, 2, cur->bss_reloc); - - while ((hr = rdfgetheaderrec(&cur->f))) - { - switch(hr->type) { - case 1: /* relocation record - need to do a fixup */ - /* - * First correct the offset stored in the segment from - * the start of the segment (which may well have changed). - * - * To do this we add to the number stored the relocation - * factor associated with the segment that contains the - * target segment. - * - * The relocation could be a relative relocation, in which - * case we have to first subtract the amount we've relocated - * the containing segment by. - */ - - if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset)) - { - fprintf(stderr, "%s: reloc to undefined segment %04x\n", - cur->name, (int) hr->r.refseg); - errorcount++; - break; - } - - isrelative = (hr->r.segment & 64) == 64; - hr->r.segment &= 63; - - if (hr->r.segment == 2 || - (localseg = rdffindsegment(&cur->f, hr->r.segment)) == -1) - { - fprintf(stderr, "%s: reloc from %s segment (%d)\n", - cur->name, - hr->r.segment == 2 ? "BSS" : "unknown", - hr->r.segment); - errorcount++; - break; - } - - if (hr->r.length != 1 && hr->r.length != 2 && hr->r.length!=4) - { - fprintf(stderr, "%s: nonstandard length reloc " - "(%d bytes)\n", cur->name, hr->r.length); - errorcount++; - break; - } - - /* - * okay, now the relocation is in the segment pointed to by - * cur->seginfo[localseg], and we know everything else is - * okay to go ahead and do the relocation - */ - data = outputseg[cur->seginfo[localseg].dest_seg].data; - data += cur->seginfo[localseg].reloc + hr->r.offset; - - /* - * data now points to the reference that needs - * relocation. Calculate the relocation factor. - * Factor is: - * offset of referred object in segment [in offset] - * (- relocation of localseg, if ref is relative) - * For simplicity, the result is stored in 'offset'. - * Then add 'offset' onto the value at data. - */ - - if (isrelative) offset -= cur->seginfo[localseg].reloc; - switch (hr->r.length) - { - case 1: - offset += *data; - if (offset < -127 || offset > 128) - fprintf(error_file, "warning: relocation out of range " - "at %s(%02x:%08lx)\n", cur->name, - (int)hr->r.segment, hr->r.offset); - *data = (char) offset; - break; - case 2: - offset += * (short *)data; - if (offset < -32767 || offset > 32768) - fprintf(error_file, "warning: relocation out of range " - "at %s(%02x:%08lx)\n", cur->name, - (int)hr->r.segment, hr->r.offset); - * (short *)data = (short) offset; - break; - case 4: - * (long *)data += offset; - /* we can't easily detect overflow on this one */ - break; - } - - /* - * If the relocation was relative between two symbols in - * the same segment, then we're done. - * - * Otherwise, we need to output a new relocation record - * with the references updated segment and offset... - */ - if (! isrelative - || cur->seginfo[localseg].dest_seg != seg) - { - hr->r.segment = cur->seginfo[localseg].dest_seg; - hr->r.offset += cur->seginfo[localseg].reloc; - hr->r.refseg = seg; - rdfaddheader(rdfheader, hr); - } - break; - - case 2: /* import symbol */ - case 7: - /* - * scan the global symbol table for the symbol - * and associate its location with the segment number - * for this module - */ - se = symtabFind(symtab, hr->i.label); - if (!se || se->segment == -1) { - if (options.warnUnresolved) { - fprintf(error_file, "warning: unresolved reference to `%s'" - " in module `%s'\n", hr->i.label, cur->name); - if (options.errorUnresolved==1) errorcount++; - } - /* - * we need to allocate a segment number for this - * symbol, and store it in the symbol table for - * future reference - */ - if (!se) { - se=malloc(sizeof(*se)); - if (!se) { - fprintf(stderr, "ldrdf: out of memory\n"); - exit(1); - } - se->name = strdup(hr->i.label); - se->flags = 0; - se->segment = availableseg++; - se->offset = 0; - symtabInsert(symtab, se); - } - else { - se->segment = availableseg++; - se->offset = 0; - } - /* - * output a header record that imports it to the - * recently allocated segment number... - */ - newrec = *hr; - newrec.i.segment = se->segment; - rdfaddheader(rdfheader, &newrec); - } - - add_seglocation(&segs, hr->i.segment, se->segment, se->offset); - - break; - - case 3: /* export symbol */ - /* - * need to insert an export for this symbol into the new - * header, unless we're stripping symbols [unless this - * symbol is in an explicit keep list]. *** FIXME *** - */ - if (options.strip) - break; - - if (hr->e.segment == 2) { - seg = 2; - offset = cur->bss_reloc; - } - else { - localseg = rdffindsegment(&cur->f, hr->e.segment); - if (localseg == -1) { - fprintf(stderr, "%s: exported symbol `%s' from " - "unrecognised segment\n", cur->name, - hr->e.label); - errorcount++; - break; - } - offset = cur->seginfo[localseg].reloc; - seg = cur->seginfo[localseg].dest_seg; - } - - hr->e.segment = seg; - hr->e.offset += offset; - rdfaddheader(rdfheader, hr); - break; - - case 8: /* module name */ - /* - * insert module name record if export symbols - * are not stripped. - */ - if (options.strip) break; - - rdfaddheader(rdfheader, hr); - break; - - case 6: /* segment fixup */ - /* - * modify the segment numbers if necessary, and - * pass straight through to the output module header - * - * *** FIXME *** - */ - if (hr->r.segment == 2) { - fprintf(stderr, "%s: segment fixup in BSS section\n", - cur->name); - errorcount++; - break; - } - localseg = rdffindsegment(&cur->f, hr->r.segment); - if (localseg == -1) { - fprintf(stderr, "%s: segment fixup in unrecognised" - " segment (%d)\n", cur->name, hr->r.segment); - errorcount++; - break; - } - hr->r.segment = cur->seginfo[localseg].dest_seg; - hr->r.offset += cur->seginfo[localseg].reloc; - - if (!get_seglocation(&segs, hr->r.refseg, &seg, &offset)) - { - fprintf(stderr, "%s: segment fixup to undefined " - "segment %04x\n", cur->name, (int)hr->r.refseg); - errorcount++; - break; - } - hr->r.refseg = seg; - rdfaddheader(rdfheader, hr); - break; - } - } - - free(header); - done_seglocations(&segs); - - } - - /* - * combined BSS reservation for the entire results - */ - newrec.type = 5; - newrec.b.reclen = 4; - newrec.b.amount = bss_length; - rdfaddheader(rdfheader, &newrec); - - /* - * Write the header - */ - for (i = 0; i < nsegs; i++) - { - if (i == 2) continue; - rdfaddsegment (rdfheader, outputseg[i].length); - } - - if (options.addMBheader) { - struct MultiBootHdrRec *mbhrec = (struct MultiBootHdrRec *)(rdfheader->buf->buffer); - unsigned l = membuflength(rdfheader->buf) + 14 + - 10*rdfheader->nsegments + rdfheader->seglength; - unsigned *ldraddr = (unsigned *)(mbhrec->mover+1); - - mbhrec->mb.LoadEndAddr = MBHloadAddr+l+10+RDFLDR_LENGTH; - mbhrec->mb.BSSendAddr = mbhrec->mb.LoadEndAddr; - *ldraddr = MBHloadAddr+l+10; - } - - rdfwriteheader(f, rdfheader); - rdfdoneheader(rdfheader); - /* - * Step through the segments, one at a time, writing out into - * the output file - */ - - for (i = 0; i < nsegs; i++) - { - int16 s; - long l; - - if (i == 2) continue; - - s = translateshort(outputseg[i].type); - fwrite(&s, 2, 1, f); - s = translateshort(outputseg[i].number); - fwrite(&s, 2, 1, f); - s = translateshort(outputseg[i].reserved); - fwrite(&s, 2, 1, f); - l = translatelong(outputseg[i].length); - fwrite(&l, 4, 1, f); - - fwrite(outputseg[i].data, outputseg[i].length, 1, f); - } - - fwrite("\0\0\0\0\0\0\0\0\0\0", 10, 1, f); -} - -/* ========================================================================= - * Main program - */ - -void usage() -{ - printf("usage:\n"); - printf(" ldrdf [options] object modules ... [-llibrary ...]\n"); - printf(" ldrdf -r\n"); - printf("options:\n"); - printf(" -v[=n] increases verbosity by 1, or sets it to n\n"); - printf(" -a nn sets segment alignment value (default 16)\n"); - printf(" -s strips exported symbols\n"); - printf(" -x warn about unresolved symbols\n"); - printf(" -o name write output in file 'name'\n"); - printf(" -j path specify objects search path\n"); - printf(" -L path specify libraries search path\n"); - printf(" -mbh [address] add multiboot header to output file. Default\n"); - printf(" loading address is 0x110000\n"); - exit(0); -} - -int main(int argc, char ** argv) -{ - char * outname = "aout.rdf"; - int moduleloaded = 0; - char *respstrings[128] = {0, }; - - options.verbose = 0; - options.align = 16; - options.warnUnresolved = 0; - options.strip = 0; - - error_file = stderr; - - argc --, argv ++; - if (argc == 0) usage(); - while (argc && **argv == '-' && argv[0][1] != 'l') - { - switch(argv[0][1]) { - case 'r': - printf("ldrdf (linker for RDF files) version " LDRDF_VERSION "\n"); - printf( _RDOFF_H "\n"); - exit(0); - case 'v': - if (argv[0][2] == '=') { - options.verbose = argv[0][3] - '0'; - if (options.verbose < 0 || options.verbose > 9) { - fprintf(stderr, "ldrdf: verbosity level must be a number" - " between 0 and 9\n"); - exit(1); - } - } - else - options.verbose++; - break; - case 'a': - options.align = atoi(argv[1]); - if (options.align <= 0) { - fprintf(stderr, - "ldrdf: -a expects a positive number argument\n"); - exit(1); - } - argv++, argc--; - break; - case 's': - options.strip = 1; - break; - case 'x': - options.warnUnresolved = 1; - if (argv[0][2]=='e') - options.errorUnresolved = 1; - break; - case 'o': - outname = argv[1]; - argv++, argc--; - break; - case 'j': - if (!objpath) - { - options.objpath = 1; - objpath = argv[1]; - argv++, argc--; - break; - } - else - { - fprintf(stderr,"ldrdf: more than one objects search path specified\n"); - exit(1); - } - case 'L': - if (!libpath) - { - options.libpath = 1; - libpath = argv[1]; - argv++, argc--; - break; - } - else - { - fprintf(stderr,"ldrdf: more than one libraries search path specified\n"); - exit(1); - } - case '@': { - int i=0; - char buf[256]; - FILE *f; - - options.respfile = 1; - if (argv[1] != NULL) f = fopen(argv[1],"r"); - else - { - fprintf(stderr,"ldrdf: no response file name specified\n"); - exit(1); - } - - if (f == NULL) - { - fprintf(stderr,"ldrdf: unable to open response file\n"); - exit(1); - } - argc-=2; - while(fgets(buf,sizeof(buf)-1,f)!=NULL) - { - char *p; - if (buf[0]=='\n') continue; - if ((p = strchr(buf,'\n')) != 0) - *p=0; - if (i >= 128) - { - fprintf(stderr,"ldrdf: too many input files\n"); - exit(1); - } - *(respstrings+i) = newstr(buf); - argc++, i++; - } - goto done; - } - case '2': - options.stderr_redir = 1; - error_file = stdout; - break; - case 'm': - if (argv[0][2] == 'b' && argv[0][3] == 'h') { - if (argv[1][0] != '-') { - MBHloadAddr = atoi(argv[1]); - } else { - MBHloadAddr = MB_DEFAULTLOADADDR; - } - options.addMBheader = 1; - break; - } - default: - usage(); - } - argv++, argc--; - } -done: - if (options.verbose > 4) { - printf("ldrdf invoked with options:\n"); - printf(" section alignment: %d bytes\n", options.align); - printf(" output name: `%s'\n", outname); - if (options.strip) - printf(" strip symbols\n"); - if (options.warnUnresolved) - printf(" warn about unresolved symbols\n"); - if (options.errorUnresolved) - printf(" error if unresolved symbols\n"); - if (options.objpath) - printf(" objects search path: %s\n",objpath); - if (options.libpath) - printf(" libraries search path: %s\n",libpath); - if (options.addMBheader) - printf(" loading address for multiboot header: 0x%X\n",MBHloadAddr); - printf("\n"); - } - - symtab = symtabNew(); - initsegments(); - - if (!symtab) { - fprintf(stderr, "ldrdf: out of memory\n"); - exit(1); - } - - if (*respstrings) argv = respstrings; - while (argc) - { - if (!strncmp(*argv, "-l", 2)) /* library */ - { - if(libpath) add_library(newstrcat(libpath,*argv + 2)); - else add_library(*argv + 2); - } - else { - if(objpath) loadmodule(newstrcat(objpath,*argv)); - else loadmodule(*argv); - moduleloaded = 1; - } - argv++, argc--; - } - - if (! moduleloaded) { - printf("ldrdf: nothing to do. ldrdf -h for usage\n"); - return 0; - } - - - search_libraries(); - - if (options.verbose > 2) - { - printf ("symbol table:\n"); - symtabDump(symtab, stdout); - } - - write_output(outname); - - if (errorcount > 0) exit(1); - return 0; -} +*************** +*** 29,42 **** + #include + #include + + #include "rdoff.h" + #include "symtab.h" + #include "collectn.h" + #include "rdlib.h" + #include "segtab.h" +- #include "multboot.h" + +- #define LDRDF_VERSION "1.01 alpha 2" + + #define RDF_MAXSEGS 64 + /* #define STINGY_MEMORY */ +--- 29,42 ---- + #include + #include + ++ #include "multboot.h" + #include "rdoff.h" + #include "symtab.h" + #include "collectn.h" + #include "rdlib.h" + #include "segtab.h" + ++ #define LDRDF_VERSION "1.02" + + #define RDF_MAXSEGS 64 + /* #define STINGY_MEMORY */ diff --git a/rdoff/rdflib.c b/rdoff/rdflib.c index 7a00fc6..5a8cf69 100644 --- a/rdoff/rdflib.c +++ b/rdoff/rdflib.c @@ -19,6 +19,7 @@ */ #include +#include #include #include diff --git a/rdoff/rdfload.c b/rdoff/rdfload.c index 4737282..6928ca2 100644 --- a/rdoff/rdfload.c +++ b/rdoff/rdfload.c @@ -19,6 +19,7 @@ #include #include +#include #include "rdfload.h" #include "symtab.h" diff --git a/rdoff/rdoff.h b/rdoff/rdoff.h index 0c57231..15f26bc 100644 --- a/rdoff/rdoff.h +++ b/rdoff/rdoff.h @@ -1,199 +1,106 @@ -/* rdoff.h RDOFF Object File manipulation routines header file - * - * 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" - * distributed in the NASM archive. - * - * Permission to use this file in your own projects is granted, as long - * as acknowledgement is given in an appropriate manner to its authors, - * with instructions of how to obtain a copy via ftp. - */ - -#ifndef _RDOFF_H -#define _RDOFF_H "RDOFF2 support routines v0.3" - -/* Some systems don't define this automatically */ -extern char *strdup(const char *); - -typedef unsigned short int16; -typedef unsigned char byte; - -#define RDF_MAXSEGS 64 - -/* the records that can be found in the RDOFF header */ - -struct RelocRec { - byte type; /* must be 1 */ - byte reclen; /* content length */ - byte segment; /* only 0 for code, or 1 for data supported, - but add 64 for relative refs (ie do not require - reloc @ loadtime, only linkage) */ - long offset; /* from start of segment in which reference is loc'd */ - byte length; /* 1 2 or 4 bytes */ - int16 refseg; /* segment to which reference refers to */ -}; - -struct ImportRec { - byte type; /* must be 2 */ - byte reclen; /* content length */ - int16 segment; /* segment number allocated to the label for reloc - records - label is assumed to be at offset zero - in this segment, so linker must fix up with offset - of segment and of offset within segment */ - char label[33]; /* zero terminated... should be written to file until - the zero, but not after it - max len = 32 chars */ -}; - -struct ExportRec { - byte type; /* must be 3 */ - byte reclen; /* content length */ - byte segment; /* segment referred to (0/1/2) */ - long offset; /* offset within segment */ - char label[33]; /* zero terminated as above. max len = 32 chars */ -}; - -struct DLLRec { - byte type; /* must be 4 */ - byte reclen; /* content length */ - char libname[128]; /* name of library to link with at load time */ -}; - -struct BSSRec { - byte type; /* must be 5 */ - byte reclen; /* content length */ - long amount; /* number of bytes BSS to reserve */ -}; - -struct ModRec { - byte type; /* must be 8 */ - byte reclen; /* content length */ - char modname[128]; /* module name */ -}; - -#ifdef _MULTBOOT_H - -#define RDFLDRMOVER_SIZE 22 - -struct MultiBootHdrRec { - byte type; /* must be 9 */ - byte reclen; /* content length */ -#ifdef __GNUC__ - struct tMultiBootHeader mb __attribute__ ((packed)); /* MultiBoot header */ -#else - struct tMultiBootHeader mb; -#endif - byte mover[RDFLDRMOVER_SIZE]; /* Mover of RDF loader */ -}; -#endif - -/* GenericRec - contains the type and length field, plus a 128 byte - char array 'data', which will probably never be used! */ - -struct GenericRec { - byte type; - byte reclen; - char data[128]; -}; - -typedef union RDFHeaderRec { - char type; /* invariant throughout all below */ - struct GenericRec g; - struct RelocRec r; /* type == 1 / 6 */ - struct ImportRec i; /* type == 2 / 7 */ - struct ExportRec e; /* type == 3 */ - struct DLLRec d; /* type == 4 */ - struct BSSRec b; /* type == 5 */ - struct ModRec m; /* type == 8 */ -#ifdef _MULTBOOT_H - struct MultiBootHdrRec mbh; /* type == 9 */ -#endif -} rdfheaderrec; - -struct SegmentHeaderRec { - /* information from file */ - int16 type; - int16 number; - int16 reserved; - long length; - - /* information built up here */ - long offset; - byte *data; /* pointer to segment data if it exists in memory */ -}; - -typedef struct RDFFileInfo { - FILE *fp; /* file descriptor; must be open to use this struct */ - int rdoff_ver; /* should be 1; any higher => not guaranteed to work */ - long header_len; - long header_ofs; - - byte *header_loc; /* keep location of header */ - long header_fp; /* current location within header for reading */ - - struct SegmentHeaderRec seg[RDF_MAXSEGS]; - int nsegs; - - long eof_offset; /* offset of the first byte beyond the end of this - module */ - - char *name; /* name of module in libraries */ - int *refcount; /* pointer to reference count on file, or NULL */ -} rdffile; - -#define BUF_BLOCK_LEN 4088 /* selected to match page size (4096) - * on 80x86 machines for efficiency */ -typedef struct memorybuffer { - int length; - byte buffer[BUF_BLOCK_LEN]; - struct memorybuffer *next; -} memorybuffer; - -typedef struct { - memorybuffer * buf; /* buffer containing header records */ - int nsegments; /* number of segments to be written */ - long seglength; /* total length of all the segments */ -} rdf_headerbuf; - -/* segments used by RDOFF, understood by rdoffloadseg */ -#define RDOFF_CODE 0 -#define RDOFF_DATA 1 -#define RDOFF_HEADER -1 -/* mask for 'segment' in relocation records to find if relative relocation */ -#define RDOFF_RELATIVEMASK 64 -/* mask to find actual segment value in relocation records */ -#define RDOFF_SEGMENTMASK 63 - -extern int rdf_errno; - -/* utility functions */ -int16 translateshort(int16 in); -long translatelong(long in); - -/* RDOFF file manipulation functions */ -int rdfopen(rdffile *f,const char *name); -int rdfopenhere(rdffile *f, FILE *fp, int *refcount, const char *name); -int rdfclose(rdffile *f); -int rdffindsegment(rdffile * f, int segno); -int rdfloadseg(rdffile *f,int segment,void *buffer); -rdfheaderrec *rdfgetheaderrec(rdffile *f); /* returns static storage */ -void rdfheaderrewind(rdffile *f); /* back to start of header */ -void rdfperror(const char *app,const char *name); - -/* functions to write a new RDOFF header to a file - - use rdfnewheader to allocate a header, rdfaddheader to add records to it, - rdfaddsegment to notify the header routines that a segment exists, and - to tell it how long the segment will be. - rdfwriteheader to write the file id, object length, and header - to a file, and then rdfdoneheader to dispose of the header */ - -rdf_headerbuf *rdfnewheader(void); -int rdfaddheader(rdf_headerbuf *h,rdfheaderrec *r); -int rdfaddsegment(rdf_headerbuf *h, long seglength); -int rdfwriteheader(FILE *fp,rdf_headerbuf *h); -void rdfdoneheader(rdf_headerbuf *h); - -/* This is needed by linker to write multiboot header record */ -int membuflength(memorybuffer *b); - -#endif /* _RDOFF_H */ +*************** +*** 9,15 **** + * as acknowledgement is given in an appropriate manner to its authors, + * with instructions of how to obtain a copy via ftp. + */ +- + #ifndef _RDOFF_H + #define _RDOFF_H "RDOFF2 support routines v0.3" + +--- 9,15 ---- + * as acknowledgement is given in an appropriate manner to its authors, + * with instructions of how to obtain a copy via ftp. + */ ++ + #ifndef _RDOFF_H + #define _RDOFF_H "RDOFF2 support routines v0.3" + +*************** +*** 48,54 **** + struct ExportRec { + byte type; /* must be 3 */ + byte reclen; /* content length */ +- byte segment; /* segment referred to (0/1) */ + long offset; /* offset within segment */ + char label[33]; /* zero terminated as above. max len = 32 chars */ + }; +--- 48,54 ---- + struct ExportRec { + byte type; /* must be 3 */ + byte reclen; /* content length */ ++ byte segment; /* segment referred to (0/1/2) */ + long offset; /* offset within segment */ + char label[33]; /* zero terminated as above. max len = 32 chars */ + }; +*************** +*** 65,70 **** + long amount; /* number of bytes BSS to reserve */ + }; + + /* GenericRec - contains the type and length field, plus a 128 byte + char array 'data', which will probably never be used! */ + +--- 65,92 ---- + long amount; /* number of bytes BSS to reserve */ + }; + ++ struct ModRec { ++ byte type; /* must be 8 */ ++ byte reclen; /* content length */ ++ char modname[128]; /* module name */ ++ }; ++ ++ #ifdef _MULTBOOT_H ++ ++ #define RDFLDRMOVER_SIZE 22 ++ ++ struct MultiBootHdrRec { ++ byte type; /* must be 9 */ ++ byte reclen; /* content length */ ++ #ifdef __GNUC__ ++ struct tMultiBootHeader mb __attribute__ ((packed)); /* MultiBoot header */ ++ #else ++ struct tMultiBootHeader mb; ++ #endif ++ byte mover[RDFLDRMOVER_SIZE]; /* Mover of RDF loader */ ++ }; ++ #endif ++ + /* GenericRec - contains the type and length field, plus a 128 byte + char array 'data', which will probably never be used! */ + +*************** +*** 82,87 **** + struct ExportRec e; /* type == 3 */ + struct DLLRec d; /* type == 4 */ + struct BSSRec b; /* type == 5 */ + } rdfheaderrec; + + struct SegmentHeaderRec { +--- 104,113 ---- + struct ExportRec e; /* type == 3 */ + struct DLLRec d; /* type == 4 */ + struct BSSRec b; /* type == 5 */ ++ struct ModRec m; /* type == 8 */ ++ #ifdef _MULTBOOT_H ++ struct MultiBootHdrRec mbh; /* type == 9 */ ++ #endif + } rdfheaderrec; + + struct SegmentHeaderRec { +*************** +*** 166,170 **** + int rdfaddsegment(rdf_headerbuf *h, long seglength); + int rdfwriteheader(FILE *fp,rdf_headerbuf *h); + void rdfdoneheader(rdf_headerbuf *h); + + #endif /* _RDOFF_H */ +--- 192,199 ---- + int rdfaddsegment(rdf_headerbuf *h, long seglength); + int rdfwriteheader(FILE *fp,rdf_headerbuf *h); + void rdfdoneheader(rdf_headerbuf *h); ++ ++ /* This is needed by linker to write multiboot header record */ ++ int membuflength(memorybuffer *b); + + #endif /* _RDOFF_H */ diff --git a/test/bintest.asm b/test/bintest.asm index 94d2bf7..96a1dce 100644 --- a/test/bintest.asm +++ b/test/bintest.asm @@ -1,56 +1,34 @@ -; test source file for assembling to binary files -; build with: -; nasm -f bin -o bintest.com bintest.asm - -; When run (as a DOS .COM file), this program should print -; hello, world -; on two successive lines, then exit cleanly. - -; This file should test the following: -; [1] Define a text-section symbol -; [2] Define a data-section symbol -; [3] Define a BSS-section symbol -; [4] Define a NASM local label -; [5] Reference a NASM local label -; [6] Reference a text-section symbol in the text section -; [7] Reference a data-section symbol in the text section -; [8] Reference a BSS-section symbol in the text section -; [9] Reference a text-section symbol in the data section -; [10] Reference a data-section symbol in the data section -; [11] Reference a BSS-section symbol in the data section - - BITS 16 - ORG 0x100 - - SECTION .text - - jmp start ; [6] - -endX mov ax,0x4c00 ; [1] - int 0x21 - -start mov byte [bss_sym],',' ; [1] [8] - mov bx,[bssptr] ; [7] - mov al,[bx] - mov bx,[dataptr] ; [7] - mov [bx],al - mov cx,2 -.loop mov dx,datasym ; [1] [4] [7] - mov ah,9 - push cx - int 0x21 - pop cx - loop .loop ; [5] [6] - mov bx,[textptr] ; [7] - jmp bx - - SECTION .data - -datasym db 'hello world', 13, 10, '$' ; [2] -bssptr dw bss_sym ; [2] [11] -dataptr dw datasym+5 ; [2] [10] -textptr dw endX ; [2] [9] - - SECTION .bss - -bss_sym resb 1 ; [3] +*************** +*** 26,32 **** + + jmp start ; [6] + +- end mov ax,0x4c00 ; [1] + int 0x21 + + start mov byte [bss_sym],',' ; [1] [8] +--- 26,32 ---- + + jmp start ; [6] + ++ endX mov ax,0x4c00 ; [1] + int 0x21 + + start mov byte [bss_sym],',' ; [1] [8] +*************** +*** 49,55 **** + datasym db 'hello world', 13, 10, '$' ; [2] + bssptr dw bss_sym ; [2] [11] + dataptr dw datasym+5 ; [2] [10] +- textptr dw end ; [2] [9] + + SECTION .bss + +--- 49,55 ---- + datasym db 'hello world', 13, 10, '$' ; [2] + bssptr dw bss_sym ; [2] [11] + dataptr dw datasym+5 ; [2] [10] ++ textptr dw endX ; [2] [9] + + SECTION .bss + -- 2.7.4