Weird code

George Robbert ghr at wucs.UUCP
Sun Oct 20 05:51:45 AEST 1985


>Ok you wizards out there, why does this program do what it does?
>Here are a couple of hints:
>	1) It only works on Vaxes
>	2) The same idea is used to initialize the UNIBUS adapters
>main()
>{
>        register int x, y;
>        int i;
>        int func();
>
>        fix((int *)func);
>        x = 1; y = 5;
>        for (i = 1; i <= 10; i++) {
>                func(1,5);
>                printf("x = %d, y = %d\n",x,y);
>        }
>}
>func(x,y)
>int x,y;
>{
>        register int a,b;
>
>        a += a; b *= 5;
>        x--; y++;
>}
>
>fix(f)
>int *f;
>{
>        *f &= ~0xc00;
>}
>% cc reg.c -N -o reg
>% reg
>x = 2, y = 25
>x = 4, y = 125
>x = 8, y = 625
>x = 16, y = 3125
>x = 32, y = 15625
>x = 64, y = 78125
>x = 128, y = 390625
>x = 256, y = 1953125
>x = 512, y = 9765625
>x = 1024, y = 48828125
>Brian Justice, Iowa State University
>UUCP: {okstate||umn-cs||csu-cs}!isucs1!justice	 CSNET: justice at iowa

The reason that you get the strange behavior of x and y is due
to fix's clearing 2 bits of the register save mask for func().
All functions on the VAX begin with a word (16 bit) that is the register 
save mask.  This word indicates which registers should be pushed on
the stack at function call time and restored on return.  Bit n set
corresponds to saving register n.  Therefore, *f &= ~0xc00; clears the 
mask for r10 and r11.  These just happen to be the two registers that
x and y are stored in.  They also happen to be the ones that a and b
are stored in.  Thus, since they are not saved and restored when
func(1,5) is called, the changes to a and b are actually changes to 
x and y.  This is why the code does what it does on the VAX.  I don't 
know why they do this to initialize unibus adapters. (except maybe
to minimize function call overhead by reducing the registers saved &
restored at each call.)

George Robbert,  Washington University
ghr at wucs.UUCP		...!ihnp4!wucs!ghr



More information about the Comp.unix.wizards mailing list