QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1581|回复: 15

请教C 语言高手

[复制链接]
发表于 2004-6-22 11:37:33 | 显示全部楼层 |阅读模式
最近在学linux的内核原理,看linux内核源码时发现好多只折行一次的一个序列语句,linux里都把这段语句包含在一个do {} while(0)的结构中。比如说执行进程切换的switch_to宏,它执行了一段内嵌的汇编代码。源码如下:
#define switch_to(prev,next,last) do {                                        \
        asm volatile("pushl %%esi\n\t"                                        \
                     "pushl %%edi\n\t"                                        \
                     "pushl %%ebp\n\t"                                        \
                     "movl %%esp,%0\n\t"        /* save ESP */                \
                     "movl %3,%%esp\n\t"        /* restore ESP */        \
                     "movl $1f,%1\n\t"                /* save EIP */                \
                     "pushl %4\n\t"                /* restore EIP */        \
                     "jmp __switch_to\n"                                \
                     "1:\t"                                                \
                     "popl %%ebp\n\t"                                        \
                     "popl %%edi\n\t"                                        \
                     "popl %%esi\n\t"                                        \
                     :"=m" (prev->tss.esp),"=m" (prev->tss.eip),        \
                      "=b" (last)                                        \
                     :"m" (next->tss.esp),"m" (next->tss.eip),                \
                      "a" (prev), "d" (next),                                \
                      "b" (prev));                                        \
} while (0)

嵌在asm volatile()中的那段汇编代码只要执行一次,可是为什么又要把它加到do{} while(0)结构里呢?为什么不直接写成以下的形式呢?
#define switch_to(prev,next,last) asm volatile("pushl %%esi\n\t"        \
                     "pushl %%edi\n\t"                                        \
                     "pushl %%ebp\n\t"                                        \
                     "movl %%esp,%0\n\t"        /* save ESP */                \
                     "movl %3,%%esp\n\t"        /* restore ESP */        \
                     "movl $1f,%1\n\t"                /* save EIP */                \
                     "pushl %4\n\t"                /* restore EIP */        \
                     "jmp __switch_to\n"                                \
                     "1:\t"                                                \
                     "popl %%ebp\n\t"                                        \
                     "popl %%edi\n\t"                                        \
                     "popl %%esi\n\t"                                        \
                     :"=m" (prev->tss.esp),"=m" (prev->tss.eip),        \
                      "=b" (last)                                        \
                     :"m" (next->tss.esp),"m" (next->tss.eip),                \
                      "a" (prev), "d" (next),                                \
                      "b" (prev));                                       


linux源代码中有很多类似的写法,请教高人原因。
发表于 2004-6-22 20:32:10 | 显示全部楼层
看《情景分析》的导言,说的很清楚。
回复

使用道具 举报

发表于 2004-6-23 02:26:31 | 显示全部楼层
this is not linux trick. this is c language trick.
回复

使用道具 举报

 楼主| 发表于 2004-6-24 10:30:31 | 显示全部楼层
2搂的大哥,我手里没有情景分析那本书呀,能不能给我介绍一下呢?谢谢
回复

使用道具 举报

发表于 2004-6-24 11:03:08 | 显示全部楼层
网上有pdf电子版,我没有,只好自己找找了
回复

使用道具 举报

发表于 2004-6-24 12:37:01 | 显示全部楼层
它保证了可以方便的嵌入到各种c语句里。

举个例子,你要写

if ()
  switch_to();
else
  。。。。

你试试用你后面的写法,能不能成功?

或者你会加个花括号,可是这样你就只能写成
if ()
  switch_to()
else
  。。。

这样就不像条正常的语句了。


内核里有成千上万的这种宏,用do while括起来后,你就可以在任何情况下把它当成一条正常的语句来使用。
回复

使用道具 举报

 楼主| 发表于 2004-6-24 20:29:56 | 显示全部楼层
呵呵,恍然大悟呀,谢谢老大
回复

使用道具 举报

发表于 2004-7-2 19:26:32 | 显示全部楼层
真是聪明
回复

使用道具 举报

发表于 2004-7-10 10:47:41 | 显示全部楼层
有机会我也试试这种聪明的作法
回复

使用道具 举报

发表于 2004-7-10 17:35:14 | 显示全部楼层
《linux内核源代码情景分析》浙江大学出版社 毛德操,胡希明著
应该买一本,很厚的,纸张也不错,就算不看当枕头也不错!
回复

使用道具 举报

发表于 2004-7-20 15:30:55 | 显示全部楼层
我晕,我前几天买了,花掉我130元(打折后)。今天在网上看到了电子版,刚下下来了。我都快吐血了!
回复

使用道具 举报

发表于 2004-7-20 19:03:11 | 显示全部楼层
[quote:c3c8e34cd5="cxh_nuaa_2001"]我晕,我前几天买了,花掉我130元(打折后)。今天在网上看到了电子版,刚下下来了。我都快吐血了![/quote]唉,还可以啦,没吐shi   
回复

使用道具 举报

发表于 2004-7-21 19:34:48 | 显示全部楼层
南京可是75折,不是很贵的,因为你看了以后会有很大收获。
我现在已经在看下册了,觉得每天都能学到很多的东西,每天都在进步,很爽啊!!
回复

使用道具 举报

发表于 2004-7-22 13:57:16 | 显示全部楼层
我的就是在南京买的。我也知道有的地方是75折。不过我懒的去跑,我就在我们学校买的,一本9折(可以报销),一本8折(自己掏腰包)。
回复

使用道具 举报

发表于 2004-7-22 13:58:12 | 显示全部楼层
书写得的确不错,不过太繁了,不怎么清晰,重点不突出。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-7 21:08 , Processed in 0.046208 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表