While-Wend loops are rejecting, Repeat-Until loops are not.
So far, so trivial. But what about for .. next loops? I thought googling would help, but maybe I'm using the wrong terms. Is there a more technical term than rejecting/non-rejecting loop?
Gfa and VB use rejecting loops. VB example:
Sub TestForLoop()
Debug.Print "Start"
For cols = 0 To -1
Debug.Print Str$(cols)
Next
Debug.Print "End"
End Sub
A C loop like for (ct=1;ct<1;ct++){myvar+=1;} is also rejecting, but that case is imho not fully comparable.
What about FreeBasic and PB?
If its only the semantics, PB has a DO / LOOP where you set your own conditionals.
DO WHILE (your condition)
LOOP
---
DO
LOOP WHILE (your condition)
Thanks, Hutch.
The PBCC page (http://www.powerbasic.com/support/help/pbcc/for_next_statements.htm) says this:
QuoteFOR Counter = start TO stop [STEP increment]
NEXT
The body of the loop is skipped altogether if the initial value of Counter is greater than stop
FreeBasic is a bit cryptic, "Putting a larger number first will not make a for-next loop count backwards" (http://gamedesign.wikidot.com/freebasic:learning-freebasic-made-quick-and-easy), but that seems to mean it's rejecting, too.
PureBasic does not give info (http://www.purebasic.com/documentation/reference/for_next.html) ::)
Anyway, it seems that rejecting is pretty much standard...
Here is a for loop in VS C++ 2010 Express:
; for (ct=0x1111;ct<0x2222;ct++){myvar+=0x3333;}
mov ct, 1111h
jmp L2
align 4
L1: mov eax, ct
add eax, 1
mov ct, eax
L2: cmp ct, 2222h
jge short L3
mov eax, myvar
add eax, 3333h
mov myvar, eax
jmp L1
L3:Same with Pelles C:
mov ct, 1111h
jmp L2
align 4
L1: add myvar, 3333h
inc ct
L2: cmp ct, 2222h
jl L1
Would not the key difference be in where the exit condition is tested? I think the correct terminology is pre-test loop and post-test loop.
dim as integer i
asm while_wend:
while i < 2
i += 1
wend
asm do_while_loop:
do while i < 2
i += 1
loop
asm do_loop_until:
do
i += 1
loop until i = 2
asm for_next:
for i = 0 to 2
next
.intel_syntax noprefix
#test.bas' compilation started at 19:34:39 (FreeBASIC 0.90.1)
.section .text
.balign 16
.globl _main
_main:
push ebp
mov ebp, esp
and esp, 0xFFFFFFF0
sub esp, 8
push ebx
push esi
push edi
mov dword ptr [ebp-4], 0
call ___main
push 0
push dword ptr [ebp+12]
push dword ptr [ebp+8]
call _fb_Init@12
.Lt_0002:
mov dword ptr [ebp-8], 0
while_wend:
.Lt_0004:
cmp dword ptr [ebp-8], 2
jge .Lt_0005
inc dword ptr [ebp-8]
jmp .Lt_0004
.Lt_0005:
do_while_loop:
.Lt_0006:
cmp dword ptr [ebp-8], 2
jge .Lt_0007
inc dword ptr [ebp-8]
jmp .Lt_0006
.Lt_0007:
do_loop_until:
.Lt_0008:
inc dword ptr [ebp-8]
.Lt_000A:
cmp dword ptr [ebp-8], 2
jne .Lt_0008
.Lt_0009:
for_next:
mov dword ptr [ebp-8], 0
.Lt_000E:
.Lt_000C:
inc dword ptr [ebp-8]
.Lt_000B:
cmp dword ptr [ebp-8], 2
jle .Lt_000E
.Lt_000D:
.Lt_0003:
push 0
call _fb_End@4
mov eax, dword ptr [ebp-4]
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
#test.bas' compilation took 0.0004873414805022236 secs
JJ,
I am not exactly sure what you are after, something like a code design to match the semantics of FOR / NEXT ? I tend to agree with Michael on where the test is performed in the instruction sequence.
Simple example of the loops but not sure it matches what you are after.
IF 0 ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Build this template with "CONSOLE ASSEMBLE AND LINK"
ENDIF ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\masm32rt.inc
.code
start:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
call main
inkey
exit
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
LOCAL cntr :DWORD
LOCAL lcnt :DWORD
; ***********************************************
mov cntr, 0
mov lcnt, 100
lp1: ; one iteration test on exit.
add cntr, 1
mov eax, lcnt
cmp cntr, eax
jbe lp1
; ***********************************************
mov cntr, 0
mov lcnt, 100
jmp inhere
lp2: ; no iteration test on exit.
add cntr, 1
inhere:
mov eax, lcnt
cmp cntr, eax
jbe lp2
; ***********************************************
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start
Quote from: hutch-- on January 25, 2014, 01:39:56 PM
JJ,
I am not exactly sure what you are after, something like a code design to match the semantics of FOR / NEXT ?
Yes, of course - code design to match the typical Basic For ... Next loop (example here (http://masm32.com/board/index.php?topic=94.msg30125#msg30125)).
I just was not sure what is the Basic standard:
- reject if begin>end, as in While ... Wend
- dive in once even if begin>end, as in Repeat ... Until
It seems that most Basic dialects reject, i.e. use the While ... Wend design; however, Michael's example is confusing me in this respect:
for_next:
mov dword ptr [ebp-8], 0
.Lt_000E:
inc dword ptr [ebp-8]
.Lt_000B:
cmp dword ptr [ebp-8], 2
jle .Lt_000EThis is FreeBasic, right?
Quote from: jj2007 on January 25, 2014, 02:27:06 PM
This is FreeBasic, right?
Yes, the most recent release:
http://www.freebasic.net/forum/viewtopic.php?f=1&t=21382
Compiled with the GAS backend code emitter:
http://www.freebasic.net/wiki/wikka.php?wakka=CompilerOptgen
The for next loop is a pure counting loop, not only in BASIC. By the way, is FreeBasic worth a try?
Gunther
Quote from: MichaelW on January 25, 2014, 08:22:06 PM
Yes, the most recent release
Mystery solved - it's a clever compiler which drops the pre-test when used with two immediate integers. With variables, the test is there:
jmp short 004015C5
...
jmp short 00401604loopStart=0
loopEnd=2
asm int 3
asm nop
asm for_next:
for i = loopStart to loopEnd
print "test 0 to 2"
next
loopStart=2
loopEnd=0
asm int 3
asm nop
asm for_next2:
for i = loopStart to loopEnd
print "test 2 to 0"
next
... translates to ...
0040158E ³. C745 F4 00000000 mov dword ptr [ebp-0C], 0
00401595 ³. C745 F0 02000000 mov dword ptr [ebp-10], 2
0040159C ³. CC int3
0040159D ³. 90 nop
0040159E ³. 8B45 F4 mov eax, [ebp-0C]
004015A1 ³. 8945 F8 mov [ebp-8], eax
004015A4 ³. 8B45 F0 mov eax, [ebp-10]
004015A7 ³. 8945 EC mov [ebp-14], eax
004015AA ³. EB 19 jmp short 004015C5
004015AC ³> 6A 01 Úpush 1
004015AE ³. 6A 0B ³push 0B ; ÚArg2 = 0B
004015B0 ³. 68 04504000 ³push offset 00405004 ; ³Arg1 = ASCII "test 0 to 2"
004015B5 ³. E8 36010000 ³call 004016F0 ; ÀLoopsMW.004016F0
004015BA ³. 50 ³push eax
004015BB ³. 6A 00 ³push 0
004015BD ³. E8 0E020000 ³call 004017D0
004015C2 ³. FF45 F8 ³inc dword ptr [ebp-8]
004015C5 ³> 8B45 EC +mov eax, [ebp-14]
004015C8 ³. 3945 F8 ³cmp [ebp-8], eax
004015CB ³. 7E DF Àjle short 004015AC
004015CD ³. C745 F4 02000000 mov dword ptr [ebp-0C], 2
004015D4 ³. C745 F0 00000000 mov dword ptr [ebp-10], 0
004015DB ³. CC int3
004015DC ³. 90 nop
004015DD ³. 8B45 F4 mov eax, [ebp-0C]
004015E0 ³. 8945 F8 mov [ebp-8], eax
004015E3 ³. 8B45 F0 mov eax, [ebp-10]
004015E6 ³. 8945 EC mov [ebp-14], eax
004015E9 ³. EB 19 jmp short 00401604
004015EB ³> 6A 01 Úpush 1
004015ED ³. 6A 0B ³push 0B ; ÚArg2 = 0B
004015EF ³. 68 10504000 ³push offset 00405010 ; ³Arg1 = ASCII "test 2 to 0"
004015F4 ³. E8 F7000000 ³call 004016F0 ; ÀLoopsMW.004016F0
004015F9 ³. 50 ³push eax
004015FA ³. 6A 00 ³push 0
004015FC ³. E8 CF010000 ³call 004017D0
00401601 ³. FF45 F8 ³inc dword ptr [ebp-8]
00401604 ³> 8B45 EC +mov eax, [ebp-14]
00401607 ³. 3945 F8 ³cmp [ebp-8], eax
0040160A ³. 7E DF Àjle short 004015EB
i recall that IBM BASIC had FOR..TO..STEP..NEXT
you could set the STEP to a negative value if you wanted to run backwards
FOR N=10 TO 1 STEP -1
...
NEXT
Quote from: Gunther on January 25, 2014, 09:20:59 PM
By the way, is FreeBasic worth a try?
I think so, if you like the BASIC syntax, or at least the FreeBASIC version of it that incorporates multiple C-like features.
Michael,
Quote from: MichaelW on January 26, 2014, 12:13:38 AM
I think so, if you like the BASIC syntax, or at least the FreeBASIC version of it that incorporates multiple C-like features.
thank you for the answer. Can one link in external assembly language procedures or is to use the inline assembler?
Gunther
Quote from: Gunther on January 26, 2014, 03:22:39 AM
Can one link in external assembly language procedures or is to use the inline assembler?
Either, the Win32 and Linux ports use stdcall as the default and the DOS port uses cdecl, and even with the GCC backend you can use Intel syntax for inline assembly, along with GAS macros, directives, etc.
Michael,
Quote from: MichaelW on January 26, 2014, 05:15:49 AM
Either, the Win32 and Linux ports use stdcall as the default and the DOS port uses cdecl, and even with the GCC backend you can use Intel syntax for inline assembly, along with GAS macros, directives, etc.
that's good news. I'll give it a try.
Gunther
Quote from: dedndave on January 25, 2014, 09:52:44 PM
i recall that IBM BASIC had FOR..TO..STEP..NEXT
you could set the STEP to a negative value if you wanted to run backwards
FOR N=10 TO 1 STEP -1
...
NEXT
Most Basic dialects do have STEP. I've looked into that, it would be feasible for MasmBasic's For ... Next loop, but it's a bit complex.
However, you gave me a REALLY good idea:
fld xInit ; REAL8 123.456 on FPU
fstp x1
.Repeat
fld x1
fadd FP8(0.0005) ; add 0.0005 to x1 (initially 123.456)
fstp x1
PrintLine Str$(x1)
.Until IsTrue(x1 ge x2) ; until x1 greater or equal x2 = 123.457Works like a charm, and allowed are
eq, ne, lt, gt, le, ge, i.e. same notation as in the macro language (of course, <, >, <>, <= and >= are off limits because of Masm's bad habit to treat <> as string delimiters...)
Testbed attached.