免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: send_linux
打印 上一主题 下一主题

[C] 去伪存真——品悟C的优雅与严谨(获奖名单已公布-2012-10-30) [复制链接]

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
231 [报告]
发表于 2012-09-30 22:52 |只看该作者
回复 229# starwing83

void (*)(char*) 与 printf有什么关系。。。
那个foo把我写死了。。。  在Windows上写了一晚上。。。  各种限制。。。
最后被LZ逼急了,换到linux下瞬间就写好了。。。  而且linux下objdump -d 比Windows快很多。。。


>> 那么其实就有问题了:如果输出的不是文件呢?如果没有printf可用呢?那效率就未必了吧……
>> 所以真正工作中,我用到putchar(的等价形式)和puts(的等价形式)非常多………………

输出的不是文件是啥意思? printf也有等价形式的啊。。。
如果没有printf可用,是指嵌入式神马的恶劣环境么。。。  那确实可能只有一个putchar。。。
还是说没有各种优化措施的printf实现?
管它的,不就是效率问题而已么。。。

在有些情况,一开始可能是 printf("%s\n", s), 稍后就可能后悔了, 需要改为 printf("\aerror: \"%s\"\n", s)。
puts我觉得改着麻烦。。。  putchar类似。。。

不过就像前面说的, 在肯定是输出一个string+\n或char, 不可能改为其他情况的时候, 我也不会偷这个懒。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
232 [报告]
发表于 2012-09-30 22:55 |只看该作者
本帖最后由 starwing83 于 2012-09-30 23:00 编辑

回复 231# OwnWaterloo


    Linux下mmap很方便的啦………………

但是我的问题是,饿,f的前四个字节最终是大于2G的吧?你怎么申请到内核空间的?还是你在第三个字节后插入了一条不用的汇编?我没找到合适的,你插的是啥?


UPDATE:我擦,直接用段来搞事了……你真狠……

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
233 [报告]
发表于 2012-09-30 22:59 |只看该作者
回复 232# starwing83

windows下也有mapviewoffile啊。。。

写内核空间我没那么大的本事。。。 要写应该也能写,代价和风险都太大了。。。  就论坛上一个回帖而已,不值得这么玩。。。

于是为了找合适的指令费了很多时间。。。 具体的指令那个帖子里我贴出来了的。。。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
234 [报告]
发表于 2012-09-30 23:01 |只看该作者

文件名残缺

为了避免 fp = fopen("stu.dat", "rb") 失败而改为
fp = fopen("C:\\stu.dat", "rb")

。。。   怎么都觉得不对头。。。  这可是硬编码。。。


实际一点的程序,可能会首先读取命令行选项,然后是当前目录下的特定文件或环境变量,最后才是用若干绝对路径们。

教学程序我也不知道该怎么写好。
要是我,直接argv[1],然后让读者自己在命令行里输正确(这对初学者也不一定就很轻松)。。。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
235 [报告]
发表于 2012-09-30 23:03 |只看该作者
回复 233# OwnWaterloo


    你够狠………………我还想着-Wa,-a看汇编,然后回过头来用mmap/MapViewOfFile神马的拿到那块内存呢。您直接就把段弄过去了……真狠……

我在Windows上面,完全一样的函数,调用没有成功,是不是对齐问题?

int f(char *s) {....}

int main(vodi) {
   char buff[1024];
   memcpy(buff, f, sizeof(buff));
   ((int(*)(char*))buff)("hello");
}

结果失败,是对齐问题么?

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
236 [报告]
发表于 2012-09-30 23:05 |只看该作者

无知乱吃药 —— strcpy()函数的误用

同样, strcpy才是函数。 strcpy()是不正确的调用。 写为strcpy(...)都应该比strcpy(...)要好。

如果两个字符串有重叠,应该使用memcpy()函数...

应该是memmove。。。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
237 [报告]
发表于 2012-09-30 23:11 |只看该作者
本帖最后由 OwnWaterloo 于 2012-09-30 23:14 编辑

回复 235# starwing83

Windows XP默认不开DEP的(我是一直开着的), 但win7默认会开。 vista记得也会开。

还有。。。  f里面是啥? 如果产生的指令里有操作数是以相对形式给出的就完蛋。。。
比如e8。。。

对齐倒是不管的。。。  i386的指令是变长的,要让每个指令都对齐代价就不小了。
只是windows下的链接器会把每个函数的入口点安排在???0上。。。
只是Windows下的链接器会在函数间写一些填充, 对齐在???0上是那天用gcc弄出的结果。 没能把这个填充弄小。。。 -fno-function-align都不行。。。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
238 [报告]
发表于 2012-09-30 23:32 |只看该作者
本帖最后由 starwing83 于 2012-09-30 23:36 编辑

回复 237# OwnWaterloo


    相对形式是啥?f里面只有一行printf("%s\n", s); s是参数。

对了,就算是DEP,栈上也是可读可写可执行吧?

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
239 [报告]
发表于 2012-09-30 23:35 |只看该作者
回复 238# starwing83

e8 ?? ?? ?? ??
是一条call指令。后面那4个字节是操作数。操作数是以相对这条指令所在地址给出的。
编译器只负责产生e8 stub-operand。 stub是由链接器在决定这条指令的地址以及被调用函数的地址后计算出的。

如果直接copy,就不对了。。。 得自己重定位。。。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
240 [报告]
发表于 2012-09-30 23:37 |只看该作者
回复 238# starwing83

BTW:看吧,你也把puts改为printf了。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP