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 !
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.
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
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)
> 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 ...".
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
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.
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)
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
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
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
mov ECX,5
_loop:
;your code
loop _next
;break code or "jmp _exit"
_next:
jmp _loop
_exit: