zoukankan      html  css  js  c++  java
  • gnu cc扩展和ABI

    gnc cc扩展标准c的语法,非常强大!!!详情请见:

    http://uw714doc.sco.com/cgi-bin/info2html?%28gcc.info%29C%2520Extensions&lang=en

    http://tigcc.ticalc.org/doc/gnuexts.html#SEC104

    https://gcc.gnu.org/onlinedocs/gcc-4.4.5/gcc/C-Extensions.html#C-Extensions

    ABI是application binary interface的缩写,规定了struct布局,函数调用规则,数据大小等。

    非常值得研究。

    比如:x86-64下,rbx,rbp,r12-r15是called saved registers。

    参考文献:http://www.x86-64.org/documentation/abi.pdf

    people.freebsd.org/~obrien/amd64-elf-abi.pdf

    #define my_min(x, y)  ({const typeof(x) __x = x; 
        const typeof(y) __y = y; 
        (void) (&__x == &__y); 
        __x < __y ? __x : __y;})
    
    struct Str
    {
        int a;
        char b;
        short c;
    } __attribute__((packed));
    
    #define ERR_PRINTF(fmt, args...) {
        char msg[1024]; 
        snprintf(msg, sizeof(msg), "%s:%d "fmt"
    ", __FUNCTION__, __LINE__, ##args);
        printf("%s", msg); 
    }
    
    #define ERR_PRINTF2(fmt, ...) 
        printf("%s:%d "fmt"
    ", __FUNCTION__, __LINE__, ##__VA_ARGS__)
    
    #define likely(x)  __builtin_expect((x), 1)
    #define unlikely(x)  __builtin_expect((x), 0)
    
    __attribute__ ((noinline))   bool CAS_64b(uint64_t* ptr, uint32_t* oldv, uint32_t* newv)
    {
        bool ret = false;
        __asm__ __volatile__ ( 
            "pushl %%ebx;"
            "movl %4, %%ebx;"
            "lock cmpxchg8b %1;
    "
            "sete %0;
    "
            "popl %%ebx;
    "
            :"=m"(ret),"+m"(*(uint64_t volatile*)(ptr)) 
            :"a"(oldv[0]), "d"(oldv[1]), "D"(newv[0]), "c"(newv[1]) 
            :"memory"); 
            return ret;
    }
    
    //#if defined(__x86_64__)
    //#define CAS(ptr, oldv, newv)  __sync_bool_compare_and_swap((uint64_t*)(ptr), *(uint64_t*)(&oldv), *(uint64_t*)(&newv))
    //#else
    #define CAS(ptr, oldv, newv) CAS_64b((uint64_t*)(ptr), (uint32_t*)(&oldv), (uint32_t*)(&newv))
    //#endif
    struct A
    {
        int a;
        int b;
    };
    
    void test_CAS()
    {
        struct A sa = {1, 2};    
        struct A sb = {3, 4};    
        struct A sc = sa;
        if(CAS(&sc, sa, sb))
            printf("success, %d %d
    ", sb.a, sb.b) ;
        else
            printf("fail, %d %d
    ", sb.a, sb.b); 
    }
    
    void f_unlikely()
    {
        printf("go unlikely
    "); 
    }
    
    
    void f_likely()
    {
        printf("go likely
    "); 
    }
    
    void test_aligned(char* p)
    {
        char* q = (char*)((((size_t)p + 3)>>2)<<2);
        *((int*)(q+1)) = 3;
    }
    
    void test_likely(int x)
    {
        if(unlikely(x))
            f_unlikely();
        else
            f_likely();
    }
    
    void test_return_addr()
    {
        void* p = __builtin_return_address(0);
        printf("address 	 %p
    ", p);
    }
    
    void test_frame_addr()
    {
        void* p = __builtin_frame_address(0);
        printf("address 	 %p
    ", p);
    }
    
    int main()
    {
        //typeof
        //statement expression
        int c = my_min(1, 2);
        printf("%d
    ", c);
    
        //packed
        printf("sizeof(Str) = %u
    ", (uint32_t)sizeof(Str));
    
        //##
        ERR_PRINTF("%d test", 1);
        ERR_PRINTF("test2");
    
        ERR_PRINTF2("%d test", 1);
        //printf("%s:%d ""test2""
    ", __FUNCTION__, 80, ); // the , still exists
        ERR_PRINTF2("test2");
    
        //__builtin_expect
        test_likely(1);
    
        //__builtin_return_address
        test_return_addr();
    
        //__builtin_frame_address
        test_frame_addr();
    
        //test aligned
        char pp[11] = {0};
        test_aligned(pp);
    
        //test CAS
        test_CAS();
    
        while(1)
            sleep(10);
        return 0;
    }
    

      

    执行结果:

    [ ~/code/test_sighup]$ ./test_gcc_ex 
    1
    sizeof(Str) = 7
    main:120 1 test
    main:121 test2
    main:123 1 test
    main:125 test2
    go unlikely
    address          0x804882b
    address          0xffb33aa8
    success, 3 4

    objdump -DC ./test_gcc_ex

    00000000004006a0 <test_likely(int)>:
      4006a0:       85 ff                   test   %edi,%edi
      4006a2:       75 05                   jne    4006a9 <test_likely(int)+0x9>
      4006a4:       e9 d7 ff ff ff          jmpq   400680 <f_likely()>
      4006a9:       e9 e2 ff ff ff          jmpq   400690 <f_unlikely()>
      4006ae:       66 90                   xchg   %ax,%ax

    参考代码:

    http://blog.csdn.net/cugxueyu/article/details/1955372

  • 相关阅读:
    剑指offer(14)链表中倒数第K个节点
    剑指offer(13)调整数组顺序使奇数位于偶数前面
    跨域资源共享CORS
    同源政策
    剑指offer(12)数值的整数次方
    剑指offer(11)二进制中1的个数
    面试金典——交点
    LeetCode——简化路径
    LeetCode——跳跃游戏 I-II
    LeetCode——最大矩形
  • 原文地址:https://www.cnblogs.com/Torstan/p/6535872.html
Copyright © 2011-2022 走看看