NASM 0.98.25

This commit is contained in:
H. Peter Anvin 2002-04-30 21:07:51 +00:00
parent 852c3eecb4
commit 9f39464e5b
5 changed files with 157 additions and 207 deletions

View File

@ -1,187 +1,100 @@
This is a specially patched version of NASM. It can be used to supplement
building of Crystal Space, the Open Source 3D Engine project. You can find
Crystal Space at the following locations:
PROLOGUE
http://crystal.linuxgames.com/
http://crystal.sourceforge.net/
One day someone wrote that nasm needs:
Details of changes in this version of NASM follow.
> - A good ALIGN mechanism, similar to GAS's. GAS pads out space by
> means of the following (32-bit) instructions:
> 8DB42600000000 lea esi,[esi+0x0]
> 8DB600000000 lea esi,[esi+0x0]
> 8D742600 lea esi,[esi+0x0]
> 8D7600 lea esi,[esi+0x0]
> 8D36 lea esi,[esi]
> 90 nop
> It uses up to two of these instructions to do up to 14-byte pads;
> when more than 14 bytes are needed, it issues a (short) jump to
> the end of the padded section and then NOPs the rest. Come up with
> a similar scheme for 16 bit mode, and also come up with a way to
> use it - internal to the assembler, so that programs using ALIGN
> don't knock over preprocess-only mode.
> Also re-work the macro form so that when given one argument in a
> code section it calls this feature.
-*- A new keyword %xdefine and its case-insensitive counterpart %ixdefine.
They work almost the same way as %define and %idefine but expand
the definition immediately, not on the invocation. Something like a cross
between %define and %assign. The "x" suffix stands for "eXpand", so
"xdefine" can be deciphered as "expand-and-define". Thus you can do
things like this:
Well palign is your friend.
%assign ofs 0
This is a modified version of nasm-0.98.24 that can accept
two new directives.The two new directives that control
the align mechanism are 'palign' and 'p2align'.They are nasm directives
that don't depend on preprocessor but rather align the code while assembling
in a gas-like style.
The syntax of these directives is
[palign n] where '0 <= n <= 6' and
[p2align n] where '0 <= n <=6'
The use of these directives is
[palign n]
Pad the location counter to a particular storage boundary.
The n is a number between 0 and 6 of low-order zero bits the location counter
must have after advancement.
For example `palign 3' advances the location counter until
it a multiple of 8.If the location counter is already a multiple of 8,
no change is needed.
If n=0 then nothing is done
if n => 6 then palign advances the location counter until it a multiple
of 64.For now the maximum is 64 bytes,if you want more use the ALIGN macro.
[p2align n]
This directive do almost the same thing with a little exception.
It will continue aligning until a directive [p2align 0] meet or until
the current section changes.So this piece of code
BITS 32
SECTION .text
[p2align 5]
%macro arg 1
%xdefine %1 dword [esp+ofs]
%assign ofs ofs+4
%endmacro
-*- Changed the place where the expansion of %$name macros are expanded.
Now they are converted into ..@ctxnum.name form when detokenizing, so
there are no quirks as before when using %$name arguments to macros,
in macros etc. For example:
%macro abc 1
%define %1 hello
%endm
abc %$here
%$here
Now last line will be expanded to "hello" as expected. This also allows
for lots of goodies, a good example are extended "proc" macros included
in this archive.
-*- Added a check for "cstk" in smacro_defined() before calling get_ctx() -
this allows for things like:
%ifdef %$abc
%endif
to work without warnings even in no context.
-*- Added a check for "cstk" in %if*ctx and %elif*ctx directives -
this allows to use %ifctx without excessive warnings. If there is
no active context, %ifctx goes through "false" branch.
-*- Removed "user error: " prefix with %error directive: it just clobbers the
output and has absolutely no functionality. Besides, this allows to write
macros that does not differ from build-in functions in any way.
-*- Added expansion of string that is output by %error directive. Now you
can do things like:
%define hello(x) Hello, x!
%define %$name andy
%error "hello(%$name)"
Same happened with %include directive.
-*- Now all directives that expect an identifier will try to expand and
concatenate everything without whitespaces in between before usage.
For example, with "unfixed" nasm the commands
%define %$abc hello
%define __%$abc goodbye
__%$abc
would produce "incorrect" output: last line will expand to
hello goodbyehello
Not quite what you expected, eh? :-) The answer is that preprocessor
treats the %define construct as if it would be
%define __ %$abc goodbye
(note the white space between __ and %$abc). After my "fix" it
will "correctly" expand into
goodbye
as expected. Note that I use quotes around words "correct", "incorrect"
etc because this is rather a feature not a bug; however current behaviour
is more logical (and allows more advanced macro usage :-).
Same change was applied to:
%push,%macro,%imacro,%define,%idefine,%xdefine,%ixdefine,
%assign,%iassign,%undef
-*- A new directive [WARNING {+|-}warning-id] have been added. It works only
if the assembly phase is enabled (i.e. it doesn't work with nasm -e).
-*- A new warning type: macro-selfref. By default this warning is disabled;
when enabled NASM warns when a macro self-references itself; for example
the following source:
[WARNING macro-selfref]
%macro push 1-*
%rep %0
push %1
%rotate 1
%endrep
%endmacro
push eax,ebx,ecx
will produce a warning, but if we remove the first line we won't see it
anymore (which is The Right Thing To Do {tm} IMHO since C preprocessor
eats such constructs without warnings at all).
-*- Added a "error" routine to preprocessor which always will set ERR_PASS1
bit in severity_code. This removes annoying repeated errors on first
and second passes from preprocessor.
-*- Added the %+ operator in single-line macros for concatenating two
identifiers. Usage example:
%define _myfunc _otherfunc
%define cextern(x) _ %+ x
cextern (myfunc)
After first expansion, third line will become "_myfunc". After this
expansion is performed again so it becomes "_otherunc".
-*- Now if preprocessor is in a non-emmitting state, no warning or error
will be emmitted. Example:
%if 1
mov eax,ebx
%else
put anything you want between these two brackets,
even macro-parameter references %1 or local labels %$zz
or macro-local labels %%zz - no warning will be emmitted.
%endif
-*- Context-local variables on expansion as a last resort are looked up
in outer contexts. For example, the following piece:
%push outer
%define %$a [esp]
%push inner
%$a
%pop
%pop
will expand correctly the fourth line to [esp]; if we'll define another
%$a inside the "inner" context, it will take precedence over outer
definition. However, this modification has been applied only to
expand_smacro and not to smacro_define: as a consequence expansion
looks in outer contexts, but %ifdef won't look in outer contexts.
This behaviour is needed because we don't want nested contexts to
act on already defined local macros. Example:
%define %$arg1 [esp+4]
test eax,eax
if nz
mov eax,%$arg1
endif
In this example the "if" mmacro enters into the "if" context, so %$arg1
is not valid anymore inside "if". Of course it could be worked around
by using explicitely %$$arg1 but this is ugly IMHO.
-------------------------------// fixes for 0.98 //-----------------------------
-*- Fixed memory leak in %undef. The origline wasn't freed before
exiting on success.
-----------------------------// Fixes for 0.98.01 //----------------------------
-*- Fixed trap in preprocessor when line expanded to empty set of tokens.
This happens, for example, in the following case:
#define SOMETHING
SOMETHING
;some code here
Andrew Zabolotny <bit@eltech.ru>
SECTION .data
;some data here
guarantee that all the instructions in the code segment will be aligned
in a 32 byte boundary so than no instruction break the cache line on a
pentium processor.
BUGS
Well my english are very very bad.
This optimization will not work
for now for 16-bit code.
Also there may be a problem with the prefixes like ds,es,rep,lock etc
so this code will work
'rep movsd'
but this may not work
'rep'
'movsd'
if you want to be sure put the prefix in the same line
with the instruction.
Also don't try this in a data or a bss segment.Use the ALIGN macro better
FEEDBACK
If you have any suggestion, comment or found a bug please email me
and i will try to reply immediately.
From your feedback it depends this project to get better as i intend
to implement more things and improve the code in the next version of nasm.
AUTHOR
Panos Minos 03-04-2002
email: <panosminos@mycosmos.gr> , <panosminos1@mycosmos.gr>

View File

@ -941,6 +941,10 @@ of any combination of a label, an instruction and a comment is allowed.
Of course, the operand field is either required or forbidden by the
presence and nature of the instruction field.
NASM uses backslash (\\) as the line continuation character; if a line
ends with backslash, the next line is considered to be a part of the
backslash-ended line.
NASM places no restrictions on white space within a line: labels may
have white space before them, or instructions may have no space
before them, or anything. The \i{colon} after a label is also
@ -1579,6 +1583,13 @@ conditional assembly, multi-level file inclusion, two forms of macro
extra macro power. Preprocessor directives all begin with a \c{%}
sign.
The preprocessor collapses all lines which end with a backslash (\\)
character into a single line. Thus:
\c %define THIS_VERY_LONG_MACRO_NAME_IS_DEFINED_TO \\
\c THIS_VALUE
will work as expected.
\H{slmacro} \i{Single-Line Macros}
@ -7192,7 +7203,7 @@ This is a larger and more unwieldy version of \c{CMPXCHG}: it
compares the 64-bit (eight-byte) value stored at \c{[mem]} with the
value in \c{EDX:EAX}. If they are equal, it sets the zero flag and
stores \c{ECX:EBX} into the memory area. If they are unequal, it
clears the zero flag and leaves the memory area untouched.
clears the zero flag and stores the memory contents into \c{EDX:EAX}.
\c{CMPXCHG8B} can be used with the \c{LOCK} prefix, to allow atomic
execution. This is useful in multi-processor and multi-tasking

View File

@ -36,6 +36,7 @@ ADC reg32,reg32 \321\301\1\x13\110 386
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,sbyte \320\1\x83\202\15 8086,SM,ND
ADC reg_ax,imm \320\1\x15\31 8086,SM
ADC reg_eax,sbyte \321\1\x83\202\15 386,SM,ND
ADC reg_eax,imm \321\1\x15\41 386,SM
@ -60,6 +61,7 @@ ADD reg32,reg32 \321\301\1\x03\110 386
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,sbyte \320\1\x83\200\15 8086,SM,ND
ADD reg_ax,imm \320\1\x05\31 8086,SM
ADD reg_eax,sbyte \321\1\x83\200\15 386,SM,ND
ADD reg_eax,imm \321\1\x05\41 386,SM
@ -84,6 +86,7 @@ AND reg32,reg32 \321\301\1\x23\110 386
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,sbyte \320\1\x83\204\15 8086,SM,ND
AND reg_ax,imm \320\1\x25\31 8086,SM
AND reg_eax,sbyte \321\1\x83\204\15 386,SM,ND
AND reg_eax,imm \321\1\x25\41 386,SM
@ -136,9 +139,9 @@ CALL imm|far \322\1\x9A\34\37 8086,ND
CALL imm16 \320\1\xE8\64 8086
CALL imm16|near \320\1\xE8\64 8086
CALL imm16|far \320\1\x9A\34\37 8086,ND
CALL imm32 \321\1\xE8\64 8086
CALL imm32|near \321\1\xE8\64 8086
CALL imm32|far \321\1\x9A\34\37 8086,ND
CALL imm32 \321\1\xE8\64 386
CALL imm32|near \321\1\xE8\64 386
CALL imm32|far \321\1\x9A\34\37 386,ND
CALL imm:imm \322\1\x9A\35\30 8086
CALL imm16:imm \320\1\x9A\31\30 8086
CALL imm:imm16 \320\1\x9A\31\30 8086
@ -177,6 +180,7 @@ CMP reg32,reg32 \321\301\1\x3B\110 386
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,sbyte \320\1\x83\207\15 8086,SM,ND
CMP reg_ax,imm \320\1\x3D\31 8086,SM
CMP reg_eax,sbyte \321\1\x83\207\15 386,SM,ND
CMP reg_eax,imm \321\1\x3D\41 386,SM
@ -291,7 +295,7 @@ FDIVRP fpureg,fpu0 \1\xDE\10\xF0 8086,FPU
FEMMS void \2\x0F\x0E PENT,3DNOW
FENI void \3\x9B\xDB\xE0 8086,FPU
FFREE fpureg \1\xDD\10\xC0 8086,FPU
FFREEP fpureg \1\xDF\10\xC0 P6,FPU,UNDOC
FFREEP fpureg \1\xDF\10\xC0 286,FPU,UNDOC
FIADD mem32 \300\1\xDA\200 8086,FPU
FIADD mem16 \300\1\xDE\200 8086,FPU
FICOM mem32 \300\1\xDA\202 8086,FPU
@ -482,9 +486,9 @@ JMP imm|far \322\1\xEA\34\37 8086,ND
JMP imm16 \320\1\xE9\64 8086
JMP imm16|near \320\1\xE9\64 8086,ND
JMP imm16|far \320\1\xEA\34\37 8086,ND
JMP imm32 \321\1\xE9\64 8086
JMP imm32|near \321\1\xE9\64 8086,ND
JMP imm32|far \321\1\xEA\34\37 8086,ND
JMP imm32 \321\1\xE9\64 386
JMP imm32|near \321\1\xE9\64 386,ND
JMP imm32|far \321\1\xEA\34\37 386,ND
JMP imm:imm \322\1\xEA\35\30 8086
JMP imm16:imm \320\1\xEA\31\30 8086
JMP imm:imm16 \320\1\xEA\31\30 8086
@ -504,15 +508,15 @@ JMP mem32 \321\300\1\xFF\204 386
LAHF void \1\x9F 8086
LAR reg16,mem \320\301\2\x0F\x02\110 286,PROT,SM
LAR reg16,reg16 \320\301\2\x0F\x02\110 286,PROT
LAR reg32,mem \321\301\2\x0F\x02\110 286,PROT,SM
LAR reg32,reg32 \321\301\2\x0F\x02\110 286,PROT
LAR reg32,mem \321\301\2\x0F\x02\110 386,PROT,SM
LAR reg32,reg32 \321\301\2\x0F\x02\110 386,PROT
LDS reg16,mem \320\301\1\xC5\110 8086
LDS reg32,mem \321\301\1\xC5\110 8086
LDS reg32,mem \321\301\1\xC5\110 386
LEA reg16,mem \320\301\1\x8D\110 8086
LEA reg32,mem \321\301\1\x8D\110 8086
LEA reg32,mem \321\301\1\x8D\110 386
LEAVE void \1\xC9 186
LES reg16,mem \320\301\1\xC4\110 8086
LES reg32,mem \321\301\1\xC4\110 8086
LES reg32,mem \321\301\1\xC4\110 386
LFS reg16,mem \320\301\2\x0F\xB4\110 386
LFS reg32,mem \321\301\2\x0F\xB4\110 386
LGDT mem \300\2\x0F\x01\202 286,PRIV
@ -547,8 +551,8 @@ LOOPZ imm,reg_cx \310\1\xE1\50 8086
LOOPZ imm,reg_ecx \311\1\xE1\50 386
LSL reg16,mem \320\301\2\x0F\x03\110 286,PROT,SM
LSL reg16,reg16 \320\301\2\x0F\x03\110 286,PROT
LSL reg32,mem \321\301\2\x0F\x03\110 286,PROT,SM
LSL reg32,reg32 \321\301\2\x0F\x03\110 286,PROT
LSL reg32,mem \321\301\2\x0F\x03\110 386,PROT,SM
LSL reg32,reg32 \321\301\2\x0F\x03\110 386,PROT
LSS reg16,mem \320\301\2\x0F\xB2\110 386
LSS reg32,mem \321\301\2\x0F\xB2\110 386
LTR mem \300\1\x0F\17\203 286,PROT,PRIV
@ -560,14 +564,14 @@ MOV mem,reg_fsgs \300\1\x8C\101 386,SM
MOV reg16,reg_cs \320\300\1\x8C\201 8086
MOV reg16,reg_dess \320\300\1\x8C\101 8086
MOV reg16,reg_fsgs \320\300\1\x8C\101 386
MOV reg32,reg_cs \321\300\1\x8C\201 8086
MOV reg32,reg_dess \321\300\1\x8C\101 8086
MOV reg32,reg_cs \321\300\1\x8C\201 386
MOV reg32,reg_dess \321\300\1\x8C\101 386
MOV reg32,reg_fsgs \321\300\1\x8C\101 386
MOV reg_dess,mem \301\1\x8E\110 8086,SM
MOV reg_fsgs,mem \301\1\x8E\110 386,SM
MOV reg_dess,reg16 \301\1\x8E\110 8086
MOV reg_fsgs,reg16 \301\1\x8E\110 386
MOV reg_dess,reg32 \301\1\x8E\110 8086
MOV reg_dess,reg32 \301\1\x8E\110 386
MOV reg_fsgs,reg32 \301\1\x8E\110 386
MOV reg_al,mem_offs \301\1\xA0\35 8086,SM
MOV reg_ax,mem_offs \301\320\1\xA1\35 8086,SM
@ -648,6 +652,7 @@ OR reg32,reg32 \321\301\1\x0B\110 386
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,sbyte \320\1\x83\201\15 8086,SM,ND
OR reg_ax,imm \320\1\x0D\31 8086,SM
OR reg_eax,sbyte \321\1\x83\201\15 386,SM,ND
OR reg_eax,imm \321\1\x0D\41 386,SM
@ -825,11 +830,11 @@ PUNPCKHDQ mmxreg,mem \301\2\x0F\x6A\110 PENT,MMX,SM
PUNPCKHDQ mmxreg,mmxreg \2\x0F\x6A\110 PENT,MMX
PUNPCKHWD mmxreg,mem \301\2\x0F\x69\110 PENT,MMX,SM
PUNPCKHWD mmxreg,mmxreg \2\x0F\x69\110 PENT,MMX
PUNPCKLBW mmxreg,mem \301\2\x0F\x60\110 PENT,MMX,SM
PUNPCKLBW mmxreg,mem32 \301\2\x0F\x60\110 PENT,MMX
PUNPCKLBW mmxreg,mmxreg \2\x0F\x60\110 PENT,MMX
PUNPCKLDQ mmxreg,mem \301\2\x0F\x62\110 PENT,MMX,SM
PUNPCKLDQ mmxreg,mem32 \301\2\x0F\x62\110 PENT,MMX
PUNPCKLDQ mmxreg,mmxreg \2\x0F\x62\110 PENT,MMX
PUNPCKLWD mmxreg,mem \301\2\x0F\x61\110 PENT,MMX,SM
PUNPCKLWD mmxreg,mem32 \301\2\x0F\x61\110 PENT,MMX
PUNPCKLWD mmxreg,mmxreg \2\x0F\x61\110 PENT,MMX
PUSH reg16 \320\10\x50 8086
PUSH reg32 \321\10\x50 386
@ -868,7 +873,7 @@ RCR rm16,imm \320\300\1\xC1\203\25 186,SB
RCR rm32,unity \321\300\1\xD1\203 386
RCR rm32,reg_cl \321\300\1\xD3\203 386
RCR rm32,imm \321\300\1\xC1\203\25 386,SB
RDSHR void \2\x0F\x36 P6,CYRIX,SMM
RDSHR rm32 \321\300\2\x0F\x36\200 P6,CYRIX,SMM
RDMSR void \2\x0F\x32 PENT,PRIV
RDPMC void \2\x0F\x33 P6
RDTSC void \2\x0F\x31 PENT
@ -940,6 +945,7 @@ SBB reg32,reg32 \321\301\1\x1B\110 386
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,sbyte \320\1\x83\203\15 8086,SM,ND
SBB reg_ax,imm \320\1\x1D\31 8086,SM
SBB reg_eax,sbyte \321\1\x83\203\15 386,SM,ND
SBB reg_eax,imm \321\1\x1D\41 386,SM
@ -1022,6 +1028,7 @@ SUB reg32,reg32 \321\301\1\x2B\110 386
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,sbyte \320\1\x83\205\15 8086,SM,ND
SUB reg_ax,imm \320\1\x2D\31 8086,SM
SUB reg_eax,sbyte \321\1\x83\205\15 386,SM,ND
SUB reg_eax,imm \321\1\x2D\41 386,SM
@ -1056,6 +1063,7 @@ TEST rm32,imm \321\300\1\xF7\200\41 386,SM
TEST mem,imm8 \300\1\xF6\200\21 8086,SM
TEST mem,imm16 \320\300\1\xF7\200\31 8086,SM
TEST mem,imm32 \321\300\1\xF7\200\41 386,SM
UD0 void \2\x0F\xFF 286,UNDOC
UD1 void \2\x0F\xB9 286,UNDOC
UD2 void \2\x0F\x0B 286
UMOV mem,reg8 \300\2\x0F\x10\101 386,UNDOC,SM
@ -1079,7 +1087,7 @@ VERW reg16 \300\1\x0F\17\205 286,PROT
WAIT void \1\x9B 8086
FWAIT void \1\x9B 8086
WBINVD void \2\x0F\x09 486,PRIV
WRSHR void \2\x0F\x37 P6,CYRIX,SMM
WRSHR rm32 \321\300\2\x0F\x37\200 P6,CYRIX,SMM
WRMSR void \2\x0F\x30 PENT,PRIV
XADD mem,reg8 \300\2\x0F\xC0\101 486,SM
XADD reg8,reg8 \300\2\x0F\xC0\101 486
@ -1124,6 +1132,7 @@ XOR reg32,reg32 \321\301\1\x33\110 386
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,sbyte \320\1\x83\206\15 8086,SM,ND
XOR reg_ax,imm \320\1\x35\31 8086,SM
XOR reg_eax,sbyte \321\1\x83\206\15 386,SM,ND
XOR reg_eax,imm \321\1\x35\41 386,SM

2
nasm.h
View File

@ -13,7 +13,7 @@
#define NASM_MAJOR_VER 0
#define NASM_MINOR_VER 98
#define NASM_VER "0.98.24"
#define NASM_VER "0.98.25"
#ifndef NULL
#define NULL 0

View File

@ -629,7 +629,7 @@ static char *
read_line(void)
{
char *buffer, *p, *q;
int bufsize;
int bufsize, continued_count;
if (stdmacpos)
{
@ -680,6 +680,7 @@ read_line(void)
bufsize = BUF_DELTA;
buffer = nasm_malloc(BUF_DELTA);
p = buffer;
continued_count = 0;
while (1)
{
q = fgets(p, bufsize - (p - buffer), istk->fp);
@ -688,7 +689,23 @@ read_line(void)
p += strlen(p);
if (p > buffer && p[-1] == '\n')
{
break;
/* Convert backslash-CRLF line continuation sequences into
nothing at all (for DOS and Windows) */
if (((p - 2) > buffer) && (p[-3] == '\\') && (p[-2] == '\r')) {
p -= 3;
*p = 0;
continued_count++;
}
/* Also convert backslash-LF line continuation sequences into
nothing at all (for Unix) */
else if (((p - 1) > buffer) && (p[-2] == '\\')) {
p -= 2;
*p = 0;
continued_count++;
}
else {
break;
}
}
if (p - buffer > bufsize - 10)
{
@ -705,7 +722,7 @@ read_line(void)
return NULL;
}
src_set_linnum(src_get_linnum() + istk->lineinc);
src_set_linnum(src_get_linnum() + istk->lineinc + continued_count);
/*
* Play safe: remove CRs as well as LFs, if any of either are