On at 2026-06-03 07:45:53 -0400, Jerome Shidel via Freedos-devel 
<[email protected]> wrote:
>
>
>> On Jun 2, 2026, at 4:57 PM, E. C. Masloch via Freedos-devel 
>> <[email protected]> wrote:
>> [..]
>> That's a "cpu 8086" directive. Indeed, it avoids allowing many 186+, 286+, 
>> or 386+ instructions.
>> 
>> More importantly, if a conditional jump needs to be widened to address a 
>> near target (if it isn't in range of a short jump) then without any "cpu" 
>> directive recent NASM versions will use the 0Fh-prefixed, 386+ 
>> single-instruction form of a near conditional jump. With "cpu 8086" it 
>> instead encodes a two-instruction workaround in which the first jump is 
>> short and conditional on the inverted condition, and the second jump is near 
>> and unconditional.
>
>Hmm. I wonder if there is a way to turn off that “double jump” feature. I 
>would much rather prefer NASM to not try and be “helpful” in this case and 
>simply generate an error if it encounters an instruction for a short jump 
>which is too far. I would much prefer it only encode the instructions I tell 
>it to use. After all, this is assembly and not some abstracted HLL.

You can use the preprocessor to do this. Here's a simple test case, also 
uploaded to our server [1]. It is so simple because it only needs "one" mmacro, 
but you have to repeat it for every of the dozens of possible jcc choices (for 
whichever choices you use). This could probably be golfed to need only a single 
mmacro and use an smacro per jcc instead.

===
test$ cat test.asm

        cpu 8086
label:
        times 256 nop
        je label

%imacro je 1.nolist
        %? short %1
%endmacro

%ifdef ERROR
        je label
%endif


test$ nasm -v
NASM version 3.01rc3 compiled on Mar  6 2026
test$ nasm test.asm -l /dev/stderr
     1
     2                                          cpu 8086
     3                                  label:
     4 00000000 90<rep 100h>                    times 256 nop
     5 00000100 7503E9FBFE                      je label
     6
     7                                  %imacro je 1.nolist
     8                                          %? short %1
     9                                  %endmacro
    10
    11                                  %ifdef ERROR
    12                                          je label
    13                                  %endif
test$ nasm test.asm -l /dev/stderr -DERROR
     1
     2                                          cpu 8086
     3                                  label:
     4 00000000 90<rep 100h>                    times 256 nop
     5 00000100 7503E9FBFE                      je label
     6
     7                                  %imacro je 1.nolist
     8                                          %? short %1
     9                                  %endmacro
    10
    11                                  %ifdef ERROR
test.asm:12: error: short jump is out of range
test.asm:12: warning: signed byte exceeds bounds [-w+number-overflow]
    12 00000105 74F9                            je label
    12          ******************       error: short jump is out of range
    12          ******************       warning: signed byte exceeds bounds 
[-w+number-overflow]
    13                                  %endif


test$ oldnasm -v
NASM version 2.15rc0 compiled on Dec 28 2018
test$ oldnasm test.asm -l /dev/stderr
     1
     2                                          cpu 8086
     3                                  label:
     4 00000000 90<rept>                        times 256 nop
     5 00000100 7503E9FBFE                      je label
     6
     7                                  %imacro je 1.nolist
     8                                          %? short %1
     9                                  %endmacro
    10
    11                                  %ifdef ERROR
    12                                          je label
    13                                  %endif
test$ oldnasm test.asm -l /dev/stderr -DERROR
     1
     2                                          cpu 8086
     3                                  label:
     4 00000000 90<rept>                        times 256 nop
     5 00000100 7503E9FBFE                      je label
     6
     7                                  %imacro je 1.nolist
     8                                          %? short %1
     9                                  %endmacro
    10
    11                                  %ifdef ERROR
test.asm:12: error: short jump is out of range
test.asm:12: warning: byte data exceeds bounds [-w+number-overflow]
    12 00000105 74F9                            je label
    12          ******************       error: short jump is out of range
    12          ******************       warning: byte data exceeds bounds 
[-w+number-overflow]
    13                                  %endif
test$
===

I also prepared a NASM macro file, jn_warn.mac [2], at some earlier point 
(apparently 2018-03-26). (Released into the Public Domain.) It works similarly 
to the above simple case, except it allows the near code but emits a warning if 
the generated machine code is longer than 2 bytes. That detects both the 8086 
workaround and the 386 single-instruction near jcc.

>Such things tend to be more trouble than they are worth and create extreme  
>problems when debugging. As someone who has pushed NASM’s macros and advanced 
>features past the breaking point several times in DOS related programming, 
>these types of “features” lead to many headaches and sleepless nights.

I'm also a rather heavy user of the NASM preprocessor. The surprising nature of 
something like this is why I want to share knowledge about it. In this case, I 
do prefer to have NASM extend the jcc jumps though.

As a question I'd suggest, can you emulate the other choice using what we have? 
As I've shown you can emulate both "error on non-short jcc" and "warn on 
non-short jcc" with things as is. If we didn't have NASM's 8086 near jcc 
workaround feature, you would have to be able to emulate *that* choice using 
the preprocessor in tandem with the assembler. I'm not sure that would be even 
possible as you need to evaluate the distances to the destination, especially 
tricky if the destination is after the jcc use.
 
>> So even if you seemingly use only 8086-clean code, NASM may generate these 
>> 386+ forms of conditional jumps. You need either "cpu 8086" or to override 
>> every conditional jump (except loopxx/jcxz) with a "short" keyword to force 
>> an error rather than using the non-8086 instruction forms.
>> 
>>> No different than specifying the offset of the code for things like COM 
>>> files by using “org 0x100”
>>> 
>>> So, that statement about it usually generates 386+ code makes no sense to 
>>> me. Unless, the statement is in regards to running NASM. Then because NASM 
>>> is huge, you would be limited to compiling using a 386+.
>> 
>> Yes, I believe that's what Rugxulo means. As the assembler was developed, it 
>> got trickier (if not impossible) to compile the assembler itself as an 
>> 8086-compatible application. I know I tried that at some point too, and I 
>> don't think I succeeded then.
>> 
>> Writing of the 8086 cleanliness of NASM output, though, even "cpu 8086" 
>> doesn't always save the day. Some 386 addressing modes and registers are 
>> allowed despite the selected machine level. I recently commented about this 
>> on a stackoverflow question [1] in which I also cited earlier NASM bug 
>> reports that I had submitted, namely an "[edx]" a32 address is assembled 
>> despite "cpu 8086" [2] and an "fs" segreg operand (not as a prefix) is also 
>> assembled where it shouldn't be. (The links lead to mirrored copies on our 
>> server as the old NASM bugzilla is down more often than not lately.)
>> 
>
>True. But, I would consider such things a compiler “bug”.

Yes, hence why I reported them to the "bug" tracker at the time ;P  As the 
responses indicated, it is a known problem but there is not enough work to fix 
it yet.

> However, if you use the “cpu 8086” directive and write 8086 code, it 
> generates 8086 code. 

Yes, that's right.

Regards,
ecm


[1]: https://pushbx.org/ecm/test/20260603/test.txt
[2]: https://hg.pushbx.org/ecm/lmacros/file/de53a9686fad/jn_warn.mac


_______________________________________________
Freedos-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freedos-devel

Reply via email to