C语言函数实现的另类方法
浏览:2896次 出处信息
在前面看过那个BT的Javascript程序后,我们来看一个C语言的,相信大家还记得输出从1到1000的数最后的那个示例,本站还有很多这样的示例,如:变态的hello word,如何教新手编程,还有恐怖的C++,在下面这个示例面前,神马都是浮云。
下面这个示例向你展示了如何写一个swap()函数(把两个值交换),这段代码在我的Linux下的 gcc v4.1.1下可以正确编译通过,连一个Warning都没有,而且可以正确工作。我能说什么?!C语言并不疯狂,疯狂的是程序员。
#include void (*swap)() = ( void (*)()) \"\\x8b\\x44\\x24\\x04\\x8b\\x5c\\x24\\x08\\x8b\\x00\\x8b\\x1b\\x31\\xc3\\x31\\xd8\\x31\\xc3\\x8b\\x4c\\x24\\x04\\x89\\x01\\x8b\\x4c\\x24\\x08\\x89\\x19\\xc3\" ; int main(){ // works on GCC 3+4 int a = 37, b = 13; swap(&a, &b); printf ( \"%d %d\\n\" ,a,b); } |
其实,这种用字符串来实现函数的方法,在原理上是很好理解的。
字符串就是一段内存空间,把一个字符串指针强转成函数指针,那么这个指针所指向的内容就是各种指令,因此,那堆乱七八糟的东西说白了就是汇编。8086的汇编。你可以使用ndisasm来看看。
# ruby -e \"print \\\"\\x8b\\x44\\x24\\x04\\x8b\\x5c\\x24\\x08\\x8b\\x00\\x8b\\x1b\\x31\\xc3\\x31\\xd8\\x31\\xc3\\x8b\\x4c\\x24\\x04\\x89\\x01\\x8b\\x4c\\x24\\x08\\x89\\x19\\xc3\\\"\" | ndisasm -u - 00000000 8B442404 mov eax,[esp+0x4] ; load pointers to two parameters into eax, ebx 00000004 8B5C2408 mov ebx,[esp+0x8] 00000008 8B00 mov eax,[eax] ; load values of two parameters from pointers (*eax, *ebx) into eax, ebx 0000000A 8B1B mov ebx,[ebx] 0000000C 31C3 xor ebx,eax ; swap two values (eax, ebx) using xor trick 0000000E 31D8 xor eax,ebx 00000010 31C3 xor ebx,eax 00000012 8B4C2404 mov ecx,[esp+0x4] ; load pointer to param 1 into ecx 00000016 8901 mov [ecx],eax ; store swapped value 1 (eax) into param 1 (*ecx) 00000018 8B4C2408 mov ecx,[esp+0x8] ; load pointer to param 2 into ecx 0000001C 8919 mov [ecx],ebx ; store swapped value 2 (ebx) into param 2 (*ecx) 0000001E C3 ret |
注意:这段汇编中使用了XOR而不是引入第三个变量来完成了变量值的交换。
关于XOR的方式,参看下面的示例:
a = a^b; b=a^b; a=b^a; |
或者更为简单的:
a^=b^=a^=b; |
(全文完)
建议继续学习:
- 不定参数的应用 function(fmt, …) (阅读:3988)
- 函数式编程 (阅读:3667)
- JavaScript的5种调用函数的方法 (阅读:3585)
- C 语言中统一的函数指针 (阅读:3025)
- 关于在函数调用时传递string引用的必要性 (阅读:2834)
- 深入理解PHP之匿名函数 (阅读:2585)
- MySQL 内部函数简介 (阅读:2434)
- PHP中htmlentities()和htmlspecialchars()这两个函数的区别 (阅读:2435)
- 情人节特献:有心之函数必然就有分手函数 (阅读:2412)
- 一个想当然造成的错误(函数引用参数的一个问题) (阅读:2388)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:在C++里写一个不能被继承的类
后一篇:异常的代价 >>
文章信息
- 作者:陈皓 来源: 酷壳 - CoolShell.cn
- 标签: 函数
- 发布时间:2011-02-13 22:49:47
建议继续学习
近3天十大热文
- [68] Go Reflect 性能
- [68] 如何拿下简短的域名
- [67] Oracle MTS模式下 进程地址与会话信
- [62] IOS安全–浅谈关于IOS加固的几种方法
- [61] 图书馆的世界纪录
- [60] 【社会化设计】自我(self)部分――欢迎区
- [58] android 开发入门
- [56] 视觉调整-设计师 vs. 逻辑
- [49] 给自己的字体课(一)——英文字体基础
- [48] 读书笔记-壹百度:百度十年千倍的29条法则