zoukankan      html  css  js  c++  java
  • 重学C第五节:常量

    在程序运行过程中,其值不能被改变的量成为常量。

    下面是符号常量的例子:

    1 #include <stdio.h>
    2 #define  PRICE 30   //符号常量
    3 void main()
    4 {
    5     int num,total;
    6     num = 10;
    7     total = num * PRICE;
    8     printf("total= %d\n",total);
    9 }

    同样的,我们汇编代码瞅瞅

     1 00401010 >|> \55            push    ebp
     2 00401011  |.  8BEC          mov     ebp, esp
     3 00401013  |.  83EC 48       sub     esp, 48
     4 00401016  |.  53            push    ebx
     5 00401017  |.  56            push    esi
     6 00401018  |.  57            push    edi
     7 00401019  |.  8D7D B8       lea     edi, dword ptr [ebp-48]
     8 0040101C  |.  B9 12000000   mov     ecx, 12
     9 00401021  |.  B8 CCCCCCCC   mov     eax, CCCCCCCC
    10 00401026  |.  F3:AB         rep     stos dword ptr es:[edi]
    11 00401028  |.  C745 FC 0A000>mov     dword ptr [ebp-4], 0A            ;  num=10
    12 0040102F  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
    13 00401032  |.  6BC0 1E       imul    eax, eax, 1E                     ;  price=0x1e
    14 00401035  |.  8945 F8       mov     dword ptr [ebp-8], eax
    15 00401038  |.  8B4D F8       mov     ecx, dword ptr [ebp-8]
    16 0040103B  |.  51            push    ecx                              ; /<%d>
    17 0040103C  |.  68 1C204200   push    0042201C                         ; |format = "total= %d",LF,""
    18 00401041  |.  E8 2A000000   call    printf                           ; \printf
    19 00401046  |.  83C4 08       add     esp, 8
    20 00401049  |.  5F            pop     edi
    21 0040104A  |.  5E            pop     esi
    22 0040104B  |.  5B            pop     ebx
    23 0040104C  |.  83C4 48       add     esp, 48
    24 0040104F  |.  3BEC          cmp     ebp, esp
    25 00401051  |.  E8 9A000000   call    _chkesp
    26 00401056  |.  8BE5          mov     esp, ebp
    27 00401058  |.  5D            pop     ebp
    28 00401059  \.  C3            retn

    我们用IDA来看看,这个PRICE在哪里?

     1 int __cdecl main()
     2 {
     3   char v1; // [sp+Ch] [bp-48h]@1
     4   int v2; // [sp+4Ch] [bp-8h]@1
     5   int v3; // [sp+50h] [bp-4h]@1
     6 
     7   memset(&v1, 0xCCCCCCCCu, 0x48u);
     8   v3 = 10;
     9   v2 = 300;
    10   printf("total= %d\n", 300);
    11   return _chkesp();
    12 }

    我修改为

     1 int __cdecl main()
     2 {
     3   char v1; // [sp+Ch] [bp-48h]@1
     4   int total; // [sp+4Ch] [bp-8h]@1
     5   int num; // [sp+50h] [bp-4h]@1
     6 
     7   memset(&v1, 0xCCCCCCCCu, 0x48u);
     8   num = 10;
     9   total = 300;
    10   printf("total= %d\n", 300);
    11   return _chkesp();
    12 }

    发现计算的过程没有了。还是看汇编代码吧:

     1 main proc near
     2 
     3 var_48= byte ptr -48h
     4 total= dword ptr -8
     5 num= dword ptr -4
     6 
     7 push    ebp
     8 mov     ebp, esp
     9 sub     esp, 48h
    10 push    ebx
    11 push    esi
    12 push    edi
    13 lea     edi, [ebp+var_48]
    14 mov     ecx, 12h
    15 mov     eax, 0CCCCCCCCh
    16 rep stosd
    17 mov     [ebp+num], 0Ah
    18 mov     eax, [ebp+num]
    19 imul    eax, 30
    20 mov     [ebp+total], eax
    21 mov     ecx, [ebp+total]
    22 push    ecx
    23 push    offset aTotalD  ; "total= %d\n"
    24 call    printf
    25 add     esp, 8
    26 pop     edi
    27 pop     esi
    28 pop     ebx
    29 add     esp, 48h
    30 cmp     ebp, esp
    31 call    __chkesp
    32 mov     esp, ebp
    33 pop     ebp
    34 retn
    35 main endp

    我们再看看Release版的有什么变化-----主函数

    1 00401000  /$  68 2C010000   push    12C
    2 00401005  |.  68 30704000   push    00407030                         ;  ASCII "total= %d",LF
    3 0040100A  |.  E8 11000000   call    00401020
    4 0040100F  |.  83C4 08       add     esp, 8
    5 00401012  \.  C3            retn

    我们没有发现计算的过程,视乎在编译的过程中就完成了计算。

    我们用IDA来看看

    1 ; int __cdecl main(int argc, const char **argv, const char **envp)
    2 _main proc near
    3 push    12Ch
    4 push    offset Format   ; "total= %d\n"
    5 call    _printf
    6 add     esp, 8
    7 retn
    8 _main endp

    果然是这样。

    工程下载地址:https://files.cnblogs.com/tk091/rl005.7z

  • 相关阅读:
    A Simple Problem with Integers-POJ3468 区间修改+区间查询
    致橡树
    OJ-Triangle
    Myeclipse+AJAX+Servlet
    opnet学习过程
    yii2在ubuntu下执行定时任务
    php创建文件夹后设置文件夹权限(转)
    “Request Entity Too Large” 上传图片出现大小限制
    慕课网,我的yii2学习笔记(基础篇)
    Yii2高级版本复制新项目出现问题解决(转)
  • 原文地址:https://www.cnblogs.com/tk091/p/2481492.html
Copyright © 2011-2022 走看看