Bit-Banging a counter

Here's a bit of code that I thought that I would share. It comes from a PLC (Programmable Logic Controllers) website, and it's an example of how to count to "n" and then reset back to zero.

It was part of a friendly challenge that gets started from time-to-time among the guys there. I thought it was an elegant solution so I thought that I would share it here.

The question isn't what it does (it counts to 9 and then resets itself back to zero), but how it does it.


1
2
3
4
5
6
7
int main(){
	int I = 0;
	do{
		I = (I + 1) & ((I - 9) >> 16);
	}while (1);
	return 0;
}


Here's the link to the challenge:

http://www.plctalk.net/qanda/showthread.php?t=47158



Here's my thought on it after reading the thread:
Too complex. If the target processor has a div instruction, then good ol' (x+1)%n compiles to fewer instructions:
x=(x+1)&((x-n)>>16);
mov eax,dword ptr [x]
add eax,1
mov ecx,dword ptr [x]
sub ecx,dword ptr [n]
shr ecx,10h
and eax,ecx
mov dword ptr [x],eax


x=(x+1)%n;
mov eax,dword ptr [x]
add eax,1
xor edx,edx
div eax,dword ptr [n]
mov dword ptr [x],edx
You're right. I personally would never use something as obscure as this in any of my programs.

Usually we aren't so constricted in the way of timing (not like the motion control guys are anyways) so there's no need to get "cute" like this.

But if you are trying to control a fast process/loop, speed does count. And you can't count on a certain PLC processor having a div instruction (each manufacturer uses whatever they want to in the hardware department).

But yeah, if that ever showed up in my code I would deserve to be beaten about the head and shoulders. :)

Nonetheless, it is simple once you figure out how it works. :)
Topic archived. No new replies allowed.