NASM 0.98.22
[platform/upstream/nasm.git] / changed.asm
1 ;This file demonstrates many of the differences between NASM version X and NASM
2 ;version 0.97
3 ;
4 ; changed.asm is copyright (C) 1998 John S. Fine
5 ;
6 ;  It may be redistributed under the same conditions as NASM as described in
7 ;  Licence file in the NASM archive
8 ;_________________________________
9 ;
10 ;  nasm changed.asm -l changed.lst
11 ;
12 ; When assembled without any -d switches, it includes examples which:
13 ;       Work correctly in version X
14 ;  and  Work incorrectly and/or display warnings in version 0.97
15 ;  and  Do not prevent the generation of output in version 0.97
16 ;
17 ; Not all the differences can be seen in the .lst file.  I suggest that you use
18 ; "ndisasm changes"  to examine the code actually generated.
19 ;_________________________________
20 ;
21 ;  nasm changed.asm -l changed.lst -doldmsg
22 ;
23 ; When assembled with -doldmsg, it adds examples which:
24 ;       Work correctly in version X
25 ;  and  Generate error messages in version 0.97 and do not generate output
26 ;_________________________________
27 ;
28 ;  nasm changed.asm -l changed.lst -doldcrash
29 ;
30 ; When assembled with -doldcrash, it adds examples which:
31 ;       Work correctly in version X
32 ;  and  Cause NASM to crash in version 0.97
33 ;_________________________________
34 ;
35 ;  nasm changed.asm -l changed.lst -dnewmsg
36 ;
37 ; When assembled with -dnewmsg, it adds examples which:
38 ;       Generate error messages in version X
39 ;  and  Generate wrong output without warning or error message in version 0.97
40 ;-----------------------------------------------------------------------------
41
42 ; Please note that I have reported the name of the person who made the
43 ; correction based on very limited information.  In several cases, I am sure I
44 ; will identify the wrong author.  Please send me any corrections;  I don't
45 ; intend to insult or exclude anyone.
46
47 ;-----------------------------------------------------------------------------
48 ; Bug fixed by Simon in assemble()
49 ;
50 ; The following generated "call next" / "call next-1" instead of
51 ; two copies of "call next"
52 ;
53         times 2 a16 call next
54 next:
55
56 ;-----------------------------------------------------------------------------
57 ; Bug fixed by John in parse_line()  (and other routines)
58 ;
59 ; This used to jmp to prior.1, when it should be here.1
60 ;
61 prior:
62 .1:
63 here:   jmp     .1
64 .1:
65
66 ;-----------------------------------------------------------------------------
67 ; Bug fixed by John in assemble()
68 ;
69 ; Strings used in dq and dt were not zero filled correctly
70 ;
71         dq      'b'
72
73
74 ;-----------------------------------------------------------------------------
75 ; Bug fixed by Simon in isn_names[]
76 ;
77 ; Was not recognised as an instruction
78 ;
79         int01                   ; Instead of INT1
80
81 ;-----------------------------------------------------------------------------
82 ; Bug fixed by Jim Hague in ???
83 ;
84 ; Forward references were instruction level rather than per operand
85 ;
86         shr word [forwardref],1
87 forwardref:
88
89 ;-----------------------------------------------------------------------------
90 ; Bug fixed by John in preproc.c
91 ;
92 ; It used to silently discard id characters appended to a multi-line
93 ; macro parameter (such as the x in %1x below).
94 ;
95 %macro xxx 1
96 %1: nop
97 %{1}x: jmp %1x
98 %endmacro
99 xxx yyy
100
101 ;-----------------------------------------------------------------------------
102 ; Bug added by John in preproc.c 0.98-J4, removed by John in 0.98-J5
103 ;
104 ; Tested here to make sure it stays removed
105 ;
106 %macro TestElse 1
107 %if %1=0
108 %elif %1=1
109 nop
110 %endif
111 %endmacro
112 TestElse 1
113
114 %ifdef oldmsg
115 ;***************************************************************
116 ;
117 ; The following examples will generate error messages in 0.97 and will generate
118 ; correct output in the new version.
119
120 ;-----------------------------------------------------------------------------
121 ; Bug fixed by Simon in isns.dat
122 ;
123 ; The optional "near" was not permitted on JMP and CALL
124 ;
125         jmp near here
126
127 ;-----------------------------------------------------------------------------
128 ; Feature added by Simon in stdscan()
129 ;
130 ; You can now use the numeric value of strings in %assign
131 ;
132 %assign xxx 'ABCD'
133         dd xxx
134
135 ;-----------------------------------------------------------------------------
136 ; Feature added by John in add_vectors()
137 ;
138 ; Stranger address expressions are now supported as long as they resolve to
139 ; something valid.
140 ;
141         mov ax, [eax + ebx + ecx - eax]
142
143 ;-----------------------------------------------------------------------------
144 ; Bug fixed by Simon in ???
145 ;
146 ; The EQU directive affected local labels in a way that was inconsistent
147 ; between passes
148 ;
149 .local:
150 neither equ $
151         jmp .local
152
153 ;-----------------------------------------------------------------------------
154 ; Feature added by Jules in parse_line
155 ;
156 ; You can override a size specifier
157 ;
158 %define arg1 dword [bp+4]
159         cmp word arg1, 2
160
161 ;-----------------------------------------------------------------------------
162 ; Bug fixed by John in preproc.c
163 ;
164 ; You could not use a label on the same line with a macro invocation, if the
165 ; macro definition began with a preprocessor directive.
166 ;
167         struc mytype
168 .long   resd    1
169         endstruc
170
171 lbl     istruc mytype
172         at mytype.long, dd 'ABCD'
173         iend
174
175 ;-----------------------------------------------------------------------------
176 ; Warning removed by John in preproc.c
177 ;
178 ; In order to allow macros that extend the definition of instructions, I
179 ; disabled the warning on a multi-line macro referencing itself.
180 ;
181 %endif                  ;NASM 0.97 doesn't handle %0 etc. inside false %if
182 %macro push 1-*         ;
183 %rep %0                 ;
184 push %1                 ;
185 %rotate 1               ;
186 %endrep                 ;
187 %endmacro               ;
188 %ifdef oldmsg           ;
189
190         push ax,bx
191
192 ;-----------------------------------------------------------------------------
193 ; Warning removed by John in preproc.c
194 ;
195 ; To support other types of macros that extend the definition of instructions,
196 ; I disabled the warning on a multi-line macro called with the wrong number of
197 ; parameters.  PUSH and POP can be extended equally well by either method, but
198 ; other intruction extensions may need one method or the other, so I made both
199 ; work.
200 ;
201 ; Note that neither of these warnings was really needed, because a later stage
202 ; of NASM would almost always give an adequate error message if the macro use
203 ; really was wrong.
204 ;
205 %endif
206 %macro pop 2-*
207 %rep %0
208 pop %1
209 %rotate 1
210 %endrep
211 %endmacro
212 %ifdef oldmsg
213
214         pop ax,bx
215 %endif
216
217
218 %ifdef newmsg  ;***************************************************************
219
220 ;-----------------------------------------------------------------------------
221 ; Bug fixed by John in parse_line()  (and other routines)
222 ;
223 ; This invalid code used to assemble without errors
224 ;
225 myself equ myself+1
226         jmp myself
227
228 ;-----------------------------------------------------------------------------
229 ; Change made by John in preproc.c
230 ;
231 ; In 0.97, an id that appears as a label on a macro invocation was always
232 ; prepended to the first line of the macro expansion.  That caused several
233 ; bugs, but also could be used in tricks like the arg macro in c16.mac and
234 ; c32.mac.
235 ;
236 ; In version X, an id that appears as a label on a macro invocation will
237 ; normally be defined as a label for the address at which the macro is
238 ; invoked, regardless of whether the first line of the macro expansion is
239 ; something that can take a label.  The new token %00 may be used for any
240 ; of the situations in which the old prepend behavior was doing something
241 ; tricky but useful.  %00 can also be used more than once and in places
242 ; other than the start of the expansion.
243 ;
244 %endif
245 %assign arg_off 0
246
247 %imacro arg 0-1 2               ;arg defined the old way
248           equ arg_off
249 %assign arg_off %1+arg_off
250 %endmacro
251
252 %ifdef newmsg
253 arg_example arg
254 %endif
255
256 %imacro arg2 0-1 2              ;arg defined the new way
257 %00       equ arg_off
258 %assign arg_off %1+arg_off
259 %endmacro
260
261 %ifdef oldmsg
262 arg_example2 arg2
263
264 ;-----------------------------------------------------------------------------
265 ; Change made by Jules and John in INSNS.DAT
266 ;
267 ; Various instruction in which the size of an immediate is built-in to the
268 ; instruction set, now allow you to redundantly specify that size as long
269 ; as you specify it correctly
270 ;
271         AAD     byte 5
272         AAM     byte 5
273         BT      bx, byte 3
274         BTC     cx, byte 4
275         BTR     dx, byte 5
276         BTS     si, byte 6
277         IN      eax, byte 0x40
278         INT     byte 21h
279         OUT     byte 70h, ax
280         RET     word 2
281         RETN    word 2
282         RETF    word 4
283
284 ; note "ENTER" has not been changed yet.
285
286 ;-----------------------------------------------------------------------------
287 ; Enhancement by hpa in insns.dat et al
288 ;
289 ; Simplified adding new instructions, and added some missing instructions
290 ;
291         int03                   ; Instead of INT3
292         ud1                     ; No documented mnemonic for this one
293         ud2
294         sysenter
295         sysexit
296         syscall
297         sysret
298         fxsave [ebx]
299         fxrstor [es:ebx+esi*4+0x3000]
300
301 ;-----------------------------------------------------------------------------
302 ; Enhancement by hpa in insns.dat et al
303 ;
304 ; Actually make SSE work, and use the -p option to ndisasm to select
305 ; one of several aliased opcodes
306 ;
307         sqrtps xmm0,[ebx+10]    ; SSE opcode
308         paddsiw mm0,[ebx+10]    ; Cyrix opcode with the same byte seq.
309         
310 ;-----------------------------------------------------------------------------
311 ; Enhancement by hpa in preproc.c
312 ;
313 ; Support %undef to remoce a single-line macro
314 ;
315 %define TEST_ME 42
316 %ifndef TEST_ME
317 %error  "TEST_ME not defined after %define"
318 %endif
319                         
320 %undef  TEST_ME
321 %ifdef  TEST_ME
322 %error  "TEST_ME defined after %undef"
323 %endif
324
325 ;-----------------------------------------------------------------------------
326 ; Bug fix by hpa in insns.dat
327 ;
328 ; PSHUFW and PINSRW weren't handling the implicit sizes correctly; all of
329 ; the entries below are (or should be) legal
330 ;
331         pshufw mm2, mm1, 3
332         pshufw mm3,[ebx],2
333         pshufw mm7,[0+edi*8],1
334         
335         pshufw mm2, mm1, byte 3
336         pshufw mm3,[ebx],byte 2
337         pshufw mm7,[0+edi*8],byte 1
338
339         pshufw mm2, mm1, 3
340         pshufw mm3, qword [ebx], 2
341         pshufw mm7, qword [0+edi*8], 1
342
343         pshufw mm2, mm1, byte 3
344         pshufw mm3, qword [ebx], byte 2
345         pshufw mm7, qword [0+edi*8], byte 1
346
347         pinsrw mm1, [esi], 1
348         pinsrw mm1, word [esi], 1
349         pinsrw mm1, [esi], byte 1
350         pinsrw mm1, word [esi], byte 1
351
352         
353 %endif                          ; oldmsg
354         
355 %ifdef oldcrash  ;*************************************************************
356
357 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___
358
359 ;-----------------------------------------------------------------------------
360 ; Bug fixed by John in preproc.c
361 ;
362 ; Builds of NASM that prohibit dereferencing a NULL pointer used to crash if a
363 ; macro that started with a blank line was invoked with a label
364 ;
365 %macro empty_macro 0
366
367 %endm
368
369 emlabel empty_macro
370         jmp     emlabel
371
372 ;-----------------------------------------------------------------------------
373 ; Enhancement by Conan Brink in preproc.c
374 ;
375 ; Allow %rep to be nested
376 ;
377 %rep 4
378 %rep 5
379         nop
380 %endrep
381 %endrep
382
383 %endif