ºìÁªLinuxÃÅ»§
Linux°ïÖú

GNUCÀ©Õ¹£ºLinux²Ù×÷ϵͳµÄÄÚºËʹÓÃ

·¢²¼Ê±¼ä:2006-05-10 01:04:55À´Ô´:ºìÁª×÷Õß:linux
GNC CC ÊÇÒ»¸ö¹¦Äܷdz£Ç¿´óµÄ¿çƽ̨ C ±àÒëÆ÷£¬Ëü¶Ô C ÓïÑÔÌṩÁ˺ܶàÀ©Õ¹£¬

ÕâЩÀ©Õ¹¶ÔÓÅ»¯¡¢Ä¿±ê´úÂë²¼¾Ö¡¢¸ü°²È«µÄ¼ì²éµÈ·½ÃæÌṩÁ˺ÜÇ¿µÄÖ§³Ö¡£±¾ÎÄ°Ñ

Ö§³Ö GNU À©Õ¹µÄ C ÓïÑÔ³ÆΪ GNU C¡£

Linux Äں˴úÂëʹÓÃÁË´óÁ¿µÄ GNU C À©Õ¹£¬ÒÔÖÁÓÚÄܹ»±àÒë Linux Äں˵ÄΨһ±à

ÒëÆ÷ÊÇ GNU CC£¬ÒÔÇ°ÉõÖÁ³öÏÖ¹ý±àÒë Linux ÄÚºËҪʹÓÃÌØÊâµÄ GNU CC °æ±¾µÄÇé

¿ö¡£±¾ÎÄÊÇ¶Ô Linux ÄÚºËʹÓÃµÄ GNU C À©Õ¹µÄÒ»¸ö»ã×Ü£¬Ï£Íûµ±Äã¶ÁÄÚºËÔ´ÂëÓö

µ½²»Àí½âµÄÓï·¨ºÍÓïÒåʱ£¬ÄÜ´Ó±¾ÎÄÕÒµ½Ò»¸ö³õ²½µÄ½â´ð£¬¸üÏêϸµÄÐÅÏ¢¿ÉÒԲ鿴

gcc.info¡£ÎÄÖеÄÀý×ÓÈ¡×Ô Linux 2.4.18¡£

Óï¾ä±í´ïʽ

==========

GNU C °Ñ°üº¬ÔÚÀ¨ºÅÖеĸ´ºÏÓï¾ä¿´×öÊÇÒ»¸ö±í´ïʽ£¬³ÆΪÓï¾ä±í´ïʽ£¬Ëü¿ÉÒÔ³ö

ÏÖÔÚÈκÎÔÊÐí±í´ïʽµÄµØ·½£¬Äã¿ÉÒÔÔÚÓï¾ä±í´ïʽÖÐʹÓÃÑ­»·¡¢¾Ö²¿±äÁ¿µÈ£¬Ô­±¾

Ö»ÄÜÔÚ¸´ºÏÓï¾äÖÐʹÓá£ÀýÈ磺

++++ include/linux/kernel.h

159: #define min_t(type,x,y) \

160: ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })

++++ net/ipv4/tcp_output.c

654: int full_space = min_t(int, tp->window_clamp, tcp_full_space(sk));

¸´ºÏÓï¾äµÄ×îºóÒ»¸öÓï¾äÓ¦¸ÃÊÇÒ»¸ö±í´ïʽ£¬ËüµÄÖµ½«³ÉΪÕâ¸öÓï¾ä±í´ïʽµÄÖµ¡£

ÕâÀﶨÒåÁËÒ»¸ö°²È«µÄÇó×îСֵµÄºê£¬ÔÚ±ê×¼ C ÖУ¬Í¨³£¶¨ÒåΪ:

#define min(x,y) ((x) < (y) ? (x) : (y))

Õâ¸ö¶¨Òå¼ÆËã x ºÍ y ·Ö±ðÁ½´Î£¬µ±²ÎÊýÓи±×÷ÓÃʱ£¬½«²úÉú²»ÕýÈ·µÄ½á¹û£¬Ê¹ÓÃ

Óï¾ä±í´ïʽֻ¼ÆËã²ÎÊýÒ»´Î£¬±ÜÃâÁË¿ÉÄܵĴíÎó¡£Óï¾ä±í´ïʽͨ³£ÓÃÓں궨Òå¡£

Typeof

======

ʹÓÃÇ°Ò»½Ú¶¨ÒåµÄºêÐèÒªÖªµÀ²ÎÊýµÄÀàÐÍ£¬ÀûÓà typeof ¿ÉÒÔ¶¨Òå¸üͨÓõĺ꣬²»

±ØÊÂÏÈÖªµÀ²ÎÊýµÄÀàÐÍ£¬ÀýÈ磺

++++ include/linux/kernel.h

141: #define min(x,y) ({ \

142: const typeof(x) _x = (x); \

143: const typeof(y) _y = (y); \

144: (void) (&_x == &_y); \

145: _x < _y ? _x : _y; })

ÕâÀï typeof(x) ±íʾ x µÄÖµÀàÐÍ£¬µÚ 142 Ðж¨ÒåÁËÒ»¸öÓë x ÀàÐÍÏàͬµÄ¾Ö²¿±ä

Á¿ _x ²¢³õʹ»¯Îª x£¬×¢ÒâµÚ 144 ÐеÄ×÷ÓÃÊǼì²é²ÎÊý x ºÍ y µÄÀàÐÍÊÇ·ñÏàͬ¡£

typeof ¿ÉÒÔÓÃÔÚÈκÎÀàÐÍ¿ÉÒÔʹÓõĵط½£¬Í¨³£ÓÃÓں궨Òå¡£

Á㳤¶ÈÊý×é

==========

GNU C ÔÊÐíʹÓÃÁ㳤¶ÈÊý×飬ÔÚ¶¨Òå±ä³¤¶ÔÏóµÄÍ·½á¹¹Ê±£¬Õâ¸öÌØÐԷdz£ÓÐÓá£Àý

È磺

++++ include/linux/minix_fs.h

85: struct minix_dir_entry {

86: __u16 inode;

87: char name[0];

88: };

½á¹¹µÄ×îºóÒ»¸öÔªËض¨ÒåΪÁ㳤¶ÈÊý×飬Ëü²»Õ¼½á¹¹µÄ¿Õ¼ä¡£ÔÚ±ê×¼ C ÖÐÔòÐèÒª

¶¨ÒåÊý×鳤¶ÈΪ 1£¬·ÖÅäʱ¼ÆËã¶ÔÏó´óС±È½Ï¸´ÔÓ¡£

¿É±ä²ÎÊýºê

==========

ÔÚ GNU C ÖУ¬ºê¿ÉÒÔ½ÓÊܿɱäÊýÄ¿µÄ²ÎÊý£¬¾ÍÏóº¯ÊýÒ»Ñù£¬ÀýÈ磺

++++ include/linux/kernel.h

110: #define pr_debug(fmt,arg...) \

111: printk(KERN_DEBUG fmt,##arg)

ÕâÀï arg ±íʾÆäÓàµÄ²ÎÊý£¬¿ÉÒÔÊÇÁã¸ö»ò¶à¸ö£¬ÕâЩ²ÎÊýÒÔ¼°²ÎÊýÖ®¼äµÄ¶ººÅ¹¹

³É arg µÄÖµ£¬ÔÚºêÀ©Õ¹Ê±Ìæ»» arg£¬ÀýÈ磺

pr_debug("%s:%d",filename,line)

À©Õ¹Îª

printk("<7>" "%s:%d", filename, line)

ʹÓà ## µÄÔ­ÒòÊÇ´¦Àí arg ²»Æ¥ÅäÈκβÎÊýµÄÇé¿ö£¬Õâʱ arg µÄֵΪ¿Õ£¬GNU

C Ô¤´¦ÀíÆ÷ÔÚÕâÖÖÌØÊâÇé¿öÏ£¬¶ªÆú ## ֮ǰµÄ¶ººÅ£¬ÕâÑù

pr_debug("success!\n")

À©Õ¹Îª

printk("<7>" "success!\n")

×¢Òâ×îºóûÓжººÅ¡£

±êºÅÔªËØ

========

±ê×¼ C ÒªÇóÊý×é»ò½á¹¹±äÁ¿µÄ³õʹ»¯Öµ±ØÐëÒԹ̶¨µÄ˳Ðò³öÏÖ£¬ÔÚ GNU C ÖУ¬Í¨

¹ýÖ¸¶¨Ë÷Òý»ò½á¹¹ÓòÃû£¬ÔÊÐí³õʼ»¯ÖµÒÔÈÎÒâ˳Ðò³öÏÖ¡£Ö¸¶¨Êý×éË÷ÒýµÄ·½·¨ÊÇÔÚ

³õʼ»¯ÖµÇ°Ð´ '[INDEX] ='£¬ÒªÖ¸¶¨Ò»¸ö·¶Î§Ê¹Óà '[FIRST ... LAST] =' µÄÐÎʽ£¬

ÀýÈ磺

+++++ arch/i386/kernel/irq.c

1079: static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };

½«Êý×éµÄËùÓÐÔªËسõʹ»¯Îª ~0UL£¬Õâ¿ÉÒÔ¿´×öÊÇÒ»ÖÖ¼òдÐÎʽ¡£

ÒªÖ¸¶¨½á¹¹ÔªËØ£¬ÔÚÔªËØֵǰд 'FIELDNAME:'£¬ÀýÈ磺

++++ fs/ext2/file.c

41: struct file_operations ext2_file_operations = {

42: llseek: generic_file_llseek,

43: read: generic_file_read,

44: write: generic_file_write,

45: ioctl: ext2_ioctl,

46: mmap: generic_file_mmap,

47: open: generic_file_open,

48: release: ext2_release_file,

49: fsync: ext2_sync_file,

50 };

½«½á¹¹ ext2_file_operations µÄÔªËØ llseek ³õʼ»¯Îª generic_file_llseek£¬

ÔªËØ read ³õʼ»¯Îª genenric_file_read£¬ÒÀ´ÎÀàÍÆ¡£ÎÒ¾õµÃÕâÊÇ GNU C À©Õ¹ÖÐ

×îºÃµÄÌØÐÔÖ®Ò»£¬µ±½á¹¹µÄ¶¨Òå±ä»¯ÒÔÖÁÔªËصÄÆ«ÒƸıäʱ£¬ÕâÖÖ³õʼ»¯·½·¨ÈÔÈ»

±£Ö¤ÒÑÖªÔªËصÄÕýÈ·ÐÔ¡£¶ÔÓÚδ³öÏÖÔÚ³õʼ»¯ÖеÄÔªËØ£¬Æä³õֵΪ 0¡£

Case ·¶Î§

=========

GNU C ÔÊÐíÔÚÒ»¸ö case ±êºÅÖÐÖ¸¶¨Ò»¸öÁ¬Ðø·¶Î§µÄÖµ£¬ÀýÈ磺

++++ arch/i386/kernel/irq.c

1062: case '0' ... '9': c -= '0'; break;

1063: case 'a' ... 'f': c -= 'a'-10; break;

1064: case 'A' ... 'F': c -= 'A'-10; break;

case '0' ... '9':

Ï൱ÓÚ

case '0': case '1': case '2': case '3': case '4':

case '5': case '6': case '7': case '8': case '9':

ÉùÃ÷µÄÌØÊâÊôÐÔ

==============

GNU C ÔÊÐíÉùÃ÷º¯Êý¡¢±äÁ¿ºÍÀàÐ͵ÄÌØÊâÊôÐÔ£¬ÒÔ±ãÊÖ¹¤µÄ´úÂëÓÅ»¯ºÍ¸ü×ÐϸµÄ´ú

Âë¼ì²é¡£ÒªÖ¸¶¨Ò»¸öÉùÃ÷µÄÊôÐÔ£¬ÔÚÉùÃ÷ºóд

__attribute__ (( ATTRIBUTE ))

ÆäÖÐ ATTRIBUTE ÊÇÊôÐÔ˵Ã÷£¬¶à¸öÊôÐÔÒÔ¶ººÅ·Ö¸ô¡£GNU C Ö§³ÖÊ®¼¸¸öÊôÐÔ£¬Õâ

Àï½éÉÜ×î³£Óõģº

* noreturn

ÊôÐÔ noreturn ÓÃÓÚº¯Êý£¬±íʾ¸Ãº¯Êý´Ó²»·µ»Ø¡£Õâ¿ÉÒÔÈñàÒëÆ÷Éú³ÉÉÔ΢ÓÅ»¯µÄ

´úÂ룬×îÖØÒªµÄÊÇ¿ÉÒÔÏû³ý²»±ØÒªµÄ¾¯¸æÐÅÏ¢±ÈÈçδ³õʹ»¯µÄ±äÁ¿¡£ÀýÈ磺

++++ include/linux/kernel.h

47: # define ATTRIB_NORET __attribute__((noreturn)) ....

61: asmlinkage NORET_TYPE void do_exit(long error_code)

ATTRIB_NORET;

* format (ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK)

ÊôÐÔ format ÓÃÓÚº¯Êý£¬±íʾ¸Ãº¯ÊýʹÓà printf, scanf »ò strftime ·ç¸ñµÄ²Î

Êý£¬Ê¹ÓÃÕâÀຯÊý×îÈÝÒ×·¸µÄ´íÎóÊǸñʽ´®Óë²ÎÊý²»Æ¥Å䣬ָ¶¨ format ÊôÐÔ¿ÉÒÔ

ÈñàÒëÆ÷¸ù¾Ý¸ñʽ´®¼ì²é²ÎÊýÀàÐÍ¡£ÀýÈ磺

++++ include/linux/kernel.h?

89: asmlinkage int printk(const char * fmt, ...)

90: __attribute__ ((format (printf, 1, 2)));

±íʾµÚÒ»¸ö²ÎÊýÊǸñʽ´®£¬´ÓµÚ¶þ¸ö²ÎÊýÆð¸ù¾Ý¸ñʽ´®¼ì²é²ÎÊý¡£

* unused

ÊôÐÔ unused ÓÃÓÚº¯ÊýºÍ±äÁ¿£¬±íʾ¸Ãº¯Êý»ò±äÁ¿¿ÉÄܲ»Ê¹Óã¬Õâ¸öÊôÐÔ¿ÉÒÔ±ÜÃâ

±àÒëÆ÷²úÉú¾¯¸æÐÅÏ¢¡£

* section ("section-name")

ÊôÐÔ section ÓÃÓÚº¯ÊýºÍ±äÁ¿£¬Í¨³£±àÒëÆ÷½«º¯Êý·ÅÔÚ .text ½Ú£¬±äÁ¿·ÅÔÚ

.data »ò .bss ½Ú£¬Ê¹Óà section ÊôÐÔ£¬¿ÉÒÔÈñàÒëÆ÷½«º¯Êý»ò±äÁ¿·ÅÔÚÖ¸¶¨µÄ

½ÚÖС£

ÀýÈ磺

++++ include/linux/init.h

78: #define __init __attribute__ ((__section__ (".text.init")))

79: #define __exit __attribute__ ((unused, __section__(".text.exit")))

80: #define __initdata __attribute__ ((__section__ (".data.init")))

81: #define __exitdata __attribute__ ((unused, __section__ (".data.exit")))

82: #define __initsetup __attribute__ ((unused,__section__ (".setup.init")))

83: #define __init_call __attribute__ ((unused,__section__ (".initcall.init")))

84: #define __exit_call __attribute_

_ ((unused,__section__ (".exitcall.exit")))

Á¬½ÓÆ÷¿ÉÒÔ°ÑÏàͬ½ÚµÄ´úÂë»òÊý¾Ý°²ÅÅÔÚÒ»Æð£¬Linux Äں˺Üϲ»¶Ê¹ÓÃÕâÖÖ¼¼Êõ£¬

ÀýÈçϵͳµÄ³õʼ»¯´úÂë±»°²ÅÅÔÚµ¥¶ÀµÄÒ»¸ö½Ú£¬ÔÚ³õʼ»¯½áÊøºó¾Í¿ÉÒÔÊÍ·ÅÕⲿ·Ö

ÄÚ´æ¡£

* aligned (ALIGNMENT)

ÊôÐÔ aligned ÓÃÓÚ±äÁ¿¡¢½á¹¹»òÁªºÏÀàÐÍ£¬Ö¸¶¨±äÁ¿¡¢½á¹¹Óò¡¢½á¹¹»òÁªºÏµÄ¶Ô

ÆëÁ¿£¬ÒÔ×Ö½ÚΪµ¥Î»£¬ÀýÈ磺

++++ include/asm-i386/processor.h

294: struct i387_fxsave_struct {

295: unsigned short cwd;

296: unsigned short swd;

297: unsigned short twd;

298: unsigned short fop;

299: long fip;

300: long fcs;

301: long foo;

......

308: } __attribute__ ((aligned (16)));

±íʾ¸Ã½á¹¹ÀàÐ͵ıäÁ¿ÒÔ 16 ×Ö½Ú¶ÔÆ롣ͨ³£±àÒëÆ÷»áÑ¡ÔñºÏÊʵĶÔÆëÁ¿£¬ÏÔʾָ

¶¨¶ÔÆëͨ³£ÊÇÓÉÓÚÌåϵÏÞÖÆ¡¢ÓÅ»¯µÈÔ­Òò¡£

* packed

ÊôÐÔ packed ÓÃÓÚ±äÁ¿ºÍÀàÐÍ£¬ÓÃÓÚ±äÁ¿»ò½á¹¹Óòʱ±íʾʹÓÃ×îС¿ÉÄܵĶÔÆ룬ÓÃ

ÓÚö¾Ù¡¢½á¹¹»òÁªºÏÀàÐÍʱ±íʾ¸ÃÀàÐÍʹÓÃ×îСµÄÄÚ´æ¡£ÀýÈ磺

++++ include/asm-i386/desc.h

51: struct Xgt_desc_struct {

52: unsigned short size;

53: unsigned long address __attribute__((packed));

54: };

Óò address ½«½ô½Ó×Å size ·ÖÅä¡£ÊôÐÔ packed µÄÓÃ;´ó¶àÊǶ¨ÒåÓ²¼þÏà¹ØµÄ½á

¹¹£¬Ê¹ÔªËØÖ®¼äûÓÐÒò¶ÔÆë¶øÔì³ÉµÄ¿Õ¶´¡£

µ±Ç°º¯ÊýÃû

==========

GNU CC Ô¤¶¨ÒåÁËÁ½¸ö±êÖ¾·û±£´æµ±Ç°º¯ÊýµÄÃû×Ö£¬__FUNCTION__ ±£´æº¯ÊýÔÚÔ´Âë

ÖеÄÃû×Ö£¬__PRETTY_FUNCTION__ ±£´æ´øÓïÑÔÌØÉ«µÄÃû×Ö¡£ÔÚ C º¯ÊýÖУ¬ÕâÁ½¸ö

Ãû×ÖÊÇÏàͬµÄ£¬ÔÚ C++ º¯ÊýÖУ¬__PRETTY_FUNCTION__ °üÀ¨º¯Êý·µ»ØÀàÐ͵ȶîÍâ

ÐÅÏ¢£¬Linux ÄÚºËֻʹÓÃÁË __FUNCTION__¡£

++++ fs/ext2/super.c

98: void ext2_update_dynamic_rev(struct super_block *sb)

99: {

100: struct ext2_super_block *es = EXT2_SB(sb)->s_es;

101:

102: if (le32_to_cpu(es->s_rev_level) > EXT2_GOOD_OLD_REV)

103: return;

104:

105: ext2_warning(sb, __FUNCTION__,

106: "updating to rev %d because of new feature flag, "

107: "running e2fsck is recommended",

108: EXT2_DYNAMIC_REV);

ÕâÀï __FUNCTION__ ½«±»Ì滻Ϊ×Ö·û´® "ext2_update_dynamic_rev"¡£ËäÈ»

__FUNCTION__ ¿´ÆðÀ´ÀàËÆÓÚ±ê×¼ C ÖÐµÄ __FILE__£¬µ«Êµ¼ÊÉÏ __FUNCTION__

ÊDZ»±àÒëÆ÷Ìæ»»µÄ£¬²»Ïó __FILE__ ±»Ô¤´¦ÀíÆ÷Ìæ»»¡£

ÄÚ½¨º¯Êý

========

GNU C ÌṩÁË´óÁ¿µÄÄÚ½¨º¯Êý£¬ÆäÖкܶàÊDZê×¼ C ¿âº¯ÊýµÄÄÚ½¨°æ±¾£¬ÀýÈç

memcpy£¬ËüÃÇÓë¶ÔÓ¦µÄ C ¿âº¯Êý¹¦ÄÜÏàͬ£¬±¾ÎIJ»ÌÖÂÛÕâÀຯÊý£¬ÆäËûÄÚ½¨º¯Êý

µÄÃû×Öͨ³£ÒÔ __builtin ¿ªÊ¼¡£

* __builtin_return_address (LEVEL)

ÄÚ½¨º¯Êý __builtin_return_address ·µ»Øµ±Ç°º¯Êý»òÆäµ÷ÓÃÕߵķµ»ØµØÖ·£¬²ÎÊý

LEVEL Ö¸¶¨ÔÚÕ»ÉÏËÑË÷¿ò¼ÜµÄ¸öÊý£¬0 ±íʾµ±Ç°º¯ÊýµÄ·µ»ØµØÖ·£¬1 ±íʾµ±Ç°º¯Êý

µÄµ÷ÓÃÕߵķµ»ØµØÖ·£¬ÒÀ´ËÀàÍÆ¡£ÀýÈ磺

++++ kernel/sched.c

437: printk(KERN_ERR "schedule_timeout: wrong timeout "

438: "value %lx from %p\n", timeout,

439: __builtin_return_address(0));

* __builtin_constant_p(EXP)

ÄÚ½¨º¯Êý __builtin_constant_p ÓÃÓÚÅжÏÒ»¸öÖµÊÇ·ñΪ±àÒëʱ³£Êý£¬Èç¹û²ÎÊý

EXP µÄÖµÊdz£Êý£¬º¯Êý·µ»Ø 1£¬·ñÔò·µ»Ø 0¡£ÀýÈ磺

++++ include/asm-i386/bitops.h

249: #define test_bit(nr,addr) \

250: (__builtin_constant_p(nr) ? \

251: constant_test_bit((nr),(addr)) : \

252: variable_test_bit((nr),(addr)))

ºÜ¶à¼ÆËã»ò²Ù×÷ÔÚ²ÎÊýΪ³£ÊýʱÓиüÓÅ»¯µÄʵÏÖ£¬ÔÚ GNU C ÖÐÓÃÉÏÃæµÄ·½·¨¿ÉÒÔ

¸ù¾Ý²ÎÊýÊÇ·ñΪ³£Êý£¬Ö»±àÒë³£Êý°æ±¾»ò·Ç³£Êý°æ±¾£¬ÕâÑù¼È²»Ê§Í¨ÓÃÐÔ£¬ÓÖÄÜÔÚ

²ÎÊýÊdz£Êýʱ±àÒë³ö×îÓÅ»¯µÄ´úÂë¡£

* __builtin_expect(EXP, C)

ÄÚ½¨º¯Êý __builtin_expect ÓÃÓÚΪ±àÒëÆ÷Ìṩ·ÖÖ§Ô¤²âÐÅÏ¢£¬Æä·µ»ØÖµÊÇÕûÊý±í

´ïʽ EXP µÄÖµ£¬C µÄÖµ±ØÐëÊDZàÒëʱ³£Êý¡£ÀýÈ磺

++++ include/linux/compiler.h

13: #define likely(x) __builtin_expect((x),1)

14: #define unlikely(x) __builtin_expect((x),0)

++++ kernel/sched.c

564: if (unlikely(in_interrupt())) {

565: printk("Scheduling in interrupt\n");

566: BUG();

567: }

Õâ¸öÄÚ½¨º¯ÊýµÄÓïÒåÊÇ EXP µÄÔ¤ÆÚÖµÊÇ C£¬±àÒëÆ÷¿ÉÒÔ¸ù¾ÝÕâ¸öÐÅÏ¢Êʵ±µØÖØÅÅ

Óï¾ä¿éµÄ˳Ðò£¬Ê¹³ÌÐòÔÚÔ¤ÆÚµÄÇé¿öÏÂÓиü¸ßµÄÖ´ÐÐЧÂÊ¡£ÉÏÃæµÄÀý×Ó±íʾ´¦ÓÚÖÐ

¶ÏÉÏÏÂÎÄÊǺÜÉÙ·¢ÉúµÄ£¬µÚ 565-566 ÐеÄÄ¿±êÂë¿ÉÄÜ»á·ÅÔÚ½ÏÔ¶µÄλÖã¬ÒÔ±£Ö¤

¾­³£Ö´ÐеÄÄ¿±êÂë¸ü½ô´Õ¡£
ÎÄÕÂÆÀÂÛ

¹²ÓÐ 0 ÌõÆÀÂÛ