A little byte problem
BlitzMax Forums/BlitzMax Beginners Area/A little byte problem Very stange.
Works fine on the Mac!
Must be a bug in the x86 code...
Must be a bug in the x86 code...
yep, runs forever on x86 version here too
yes it will only run up to 254
without the print get follow asm code
look here
_3:
add byte [edx],1
_9:
movzx eax,byte [edx]
cmp eax,255 !
jle _5 !
_4:
mov eax,0
jmp _6
_6:
pop ebp
ret
without the print get follow asm code
look here
_3:
add byte [edx],1
_9:
movzx eax,byte [edx]
cmp eax,255 !
jle _5 !
_4:
mov eax,0
jmp _6
_6:
pop ebp
ret
Hehehehee bmx on x86 adds one to the variable and then checks to see if it is over the loop's count limit. By that time, the variable has reset to 0 ;]
It's the same for regular integers.
Apparently this bug was always in Blitz, but nobody noticed.
I guess there's not much call for loops that go up to 2147483647.
Apparently this bug was always in Blitz, but nobody noticed.
I guess there's not much call for loops that go up to 2147483647.
ive not come across this, and ive written a simple emulator that did 0-255....
oh wait.. there were no "bytes" in blitz.. so it would work with those values.. hmm...
I must say, this is interesting. Mark, whats the plan? ^.^
oh wait.. there were no "bytes" in blitz.. so it would work with those values.. hmm...
I must say, this is interesting. Mark, whats the plan? ^.^
ive not come across this, and ive written a simple emulator that did 0-255....
oh wait.. there were no "bytes" in blitz.. so it would work with those values.. hmm...
I must say, this is interesting. Mark, whats the plan? ^.^
its okay for this to wrap forever as its understandable, (well, as a programmer used to 6502, 8 bit assembler)
however the following realy should work. maybe a simple clause will fix it in the compiler? i dont know. i know as much about Bmax's infrastructure as i do x86 assembly... hehehe. (nothing by the way)
oh wait.. there were no "bytes" in blitz.. so it would work with those values.. hmm...
I must say, this is interesting. Mark, whats the plan? ^.^
its okay for this to wrap forever as its understandable, (well, as a programmer used to 6502, 8 bit assembler)
Global b:Byte = 0 While b < 256 Print b b:+1 End While
however the following realy should work. maybe a simple clause will fix it in the compiler? i dont know. i know as much about Bmax's infrastructure as i do x86 assembly... hehehe. (nothing by the way)
Global b:byte For b=0 To 255 Print b Next
@JimB
The 1 to 5 loop works here. Are you sure the 1 was missing?
I've gotten seriously confused by apparently missing console output. Sometimes the window will scroll down even when the output is nowhere near the bottom.
The 1 to 5 loop works here. Are you sure the 1 was missing?
I've gotten seriously confused by apparently missing console output. Sometimes the window will scroll down even when the output is nowhere near the bottom.
@jimb
will work here
framework brl.basic
Local b:Byte
For b=1 To 5
Print b
next
1
2
3
4
5
will work here
framework brl.basic
Local b:Byte
For b=1 To 5
Print b
next
1
2
3
4
5
yes it will only run up to 254
Huh? Runs up to 255 here...JimBs example also prints the one here.
What kind of CPU's has everyone got?
@Floyd,
Mmmm, bizzare. it works now.
Restarting the IDE (Win32 Beta) must have cured the output fault.
@FD,
CPU=Pentium 4 Mobile 3.06Ghz
Mmmm, bizzare. it works now.
Restarting the IDE (Win32 Beta) must have cured the output fault.
@FD,
CPU=Pentium 4 Mobile 3.06Ghz
if you make it a local it works here, but global keeps looping??
CPU=3.2Ghz P4
CPU=3.2Ghz P4
if you make it a local it works here, but global keeps looping??
Yeah same here. Wierd that.CPU = 3.6 GHz Prescott.
It kind of makes sense, because I bet globals are being written to memory and read in again, whereas the local version will be stored in a register pernamently.
That's exactly what's happenning.
My interpretation is this:
Because you are asking for your loop variable to be a byte, and the biggest value you can store in a byte is 255, I think the For..Next loop perhaps adds 1 to the loop value PRIOR to testing to see if it is *greater than* the highest amount of the loop counter ie 255. So it would go something like this:
Counter is at 253
Do the loop with counter at 253
Add 1 to the loop counter
Is the counter>255? no, its 254, loop round
Counter is at 254
Do the loop with counter at 254
Add 1 to the loop counter
Is the counter >255 .... counter is now 255 but not >255, loop around
Counter is at 255
Do the loop with counter at 255
Add 1 to the loop counter - should be 256 but 256 in binary is %100000000 and since the variable is only a byte, the `1` bit is ignored - it thinks counter=%00000000
Is the counter>255? ... should be yes but it only reads Counter as a byte which has gone beyond its numerical range, so Counter=0, keep looping
and looping
and loping forever because this keeps happening.
That's my take on it. The loop counter is checking for a number greater than the loop limit, and adds the step to the counter at the END of each loop, BEFORE deciding whether to do another iteration. So if your loop limit is equal to the maximum number that can be stored in a variable of a given type (ie byte word long etc), there is an `overflow` that accidentally produces a value of 0 again, keeping the loop going.
If this is true, you could *probably* test it by also doing a short/word sized loop, going from 0 to 65535, and when it reaches 65535 the counter should internally become %10000000000000000 (65536), even though only the lower 16-bits are recognized (=0).
Maybe someone can test if this is the reason behind it. If so, maybe the Blitz developers need to come up with a fix to this design flaw.
I am also expecting that when you define the Counter as a Local, it works, because Locals are kept in registers which are usually 32-bit, and I expect there is no difference in speed between comparing a byte value and comparing a long value, so it probably knows that the number reaches 256 instead of seeing it as 0?
If this isn't exactly the reasoning behind it my second guess is perhaps the loop-counter value is held in an `immediate` value in assembly language, ie something like cmp #255,register, and really it needs to be a 16-bit compare in order to avoid the overflow problem?
Feedback please.
Because you are asking for your loop variable to be a byte, and the biggest value you can store in a byte is 255, I think the For..Next loop perhaps adds 1 to the loop value PRIOR to testing to see if it is *greater than* the highest amount of the loop counter ie 255. So it would go something like this:
Counter is at 253
Do the loop with counter at 253
Add 1 to the loop counter
Is the counter>255? no, its 254, loop round
Counter is at 254
Do the loop with counter at 254
Add 1 to the loop counter
Is the counter >255 .... counter is now 255 but not >255, loop around
Counter is at 255
Do the loop with counter at 255
Add 1 to the loop counter - should be 256 but 256 in binary is %100000000 and since the variable is only a byte, the `1` bit is ignored - it thinks counter=%00000000
Is the counter>255? ... should be yes but it only reads Counter as a byte which has gone beyond its numerical range, so Counter=0, keep looping
and looping
and loping forever because this keeps happening.
That's my take on it. The loop counter is checking for a number greater than the loop limit, and adds the step to the counter at the END of each loop, BEFORE deciding whether to do another iteration. So if your loop limit is equal to the maximum number that can be stored in a variable of a given type (ie byte word long etc), there is an `overflow` that accidentally produces a value of 0 again, keeping the loop going.
If this is true, you could *probably* test it by also doing a short/word sized loop, going from 0 to 65535, and when it reaches 65535 the counter should internally become %10000000000000000 (65536), even though only the lower 16-bits are recognized (=0).
Maybe someone can test if this is the reason behind it. If so, maybe the Blitz developers need to come up with a fix to this design flaw.
I am also expecting that when you define the Counter as a Local, it works, because Locals are kept in registers which are usually 32-bit, and I expect there is no difference in speed between comparing a byte value and comparing a long value, so it probably knows that the number reaches 256 instead of seeing it as 0?
If this isn't exactly the reasoning behind it my second guess is perhaps the loop-counter value is held in an `immediate` value in assembly language, ie something like cmp #255,register, and really it needs to be a 16-bit compare in order to avoid the overflow problem?
Feedback please.
I am also expecting that when you define the Counter as a Local, it works, because Locals are kept in registers which are usually 32-bit, and I expect there is no difference in speed between comparing a byte value and comparing a long value, so it probably knows that the number reaches 256 instead of seeing it as 0?
I'm thinking this sounds probable.