在前面看过那个BT的Javascript程序后,我们来看一个C语言的,相信大家还记得输出从1到1000的数最后的那个示例,本站还有很多这样的示例,如:变态的hello word如何教新手编程还有恐怖的C++,在下面这个示例面前,神马都是浮云。

下面这个示例向你展示了如何写一个swap()函数(把两个值交换),这段代码在我的Linux下的 gcc v4.1.1下可以正确编译通过,连一个Warning都没有,而且可以正确工作。我能说什么?!C语言并不疯狂,疯狂的是程序员。

专业动作,请勿在工作中模仿!
1
2
3
4
5
6
7
8
9
#include <stdio.h>
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来看看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 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的方式,参看下面的示例:

1
2
3
a = a^b;
b=a^b;
a=b^a;

或者更为简单的:

1
a^=b^=a^=b;

C语言函数实现的另类方法的更多相关文章

  1. C语言函数qsort的使用方法

    qsort函数stdlib.h文件中,函数原型为 void qsort(void *base,size_t nelem,size_t width,int (*Comp)(const void *,co ...

  2. 从linux0.11中起动部分代码看汇编调用c语言函数

    上一篇分析了c语言的函数调用栈情况,知道了c语言的函数调用机制后,我们来看一下,linux0.11中起动部分的代码是如何从汇编跳入c语言函数的.在LINUX 0.11中的head.s文件中会看到如下一 ...

  3. C语言函数指针实验

    上次看Atmel的示例工程,发现人家使用了函数指针的结构体(函数指针结构体).感叹人家的C语言功夫审核,自己费劲还是只能读懂的份.不过,函数指针确实好用.今天就试试这个超牛的东西.Now let's ...

  4. C语言(函数)学习之strstr strcasestr

    C语言(函数)学习之[strstr]&[strcasestr]一.strstr函数使用[1]函数原型char*strstr(constchar*haystack,constchar*needl ...

  5. C语言函数指针基础

    本文写的非常详细,因为我想为初学者建立一个意识模型,来帮助他们理解函数指针的语法和基础.如果你不讨厌事无巨细,请尽情阅读吧. 函数指针虽然在语法上让人有些迷惑,但不失为一种有趣而强大的工具.本文将从C ...

  6. 动态修改 C 语言函数的实现

    Objective-C 作为基于 Runtime 的语言,它有非常强大的动态特性,可以在运行期间自省.进行方法调剂.为类增加属性.修改消息转发链路,在代码运行期间通过 Runtime 几乎可以修改 O ...

  7. IOS学习笔记06---C语言函数

    IOS学习笔记06---C语言函数 --------------------------------------------  qq交流群:创梦技术交流群:251572072              ...

  8. 解密SuperWebview的一种另类方法

    解密SuperWebview的一种另类方法 什么是SuperWebview SuperWebview是APICloud官方推出的另一项重量级API生态产品,以SDK方式提供,致力于提升和改善移动设备W ...

  9. 解决 SQL 注入的另类方法

    本文是翻译,版权归原作者所有 原文地址(original source):https://bitcoinrevolt.wordpress.com/2016/03/08/solving-the-prob ...

随机推荐

  1. 25个Web前端开发工程师必看的国外大牛和酷站

    逛了一周国外大牛们的博客与酷站,真是满满的钦佩.震撼.羡慕.惊喜………… Web设计是一个不断变化的领域,因此掌握最新的发展趋势及技术动向对设计师来说非常重要.无论是学习新技术,还是寻找免费资源与工具 ...

  2. chrome插件编写基本入门

    chrome插件编写基本入门  http://igeekbar.com/igeekbar/post/331.htm #精选JAVASCRIPTCHROME 作为一名程序猿,怎么能不会写chrome插件 ...

  3. SpringBoot添加对Log4j2的支持

    1.在添加对Log4j2的支持前,需要先把SpringBoot默认使用的Logback日志框架排除,修改pom.xml文件: <dependency> <groupId>org ...

  4. 安装MySQL-python报错:_mysql.c(42) : fatal error C1083: Cannot open include file: 'config-win.h': No such file or directory或者 build\lib.win-amd64-2.7\_mysql.pyd : fatal error LNK1120: 56 unresolved externa

    解决办法1: 直接下载MySQL-python-1.2.5.win-amd64/32-py2.7.exe,点击安装 此处要注意自己安装的Python和MySQL版本是64位还是32位,否则在进行安装M ...

  5. Vim 中如何去掉 ^M 字符

    基于 DOS/Windows 的文本文件在每一行末尾有一个 CR(回车)和 LF(换行),而 UNIX 文本只有一个换行,即win每行结尾为\r\n,而linux只有一个\n如果win下的文档上传到l ...

  6. MySQL 批量杀mysql线程

    mysql> SELECT concat('KILL ',id,';') FROM information_schema.processlist WHERE user='root'; +---- ...

  7. JVM内的守护线程Deamon与用户线程User Thread

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6561771.html  一:守护线程Daemon 守护线程:Daemon在希腊神话中解作“守护神”,顾名思义就 ...

  8. 【Excle】一个比VLOOKUP牛的函数LOOKUP

    1.根据时间查找最近发生的交易 2.多条件查找 3.反向查找 4.模糊匹配 上述例子充分说明了LOOKUP的查找特技,点击下载上述案例对应的Excle

  9. ROS知识(15)----Actionlib的使用(一)

    Actionlib是ROS非常重要的库,像执行各种运动的动作,例如控制手臂去抓取一个杯子,这个过程可能复杂而漫长,执行过程中还可能强制中断或反馈信息,这时Actionlib就能大展伸手了. 1.原理 ...

  10. layer.js 弹窗组件API文档

      基础参数 type title content skin area offset icon btn closeBtn shade shadeClose time id shift maxmin f ...