如何运用技巧c来提升工作效率?

2026-04-16 23:221阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2663个文字,预计阅读时间需要11分钟。

如何运用技巧c来提升工作效率?

一、逻辑运算符 + 1、或运算符(C语言中的 ||)+ 条件真和假 + 非零为真,零为假:+ 为(假假为假)+ 截断原理 + if(a || b) + 判断前面是否为真,视为可执行大的放在前面 + c=i || j; + if(c) + {“}

一、逻辑运算符

  1、或运算(c语言中的 || )

    条件真和假 :

       非零为真,零为假

    ++为+(假假为假)

    截断原理 if(a || b) 判断前面是否为真,把认为可能行大的放在最前面

    c = i || j;

    if (c) {}

    以汇编指令去看

    /*

009E1014 |. C745 FC 330>mov [local.1],0x33
009E101B |. C745 F4 660>mov [local.3],0x66
009E1022 |. 837D FC 00 cmp [local.1],0x0
009E1026 |. 75 0F jnz short 汇编.009E1037 // jnz 不为0 跳转 因 local-1 与 0 比较 不为0 跳转 ,所以导致第二个参数不用判断,效率快

009E1028 |. 837D F4 00 cmp [local.3],0x0 // 如果为0不跳转, 则继续与第二个参数比较 (假假为假)

009E102C |. 75 09 jnz short 汇编.009E1037
009E102E |. C745 F0 000>mov [local.4],0x0
009E1035 |. EB 07 jmp short 汇编.009E103E
009E1037 |> C745 F0 010>mov [local.4],0x1
009E103E |> 8B45 F0 mov eax,[local.4] ; 汇编.envpcurity_cookie_complement
009E1041 |. 8945 F8 mov [local.2],eax
009E1044 |. 8BC0 mov eax,eax

    */

  

  2、按位或(c语言中的 |)  

      0x33 ==>> 00 11 00 11

    | 0x66 + 01 10 01 10

    = 0x77 ==> = 01 11 01 11 (假假为假)

    /*

009E1046 |. 8B4D FC mov ecx,[local.1] ; msvcr100.72AD266D
009E1049 |. 0B4D F4 or ecx,[local.3]
009E104C |. 894D F8 mov [local.2],ecx ; msvcr100.__initenv

    */

    汇编是使用 or 指令

  3、与运算

    ==>>逻辑与(c语言中的 && )

        真真为真

      c = a && b // 自己的代码 a 认为 是假 放在前面 。判断前面是否为假,把认为可能行大的放在最前面

      if ( c ){}

      截断原理

    ==>>按位与 (c语言中的 &)

      0x33 ==>> 00 11 00 11

    & 0x66 + 01 10 01 10

    = 0x22 ==> = 00 10 0010 (真真为真)

    /*

  4、非运算

    (1)逻辑取反(c语言中的 ! )

       假变真, 真变假

      sete(setz) 取ZF标志位的值保存

      setne(setnz) 将ZF标志位的值取反保存

     (2) 按位取反(c语言中的 ~ )

      

    c语言代码中的汇编指令

      #include <cstdio>
      int main(){
      printf("fsadfasd");
      int i, j;
      i = 0x7787;
      j = !i ; // 0

      /*

      

      */

      __asm mov eax, eax
      j = ~i;

          


      return 0;

      }

       NOT 指令

   5、异或运算

     (1)按位异或(c语言中的^)

      1^1 = 0 ,0^0 = 0 ,相同为0

      0^1 = 1 , 1^0 = 1 , 不同为1

      eg : 1101

        ^ 0110

        = 1011

      

    经典练习题:

        (1)不借助第三个变量,将两个数交换(数值大的数会有问题,溢出)

            int a = 5, b = 7;

            a = a+b; // a = 12

            b = a - b; // b = 12 - 7 = 5

            a = a - b; // a = 12 - 5 = 7

        (2)用异或计算高效

          

    逻辑运算指令总结:

       (1) or : 按位或运算,假假为假(有1为1,全0为0)

          如:101100

           | 110101

           = 111101

       (2) and : 按位与运算,真真为真(有0为0,全1为1)

          如: 101100

           & 110101

           = 100100

       (3) Not: 取反运算

          如:not 1011

             = 0100

        (4) xor : 异或运算(相同为0,不同为1)

          如 : 101100

            ^ 110101

            = 011001

                  

二、字符操作相关指令

  1、字符串的比较函数 strcmp 反汇编分析:

  2、REPNE和SCASB指令

    (1)SCASB指令:

      SCASB编译后:

        SCASB BTYP PTR ES:[EDI] char s1[0] byte 1

        //// SCASW WORD PTR [EDI] short s1[0] word 2

        //// SCASD DWORD PTR [EDI] int s1[0] dword 4

      相当于

        cmp byte prt [edi], al

      对标志位的影响相当于SUB指令,同时还会修改寄存器EDI的值

        如果标志位DF为0, 则 inc EDI

        否则,dec EDI

      

    (2)REPNE指令(连续执行)

        repnz scasb 编译后 :repne scas bype ptr es:[edi]

        当ecx != 0 并且 ZF = 0 时,重复执行后边的指令scas bype ptr es:[edi]

        每执行一 次EDI的值加1,ECX的值减1

        

        // 此汇编代码 是 获取字符的长度 (主要是实现逻辑思想)

        repne 和 repnz 是同一条指令的不同助记符

  3、REPE/REPZ和CMPSB, CMPSW, CMPSD指令

    (1)CMPS

        cmps byte ptr [edi] , byte ptr [esi]

        cmps word ptr [edi] , byte ptr [esi]

        cmps dword ptr [edi] , byte ptr [esi]

        对标志位的影响相当于sub指令, 同时还会修改寄存器EDI和ESI的值

          如果标志DF为0, 则EDI, ESI按相对于大小(byte, word, dword) 递增

          如果标志DF为1, 则EDI, ESI按相对于大小(byte word dword) 递减

    (2)REPE/REPZ

        repe/repz cmpsb 当ecx!=0并且zf = 1时, 重复执行后面的指令

        每执行一次ecx的值减1

    (3)实例运用

        比较串是否相等

        

      (4)汇编编写字符串比较函数

         (1)asm_strcmp 函数

            _declspec(naked) 告诉编译器用纯汇编方式编译函数, 不自动添加

                      寄存器保护和堆栈平衡代码

         (2)STD/CLD指令(DF方向标志位相关)

            std df = 1

            cld df = 0

三、串存储和串的加载指令

    (1)串存储指令STOSB、STOSW、STOSD

        STOSB STOS BYTE PTR [EDI]

        STOSW STOS WORD PTR [EDI]

        STOSD STOS DWORD PTR [EDI]

        相当于:

          mov byte ptr [edi], al

          mov word ptr [edi], ax

          mov dword ptr [edi], eax

        rep stosb rep stos byte ptr [edi]

如何运用技巧c来提升工作效率?

        用al 的值 填充byte ptr [edi],每次ecx值减1,edi加1

     定位main()函数位置的步骤:

      第一步:打开程序, 程序启动后停在这里,直接jmp跳转

      第二步:jmp跳转跟随之后, 找到call dword ptr [<xxxxx.exit>]退出的代码的位置

      第三步:call dword ptr [<xxxxx.exit >] 前一个call就是main函数。

    (2) 串载入指令LODSB, LODSW,LODSD

      lodsb lods byte ptr [esi]

      lodsw lods woedptr [esi]

      lodsd lods dword ptr [esi]

      

     rep lodsb ==>> rep lods byte ptr [esi]

     用byte ptr [esi] 的值, 填充al, 每次ecx值减1 , esi的值加1

本文共计2663个文字,预计阅读时间需要11分钟。

如何运用技巧c来提升工作效率?

一、逻辑运算符 + 1、或运算符(C语言中的 ||)+ 条件真和假 + 非零为真,零为假:+ 为(假假为假)+ 截断原理 + if(a || b) + 判断前面是否为真,视为可执行大的放在前面 + c=i || j; + if(c) + {“}

一、逻辑运算符

  1、或运算(c语言中的 || )

    条件真和假 :

       非零为真,零为假

    ++为+(假假为假)

    截断原理 if(a || b) 判断前面是否为真,把认为可能行大的放在最前面

    c = i || j;

    if (c) {}

    以汇编指令去看

    /*

009E1014 |. C745 FC 330>mov [local.1],0x33
009E101B |. C745 F4 660>mov [local.3],0x66
009E1022 |. 837D FC 00 cmp [local.1],0x0
009E1026 |. 75 0F jnz short 汇编.009E1037 // jnz 不为0 跳转 因 local-1 与 0 比较 不为0 跳转 ,所以导致第二个参数不用判断,效率快

009E1028 |. 837D F4 00 cmp [local.3],0x0 // 如果为0不跳转, 则继续与第二个参数比较 (假假为假)

009E102C |. 75 09 jnz short 汇编.009E1037
009E102E |. C745 F0 000>mov [local.4],0x0
009E1035 |. EB 07 jmp short 汇编.009E103E
009E1037 |> C745 F0 010>mov [local.4],0x1
009E103E |> 8B45 F0 mov eax,[local.4] ; 汇编.envpcurity_cookie_complement
009E1041 |. 8945 F8 mov [local.2],eax
009E1044 |. 8BC0 mov eax,eax

    */

  

  2、按位或(c语言中的 |)  

      0x33 ==>> 00 11 00 11

    | 0x66 + 01 10 01 10

    = 0x77 ==> = 01 11 01 11 (假假为假)

    /*

009E1046 |. 8B4D FC mov ecx,[local.1] ; msvcr100.72AD266D
009E1049 |. 0B4D F4 or ecx,[local.3]
009E104C |. 894D F8 mov [local.2],ecx ; msvcr100.__initenv

    */

    汇编是使用 or 指令

  3、与运算

    ==>>逻辑与(c语言中的 && )

        真真为真

      c = a && b // 自己的代码 a 认为 是假 放在前面 。判断前面是否为假,把认为可能行大的放在最前面

      if ( c ){}

      截断原理

    ==>>按位与 (c语言中的 &)

      0x33 ==>> 00 11 00 11

    & 0x66 + 01 10 01 10

    = 0x22 ==> = 00 10 0010 (真真为真)

    /*

  4、非运算

    (1)逻辑取反(c语言中的 ! )

       假变真, 真变假

      sete(setz) 取ZF标志位的值保存

      setne(setnz) 将ZF标志位的值取反保存

     (2) 按位取反(c语言中的 ~ )

      

    c语言代码中的汇编指令

      #include <cstdio>
      int main(){
      printf("fsadfasd");
      int i, j;
      i = 0x7787;
      j = !i ; // 0

      /*

      

      */

      __asm mov eax, eax
      j = ~i;

          


      return 0;

      }

       NOT 指令

   5、异或运算

     (1)按位异或(c语言中的^)

      1^1 = 0 ,0^0 = 0 ,相同为0

      0^1 = 1 , 1^0 = 1 , 不同为1

      eg : 1101

        ^ 0110

        = 1011

      

    经典练习题:

        (1)不借助第三个变量,将两个数交换(数值大的数会有问题,溢出)

            int a = 5, b = 7;

            a = a+b; // a = 12

            b = a - b; // b = 12 - 7 = 5

            a = a - b; // a = 12 - 5 = 7

        (2)用异或计算高效

          

    逻辑运算指令总结:

       (1) or : 按位或运算,假假为假(有1为1,全0为0)

          如:101100

           | 110101

           = 111101

       (2) and : 按位与运算,真真为真(有0为0,全1为1)

          如: 101100

           & 110101

           = 100100

       (3) Not: 取反运算

          如:not 1011

             = 0100

        (4) xor : 异或运算(相同为0,不同为1)

          如 : 101100

            ^ 110101

            = 011001

                  

二、字符操作相关指令

  1、字符串的比较函数 strcmp 反汇编分析:

  2、REPNE和SCASB指令

    (1)SCASB指令:

      SCASB编译后:

        SCASB BTYP PTR ES:[EDI] char s1[0] byte 1

        //// SCASW WORD PTR [EDI] short s1[0] word 2

        //// SCASD DWORD PTR [EDI] int s1[0] dword 4

      相当于

        cmp byte prt [edi], al

      对标志位的影响相当于SUB指令,同时还会修改寄存器EDI的值

        如果标志位DF为0, 则 inc EDI

        否则,dec EDI

      

    (2)REPNE指令(连续执行)

        repnz scasb 编译后 :repne scas bype ptr es:[edi]

        当ecx != 0 并且 ZF = 0 时,重复执行后边的指令scas bype ptr es:[edi]

        每执行一 次EDI的值加1,ECX的值减1

        

        // 此汇编代码 是 获取字符的长度 (主要是实现逻辑思想)

        repne 和 repnz 是同一条指令的不同助记符

  3、REPE/REPZ和CMPSB, CMPSW, CMPSD指令

    (1)CMPS

        cmps byte ptr [edi] , byte ptr [esi]

        cmps word ptr [edi] , byte ptr [esi]

        cmps dword ptr [edi] , byte ptr [esi]

        对标志位的影响相当于sub指令, 同时还会修改寄存器EDI和ESI的值

          如果标志DF为0, 则EDI, ESI按相对于大小(byte, word, dword) 递增

          如果标志DF为1, 则EDI, ESI按相对于大小(byte word dword) 递减

    (2)REPE/REPZ

        repe/repz cmpsb 当ecx!=0并且zf = 1时, 重复执行后面的指令

        每执行一次ecx的值减1

    (3)实例运用

        比较串是否相等

        

      (4)汇编编写字符串比较函数

         (1)asm_strcmp 函数

            _declspec(naked) 告诉编译器用纯汇编方式编译函数, 不自动添加

                      寄存器保护和堆栈平衡代码

         (2)STD/CLD指令(DF方向标志位相关)

            std df = 1

            cld df = 0

三、串存储和串的加载指令

    (1)串存储指令STOSB、STOSW、STOSD

        STOSB STOS BYTE PTR [EDI]

        STOSW STOS WORD PTR [EDI]

        STOSD STOS DWORD PTR [EDI]

        相当于:

          mov byte ptr [edi], al

          mov word ptr [edi], ax

          mov dword ptr [edi], eax

        rep stosb rep stos byte ptr [edi]

如何运用技巧c来提升工作效率?

        用al 的值 填充byte ptr [edi],每次ecx值减1,edi加1

     定位main()函数位置的步骤:

      第一步:打开程序, 程序启动后停在这里,直接jmp跳转

      第二步:jmp跳转跟随之后, 找到call dword ptr [<xxxxx.exit>]退出的代码的位置

      第三步:call dword ptr [<xxxxx.exit >] 前一个call就是main函数。

    (2) 串载入指令LODSB, LODSW,LODSD

      lodsb lods byte ptr [esi]

      lodsw lods woedptr [esi]

      lodsd lods dword ptr [esi]

      

     rep lodsb ==>> rep lods byte ptr [esi]

     用byte ptr [esi] 的值, 填充al, 每次ecx值减1 , esi的值加1