Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Converting loops to GOTO statements.
#1
If, theoretically, I want to convert:

Code:
for i% = start1% to end1% step1%
next i%

Is this the correct code?

Code:
i% = start%
A1:
IF i% > end1% THEN GOTO C1
i% = i% + step1%
B1:
GOTO A1
C1:

I tried it out, and it seems to be the correct code, but it performs slower than a for loop. Some (I think) ignorant people suggested it's easier just because a for loop is simpler, but I don't think compiled code has for loops...
Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."

Visit www.neobasic.net to see rubbish in all its finest.
Reply
#2
Aga,
Yes, the FOR loop will run faster than your code. Whe the compiler generates code for a FOR loop, it generates very efficient code. To equal that without using FOR, you would have to take a look at the generated code by using DEBUG, and then try to do the same thing with individual instructions.
Code:
i% = start%
A1:
IF i% > end1% THEN GOTO C1
i% = i% + step1%
B1:
GOTO A1
C1:
You could streamline you code a little, as follow:
Code:
i% = start%
A1:
i% = i% + 1
IF i% <= end1% then GOTO A1
This increments 1 beyond end1%, but so does a FOR.
*****
Reply
#3
No:

start1% = 1
end1% = 0
step1% = 1

Your example doesn't check that immediately, but a FOR loop does.

But I still don't understand why a FOR loop would be any better..
Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."

Visit www.neobasic.net to see rubbish in all its finest.
Reply
#4
Aga,

Your original goto code didn't check the zero ending case either.

The FOR is better because, like I said before, the compiler generates more efficient code. It's possible that you cannot write straightline code which generates code as good. I read somewhere that in assembler there is a sequence of instructions operationally very similar to a FOR/NEXT loop. Therefore this is what the compiler generates. Soory, but I'm not an expert on this subject.
*****
Reply
#5
Yea agamemnus: Moneo is right. A FOR loop is translated to machine code (more or less efficiently) and your "low level FOR" in QB translates to machine code with more memory-to-register movs and additions using memory as destination:

Code:
0066   000E    FOR i% = start% TO end1% STEP step1%
0066    **            I00005: mov   ax,offset <const>
0069    **                    push  ax
006A    **                    call  B$PESD
006F    **                    mov   ax,END1%
0072    **                    mov   t%,ax
0075    **                    mov   ax,STEP1%
0078    **                    mov   t%,ax
007B    **                    mov   ax,START%
007E    **                    jmp   I00007
0082   0012    NEXT i%
0081    **            I00008: add   ax,t%
0086    **            I00007: mov   I%,ax
0089    **                    cmp   word ptr t%,00h
008E    **                    jl    $+03h
0090    **                    jmp   I00009
0093    **                    cmp   ax,t%
0097    **                    jnl   $-17h
0099    **                    jmp   I00010
009C    **            I00009: cmp   ax,t%
00A0    **                    jng   $-20h

And your "low level loop" translates to this:

Code:
0030   0006    A1:
0030    **            I00002: mov   ax,offset <const>
0033    **                    push  ax
0034    **                    call  B$PESD
0039    **                    mov   START%,0000h
003F    **                    mov   END1%,000Ah
0045    **                    mov   STEP1%,0001h
004B    **                    mov   ax,START%
004E    **                    mov   I%,ax
0051   000E    IF i% > end1% THEN GOTO C1
0051    **            I00003: mov   ax,END1%
0054    **                    cmp   ax,I%
0058    **                    jnl   $+03h
005A    **                    jmp   I00005
005D   000E    i% = i% + step1%
005D   000E    B1:
005D    **                    mov   ax,STEP1%
0060    **                    add   I%,ax
0064   000E    GOTO A1
0064   000E    C1:
0064    **            I00006: jmp   $-15h

Note that the add which makes you accumulator increase is done differently in each portion of code (in the FOR loop you just increase a variable in the QB very own data segment, but in your loop it increases i% with Step% which means two accesses to far memory), plus there is more interaction with memory in a far segment in your code (that t% variable defined in the for LOOP is faster to access that your variables).
SCUMM (the band) on Myspace!
ComputerEmuzone Games Studio
underBASIC, homegrown musicians
[img]http://www.ojodepez-fanzine.net/almacen/yoghourtslover.png[/i
Reply
#6
Quote:Aga,

Your original goto code didn't check the zero ending case either.

Er, oh.

So it's ">=" instead.. oops..

EDIT: Nathan, how do I check the debug code myself (if I want to check what >= looks like, for a better comparison of the code?)

***EDIT, AGAIN***:

I just realized that I messed up describing the two FOR statements to you all. The second one used one less variable and one more constant. Smile

I tried 4 million loops, and the timing is -----the same!!-----. So it must be the same ASM code, This Time! Smile

Code:
CLS
start% = 0
end1% = 1
step1% = 1
GOSUB try1
GOSUB try2
SLEEP
SYSTEM

try1:
t1# = TIMER
FOR j& = 1 TO 4000000
i% = start%
1 IF i% >= end1% THEN GOTO 2
i% = i% + step1%
GOTO 1
2 NEXT j&
t2# = TIMER

try2:
t1# = TIMER
FOR j& = 1 TO 4000000
FOR i% = start1% TO end1% STEP step1%
NEXT i%
NEXT j&
t2# = TIMER
PRINT t2# - t1#
RETURN
Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."

Visit www.neobasic.net to see rubbish in all its finest.
Reply
#7
Aga,
One caveat about using TIMER. If you are testing right around midnight on your machine, the TIMER will wrap back to zero, and you could get some weird elapsed times.
*****
Reply
#8
Moneo, for a test case like that, that he just made up to test it, you would understand that he wouldn't bother to put midnight support in. It's called the 20%/80% theory (If you've heard of it). His code was just to show the algo.
Reply
#9
Aga, to get the ASM code I did:

Code:
BC /A

When I was asked, I entered the .BAS name, then the .OBJ name and in the LISTING file I entered ASM.LST for example. You get the ASM listing in the LISTING file.
SCUMM (the band) on Myspace!
ComputerEmuzone Games Studio
underBASIC, homegrown musicians
[img]http://www.ojodepez-fanzine.net/almacen/yoghourtslover.png[/i
Reply
#10
Quote:Moneo, for a test case like that, that he just made up to test it, you would understand that he wouldn't bother to put midnight support in. It's called the 20%/80% theory (If you've heard of it). His code was just to show the algo.
Yes,Oracle, I just mentioned the bit about midnight in case he hadn't thought about it, for future reference.

Yes, the rule of 20/80, also known as the rule of Pareto, is well known, meaning that with 20% of the total effort you can solve 80% a task, but to finish the remaining 20% of the task will take 80% of the effort. Doing something "quick and dirty" is often referred as doing a 20/80 or a Pareto.
*****
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)