[Ubuntu-zh] 懂GCC的老师们,求求您们了,一个鬼问题,这倒底是什么原因,先谢谢了!!
Peng潇湘竹影
pengdong1228在live.cn
星期二 七月 12 07:47:08 UTC 2011
先看头文件
text.h
代码:typedef struct S_atomic_t
{
volatile int indx;
} atomic_t;
typedef struct S_counter_t
{
atomic_t l;
int indx32;
}counter_t;
static inline void atomic_inc(atomic_t *v)
{
asm volatile("lock;" "incl %0"
: "+m" (v->indx));
}
static inline void atomic_incl(volatile int *indx)
{
asm volatile("lock;" "incl %0"
: "+m" (indx));
}
在看源文件
text.c
第一种是正确的结果:
大家请看
代码:#include "text.h"static counter_t du_count;void counter_update(){ atomic_inc(&du_count.l);}
第一种正确结果编译出来的汇编代码text.S:
大家请看:
代码: .file "text.c"
.text
.p2align 4,,15
.globl counter_update
.type counter_update, @function
counter_update:
pushl %ebp
movl %esp, %ebp
#APP
# 22 "text.h" 1
lock;incl du_count
# 0 "" 2
#NO_APP
popl %ebp
ret
.size counter_update, .-counter_update
.local du_count
.comm du_count,8,4
.section .note.GNU-stack,"",在progbits
好,大家看到的以上这种情况是绝对正确的,在来看看下面出问题的这种情况:
头文件还是上面那个相同的头文件text.h(我就不重复了)
来看下面出问题的源文件:
text.c
代码:#include "text.h"
static counter_t du_count;
void counter_update()
{
atomic_incl(&du_count.indx32);//注意这次调用的函数变了
}
第二种有问题的结果编译出来的汇编代码text.S:
大家请看:
代码: .file "text.c"
.text
.p2align 4,,15
.globl counter_update
.type counter_update, @function
counter_update:
pushl %ebp
movl %esp, %ebp
subl $16, %esp //大家看问题在这里开始了。
movl $du_count+4, -4(%ebp)//du_count+4正是&du_count.indx32的地址,它把这个地方的数据mov到好像是这个函数的调用栈帧里去了
#APP
# 36 好像"text.h" 1
lock;incl -4(%ebp)// 在把这个调用栈帧里的数加1 完事了 分两步 也不是和上面那样原子的对&du_count.indx32地址的数据加1了,我要得就是原子执行加1
# 0 "" 2
#NO_APP
leave //清理栈 数据也丢了
ret //返回了 &du_count.indx32地方的数据还是原来的数据
.size counter_update, .-counter_update
.local du_count
.comm du_count,8,4
.section .note.GNU-stack,"",在progbits
编译选项都是 gcc -O2 -S -fno-ident -Wall -fno-builtin -fno-stack-protector text.S text.c
gcc -O2 -c -fno-ident -Wall -fno-builtin -fno-stack-protector text.o text.c
我想问的问题是为什么 对于结构
typedef struct S_atomic_t
{
volatile int indx;
} atomic_t;
是对的 而对于一个整形娈量&du_count.indx32就不行了 编译处理都是地址 一个结构体的地址 一个是整形变量的地址 并且atomic_t的地址的atomic_t.indx地址上是重叠的是相等的
而为什么编译器编译出的却是两种结果,有一种还是错的(注意一定要是原子执行加一)为什么呢????大家都说说啊,先谢谢了
-------------- 下一部分 --------------
一个HTML附件被移除...
URL: <https://lists.ubuntu.com/archives/ubuntu-zh/attachments/20110712/a85e0b76/attachment.html>
关于邮件列表 ubuntu-zh 的更多信息