mirror of
				https://github.com/netwide-assembler/nasm.git
				synced 2025-10-10 00:25:06 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			384 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
			
		
		
	
	
			384 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
| ;This file demonstrates many of the differences between NASM version X and NASM
 | |
| ;version 0.97
 | |
| ;
 | |
| ; changed.asm is copyright (C) 1998 John S. Fine
 | |
| ;
 | |
| ;  It may be redistributed under the same conditions as NASM as described in
 | |
| ;  LICENSE file in the NASM archive
 | |
| ;_________________________________
 | |
| ;
 | |
| ;  nasm changed.asm -l changed.lst
 | |
| ;
 | |
| ; When assembled without any -d switches, it includes examples which:
 | |
| ;       Work correctly in version X
 | |
| ;  and  Work incorrectly and/or display warnings in version 0.97
 | |
| ;  and  Do not prevent the generation of output in version 0.97
 | |
| ;
 | |
| ; Not all the differences can be seen in the .lst file.  I suggest that you use
 | |
| ; "ndisasm changes"  to examine the code actually generated.
 | |
| ;_________________________________
 | |
| ;
 | |
| ;  nasm changed.asm -l changed.lst -doldmsg
 | |
| ;
 | |
| ; When assembled with -doldmsg, it adds examples which:
 | |
| ;       Work correctly in version X
 | |
| ;  and  Generate error messages in version 0.97 and do not generate output
 | |
| ;_________________________________
 | |
| ;
 | |
| ;  nasm changed.asm -l changed.lst -doldcrash
 | |
| ;
 | |
| ; When assembled with -doldcrash, it adds examples which:
 | |
| ;       Work correctly in version X
 | |
| ;  and  Cause NASM to crash in version 0.97
 | |
| ;_________________________________
 | |
| ;
 | |
| ;  nasm changed.asm -l changed.lst -dnewmsg
 | |
| ;
 | |
| ; When assembled with -dnewmsg, it adds examples which:
 | |
| ;       Generate error messages in version X
 | |
| ;  and  Generate wrong output without warning or error message in version 0.97
 | |
| ;-----------------------------------------------------------------------------
 | |
| 
 | |
| ; Please note that I have reported the name of the person who made the
 | |
| ; correction based on very limited information.  In several cases, I am sure I
 | |
| ; will identify the wrong author.  Please send me any corrections;  I don't
 | |
| ; intend to insult or exclude anyone.
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Bug fixed by Simon in assemble()
 | |
| ;
 | |
| ; The following generated "call next" / "call next-1" instead of
 | |
| ; two copies of "call next"
 | |
| ;
 | |
| 	times 2 a16 call next
 | |
| next:
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Bug fixed by John in parse_line()  (and other routines)
 | |
| ;
 | |
| ; This used to jmp to prior.1, when it should be here.1
 | |
| ;
 | |
| prior:
 | |
| .1:
 | |
| here:	jmp	.1
 | |
| .1:
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Bug fixed by John in assemble()
 | |
| ;
 | |
| ; Strings used in dq and dt were not zero filled correctly
 | |
| ;
 | |
| 	dq	'b'
 | |
| 
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Bug fixed by Simon in isn_names[]
 | |
| ;
 | |
| ; Was not recognised as an instruction
 | |
| ;
 | |
| 	int01			; Instead of INT1
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Bug fixed by Jim Hague in ???
 | |
| ;
 | |
| ; Forward references were instruction level rather than per operand
 | |
| ;
 | |
| 	shr word [forwardref],1
 | |
| forwardref:
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Bug fixed by John in preproc.c
 | |
| ;
 | |
| ; It used to silently discard id characters appended to a multi-line
 | |
| ; macro parameter (such as the x in %1x below).
 | |
| ;
 | |
| %macro xxx 1
 | |
| %1: nop
 | |
| %{1}x: jmp %1x
 | |
| %endmacro
 | |
| xxx yyy
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Bug added by John in preproc.c 0.98-J4, removed by John in 0.98-J5
 | |
| ;
 | |
| ; Tested here to make sure it stays removed
 | |
| ;
 | |
| %macro TestElse 1
 | |
| %if %1=0
 | |
| %elif %1=1
 | |
| nop
 | |
| %endif
 | |
| %endmacro
 | |
| TestElse 1
 | |
| 
 | |
| %ifdef oldmsg
 | |
| ;***************************************************************
 | |
| ;
 | |
| ; The following examples will generate error messages in 0.97 and will generate
 | |
| ; correct output in the new version.
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Bug fixed by Simon in isns.dat
 | |
| ;
 | |
| ; The optional "near" was not permitted on JMP and CALL
 | |
| ;
 | |
| 	jmp near here
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Feature added by Simon in stdscan()
 | |
| ;
 | |
| ; You can now use the numeric value of strings in %assign
 | |
| ;
 | |
| %assign xxx 'ABCD'
 | |
| 	dd xxx
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Feature added by John in add_vectors()
 | |
| ;
 | |
| ; Stranger address expressions are now supported as long as they resolve to
 | |
| ; something valid.
 | |
| ;
 | |
| 	mov ax, [eax + ebx + ecx - eax]
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Bug fixed by Simon in ???
 | |
| ;
 | |
| ; The EQU directive affected local labels in a way that was inconsistent
 | |
| ; between passes
 | |
| ;
 | |
| .local:
 | |
| neither equ $
 | |
| 	jmp .local
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Feature added by Jules in parse_line
 | |
| ;
 | |
| ; You can override a size specifier
 | |
| ;
 | |
| %define arg1 dword [bp+4]
 | |
| 	cmp word arg1, 2
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Bug fixed by John in preproc.c
 | |
| ;
 | |
| ; You could not use a label on the same line with a macro invocation, if the
 | |
| ; macro definition began with a preprocessor directive.
 | |
| ;
 | |
| 	struc mytype
 | |
| .long	resd	1
 | |
| 	endstruc
 | |
| 
 | |
| lbl	istruc mytype
 | |
| 	at mytype.long, dd 'ABCD'
 | |
| 	iend
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Warning removed by John in preproc.c
 | |
| ;
 | |
| ; In order to allow macros that extend the definition of instructions, I
 | |
| ; disabled the warning on a multi-line macro referencing itself.
 | |
| ;
 | |
| %endif			;NASM 0.97 doesn't handle %0 etc. inside false %if
 | |
| %macro push 1-*		;
 | |
| %rep %0			;
 | |
| push %1			;
 | |
| %rotate 1		;
 | |
| %endrep			;
 | |
| %endmacro		;
 | |
| %ifdef oldmsg		;
 | |
| 
 | |
| 	push ax,bx
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Warning removed by John in preproc.c
 | |
| ;
 | |
| ; To support other types of macros that extend the definition of instructions,
 | |
| ; I disabled the warning on a multi-line macro called with the wrong number of
 | |
| ; parameters.  PUSH and POP can be extended equally well by either method, but
 | |
| ; other intruction extensions may need one method or the other, so I made both
 | |
| ; work.
 | |
| ;
 | |
| ; Note that neither of these warnings was really needed, because a later stage
 | |
| ; of NASM would almost always give an adequate error message if the macro use
 | |
| ; really was wrong.
 | |
| ;
 | |
| %endif
 | |
| %macro pop 2-*
 | |
| %rep %0
 | |
| pop %1
 | |
| %rotate 1
 | |
| %endrep
 | |
| %endmacro
 | |
| %ifdef oldmsg
 | |
| 
 | |
| 	pop ax,bx
 | |
| %endif
 | |
| 
 | |
| 
 | |
| %ifdef newmsg  ;***************************************************************
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Bug fixed by John in parse_line()  (and other routines)
 | |
| ;
 | |
| ; This invalid code used to assemble without errors
 | |
| ;
 | |
| myself equ myself+1
 | |
| 	jmp myself
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Change made by John in preproc.c
 | |
| ;
 | |
| ; In 0.97, an id that appears as a label on a macro invocation was always
 | |
| ; prepended to the first line of the macro expansion.  That caused several
 | |
| ; bugs, but also could be used in tricks like the arg macro in c16.mac and
 | |
| ; c32.mac.
 | |
| ;
 | |
| ; In version X, an id that appears as a label on a macro invocation will
 | |
| ; normally be defined as a label for the address at which the macro is
 | |
| ; invoked, regardless of whether the first line of the macro expansion is
 | |
| ; something that can take a label.  The new token %00 may be used for any
 | |
| ; of the situations in which the old prepend behavior was doing something
 | |
| ; tricky but useful.  %00 can also be used more than once and in places
 | |
| ; other than the start of the expansion.
 | |
| ;
 | |
| %endif
 | |
| %assign arg_off 0
 | |
| 
 | |
| %imacro arg 0-1 2		;arg defined the old way
 | |
| 	  equ arg_off
 | |
| %assign arg_off %1+arg_off
 | |
| %endmacro
 | |
| 
 | |
| %ifdef newmsg
 | |
| arg_example arg
 | |
| %endif
 | |
| 
 | |
| %imacro arg2 0-1 2		;arg defined the new way
 | |
| %00	  equ arg_off
 | |
| %assign arg_off %1+arg_off
 | |
| %endmacro
 | |
| 
 | |
| %ifdef oldmsg
 | |
| arg_example2 arg2
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Change made by Jules and John in INSNS.DAT
 | |
| ;
 | |
| ; Various instruction in which the size of an immediate is built-in to the
 | |
| ; instruction set, now allow you to redundantly specify that size as long
 | |
| ; as you specify it correctly
 | |
| ;
 | |
| 	AAD	byte 5
 | |
| 	AAM	byte 5
 | |
| 	BT	bx, byte 3
 | |
| 	BTC	cx, byte 4
 | |
| 	BTR	dx, byte 5
 | |
| 	BTS	si, byte 6
 | |
| 	IN	eax, byte 0x40
 | |
| 	INT	byte 21h
 | |
| 	OUT	byte 70h, ax
 | |
| 	RET	word 2
 | |
| 	RETN	word 2
 | |
| 	RETF	word 4
 | |
| 
 | |
| ; note "ENTER" has not been changed yet.
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Enhancement by hpa in insns.dat et al
 | |
| ;
 | |
| ; Simplified adding new instructions, and added some missing instructions
 | |
| ;
 | |
| 	int03			; Instead of INT3
 | |
| 	ud1			; No documented mnemonic for this one
 | |
| 	ud2
 | |
| 	sysenter
 | |
| 	sysexit
 | |
| 	syscall
 | |
| 	sysret
 | |
| 	fxsave [ebx]
 | |
| 	fxrstor [es:ebx+esi*4+0x3000]
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Enhancement by hpa in insns.dat et al
 | |
| ;
 | |
| ; Actually make SSE work, and use the -p option to ndisasm to select
 | |
| ; one of several aliased opcodes
 | |
| ;
 | |
| 	sqrtps xmm0,[ebx+10]	; SSE opcode
 | |
| 	paddsiw mm0,[ebx+10]	; Cyrix opcode with the same byte seq.
 | |
| 	
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Enhancement by hpa in preproc.c
 | |
| ;
 | |
| ; Support %undef to remoce a single-line macro
 | |
| ;
 | |
| %define	TEST_ME 42
 | |
| %ifndef TEST_ME
 | |
| %error	"TEST_ME not defined after %define"
 | |
| %endif
 | |
| 			
 | |
| %undef  TEST_ME
 | |
| %ifdef  TEST_ME
 | |
| %error	"TEST_ME defined after %undef"
 | |
| %endif
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Bug fix by hpa in insns.dat
 | |
| ;
 | |
| ; PSHUFW and PINSRW weren't handling the implicit sizes correctly; all of
 | |
| ; the entries below are (or should be) legal
 | |
| ;
 | |
| 	pshufw mm2, mm1, 3
 | |
| 	pshufw mm3,[ebx],2
 | |
| 	pshufw mm7,[0+edi*8],1
 | |
| 	
 | |
| 	pshufw mm2, mm1, byte 3
 | |
| 	pshufw mm3,[ebx],byte 2
 | |
| 	pshufw mm7,[0+edi*8],byte 1
 | |
| 
 | |
| 	pshufw mm2, mm1, 3
 | |
| 	pshufw mm3, qword [ebx], 2
 | |
| 	pshufw mm7, qword [0+edi*8], 1
 | |
| 
 | |
| 	pshufw mm2, mm1, byte 3
 | |
| 	pshufw mm3, qword [ebx], byte 2
 | |
| 	pshufw mm7, qword [0+edi*8], byte 1
 | |
| 
 | |
| 	pinsrw mm1, [esi], 1
 | |
| 	pinsrw mm1, word [esi], 1
 | |
| 	pinsrw mm1, [esi], byte 1
 | |
| 	pinsrw mm1, word [esi], byte 1
 | |
| 
 | |
| 	
 | |
| %endif				; oldmsg
 | |
| 	
 | |
| %ifdef oldcrash  ;*************************************************************
 | |
| 
 | |
| This_label_is_256_characters_long__There_used_to_be_a_bug_in_stdscan_which_made_it_crash_when_it_did_a_keyword_search_on_any_label_longer_than_255_characters__Now_anything_longer_than_MAX_KEYWORD_is_always_a_symbol__It_will_not_even_try_a_keyword_search___
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Bug fixed by John in preproc.c
 | |
| ;
 | |
| ; Builds of NASM that prohibit dereferencing a NULL pointer used to crash if a
 | |
| ; macro that started with a blank line was invoked with a label
 | |
| ;
 | |
| %macro empty_macro 0
 | |
| 
 | |
| %endm
 | |
| 
 | |
| emlabel empty_macro
 | |
| 	jmp	emlabel
 | |
| 
 | |
| ;-----------------------------------------------------------------------------
 | |
| ; Enhancement by Conan Brink in preproc.c
 | |
| ;
 | |
| ; Allow %rep to be nested
 | |
| ;
 | |
| %rep 4
 | |
| %rep 5
 | |
| 	nop
 | |
| %endrep
 | |
| %endrep
 | |
| 
 | |
| %endif
 |