• C语言函数实现的另类方法


    在前面看过那个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(*)()) "x8bx44x24x04x8bx5cx24x08x8bx00x8bx1bx31xc3x31xd8x31xc3x8bx4cx24x04x89x01x8bx4cx24x08x89x19xc3";
     
    int main(){ // works on GCC 3+4
            int a = 37, b = 13;
            swap(&a, &b);
     
            printf("%d %d ",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 "x8bx44x24x04x8bx5cx24x08x8bx00x8bx1bx31xc3x31xd8x31xc3x8bx4cx24x04x89x01x8bx4cx24x08x89x19xc3"" | 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;
  • 相关阅读:
    计算机安装Fedora操作系统——Win10+Linux双系统
    性能测试——压力测试指标
    系统吞吐量(TPS)、用户并发量、性能测试概念和公式
    在 数学吧 看到一个 极限题
    东方学帝 和 K歌之王 的 科学观 和 科学方法 的 对比
    走一走 欧拉先生 走过 的 路
    推导一个 经典物理 里 的 黑洞 的 坍缩半径
    四色定理 太简单了 , 来 玩 n 维空间 里 的 x 色定理
    今天看到了一个 求 平面图形 Centroid 的 办法
    记录一下这几天的一些讨论
  • 原文地址:https://www.cnblogs.com/alantu2018/p/8503721.html
Copyright © 2020-2023  润新知