H
Herbert Kleebauer
As part of a simple X demo for Linux I send the byte string
in "send8" to the X server. This byte string displays a circle
at the x/y position send8.s8x/send8.s8y. In "display()" a 8x8
grid of circles is displayed. But when I compile the code
below with -O3, then in the "j" loop not send8.s8x is incremented
by 50 (send8.s8x += 50 but only a local copy of it. As a result,
the byte string sent to the X server (x_send((char*)&send8, sizeof(send8))
contains always the same x position for the circle. If I replace
"struct .." by "volatile struct .." all is ok. Is this a correct
behaviour of the compiler? Do I have to declare any global variable
"volatile" if I use only the address of the variable in a function
call?
struct {char a[2]; short b; int s8a,s8b; short s8x,s8y,c[4];}
send8={71,0,sizeof(send8)/4,0,0,0,0,50,50,0*64,360*64};
int eax, x_handle, brett[10][10];
void display();
void x_send();
void exit();
main()
{display();}
void display()
{int i,j;
send8.s8y=0;
for (i=1;i<9;i++)
{send8.s8x=0;
for (j=1;j<9;j++)
{if (brett[j]) x_send((char*)&send8, sizeof(send8));
send8.s8x += 50;
}
send8.s8y += 50;
}
}
/******************** send message to X server ****************************/
void x_send(p,n) char *p; int n;
{while (n)
{eax=-11;
const int par[]={x_handle, (int)p, n, 0};
while (eax == -11)
asm volatile ("int $0x80":"=a" (eax): "0" (102), "b" (9), "c" (&par));
if (eax>=-4095) exit(0);
n -= eax; p += eax;
}
}
/**************************************************************************/
display:
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %esi
pushl %ebx
subl $44, %esp
movl x_handle, %eax
movw $0, send8+14
leal -28(%ebp), %ecx
movl $1, -48(%ebp)
movl $40, -52(%ebp)
movl %eax, -40(%ebp)
..L17:
movl -52(%ebp), %eax
movw $0, send8+12 <- send8.s8x
movl $1, -44(%ebp)
movw $0, -34(%ebp) <- local copy of send8.s8x
addl $brett, %eax
movl %eax, -32(%ebp)
..L18:
movl -32(%ebp), %eax
movl 4(%eax), %eax
testl %eax, %eax
je .L19
movl $send8, %edi
movl $24, %esi
movl $102, %edx
movl $9, %ebx
.p2align 4,,7
..L21:
movl -40(%ebp), %eax
movl $-11, eax
movl %edi, -24(%ebp)
movl %esi, -20(%ebp)
movl %eax, -28(%ebp)
movl $0, -16(%ebp)
.p2align 4,,7
..L22:
movl %edx, %eax
#APP
int $0x80
#NO_APP
cmpl $-11, %eax
je .L22
cmpl $-4095, %eax
movl %eax, eax
jge .L37
subl %eax, %esi
je .L19
addl %eax, %edi
jmp .L21
..L19:
addl $1, -44(%ebp)
addw $50, -34(%ebp) <- only the local copy is modified but not send8.s8x
addl $4, -32(%ebp)
cmpl $9, -44(%ebp)
jne .L18
addl $1, -48(%ebp)
addw $50, send8+14
addl $40, -52(%ebp)
cmpl $9, -48(%ebp)
movw $400, send8+12
jne .L17
addl $44, %esp
popl %ebx
popl %esi
popl %edi
popl %ebp
ret
in "send8" to the X server. This byte string displays a circle
at the x/y position send8.s8x/send8.s8y. In "display()" a 8x8
grid of circles is displayed. But when I compile the code
below with -O3, then in the "j" loop not send8.s8x is incremented
by 50 (send8.s8x += 50 but only a local copy of it. As a result,
the byte string sent to the X server (x_send((char*)&send8, sizeof(send8))
contains always the same x position for the circle. If I replace
"struct .." by "volatile struct .." all is ok. Is this a correct
behaviour of the compiler? Do I have to declare any global variable
"volatile" if I use only the address of the variable in a function
call?
struct {char a[2]; short b; int s8a,s8b; short s8x,s8y,c[4];}
send8={71,0,sizeof(send8)/4,0,0,0,0,50,50,0*64,360*64};
int eax, x_handle, brett[10][10];
void display();
void x_send();
void exit();
main()
{display();}
void display()
{int i,j;
send8.s8y=0;
for (i=1;i<9;i++)
{send8.s8x=0;
for (j=1;j<9;j++)
{if (brett[j]) x_send((char*)&send8, sizeof(send8));
send8.s8x += 50;
}
send8.s8y += 50;
}
}
/******************** send message to X server ****************************/
void x_send(p,n) char *p; int n;
{while (n)
{eax=-11;
const int par[]={x_handle, (int)p, n, 0};
while (eax == -11)
asm volatile ("int $0x80":"=a" (eax): "0" (102), "b" (9), "c" (&par));
if (eax>=-4095) exit(0);
n -= eax; p += eax;
}
}
/**************************************************************************/
display:
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %esi
pushl %ebx
subl $44, %esp
movl x_handle, %eax
movw $0, send8+14
leal -28(%ebp), %ecx
movl $1, -48(%ebp)
movl $40, -52(%ebp)
movl %eax, -40(%ebp)
..L17:
movl -52(%ebp), %eax
movw $0, send8+12 <- send8.s8x
movl $1, -44(%ebp)
movw $0, -34(%ebp) <- local copy of send8.s8x
addl $brett, %eax
movl %eax, -32(%ebp)
..L18:
movl -32(%ebp), %eax
movl 4(%eax), %eax
testl %eax, %eax
je .L19
movl $send8, %edi
movl $24, %esi
movl $102, %edx
movl $9, %ebx
.p2align 4,,7
..L21:
movl -40(%ebp), %eax
movl $-11, eax
movl %edi, -24(%ebp)
movl %esi, -20(%ebp)
movl %eax, -28(%ebp)
movl $0, -16(%ebp)
.p2align 4,,7
..L22:
movl %edx, %eax
#APP
int $0x80
#NO_APP
cmpl $-11, %eax
je .L22
cmpl $-4095, %eax
movl %eax, eax
jge .L37
subl %eax, %esi
je .L19
addl %eax, %edi
jmp .L21
..L19:
addl $1, -44(%ebp)
addw $50, -34(%ebp) <- only the local copy is modified but not send8.s8x
addl $4, -32(%ebp)
cmpl $9, -44(%ebp)
jne .L18
addl $1, -48(%ebp)
addw $50, send8+14
addl $40, -52(%ebp)
cmpl $9, -48(%ebp)
movw $400, send8+12
jne .L17
addl $44, %esp
popl %ebx
popl %esi
popl %edi
popl %ebp
ret