2019-2020-1 《信息安全系统设计基础》第1周学习总结


教材学习内容总结

  • 第一周要点:
    • 要点1:vim编辑器的基本操作;
    • 要点2:正则表达式基础;
    • 要点3:Linux C编程基础:
      • 编译器GCC;
      • 调试器GDB;
      • Makefile。
    • 要点4:教材第一章、第七章。

  • 教材第一章 “计算机系统漫游” 要点:
    • 要点1:信息就是位+上下文;
    • 要点2:存储设备形成层次结构;
    • 要点3:重要主题(概念):
      • Amdahl 定律;
      • 并发和并行;
      • 抽象。

  • 教材第七章 “链接” 要点:
    • 要点1:静态链接两个主要任务:
      • 符号解析;
      • 重定位。
    • 要点2:目标文件:
    • 要点3:符号和符号表;
    • 要点4:符号解析:
      • 链接器如何解析多重定义的全局符号;
      • (未完)


教材学习中的问题和解决过程

1. 生成二进制文件时命令错误。

根据PPT中:

的命令出错。

在如下项目结构中:

使用 gcc -c -I/include src/say_hello.c 命令出错。

复制src/say_hello.c:2:11: 致命错误:say_hello.h:没有那个文件或目录
    2 | # include "say_hello.h"
      |           ^~~~~~~~~~~~~
编译中断。
  • 问题原因分析:
    gcc命令格式出错,-I 应与 头文件所在目录 分离。

  • 问题解决方案:

-I头文件所在目录 分离,再将生成文件导出到 include 文件夹下,命令如下:

复制gcc -c -I include src/say_hello.c -o include/say_hello.o

可生成:

复制[yogile@yogile-pc gcc_test]$ tree
.
├── bin
├── include
│   ├── say_hello.h
│   └── say_hello.o
├── libs
├── makefile
├── Readme.md
└── src
    ├── main.c
    └── say_hello.c

4 directories, 6 files

2. 在最终链接时报错。

输入命令 gcc src/main.c -I include/ -L libs/ -o bin/main 报错。

复制[yogile@yogile-pc gcc_test]$ gcc src/main.c -I include/ -L libs/ -o bin/main
src/main.c: 在函数‘main’中:
src/main.c:5:2: 警告:隐式声明函数‘say_hello’ [-Wimplicit-function-declaration]
    5 |  say_hello();
      |  ^~~~~~~~~
/usr/bin/ld: /tmp/ccKSn7Vo.o: in function `main':
main.c:(.text+0xa): undefined reference to `say_hello'
collect2: 错误:ld 返回 1
  • 问题原因分析:
    发生"undefined reference to" 错误有多种原因(点击查看)。在这里是由于链接时缺失了二进制文件(say_hello.o)。

  • 问题解决方案:

方法一:
将命令中最开始的 "src/main.c" 改为"src/*.c" ,直接将所有的源文件一起重新汇编成二进制文件,再一起编译。

复制gcc src/*.c -I include/ -L libs/ -o bin/main

方法二:
直接将缺少的二进制文件加入编译命令,在 src/main.c -I 中间添加 include/say_hello.o

复制[yogile@yogile-pc gcc_test]$ gcc src/*.c -I include/ -L libs/ -o bin/main
[yogile@yogile-pc gcc_test]$ bin/main 
hello word

3. 静态函数库、动态函数库命令编译步骤。

  • 静态库
复制gcc -c -I include/ src/say_hello.c -o include/say_hello.o

ar rcvs libs/libsay_h.a include/say_hello.o
# 屏幕输出提示:r - include/say_hello.o

gcc src/*.c -I include/ -L libs/ -o bin/main

# 运行可执行文件即可:
[yogile@yogile-pc gcc_test]$ bin/main
hello word
  • 动态库
复制gcc -fPIC -c -I include/ src/say_hello.c -o include_so/say_hello.o

gcc -shared -o include_so/libsay_h.so include_so/say_hello.o

gcc src/main.c include_so/say_hello.o -I include/ -L libs/ -o bin/main_so

# 运行可执行文件即可:
[yogile@yogile-pc gcc_test]$ bin/main_so 
hello word
  • 创建的项目结构
项目结构
复制

4. 对链接器解析多重定义全局符号 规则 的疑惑。

强弱符号解析处理规则有三:

  1. 不允许多个同名的强符号;
  2. 若有一个强符号和多个弱符号同名,则则选择强符号;
  3. 若有多个弱符号同名,则任取一个。

疑惑1:对于规则2,若在 main.c 文件中,定义弱符号 x;在 module_2.c 文件中,定义强符号 x=3,在 main.c 中输出显示 x 为多少?
疑惑2:对于规则3,到底会选用哪个弱符号?

  • 分析回答:

回答疑惑1:
对于规则2,无论强符号在哪个模块定义,在其他模块调用同名符号时,链接器都会选择该模块的强符号,测试如下。

测试1
复制






作者:Yogile

出处:https://www.cnblogs.com/Yogile/p/11551624.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Yogile  阅读(250)  评论(0编辑  收藏  举报
编辑推荐:
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
阅读排行:
· 手把手教你更优雅的享受 DeepSeek
· AI工具推荐:领先的开源 AI 代码助手——Continue
· 探秘Transformer系列之(2)---总体架构
· V-Control:一个基于 .NET MAUI 的开箱即用的UI组件库
· 乌龟冬眠箱湿度监控系统和AI辅助建议功能的实现
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up light_mode palette
选择主题