加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

技巧“c”

发布时间:2020-12-16 09:12:32 所属栏目:百科 来源:网络整理
导读:一、逻辑运算符 1、或运算(c语言中的? ||? )? 条件真和假 :? 非零为真,零为假 ++为+(假假为假) 截断原理? if(a || b) 判断前面是否为真,把认为可能行大的放在最前面 c = i || j; if (c) {} 以汇编指令去看 /* 009E1014 |. C745 FC 330mov [local.1],0

一、逻辑运算符

  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]

       ? ?用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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读