当前位置: 首页 > news >正文

官网网站备案流程图互联网公司介绍文案

官网网站备案流程图,互联网公司介绍文案,学做网站视频教程,php网站如何做多语言Ⅰ、虚拟空间布局模型 理论模型 包括上节的动态库与静态库#xff0c;加上本节后面两个内容其实都是对gcc的扩展与补充知识#xff0c;也是需要了解和掌握的知识。在开讲之前#xff0c;我们先来说一下在32位x86的Linux系统中#xff0c;虚拟地址空间布局模型#xff1a…Ⅰ、虚拟空间布局模型 理论模型 包括上节的动态库与静态库加上本节后面两个内容其实都是对gcc的扩展与补充知识也是需要了解和掌握的知识。在开讲之前我们先来说一下在32位x86的Linux系统中虚拟地址空间布局模型系统编程阶段有重要意义 ①text段用来存放程序执行代码的内存区域。这部分区域的大小在程序运行前确定并且内存区域通常是只读(某些架构也允许代码段为可写即允许修改程序)。 ②rodata段read only data segment即只读数据段。存放一些只读的常数变量例如字符串常量等。 ③data段用来存放程序中已初始化的全局变量的内存区域属于静态内存分配。 ④bss段Block Started by Symbol的简称用来存放程序中未初始化的全局变量的内存区域属于静态内存分配。 ⑤heap堆区空间向上增长stack栈区空间向下增长。 ⑥stack和heap中间的部分用于存放我们的.so等文件 ⑦stack上方与内核中间那段空间是用来存放环境变量的。 tips真正的段空间不止这几个大概在30多个的样子吧。但那些对我们来说并没有很直接的关联暂时不提。例如plt就有一个与自己对应的段空间 当关闭终端时我们的虚拟内存就会“消失”然后我们重新打开终端时虚拟内存就会重新“出现”。所以我们使用export导入的环境变量例如前文提到的LD_LIBRARY_PATH所以这就是这个环境变量临时性的本质。注意这里并不是真的消失和出现而是说像我们运行C程序时一样定义的变量并不会在下次重新启动时依旧保存上次运行的状态 在初始化时bss段部分将会清零。bss段属于静态内存分配即程序一开始就将其清零了。比如在C语言之类的程序编译完成后已初始化的全局变量保存在.data段中未初始化的全局变量保存在.bss段中。 text和data段都在可执行文件中由系统从可执行文件中加载。 而bss段不在可执行文件中由系统初始化。 让我们先写一段代码来进行探究 实验一 使用vim test.c完成下面的代码的编写。完事后 :wq保存并退出。 使用objdump(为object-dump的缩写) -t 反汇编查看变量的存储位置 可以看到变量在内存中的位置与注释一致。上图中l代表local局部的g代表global全局的。然后我们再来运行一下test程序看一下打印出来的内存与上图有什么关联 我们再来对比一下两图找到bss_1在objdump -t查看的内存为000000000000401c而打印出来的是0x61e88502401c取末四位401c401c对应上了吧。经过这个实验我们可以发现data段确实是位于bss段的下方的。 实验二 使用vim创建m1.c然后再在末行模式输入:vsp m2.c分屏再建一个m2.c文件然后分别编写程序如下左m2.c右m1.c。最后在末行模式输入wqall保存并退出所有打开的文件。 此时已经退出了vim模式我们对这两个文件进行编译 我们发现m2编译之后比m1的文件要大很多。m1大小只有15800bm2大小却达到了27816b。所以此时我们打算继续使用objdump -t 反汇编来查看变量arr所在的存储位置 突然就发现不对劲了m1没有初始化arr所以m1中的arr处于bss段中而m2相反初始化为非零值所以m2的arr处于data段中。因为text、bss、data段在编译时已经决定了进程将占用多少VM所以我们使用size命令来查看一下两个文件的段的大小。 我们发现data段和bss段的大小的差别很大。所以问题肯定是出现在了这个上面。 然后我们使用objdump -s来查看两个文件中.data段中的数据可以看到有一长串的数据 m2 文件格式 elf64-x86-64 //省略 Contents of section .data:4000 00000000 00000000 08400000 00000000 ...............//....此处为个人删除省略内容....//此处省略了大约六万的字符数6ef0 00000000 00000000 00000000 00000000 ................ //省略 m1 文件格式 elf64-x86-64 //省略 Contents of section .data:4000 00000000 00000000 08400000 00000000 ............... //省略 .bss 是不占用.exe文件空间的其内容由操作系统初始化清零 .data 却需要占用其内容由程序初始化。因此造成了上述情况。 数据段合并和地址回填通常是操作系统和编译器在内存管理和程序加载时涉及的概念。 在 使用动态库 时就涉及到这两个操作 Ⅱ、数据段合并 数据段合并主要是在程序链接的过程中进行的。当多个目标文件被链接时它们可能包含多个相同类型的数据段例如 .data、.bss。链接器会将这些数据段合并成一个统一的数据段减少内存使用和提高访问效率。 将上面的图拿过来进行说明 提前声明每个段的空间为1个页page的大小--4K。 在该内存中每个段都会有访问权限对于该图中的text段和rodata段都是ro权限而data和bss段是rw权限。如果text段和rodata都单独占一个段空间那么就会占用两个4K的空间所以为了节省空间在链接阶段我们有一个数据段合并的过程并不是说只合并数据段很多段都会根据标准进行合并这里给出四个段 text段与rodata段说你也是只读我也是只读咱俩凑合凑合过吧然后就进行合并了data和bss段也一样进行合并了那么就节省了至少2个4K的空间。 Ⅲ、地址回填 地址回填是指在程序的加载或链接过程中将目标文件中使用的符号地址转换为实际内存地址的过程。当程序被加载到内存中时操作系统需要将符号如函数或变量的地址填充到代码和数据段中以便程序能顺利运行。 在main函数中里面有两个函数fuc1和fuc2这两个函数在链接阶段进行地址回填。那么怎么进行地址回填呢这通常涉及到以下几个步骤 符号解析将符号名称解析为实际的内存地址。地址替换在目标文件中占位符的地址被实际计算出的地址所替换。重定位处理程序在不同内存地址加载时需要调整地址代码和数据。 完成链接后得到的a.out的地址是以main函数地址为依据的。 假设main的地址为1000那么func1依据main而定义假设间隔为100那么func1的地址就为1000100假设func2与main间隔为200那么func2的地址就为1000200。 但是我们也说了这是完成链接后的事情在完成编译后的main.o文件中main的地址标记为0。但下面的关系依然存在那也就是说 当从hello.o执行到a.out的操作过程中我们就完成了链接在链接的过程中进行了一个地址回填看一下填的是什么其实填的就是main的地址本来main的地址以main符代替链接完然main具有地址后就会将地址进行回填。 那么制作动态库呢制作动态库时func1、func2被制成了.o文件那func1和func2还是以main作为依据吗不是了。因为动态库内的函数调用方法与文件内的函数的调用时处理方法不同。 先创建一个test.c文件 然后我们使用objdump -dS 来查看反汇编 test.shared 文件格式 elf64-x86-64Disassembly of section .init:0000000000001000 _init:1000: f3 0f 1e fa endbr64 1004: 48 83 ec 08 sub $0x8,%rsp1008: 48 8b 05 d9 2f 00 00 mov 0x2fd9(%rip),%rax # 3fe8 __gmon_start__Base100f: 48 85 c0 test %rax,%rax1012: 74 02 je 1016 _init0x161014: ff d0 call *%rax1016: 48 83 c4 08 add $0x8,%rsp101a: c3 ret Disassembly of section .plt:0000000000001020 .plt:1020: ff 35 8a 2f 00 00 push 0x2f8a(%rip) # 3fb0 _GLOBAL_OFFSET_TABLE_0x81026: f2 ff 25 8b 2f 00 00 bnd jmp *0x2f8b(%rip) # 3fb8 _GLOBAL_OFFSET_TABLE_0x10102d: 0f 1f 00 nopl (%rax)1030: f3 0f 1e fa endbr64 1034: 68 00 00 00 00 push $0x01039: f2 e9 e1 ff ff ff bnd jmp 1020 _init0x20103f: 90 nop1040: f3 0f 1e fa endbr64 1044: 68 01 00 00 00 push $0x11049: f2 e9 d1 ff ff ff bnd jmp 1020 _init0x20104f: 90 nop1050: f3 0f 1e fa endbr64 1054: 68 02 00 00 00 push $0x21059: f2 e9 c1 ff ff ff bnd jmp 1020 _init0x20105f: 90 nopDisassembly of section .plt.got:0000000000001060 __cxa_finalizeplt:1060: f3 0f 1e fa endbr64 1064: f2 ff 25 8d 2f 00 00 bnd jmp *0x2f8d(%rip) # 3ff8 __cxa_finalizeGLIBC_2.2.5106b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)Disassembly of section .plt.sec:0000000000001070 addplt:1070: f3 0f 1e fa endbr64 1074: f2 ff 25 45 2f 00 00 bnd jmp *0x2f45(%rip) # 3fc0 addBase107b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)0000000000001080 printfplt:1080: f3 0f 1e fa endbr64 1084: f2 ff 25 3d 2f 00 00 bnd jmp *0x2f3d(%rip) # 3fc8 printfGLIBC_2.2.5108b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)0000000000001090 subplt:1090: f3 0f 1e fa endbr64 1094: f2 ff 25 35 2f 00 00 bnd jmp *0x2f35(%rip) # 3fd0 subBase109b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)Disassembly of section .text:00000000000010a0 _start:10a0: f3 0f 1e fa endbr64 10a4: 31 ed xor %ebp,%ebp10a6: 49 89 d1 mov %rdx,%r910a9: 5e pop %rsi10aa: 48 89 e2 mov %rsp,%rdx10ad: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp10b1: 50 push %rax10b2: 54 push %rsp10b3: 45 31 c0 xor %r8d,%r8d10b6: 31 c9 xor %ecx,%ecx10b8: 48 8d 3d e1 00 00 00 lea 0xe1(%rip),%rdi # 11a0 main10bf: ff 15 13 2f 00 00 call *0x2f13(%rip) # 3fd8 __libc_start_mainGLIBC_2.3410c5: f4 hlt 10c6: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1)10cd: 00 00 00 00000000000010d0 deregister_tm_clones:10d0: 48 8d 3d 39 2f 00 00 lea 0x2f39(%rip),%rdi # 4010 __TMC_END__10d7: 48 8d 05 32 2f 00 00 lea 0x2f32(%rip),%rax # 4010 __TMC_END__10de: 48 39 f8 cmp %rdi,%rax10e1: 74 15 je 10f8 deregister_tm_clones0x2810e3: 48 8b 05 f6 2e 00 00 mov 0x2ef6(%rip),%rax # 3fe0 _ITM_deregisterTMCloneTableBase10ea: 48 85 c0 test %rax,%rax10ed: 74 09 je 10f8 deregister_tm_clones0x2810ef: ff e0 jmp *%rax10f1: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)10f8: c3 ret 10f9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)0000000000001100 register_tm_clones:1100: 48 8d 3d 09 2f 00 00 lea 0x2f09(%rip),%rdi # 4010 __TMC_END__1107: 48 8d 35 02 2f 00 00 lea 0x2f02(%rip),%rsi # 4010 __TMC_END__110e: 48 29 fe sub %rdi,%rsi1111: 48 89 f0 mov %rsi,%rax1114: 48 c1 ee 3f shr $0x3f,%rsi1118: 48 c1 f8 03 sar $0x3,%rax111c: 48 01 c6 add %rax,%rsi111f: 48 d1 fe sar %rsi1122: 74 14 je 1138 register_tm_clones0x381124: 48 8b 05 c5 2e 00 00 mov 0x2ec5(%rip),%rax # 3ff0 _ITM_registerTMCloneTableBase112b: 48 85 c0 test %rax,%rax112e: 74 08 je 1138 register_tm_clones0x381130: ff e0 jmp *%rax1132: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)1138: c3 ret 1139: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)0000000000001140 __do_global_dtors_aux:1140: f3 0f 1e fa endbr64 1144: 80 3d c5 2e 00 00 00 cmpb $0x0,0x2ec5(%rip) # 4010 __TMC_END__114b: 75 2b jne 1178 __do_global_dtors_aux0x38114d: 55 push %rbp114e: 48 83 3d a2 2e 00 00 cmpq $0x0,0x2ea2(%rip) # 3ff8 __cxa_finalizeGLIBC_2.2.51155: 00 1156: 48 89 e5 mov %rsp,%rbp1159: 74 0c je 1167 __do_global_dtors_aux0x27115b: 48 8b 3d a6 2e 00 00 mov 0x2ea6(%rip),%rdi # 4008 __dso_handle1162: e8 f9 fe ff ff call 1060 __cxa_finalizeplt1167: e8 64 ff ff ff call 10d0 deregister_tm_clones116c: c6 05 9d 2e 00 00 01 movb $0x1,0x2e9d(%rip) # 4010 __TMC_END__1173: 5d pop %rbp1174: c3 ret 1175: 0f 1f 00 nopl (%rax)1178: c3 ret 1179: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)0000000000001180 frame_dummy:1180: f3 0f 1e fa endbr64 1184: e9 77 ff ff ff jmp 1100 register_tm_clones0000000000001189 mul:1189: f3 0f 1e fa endbr64 118d: 55 push %rbp118e: 48 89 e5 mov %rsp,%rbp1191: 89 7d fc mov %edi,-0x4(%rbp)1194: 89 75 f8 mov %esi,-0x8(%rbp)1197: 8b 45 fc mov -0x4(%rbp),%eax119a: 0f af 45 f8 imul -0x8(%rbp),%eax119e: 5d pop %rbp119f: c3 ret 00000000000011a0 main:11a0: f3 0f 1e fa endbr64 11a4: 55 push %rbp11a5: 48 89 e5 mov %rsp,%rbp11a8: 48 83 ec 20 sub $0x20,%rsp11ac: 89 7d ec mov %edi,-0x14(%rbp)11af: 48 89 75 e0 mov %rsi,-0x20(%rbp)11b3: c7 45 f8 0a 00 00 00 movl $0xa,-0x8(%rbp)11ba: c7 45 fc 05 00 00 00 movl $0x5,-0x4(%rbp)11c1: 8b 55 fc mov -0x4(%rbp),%edx11c4: 8b 45 f8 mov -0x8(%rbp),%eax11c7: 89 d6 mov %edx,%esi11c9: 89 c7 mov %eax,%edi11cb: e8 a0 fe ff ff call 1070 addplt11d0: 89 c1 mov %eax,%ecx11d2: 8b 55 fc mov -0x4(%rbp),%edx11d5: 8b 45 f8 mov -0x8(%rbp),%eax11d8: 89 c6 mov %eax,%esi11da: 48 8d 05 23 0e 00 00 lea 0xe23(%rip),%rax # 2004 _IO_stdin_used0x411e1: 48 89 c7 mov %rax,%rdi11e4: b8 00 00 00 00 mov $0x0,%eax11e9: e8 92 fe ff ff call 1080 printfplt11ee: 8b 55 fc mov -0x4(%rbp),%edx11f1: 8b 45 f8 mov -0x8(%rbp),%eax11f4: 89 d6 mov %edx,%esi11f6: 89 c7 mov %eax,%edi11f8: e8 93 fe ff ff call 1090 subplt11fd: 89 c1 mov %eax,%ecx11ff: 8b 55 fc mov -0x4(%rbp),%edx1202: 8b 45 f8 mov -0x8(%rbp),%eax1205: 89 c6 mov %eax,%esi1207: 48 8d 05 04 0e 00 00 lea 0xe04(%rip),%rax # 2012 _IO_stdin_used0x12120e: 48 89 c7 mov %rax,%rdi1211: b8 00 00 00 00 mov $0x0,%eax1216: e8 65 fe ff ff call 1080 printfplt121b: 8b 55 fc mov -0x4(%rbp),%edx121e: 8b 45 f8 mov -0x8(%rbp),%eax1221: 89 d6 mov %edx,%esi1223: 89 c7 mov %eax,%edi1225: e8 5f ff ff ff call 1189 mul122a: 89 c1 mov %eax,%ecx122c: 8b 55 fc mov -0x4(%rbp),%edx122f: 8b 45 f8 mov -0x8(%rbp),%eax1232: 89 c6 mov %eax,%esi1234: 48 8d 05 e5 0d 00 00 lea 0xde5(%rip),%rax # 2020 _IO_stdin_used0x20123b: 48 89 c7 mov %rax,%rdi123e: b8 00 00 00 00 mov $0x0,%eax1243: e8 38 fe ff ff call 1080 printfplt1248: b8 00 00 00 00 mov $0x0,%eax124d: c9 leave 124e: c3 ret Disassembly of section .fini:0000000000001250 _fini:1250: f3 0f 1e fa endbr64 1254: 48 83 ec 08 sub $0x8,%rsp1258: 48 83 c4 08 add $0x8,%rsp125c: c3 ret 看一下main函数中的调用语句 #11cb: e8 a0 fe ff ff call 1070 addplt11d0: 89 c1 mov %eax,%ecx11d2: 8b 55 fc mov -0x4(%rbp),%edx11d5: 8b 45 f8 mov -0x8(%rbp),%eax11d8: 89 c6 mov %eax,%esi#1225: e8 5f ff ff ff call 1189 mul122a: 89 c1 mov %eax,%ecx122c: 8b 55 fc mov -0x4(%rbp),%edx122f: 8b 45 f8 mov -0x8(%rbp),%eax1232: 89 c6 mov %eax,%esi所以说我们的调用方式是看不出任何问题的因为我们说了区别在于调用函数之后的处理方式。 我们将mul和add(或sub)拉出来对比 我们发现动态库中的函数后面会有一个plt后缀而且执行的语句也不一样。调用mul函数后利用push压栈mov赋值pop出栈等常规操作处理该函数但调用add函数后利用的时bnd jmp跳转到动态库中进行操作。plt是一个与程序链接和运行时符号解析相关的概念 PLTProcedure linkage Table--过程链接表是动态链接的一个结构主要用于解决动态函数调用尤其是未解析的外部函数。工作原理 动态链接当一个程序调用一个动态链接库中的函数时这个函数的地址在编译时并不确定因此在编译时并没有直接的地址。相反编译器写入指向 PLT 中相应入口的调用。 PLT 表项每个外部函数例如一个来自共享库的函数都有一个 PLT 表项。当一个函数被调用时程序首先跳转到 PLT 表项。 首次调用在首次调用该函数时PLT 将控制权传递给动态链接器通常是 ld-linux.so该链接器负责解析该函数的实际地址。这时动态链接器会更新 PLT 中的表项将实际地址填入以便后续调用可以直接跳转到该地址。 性能优势使用 PLT可以在不需要提前链接所有外部符号的情况下启动和运行程序简化了链接过程并支持共享库的动态更新 当程序第一次调用 动态库函数add 时它会跳转到 add 的 PLT 条目这样动态链接器会处理真正的地址解析。 可以使用 objdump 或 gdb 等工具查看编译后的程序的 PLT 表。例如使用以下命令 objdump -D test.shared | grep add 这是运行结果截出来的两段内容这就是程序跟add有关的PLT表显示了add在PLT中的地址 因为调用动态库的函数比程序文件自己的函数慢所以有些地方会描述动态库为延迟绑定。 结论生成.o文件时要求生成与位置无关的代码也就是加-fPIC选项的目的。 假设我们有多个目标文件每个文件都有一个全局变量count。链接器会将这些变量合并只保留一份并分配一个内存地址之后所有对count的引用将在运行时替换为这个地址。 感谢大家
http://www.hkea.cn/news/14372968/

相关文章:

  • 怎么做网站导航栏怎样建设手机网站
  • 做金融网站有哪些要求建设网站企业邮箱
  • 北京东直门网站建设编程怎样自学
  • 智能网站建设软件有哪些方面做科技汽车的视频网站有哪些
  • 哪里做网络推广好网站代码优化方法
  • 阜阳交通建设工程质监局网站比wordpress轻量的
  • j2ee只做网站做招商加盟做得比较好的网站
  • 福建自适应网站建设卢松松网站的百度广告怎么做的
  • 网站群建设公司排行榜6建设网站专业公司
  • 网站搭建后台mt7620a做网站
  • 网站建设教程科普网页设计心得体会2000字
  • 如何做百度的网站微信公众平台开发软件
  • 后台查看网站容量大街网企业招聘官网
  • 资源最多的磁力搜索引擎东莞seo优化seo关键词
  • 物流网站建设推广网站模板文件怎么下载
  • 新乡微信网站建设助君网络怎么样
  • 深圳企业网站ui设计app
  • 教育技术学网站模版国内最新消息新闻
  • 无极领域网站加盟平台
  • 购物网站项目建设内容网站建设的特点
  • 免费卖货平台行者seo
  • 简约手机网站源码把网站打包微信小程序
  • 中国可信网站查询如何下载网页在线视频
  • 网站虚拟主机管理小说网站的图片长图怎么做的
  • 网站建设定制开发软文范例
  • 青岛网站排名外包企业logo设计软件
  • 建设银行人力资源网站做版面的网站
  • 怎么可以联系到网站开发者苏州做网站优化哪家好
  • 网站推广策划书模板住建局特种作业证
  • 查排名网站长沙3合1网站建设