News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Jump destination too far

Started by Technomancer, June 27, 2006, 02:22:15 PM

Previous topic - Next topic

Technomancer

I tried doing a loop at the end of my program before exiting to make it "refresh" 5 times.

So i did the standard mov ecx,5 ... loop start etc and i got an error saying  my Jump destintion is too far by "286 bytes". I have to end up doing :

mov ecx,5
start:
..CODES HERE...
cmp ecx,0
jz quit
dec ecx
jmp start

and the assembler is satisfied with this. But i am sure there are better alternatives. Can you guys provide some better examples where i can use an instruction like loop but yet avoid the error of jump destination being too far.

Another problem is that i am using ECX as my loop counter. As you can see i only want my program to "refresh" 5 times but it kept refreshing (infinite loop). I think it is probably because some of the macros or whatever i use in my codes modified ECX without me knowing.

So can someone also suggest another alternative where i can make the program "refresh" 5 times (i already tried using other registers as the counter, but the program kept going in an infinite loop too) Any macros or win32 api function i can use to "refresh" a program 5 times? Any other better way to program this will be appreciated too. Thanks !

hutch--

Try something like this.


  push esi

  mov esi, 5
lbl:
  ; run code here
  sub esi, 1
  jnz lbl

  pop esi


I have used ESI rather than ECX because ECX is a volatile register that often gets overwritten by called procedures.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

Ratch

Technomancer,

     Or if you don't want to use a register, use the stack instead.  Be aware, however, that any changes to the ESP will have to be compensated before the loop counter referenced by ESP is read/written.  Ratch

PUSH 5
@@:
   ; LOTSA CODE HERE
   ; LOTS MORE CODE HERE
DEC D[ESP]
JNZ @B
POP EAX ; or ADD ESP,DWORD to balance stack

P1

Quote from: Technomancer on June 27, 2006, 02:22:15 PM
mov ecx,5
start:
..CODES HERE...
cmp ecx,0
jz quit
dec ecx
jmp start

mov ecx,5
start:
..CODES HERE...
cmp ecx,0
jz quit_s
dec ecx
jmp start
quit_s:
jmp quit
To fix a short jmp out of range problem.  Put a label within range, use a normal jmp to the out of range label.

Regards,  P1  :8)

japheth

> To fix a short jmp out of range problem.  Put a label within range, use a normal jmp to the out of range label.

the "JZ label" will not get out of range on a 80386 (unless you use the "SHORT" modifier), so your suggestion doesn't make much sense. Technomancer used the "LOOP" opcode, however, which still has a -128 to +127 range even on a 80386+.

As a sidenote to technomancer: to use "LOOP" is not recommended anymore, because it is slower than "DEC ECX JNZ ...".

Mark Jones

Quote from: Technomancer on June 27, 2006, 02:22:15 PM
So can someone also suggest another alternative where i can make the program "refresh" 5 times

Sure. :U


start:
    invoke myFunc
    invoke myFunc
    invoke myFunc
    invoke myFunc
    invoke myFunc
    invoke ExitProcess,0
end start
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

tenkey

MASM 6 defaults to assembling only 8086/8088 code.

Specify a processor to enable the long Jcc jumps.

If your first two lines are

.586
.model flat

then you will eliminate the "long jump" problem.
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

P1

Sometimes, it's Ok to answer the question at hand.

He really did not give much detail to what he was doing.  16bit vs. 32bit.  or uP directives, etc.

I simple remember doing a 16 bit software robot challenge once, back long ago.  So I knew the error was real without asking him what he was doing. 

Maybe he is antique software dealer   :lol

Regards,  P1  :8)

Mark Jones

Or, use a dreaded "global variable!" :bdg


.data?
    UhOh    dd ?
.code
start:
; all other code

    mov UhOh,5              ; preset UhOh to 5 counts
loopit:
    invoke/call/jmp to whatever you want to run 5 times
    sub UhOh,1              ; decrement UhOh, set zero flag
    jnz loopit              ; if zero flag NOT set, jump
    invoke ExitProcess,0    ; UhOh was zero, so exit...
   
end start
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

Technomancer

Thanks for all the help guys.

Well if the loop instruction is slower than dec ecx jnz #, i won't use loop anymore but ...

Ratch: Actually i thought of using the stack to be my "loop counter", but it is kind of messy to do so. May i know what is DEC D[ESP] though ? What is the D for ? This is a macro or something ? JNZ @B means JNZ to @@ but the 'B' here means backward/behind? Sorry, this is the first few attempt at programming in masm32, thanks.

Mark Jones: I guess for now i will use a loop with invoke/call like your example to "refresh" my program 5 times, thanks for the suggestion. By the way, if i used a jmp though, it will be an infinite loop again :bg

Ratch

Technomancer,

QuoteRatch: Actually i thought of using the stack to be my "loop counter", but it is kind of messy to do so. May i know what is DEC D[ESP] though ? What is the D for ? This is a macro or something ? JNZ @B means JNZ to @@ but the 'B' here means backward/behind? Sorry, this is the first few attempt at programming in masm32, thanks.

     If you put the loop counter on the stack, don't forget to remove it when the loop completes.  Also any references using ESP have to be compensated while inside the loop.  My fault, the "D" in DEC D[ESP] is EQU'd as D EQU DWORD PTR.  I should have supplied that EQU in the code I submitted.  @B is standard MASM.  Its counterpart, a forward jump is @F. Ratch

Rockphorr

        mov ECX,5
_loop:
       ;your code

        loop _next

       ;break code or "jmp _exit"

_next:
       jmp _loop
_exit:
Strike while the iron is hot - Бей утюгом, пока он горячий