Very limited MASM emulation.
The parser has been extended to emulate the PTR keyword if the
corresponding macro is enabled, and the syntax displacement[index] for
memory operations is now recognized.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
The memory operand size of LEA doesn't matter in any way as it isn't
"real memory". Add an ANYSIZE option to ignore sizes entirely.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Encapsulate the list_options() encoding in an inline function. We only
ever compute a mask with a non-constant input in two places (command
line and pragma parsing), so a slightly more complex mapping is of no
consequence; thus map a-z, A-Z and 0-9 as being the most likely
characters we may want to use as options. Space is left for two more :)
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Add a %pragma to set (or clear) listing options. It only takes effect
on the next assembly pass, however!
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
tline got advanced a token too far, with the obvious results that the
facility name got truncated. Skip whitespace *after* expand_smacro(),
not before.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
expand_smacro() consumes its input, so we need to truncate the input
list so we can call free_tline(origline) safely.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Add listing options:
-Lb to show builtin macro packages
-Lf to override .nolist
Do some cleanups in the process, in particular generalize read_line()
between stdmac and file alternatives.
When processing stdmac, create an istk entry for it. This means stdmac
can be identified by istk->fp == NULL. At some future date there could
even be a function pointer to an appropriate read function.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
With the -Lp option, the listing generator gets invoked multiple times
in the same session. If we already have a list file open, call
list_cleanup() before reinitializing; otherwise we get stray output in
the updated file.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Merge TIMES in the nonfinal passes, there is no point in getting <len
...> an arbitrary number of times.
Actually print <len> (OUT_RAWDATA without a data pointer), not <res>
(OUT_RESERVE).
Dropping the zero-fill for the hex format made the listing more
manageable, but it also doesn't immediately look like hex, plus there
is now the -Ld option. Put an h after hex (shorter than leading 0x) to
make it obvious.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Additional listing options:
-Ld to display counts in decimal
-Lp to output a list file in every pass (to make sure one exists)
Clean up the help output and make it comprehensive. The -hf and -y
options are no longer necessary, although they are supported for
backwards compatiblity.
Fix macro-levels so it actually count descent levels; a new
macro-tokens limit introduced for the actual token limit.
Slightly simplify the limits code.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
When printing lines coming from %rep blocks and macros, show the line
number corresponding to the line actually being printed.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
It turns out that in tokenize() we would sometimes truncate a token
string by inserting a NUL into the input string, expecting new_Token()
to pick it up using strlen(). With explicit lengths, that no longer
works, but there is a better solution anyway: instead of inserting
NUL characters, keep track of where the token actually ends and feed
the correct length to new_Token().
This triggered a buffer overflow in detoken(), add a debug level 2
assert for this condition. Use a relatively high debug level, because
strlen() is fairly expensive, and this is an extremely
performance-critical path.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
"instruction never implemented and removed from the target CPU"
... doesn't really make sense, so change it to ...
"instruction never implemented and invalid on the target CPU"
(still may seen redundant, but it is to distingush it from "and is a
noop on...")
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Distinguish instructions which have once been valid (OBSOLETE) from
those that never saw the light of day (NEVER). Futhermore, flag
instructions which devolve to an architectural noop from those with
undefined behavior and possibly recycled opcodes.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Just becase one is compiling for an old CPU doesn't mean one wants to
use obsolete instructions that would not be forward compatible. Rename
the "obsolete" warning to "obsolete-removed" and create a new
"obsolete-valid" warning to go with it (-w[+-]obsolete controls both
options, as usual.)
Suggested-by: C. Masloch <pushbx@38.de>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
The idiom scalar(%hash) seems similar to scalar(@array), and in fact
is in current versions of Perl. However, in older versions of Perl,
the former is totally useless:
Prior to Perl 5.25 the value returned was a string consisting
of the number of used buckets and the number of allocated
buckets, separated by a slash. This is pretty much useful only
to find out whether Perl's internal hashing algorithm is
performing poorly on your data set. For example, you stick
10,000 things in a hash, but evaluating %HASH in scalar context
reveals "1/16", which means only one out of sixteen buckets has
been touched, and presumably contains all 10,000 of your items.
This isn't supposed to happen.
As of Perl 5.25 the return was changed to be the count of keys
in the hash. If you need access to the old behavior you can use
"Hash::Util::bucket_ratio()" instead.
Use scalar(keys %hash) instead.
Reported-by: Orkan Sezer <sezeroz@gmail.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Clean up some perl warnings, some of which were legitimate (apparently
undef doesn't actually take a list of arguments, a common enough
mistake that it is mentioned in the man page!, and a list of variables
after "my" can be cantankerous), and some of which were nuisance but
were easy enough to clean up.
Maybe this can resolve the problems with very old version of Perl?
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Add an -L option for additional listing information. Currently
supported is -Le, which emits each line after processing through the
preprocessor, and -Lm, which displays each single-line macro defined
or undefined.
NASM doesn't preserve the names of unused arguments, nor does it have
any technical reason to do so. Instead of adding complexity to save
them, make unnamed parameters official by specifying an empty string
in the argument list.
This has the additional advantage that () is now simply considered a
single empty argument, which means that NASM should now properly
handle things like:
%define myreg() eax
mov edx,myreg()
... similar to how the C preprocessor allows an empty macro argument
list which is distinct from a macro with no arguments whatsoever.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Make debug messages more dynamic by making it easy to conditionalize
the messages.
Change ERR_NOTE to ERR_INFO which reflects the usage better. Other
compilers use note: for additional information.
Don't unwind the macro stack with ERR_HERE; it is only going to give
confusing results as it will unwind the wrong macro stack.
Add ERR_LISTMSG level which is *always* suppressed, but will still
appear in the list file.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
ERR_NOTE just confuses things, especially in the case of a suppressed
warning.
The preprocessor doesn't use it for unwinding macros, either.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This allows the K instructions to be specified without a size suffix
as long as the operands are sized; this matches the way most other x86
instructions work. As this is not the syntax specified in the SDM,
don't use it for disassembly.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
The single-line macro argument parsing was completely broken as a
comma would not be recognized as an argument separator.
In the process of fixing this, make a fair bit of code cleanups.
Note: reverse tokens for smacro->expansion doesn't actually make any
sense anymore, might reconsider that.
This checkin also removes the distinction between "magic" and plain
smacros; the only difference is which specific expand method is being
invoked.
Finally, extend the allocating-string functions such that *all* the
allocating string functions support querying the length of the string
a posteori.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
We have to call expand_one_smacro() recursively, otherwise we will not
expand smacros which point to other smacros. We cannot simply do this
by looping after token pasting, because we need to make sure we don't
recursively expand the same smacro.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
For constructs like TIMES xx RESB yy merge the TIMES and RESB and feed
a single reservation to the backend; this can (obviously) be
dramatically faster.
Add byte count in listings for <incbin> and repeat count to <rept>; to
make them more reasonable in length shorten to <bin ...> and <rep ...>
respectively, and don't require leading zeroes in bin/rep/res count.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Print a warning if one tries to assemble an obsolete instruction,
unless there is an exact match for the CPU directive.
For example:
CPU 386
POP CS ; Warning - obsolete instruction
CPU 8086
POP CS ; No warning
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Fix the definition of IF_CPU_LEVEL_MASK (which was missing the top
bit, IFM_ANY itself).
Add CPU definitions that we actually have into directiv.c.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Have warnings.pl give a warning(!) message if a warning definition is
found to be duplicated, including the location of both
definitions. Much better than silently creating bogus output.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
If an UTF-8 value exceeds 0x7fffffff, there is no legitimate encoding
for it. However, using FE or FF as leading bytes provide at least some
kind of encoding. This is assembly, and the programmer is (almost?)
always right. It might be worthwhile to add a suppressible warning for
invalid UTF-8 strings in general, though, including any character >
0x10ffff, surrogates, or a string that is constructed by hand.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Returning NULL makes more sense than returning the initial pointer
(the only other sensible alternative would be to return a pointer the
final null character.)
This currently can't happen, as all callers to nasm_skip_string()
currently explicitly tests for an initial quote.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
The merging of adjacent ' or " strings really does nothing but
introduce gratuitous incompatiblities; drop it.
Allow *some* control characters (BEL BS TAB ESC) in
nasm_unquote_cstr().
The ` state machine can be greatly simplified by treating \0 as just
another character and let it terminate the string in appropriate
contexts, just like `. The only difference with ` is when it occurs
in state st_backslash: you can't escape the null character.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
TOKEN_ID is from enum pp_token_type, but struct Type has enum
token_type. TOK_ID seems to be a matched one.s
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Split the code for getting a line of tokens from the code that sets
verror and detokenizes the resulting string.
While we are at it, merge the handling of EOF and ^Z into the general
loop in read_line().
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
The smacro expansion code was virtually impossible to understand, and
was leading to very strange failures. Clean it up, and do much better
handling of magic macros. This should also allow for recursive
macros, but recursive macros are extremely tricky in that it is very
hard to keep them from recursing forever, unless there is at least one
argument which is never expanded. They are not currently implemented.
Even so, I believe token pasting makes it possible to create infinite
loops; e.g.:
%define foo foo %+
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
In nasm_unquote_cstr(), disallow any control character, not just
NUL. This will matter when allowing quoting symbols.
Merge nasm_unquote() and nasm_unquote_cstr().
Strings can now be concatenated, C style: adjacent quoted strings
(including whitespace-separated) are merged into a single string.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
All directives which create single-line macros now have %i... variants
to define case-insensitive versions. Case insensitive rather sucks,
but at least this way it is consistent.
Single-line macro parameters can now be evaluated as a number, as done
by %assign. To do so, declare a parameter starting with =, for
example:
%define foo(x,=y) mov [x],macro_array_y
... would evaluate y as a number but leave x as a string.
NOTE: it would arguably be better to have this as a per-instance
basis, but it is easily handled by having a secondary macro called
with the same argument twice.
Finally, add a more consistent method for defining "magic" macros,
which need to be evaluated at runtime. For now, it is only used by the
special macros __FILE__, __LINE__, __BITS__, __PTR__, and __PASS__.
__PTR__ is a new macro which evaluates to word, dword or qword
matching the value of __BITS__.
The magic macro framework, however, provides a natural hook for a
future plug-in infrastructure to hook into a scripting language.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>