Help! JMP out of range?

1426 views
Skip to first unread message

vassone

unread,
Apr 19, 2000, 3:00:00 AM4/19/00
to

Can someone please explain why MASM is reporting "Jump out of range by
130(bytes)

What does this means?

Any help would be very much appreciated..

Vassone

mailto:vas...@hotmail.com


Alexei A. Frounze

unread,
Apr 19, 2000, 3:00:00 AM4/19/00
to

Conditional jumps such as JZ or JNC, etc are limited to 127/128 bytes. You cant
jump over 127 or 128 bytes backward or forward.

If you had:
------8<-------
JZ label1
------8<-------

you should make it like this:

------8<-------
JNZ label2
JMP label1
label2:
------8<-------

this solves your problem.

Good Luck
Alexei A. Frounze
-----------------------------------------
Homepage: http://alexfru.chat.ru
Mirror: http://members.xoom.com/alexfru

leg0

unread,
Apr 19, 2000, 3:00:00 AM4/19/00
to

vassone wrote:
>
> Can someone please explain why MASM is reporting "Jump out of range by
> 130(bytes)
>
> What does this means?

this means that the jump destiantion is too far. you should not use jmp
short @label at this point. just use jmp @label.
short jumps range is +-128 bytes from current position.

--
leg0
(le...@nospam.localhost.ee)


vassone

unread,
Apr 19, 2000, 3:00:00 AM4/19/00
to

In article <sfs1057...@corp.supernews.com>, alex...@mtu-net.ru
says...
->
->Conditional jumps such as JZ or JNC, etc are limited to 127/128 bytes. You cant
->jump over 127 or 128 bytes backward or forward.
->
->If you had:
->------8<-------
->JZ label1
->------8<-------
->
->you should make it like this:
->
->------8<-------
->JNZ label2
->JMP label1
->label2:
->------8<-------
->
->this solves your problem.
->
->Good Luck
->Alexei A. Frounze
->-----------------------------------------
->Homepage: http://alexfru.chat.ru
->Mirror: http://members.xoom.com/alexfru
->
->vassone wrote:
->>
->> Can someone please explain why MASM is reporting "Jump out of range by
->> 130(bytes)
->>
->> What does this means?
->>
->> Any help would be very much appreciated..
->>
->> Vassone
->>
->> mailto:vas...@hotmail.com
->>
->
->
->
->

--
Vassone

mailto:vas...@hotmail.com


Bart Oldeman

unread,
Apr 19, 2000, 3:00:00 AM4/19/00
to

On Wed, 19 Apr 2000, Alexei A. Frounze wrote:

> Conditional jumps such as JZ or JNC, etc are limited to 127/128 bytes. You cant

> jump over 127 or 128 bytes backward or forward.

This depends on the processor. On a 386 or higher you can do

jz near address

which takes you as far as -32768 to 32767 in 16-bit mode or
-2147483648 to 2147483647 in 32-bit mode.

Some assemblers like tasm convert automatically depending on the processor
and the usage of the 'JUMPS' directive.

One caveat is that if you try to do a 16 bit relative jump in 32 bit mode,
it ands EIP with 0FFFFh, and causes (e.g.) a segmentation fault under
Linux.

so the code in hex: 67 0F 85 00 00 (JNZ rel16 0) ands EIP with 0FFFFh in
32-bit mode!

Bart


Henrik Nebrin

unread,
Apr 20, 2000, 3:00:00 AM4/20/00
to

Bart Oldeman skrev i meddelandet ...

|One caveat is that if you try to do a 16 bit relative jump in 32 bit mode,
|it ands EIP with 0FFFFh, and causes (e.g.) a segmentation fault under
|Linux.

Yes, Intel has also documented it if you look in the manual (esp., in the
JMP/Jcc pseudo code someplace in IADEVMAN2)

|
|so the code in hex: 67 0F 85 00 00 (JNZ rel16 0) ands EIP with 0FFFFh in
|32-bit mode!

Change the "67" to a "66" and it should work.


Alexei A. Frounze

unread,
Apr 20, 2000, 3:00:00 AM4/20/00
to

Bart Oldeman wrote:
>
> On Wed, 19 Apr 2000, Alexei A. Frounze wrote:
>
> > Conditional jumps such as JZ or JNC, etc are limited to 127/128 bytes. You cant
> > jump over 127 or 128 bytes backward or forward.
>
> This depends on the processor. On a 386 or higher you can do
>
> jz near address
>
> which takes you as far as -32768 to 32767 in 16-bit mode or
> -2147483648 to 2147483647 in 32-bit mode.

Seems yo be right if either data or addressing mode is changed by 66h/67h. Don't
remember which. I need to take a look at the manual. :)

> Some assemblers like tasm convert automatically depending on the processor
> and the usage of the 'JUMPS' directive.
>

> One caveat is that if you try to do a 16 bit relative jump in 32 bit mode,
> it ands EIP with 0FFFFh, and causes (e.g.) a segmentation fault under
> Linux.
>

> so the code in hex: 67 0F 85 00 00 (JNZ rel16 0) ands EIP with 0FFFFh in
> 32-bit mode!

Yeah.

bye.

Bart Oldeman

unread,
Apr 20, 2000, 3:00:00 AM4/20/00
to

On Thu, 20 Apr 2000, Henrik Nebrin wrote:

> Bart Oldeman skrev i meddelandet ...

> |One caveat is that if you try to do a 16 bit relative jump in 32 bit mode,


> |it ands EIP with 0FFFFh, and causes (e.g.) a segmentation fault under
> |Linux.
>

> Yes, Intel has also documented it if you look in the manual (esp., in the
> JMP/Jcc pseudo code someplace in IADEVMAN2)
>
> |

> |so the code in hex: 67 0F 85 00 00 (JNZ rel16 0) ands EIP with 0FFFFh in
> |32-bit mode!
>

> Change the "67" to a "66" and it should work.

I checked again and it seems both of us are wrong:
67h (address-size prefix) does not affect JMP/Jcc instructions.
66h (operand-size prefix) does affect those, and
hex 66 E9 00 00 (JMP rel16 0) could be written as "AND EIP, 0FFFFh" (in
32-bit mode, that is.)

So we cannot generally save one byte in a program by using these kinds of
jumps instead of e.g. "E9 dword" (JMP rel32).

Bart


Henrik Nebrin

unread,
Apr 21, 2000, 3:00:00 AM4/21/00
to

Bart Oldeman skrev i meddelandet ...
|
|On Thu, 20 Apr 2000, Henrik Nebrin wrote:
|
|> Bart Oldeman skrev i meddelandet ...
|> |
|> |so the code in hex: 67 0F 85 00 00 (JNZ rel16 0) ands EIP with 0FFFFh
in
|> |32-bit mode!
|>
|> Change the "67" to a "66" and it should work.
|
|I checked again and it seems both of us are wrong:

Where was I wrong?

|67h (address-size prefix) does not affect JMP/Jcc instructions.
|66h (operand-size prefix) does affect those, and
|hex 66 E9 00 00 (JMP rel16 0) could be written as "AND EIP, 0FFFFh" (in
|32-bit mode, that is.)

Not exactly, it's (EIP+size_of_instr+displ) AND FFFFh


Bart Oldeman

unread,
Apr 23, 2000, 3:00:00 AM4/23/00
to
On Fri, 21 Apr 2000, Henrik Nebrin wrote:

> Bart Oldeman skrev i meddelandet ...
> |
> |On Thu, 20 Apr 2000, Henrik Nebrin wrote:
> |
> |> Bart Oldeman skrev i meddelandet ...
> |> |
> |> |so the code in hex: 67 0F 85 00 00 (JNZ rel16 0) ands EIP with
> 0FFFFh in
> |> |32-bit mode!
> |>
> |> Change the "67" to a "66" and it should work.
> |
> |I checked again and it seems both of us are wrong:
> Where was I wrong?

"66 0F 85 00 00" also eats the next two bytes, since the 66h does not
influence the instruction.

> |67h (address-size prefix) does not affect JMP/Jcc instructions.
> |66h (operand-size prefix) does affect those, and
> |hex 66 E9 00 00 (JMP rel16 0) could be written as "AND EIP, 0FFFFh"
> (in |32-bit mode, that is.)
>
> Not exactly, it's (EIP+size_of_instr+displ) AND FFFFh

Here, displ=0 and you expect size_of_instr to get added to EIP for a
non-jumping instruction anyway.

But this is just nitpicking.

Bart


Henrik Nebrin

unread,
Apr 23, 2000, 3:00:00 AM4/23/00
to

Bart Oldeman skrev i meddelandet <8duvif$813$1...@bob.news.rcn.net>...

|On Fri, 21 Apr 2000, Henrik Nebrin wrote:
|
|> Bart Oldeman skrev i meddelandet ...
|> |
|> |On Thu, 20 Apr 2000, Henrik Nebrin wrote:
|> |
|> |> Bart Oldeman skrev i meddelandet ...
|> |> |
|> |> |so the code in hex: 67 0F 85 00 00 (JNZ rel16 0) ands EIP with
|> 0FFFFh in
|> |> |32-bit mode!
|> |>
|> |> Change the "67" to a "66" and it should work.
|> |
|> |I checked again and it seems both of us are wrong:
|> Where was I wrong?
|
|"66 0F 85 00 00" also eats the next two bytes, since the 66h does not
|influence the instruction.

Wrong! 66h is the operand size prefix and _IS_ used. The above code is
executed in a 32-bit code segemnt, and if no 66h prefix is used, the CPU
will fetch a 32-bit word. If the 66h prefix is used, then the CPU will only
read a 16-bit word.

[CS.D=1, i.e., 32-bit code segment]
660F850000 JNZ $+5

and NOT:

660F850000xxyy


Bart Oldeman

unread,
Apr 23, 2000, 3:00:00 AM4/23/00
to

On Sun, 23 Apr 2000, Henrik Nebrin wrote:

>
> Bart Oldeman skrev i meddelandet <8duvif$813$1...@bob.news.rcn.net>...
> |On Fri, 21 Apr 2000, Henrik Nebrin wrote:
> |
> |> Bart Oldeman skrev i meddelandet ...
> |> |
> |> |On Thu, 20 Apr 2000, Henrik Nebrin wrote:
> |> |
> |> |> Bart Oldeman skrev i meddelandet ...
> |> |> |
> |> |> |so the code in hex: 67 0F 85 00 00 (JNZ rel16 0) ands EIP with
> |> 0FFFFh in
> |> |> |32-bit mode!
> |> |>
> |> |> Change the "67" to a "66" and it should work.
> |> |
> |> |I checked again and it seems both of us are wrong:
> |> Where was I wrong?
> |
> |"66 0F 85 00 00" also eats the next two bytes, since the 66h does not
> |influence the instruction.
>
> Wrong!

Yes my fault.

67h is the address size prefix and is _NOT_ used.
I should have written:
"67 0F 85 00 00" also eats the next two bytes, since the 67h does not
influence the instruction.

> 66h is the operand size prefix and _IS_ used.
Yes.

> The above code is
> executed in a 32-bit code segemnt, and if no 66h prefix is used, the CPU
> will fetch a 32-bit word. If the 66h prefix is used, then the CPU will only
> read a 16-bit word.
>
> [CS.D=1, i.e., 32-bit code segment]
> 660F850000 JNZ $+5

Yes, and it ANDs EIP with 0FFFFh.

Summary from the first mail.
I was wrong in claiming that 67h influenced the instruction.
You were wrong in claiming that the 66h does not cause EIP to be ANDed
with 0FFFFh.

Bart


Henrik Nebrin

unread,
Apr 24, 2000, 3:00:00 AM4/24/00
to

Excuse me, but where did I say that? Here's my first reply:

<<<<<<<<<<<<<<<<<<<<<<<
Bart Oldeman skrev i meddelandet ...

|One caveat is that if you try to do a 16 bit relative jump in 32 bit mode,
|it ands EIP with 0FFFFh, and causes (e.g.) a segmentation fault under
|Linux.

Yes, Intel has also documented it if you look in the manual (esp., in the
JMP/Jcc pseudo code someplace in IADEVMAN2)

|


|so the code in hex: 67 0F 85 00 00 (JNZ rel16 0) ands EIP with 0FFFFh in
|32-bit mode!

Change the "67" to a "66" and it should work.
>>>>>>>>>>>>>>>>>>>>>

Read the last answer and tell me where I said that a 16-bit operand size
does NOT AND EIP with FFFFh.


Bart Oldeman

unread,
Apr 24, 2000, 3:00:00 AM4/24/00
to
On Mon, 24 Apr 2000, Henrik Nebrin wrote:

> |Summary from the first mail.
> |I was wrong in claiming that 67h influenced the instruction.
> |You were wrong in claiming that the 66h does not cause EIP to be ANDed
> |with 0FFFFh.
>
> Excuse me, but where did I say that? Here's my first reply:
>
> <<<<<<<<<<<<<<<<<<<<<<<
> Bart Oldeman skrev i meddelandet ...
> |One caveat is that if you try to do a 16 bit relative jump in 32 bit mode,
> |it ands EIP with 0FFFFh, and causes (e.g.) a segmentation fault under
> |Linux.
>
> Yes, Intel has also documented it if you look in the manual (esp., in the
> JMP/Jcc pseudo code someplace in IADEVMAN2)
>
> |
> |so the code in hex: 67 0F 85 00 00 (JNZ rel16 0) ands EIP with 0FFFFh in
> |32-bit mode!
>
> Change the "67" to a "66" and it should work.
> >>>>>>>>>>>>>>>>>>>>>
>
> Read the last answer and tell me where I said that a 16-bit operand size
> does NOT AND EIP with FFFFh.

Then it's merely in the interpretation of the word 'work':
I interpreted "it should work" as "it does a 16 bit relative jump and does
not AND EIP with FFFFh", because "work" to me means "work as intended".

You meant with "work": it goes that way, something like:
"Change the "67" to a "66" and your sentence is correct."

Fine. Sorry for the misinterpretation.

Bart


Nicolae Nasturica

unread,
Nov 22, 2021, 3:43:10 PM11/22/21
to
Pe miercuri, 19 aprilie 2000, la 10:00:00 UTC+3, Alexei A. Frounze a scris:
> Conditional jumps such as JZ or JNC, etc are limited to 127/128 bytes. You cant
> jump over 127 or 128 bytes backward or forward.
> If you had:
> ------8<-------
> JZ label1
> ------8<-------
> you should make it like this:
> ------8<-------
> JNZ label2
> JMP label1
> label2:
> ------8<-------
> this solves your problem.
> Good Luck
> Alexei A. Frounze
> -----------------------------------------
> Homepage: http://alexfru.chat.ru
> Mirror: http://members.xoom.com/alexfru
> vassone wrote:
> >
> > Can someone please explain why MASM is reporting "Jump out of range by
> > 130(bytes)
> >
> > What does this means?
> >
> > Any help would be very much appreciated..
> >
> > Vassone
> >
> > mailto:vas...@hotmail.com
> >
I like your games :)

wolfgang kern

unread,
Nov 23, 2021, 7:55:29 AM11/23/21
to
On 22/11/2021 20:16, Nicolae Nasturica posted:
---
>>> Can someone please explain why MASM is reporting "Jump out of range by
>>> 130(bytes)

because the range is a signed byte (+127..-128) and because MASM don't
know about long CC-instructions (perhaps it knows with hint "long"):

0F 8x 43 21 jmp cc rel+4+2143

versus short:
7x 12 jmp cc rel+2+12

both variants use signed values relative to the address after the jump.
__
wolfgang

Kerr-Mudd, John

unread,
Nov 24, 2021, 9:35:33 AM11/24/21
to
On Tue, 23 Nov 2021 07:40:41 +0100
wolfgang kern <now...@nospicedham.nevernet.at> wrote:

> On 22/11/2021 20:16, Nicolae Nasturica posted:
> ---
> >>> Can someone please explain why MASM is reporting "Jump out of
> >>> range by 130(bytes)
>
> because the range is a signed byte (+127..-128) and because MASM
> don't know about long CC-instructions (perhaps it knows with hint
> "long"):
>
> 0F 8x 43 21 jmp cc rel+4+2143

There are also the unconditional jmps
E9 xx xx jmp
EB xx jmp near[/short]
has the same +127-128 range, but means a slightly increased jmp
forward, ability as the jmp is from the address of the next op code.
>
> versus short:
> 7x 12 jmp cc rel+2+12
>
> both variants use signed values relative to the address after the
> jump. __
> wolfgang
>

It might be useful to someone here; but Alexei answered Vassone's
question back in 2000.


--
Bah, and indeed Humbug.

Terje Mathisen

unread,
Nov 24, 2021, 10:35:39 AM11/24/21
to
2000?

You young wippersnappers! :-)

This particular issue came up regularly even before the 808x was
invented, the solution was always the same, i.e. use some other method
for the far jump and a short branch past this code to avoid it.

TASM (maybe around 1986?) had options to handle this automatically: By
starting with the long jump macro at every branch location and then make
one or a couple of passes, nearly all of them could be converted to the
short form.

By starting with the long form

Long branch on Greater to target
jle $+3
jmp target

and then for each target checking the offset and if in the -128 to +127
range, convert to the two-byte form, no previously converted branch can
go out of range, so the process is stable. After 2 or 3 iterations
you'll probably find that either all of them are now short, or that no
more can be converted.

I think there were other assemblers which did the same trick.

Terje


--
- <Terje.Mathisen at tmsw.no>
"almost all programming can be viewed as an exercise in caching"

Kerr-Mudd, John

unread,
Nov 24, 2021, 12:35:48 PM11/24/21
to
I presume the 2nd jmp is the 3 byte version.

>
> and then for each target checking the offset and if in the -128 to
> +127 range, convert to the two-byte form, no previously converted
> branch can go out of range, so the process is stable. After 2 or 3
> iterations you'll probably find that either all of them are now
> short, or that no more can be converted.
>
> I think there were other assemblers which did the same trick.
>
Nasm does; if I spot this I try re-ordering my code to remove them.
>
>
> --
> - <Terje.Mathisen at tmsw.no>
> "almost all programming can be viewed as an exercise in caching"
>


Reply all
Reply to author
Forward
0 new messages