http://521daxue.wikidot.com/hmwangduh https://vk.com/id690753581 https://vk.com/public209578729 https://vk.com/public209578716 https://vk.com/public209578706 https://vk.com/public209578700 https://vk.com/public209578693 https://vk.com/public209578677 https://vk.com/public209578671 https://vk.com/public209578660 https://vk.com/public209578655 https://vk.com/public209578647 https://vk.com/public209578639 https://vk.com/public209578620 https://vk.com/public209511857 https://vk.com/public209511580 https://vk.com/public209511287 https://vk.com/public209511116 https://vk.com/public209510911 https://vk.com/public209510773 https://vk.com/public209510425 https://vk.com/public209510300 https://vk.com/public209510020 https://vk.com/public209509912 https://vk.com/public209509711 https://vk.com/public209509707 https://vk.com/public209509699 https://vk.com/public209468344 https://vk.com/public209468335 https://vk.com/public209468320 https://vk.com/public209468312 https://vk.com/public209468304 https://vk.com/public209468299 https://vk.com/public209468293 https://vk.com/public209468283 https://vk.com/public209468271 https://vk.com/public209468261 https://vk.com/public209468250 https://vk.com/public209468240 https://vk.com/public209468230 https://vk.com/public209428688 https://vk.com/public209428684 https://vk.com/public209428672 https://vk.com/public209428669 https://vk.com/public209428665 https://vk.com/public209428661 https://vk.com/public209428659 https://vk.com/public209428656 https://vk.com/public209428653 https://vk.com/public209428651 https://vk.com/public209428646 https://vk.com/public209428641 https://vk.com/public209428633 https://vk.com/public209371893 https://vk.com/public209371887 https://vk.com/public209371877 https://vk.com/public209371858 https://vk.com/public209371852 https://vk.com/public209371841 https://vk.com/public209371834 https://vk.com/public209371813 https://vk.com/public209371826 https://vk.com/public209371802 https://vk.com/public209371790 https://vk.com/public209371780 https://vk.com/public209298957 https://vk.com/public209298947 https://vk.com/public209298934 https://vk.com/public209298926 https://vk.com/public209298917 https://vk.com/public209298875 https://vk.com/public209298871 https://vk.com/public209298862 https://vk.com/public209298719 https://vk.com/public209298858 https://vk.com/public209298843 https://vk.com/public209250048 https://vk.com/public209250049 https://vk.com/public209298805 https://vk.com/public209298789 https://vk.com/public209250046 https://vk.com/public209249995 https://vk.com/public209249993 https://vk.com/public209249990 https://vk.com/public209211432 https://vk.com/public209249983 https://vk.com/public209249955 https://vk.com/public209249951 https://vk.com/public209249946 https://vk.com/public209249859 https://vk.com/public209249942 https://vk.com/public209249892 https://vk.com/id691331608 https://vk.com/public209578989 https://vk.com/public209578950 https://vk.com/public209578938 https://vk.com/public209578933 https://vk.com/public209578925 https://vk.com/public209578914 https://vk.com/public209578899 https://vk.com/public209578888 https://vk.com/public209578880 https://vk.com/public209578893 https://vk.com/public209578873 https://vk.com/public209578867 https://vk.com/public209578862 https://vk.com/public209512875 https://vk.com/public209512865 https://vk.com/public209512856 https://vk.com/public209512847 https://vk.com/public209512843 https://vk.com/public209512838 https://vk.com/public209512826 https://vk.com/public209512816 https://vk.com/public209512811 https://vk.com/public209512801 https://vk.com/public209512791 https://vk.com/public209512748 https://vk.com/public209512718 https://vk.com/public209468471 https://vk.com/public209468465 https://vk.com/public209468449 https://vk.com/public209468440 https://vk.com/public209468455 https://vk.com/public209468436 https://vk.com/public209468430 https://vk.com/public209468423 https://vk.com/public209468420 https://vk.com/public209468418 https://vk.com/public209468400 https://vk.com/public209468391 https://vk.com/public209468380 https://vk.com/public209428748 https://vk.com/public209428746 https://vk.com/public209428735 https://vk.com/public209428738 https://vk.com/public209428732 https://vk.com/public209428729 https://vk.com/public209428726 https://vk.com/public209428723 https://vk.com/public209428721 https://vk.com/public209428705 https://vk.com/public209428700 https://vk.com/public209428710 https://vk.com/public209372099 https://vk.com/public209372093 https://vk.com/public209372086 https://vk.com/public209372073 https://vk.com/public209372066 https://vk.com/public209372059 https://vk.com/public209372050 https://vk.com/public209372042 https://vk.com/public209372033 https://vk.com/public209372028 https://vk.com/public209372018 https://vk.com/public209372011 https://vk.com/public209300371 https://vk.com/public209300362 https://vk.com/public209300352 https://vk.com/public209300343 https://vk.com/public209300333 https://vk.com/public209300325 https://vk.com/public209300315 https://vk.com/public209300304 https://vk.com/public209300300 https://vk.com/public209300297 https://vk.com/public209300275 https://vk.com/public209300271 https://vk.com/public209300252 https://vk.com/id691333652 https://vk.com/public209579274 https://vk.com/public209579265 https://vk.com/public209579260 https://vk.com/public209579251 https://vk.com/public209579240 https://vk.com/public209579232 https://vk.com/public209579224 https://vk.com/public209579217 https://vk.com/public209579208 https://vk.com/public209579199 https://vk.com/public209579187 https://vk.com/public209579176 https://vk.com/public209579168 https://vk.com/public209513027 https://vk.com/public209513018 https://vk.com/public209513011 https://vk.com/public209513004 https://vk.com/public209512995 https://vk.com/public209512986 https://vk.com/public209512977 https://vk.com/public209512971 https://vk.com/public209512966 https://vk.com/public209512957 https://vk.com/public209512953 https://vk.com/public209512946 https://vk.com/public209512938 https://vk.com/public209468590 https://vk.com/public209468563 https://vk.com/public209468557 https://vk.com/public209468551 https://vk.com/public209468544 https://vk.com/public209468537 https://vk.com/public209468527 https://vk.com/public209468523 https://vk.com/public209468515 https://vk.com/public209468505 https://vk.com/public209468499 https://vk.com/public209468493 https://vk.com/public209428794 https://vk.com/public209428790 https://vk.com/public209428788 https://vk.com/public209428785 https://vk.com/public209428780 https://vk.com/public209428777 https://vk.com/public209428774 https://vk.com/public209428771 https://vk.com/public209428768 https://vk.com/public209428766 https://vk.com/public209428761 https://vk.com/public209428759 https://vk.com/public209428755 https://vk.com/public209372256 https://vk.com/public209372248 https://vk.com/public209372245 https://vk.com/public209372227 https://vk.com/public209372216 https://vk.com/public209372238 https://vk.com/public209372200 https://vk.com/public209372196 https://vk.com/public209372175 https://vk.com/public209372184 https://vk.com/public209372161 https://vk.com/public209372138 https://vk.com/public209300713 https://vk.com/public209300701 https://vk.com/public209372149 https://vk.com/public209300682 https://vk.com/public209300675 https://vk.com/public209300660 https://vk.com/public209300654 https://vk.com/public209300616 https://vk.com/public209300624 https://vk.com/public209300610 https://vk.com/public209300604 https://vk.com/public209300592 https://vk.com/public209300584 https://vk.com/public209300527 https://vk.com/id691338584 https://vk.com/public209579598 https://vk.com/public209579588 https://vk.com/public209579579 https://vk.com/public209579574 https://vk.com/public209579568 https://vk.com/public209579560 https://vk.com/public209579549 https://vk.com/public209579535 https://vk.com/public209579527 https://vk.com/public209579522 https://vk.com/public209579514 https://vk.com/public209579508 https://vk.com/public209579500 https://vk.com/public209513195 https://vk.com/public209513186 https://vk.com/public209513173 https://vk.com/public209513165 https://vk.com/public209513151 https://vk.com/public209513142 https://vk.com/public209513118 https://vk.com/public209513114 https://vk.com/public209513109 https://vk.com/public209513099 https://vk.com/public209513083 https://vk.com/public209513078 https://vk.com/public209513063 https://vk.com/public209468710 https://vk.com/public209468704 https://vk.com/public209468692 https://vk.com/public209468685 https://vk.com/public209468681 https://vk.com/public209468673 https://vk.com/public209468664 https://vk.com/public209468659 https://vk.com/public209468649 https://vk.com/public209468644 https://vk.com/public209468636 https://vk.com/public209468629 https://vk.com/public209468622 https://vk.com/public209428854 https://vk.com/public209428850 https://vk.com/public209428846 https://vk.com/public209428840 https://vk.com/public209428836 https://vk.com/public209428832 https://vk.com/public209428828 https://vk.com/public209428825 https://vk.com/public209428823 https://vk.com/public209428818 https://vk.com/public209428809 https://vk.com/public209428808 https://vk.com/public209428804 https://vk.com/public209372563 https://vk.com/public209372541 https://vk.com/public209372512 https://vk.com/public209372485 https://vk.com/public209372457 https://vk.com/public209372402 https://vk.com/public209372429 https://vk.com/public209372379 https://vk.com/public209372370 https://vk.com/public209372352 https://vk.com/public209372345 https://vk.com/public209372364 https://vk.com/public209372337 https://vk.com/public209302220 https://vk.com/public209302215 https://vk.com/public209302204 https://vk.com/public209302191 https://vk.com/public209302182 https://vk.com/public209302173 https://vk.com/public209302166 https://vk.com/public209302150 https://vk.com/public209302146 https://vk.com/public209302138 https://vk.com/public209302131 https://vk.com/public209302036 https://vk.com/public209301900 https://vk.com/public209301786 https://vk.com/id691343832 https://vk.com/public209579817 https://vk.com/public209579811 https://vk.com/public209579800 https://vk.com/public209579793 https://vk.com/public209579774 https://vk.com/public209579784 https://vk.com/public209579758 https://vk.com/public209579762 https://vk.com/public209579752 https://vk.com/public209579741 https://vk.com/public209579732 https://vk.com/public209579725 https://vk.com/public209513346 https://vk.com/public209513337 https://vk.com/public209579724 https://vk.com/public209513322 https://vk.com/public209513316 https://vk.com/public209513305 https://vk.com/public209513297 https://vk.com/public209513281 https://vk.com/public209513270 https://vk.com/public209513264 https://vk.com/public209513258 https://vk.com/public209513244 https://vk.com/public209513238 https://vk.com/public209513227 https://vk.com/public209468855 https://vk.com/public209468797 https://vk.com/public209468790 https://vk.com/public209468806 https://vk.com/public209468775 https://vk.com/public209468784 https://vk.com/public209468763 https://vk.com/public209468753 https://vk.com/public209468746 https://vk.com/public209468741 https://vk.com/public209468734 https://vk.com/public209468732 https://vk.com/public209468726 https://vk.com/public209428902 https://vk.com/public209428898 https://vk.com/public209428896 https://vk.com/public209428891 https://vk.com/public209428887 https://vk.com/public209428892 https://vk.com/public209428879 https://vk.com/public209428881 https://vk.com/public209428876 https://vk.com/public209428863 https://vk.com/public209428861 https://vk.com/public209428858 https://vk.com/public209428856 https://vk.com/public209372843 https://vk.com/public209372837 https://vk.com/public209372833 https://vk.com/public209372826 https://vk.com/public209372822 https://vk.com/public209372811 https://vk.com/public209372767 https://vk.com/public209372715 https://vk.com/public209372777 https://vk.com/public209372739 https://vk.com/public209372696 https://vk.com/public209372679 https://vk.com/public209302709 https://vk.com/public209302701 https://vk.com/public209302695 https://vk.com/public209302683 https://vk.com/public209302648 https://vk.com/public209302675 https://vk.com/public209302662 https://vk.com/public209302640 https://vk.com/public209302634 https://vk.com/public209302628 https://vk.com/public209302606 https://vk.com/public209302599 https://vk.com/public209302591 https://vk.com/id691579795 https://vk.com/public209580125 https://vk.com/public209580120 https://vk.com/public209580107 https://vk.com/public209580094 https://vk.com/public209580091 https://vk.com/public209580079 https://vk.com/public209580074 https://vk.com/public209580068 https://vk.com/public209580055 https://vk.com/public209580045 https://vk.com/public209580059 https://vk.com/public209580034 https://vk.com/public209580027 https://vk.com/public209513550 https://vk.com/public209513547 https://vk.com/public209513535 https://vk.com/public209513526 https://vk.com/public209513522 https://vk.com/public209513514 https://vk.com/public209513504 https://vk.com/public209513495 https://vk.com/public209513486 https://vk.com/public209513476 https://vk.com/public209513440 https://vk.com/public209513413 https://vk.com/public209468973 https://vk.com/public209513403 https://vk.com/public209468965 https://vk.com/public209468943 https://vk.com/public209468937 https://vk.com/public209468922 https://vk.com/public209468915 https://vk.com/public209468909 https://vk.com/public209468905 https://vk.com/public209468900 https://vk.com/public209468895 https://vk.com/public209468885 https://vk.com/public209468879 https://vk.com/public209468874 https://vk.com/public209428950 https://vk.com/public209428945 https://vk.com/public209428939 https://vk.com/public209428936 https://vk.com/public209428934 https://vk.com/public209428942 https://vk.com/public209428913 https://vk.com/public209428926 https://vk.com/public209428922 https://vk.com/public209428920 https://vk.com/public209428917 https://vk.com/public209428909 https://vk.com/public209428908 https://vk.com/public209373045 https://vk.com/public209373037 https://vk.com/public209373029 https://vk.com/public209373015 https://vk.com/public209373004 https://vk.com/public209372991 https://vk.com/public209372979 https://vk.com/public209372955 https://vk.com/public209372947 https://vk.com/public209372929 https://vk.com/public209372901 https://vk.com/public209372880 https://vk.com/public209372893

【转载】C 代码是如何跑起来的

C 语言提供了什么

C 语言作为高级语言,为程序员提供了更友好的表达方式。在我看来,主要是提供了以下抽象能力:

  1. 变量,以及延伸出来的复杂结构体
    我们可以基于变量来描述复杂的状态。
  2. 函数
    我们可以基于函数,把复杂的行为逻辑,拆分到不同的函数里,以简化复杂的逻辑以。以及,我们可以复用相同目的的函数,现实世界里大量的基础库,简化了程序员的编码工作。

示例代码

构建一个良好的示例代码,可以很好帮助我们去理解。
下面的示例里,我们可以看到 变量 和 函数 都用上了。

#include "stdio.h"

int add (int a, int b) {
    return a + b;
}

int main () {
    int a = 1;
    int b = 2;
    int c = add(a, b);

    printf("a + b = %d\n", c);

    return 0;
}

编译执行

毫无意外,我们得到了期望的 3

$ gcc -O0 -g3 -Wall -o simple simple.c
$ ./simple
a + b = 3

汇编代码

我们还是用 objdump 来看看,编译器生成了什么代码:

  1. 变量
    局部变量,包括函数参数,全部被压入了 栈 里。
  2. 函数
    函数本身,被单独编译为了一段机器指令
    函数调用,被编译为了 call 指令,参数则是函数对应那一段机器指令的第一个指令地址。
$ objdump -M intel -j .text -d simple

# 截取其中最重要的部分

000000000040052d <add>:
  40052d:       55                      push   rbp
  40052e:       48 89 e5                mov    rbp,rsp
  400531:       89 7d fc                mov    DWORD PTR [rbp-0x4],edi
  400534:       89 75 f8                mov    DWORD PTR [rbp-0x8],esi
  400537:       8b 45 f8                mov    eax,DWORD PTR [rbp-0x8]
  40053a:       8b 55 fc                mov    edx,DWORD PTR [rbp-0x4]
  40053d:       01 d0                   add    eax,edx
  40053f:       5d                      pop    rbp
  400540:       c3                      ret

0000000000400541 <main>:
  400541:       55                      push   rbp
  400542:       48 89 e5                mov    rbp,rsp
  400545:       48 83 ec 10             sub    rsp,0x10
  400549:       c7 45 fc 01 00 00 00    mov    DWORD PTR [rbp-0x4],0x1
  400550:       c7 45 f8 02 00 00 00    mov    DWORD PTR [rbp-0x8],0x2
  400557:       8b 55 f8                mov    edx,DWORD PTR [rbp-0x8]
  40055a:       8b 45 fc                mov    eax,DWORD PTR [rbp-0x4]
  40055d:       89 d6                   mov    esi,edx
  40055f:       89 c7                   mov    edi,eax
  400561:       e8 c7 ff ff ff          call   40052d <add>
  400566:       89 45 f4                mov    DWORD PTR [rbp-0xc],eax
  400569:       8b 45 f4                mov    eax,DWORD PTR [rbp-0xc]
  40056c:       89 c6                   mov    esi,eax
  40056e:       bf 20 06 40 00          mov    edi,0x400620
  400573:       b8 00 00 00 00          mov    eax,0x0
  400578:       e8 93 fe ff ff          call   400410 <printf@plt>
  40057d:       b8 00 00 00 00          mov    eax,0x0
  400582:       c9                      leave
  400583:       c3                      ret
  400584:       66 2e 0f 1f 84 00 00    nop    WORD PTR cs:[rax+rax*1+0x0]
  40058b:       00 00 00
  40058e:       66 90                   xchg   ax,ax

函数内的局部变量,为什么会放入栈空间呢?

这个刚好和局部变量的作用域关联起来了:

  1. 函数执行结束,返回的时候,局部变量也应该失效了
  2. 函数返回的时候,刚好要恢复栈高度到上一个调用者函数。

这样的话,只需要栈高度恢复,也就意味着被调用函数的所有的临时变量,全部失效了。

函数内的局部变量,一定会放入栈空间吗?

答案是,不一定。
上面我们是通过 -O0 编译的,接下来,我们看下 -O1 编译生成的机器码。

此时的局部变量直接放在寄存器里了,不需要写入到栈空间了。
不过,此时 main 都已经不再调用 add 函数了,因为已经被 gcc 内联优化了。
好吧,构建个合适的用例也不容易。

000000000040052d <add>:
  40052d:       8d 04 37                lea    eax,[rdi+rsi*1]
  400530:       c3                      ret

0000000000400531 <main>:
  400531:       48 83 ec 08             sub    rsp,0x8
  400535:       be 03 00 00 00          mov    esi,0x3
  40053a:       bf f0 05 40 00          mov    edi,0x4005f0
  40053f:       b8 00 00 00 00          mov    eax,0x0
  400544:       e8 c7 fe ff ff          call   400410 <printf@plt>
  400549:       b8 00 00 00 00          mov    eax,0x0
  40054e:       48 83 c4 08             add    rsp,0x8
  400552:       c3                      ret
  400553:       66 2e 0f 1f 84 00 00    nop    WORD PTR cs:[rax+rax*1+0x0]
  40055a:       00 00 00
  40055d:       0f 1f 00                nop    DWORD PTR [rax]

禁止内联优化

我们用如下命令,关闭 gcc 的内联优化:

gcc -fno-inline -O1 -g3 -Wall -o simple simple.c

再来看下汇编代码,此时的机器码就符合理想的验证结果了。

000000000040052d <add>:
  40052d:       8d 04 37                lea    eax,[rdi+rsi*1]
  400530:       c3                      ret

0000000000400531 <main>:
  400531:       48 83 ec 08             sub    rsp,0x8
  400535:       be 02 00 00 00          mov    esi,0x2
  40053a:       bf 01 00 00 00          mov    edi,0x1
  40053f:       e8 e9 ff ff ff          call   40052d <add>
  400544:       89 c6                   mov    esi,eax
  400546:       bf f0 05 40 00          mov    edi,0x4005f0
  40054b:       b8 00 00 00 00          mov    eax,0x0
  400550:       e8 bb fe ff ff          call   400410 <printf@plt>
  400555:       b8 00 00 00 00          mov    eax,0x0
  40055a:       48 83 c4 08             add    rsp,0x8
  40055e:       c3                      ret
  40055f:       90                      nop

总结

    1. 对于 C 语言的变量,编译器会为其分配一段内存空间来存储
      函数内的局部变量,放入栈空间是理想的映射方式。不过编译的优化模式下,则会尽量使用寄存器来存储,寄存器不够用了,才会使用栈空间。
      全局变量,则有对应的内存段来存储,这个以后可以再聊。
    2. 对于 C 语言的函数,编译器会编译为独立的一段机器指令
      调用该函数,则是执行 call 指令,意思是接下来跳转到执行这一段机器指令。
posted @ 2021-05-06 16:12  前所未有  阅读(263)  评论(0)    收藏  举报
http://energyfuture.wikidot.com/