2019-2020-1 20209313《Linux内核原理与分析》第二周作业

零、总结

阐明自己对“计算机是如何工作的”理解。

一、myod

步骤

  1. 复习c文件处理内容
  2. 编写myod.c 用myod XXX实现Linux下od -tx -tc XXX的功能
  3. main与其他分开,制作静态库和动态库
  4. 编写Makefile
  5. 提交测试代码和运行结果截图, 提交调试过程截图,要全屏,包含自己的学号信息
  6. 在博客园发表一篇博客,重点写遇到的问题和解决过程

总结

  1. 问题:命名修改导致不停输错命令

    解决:进行命名管理;使用批量替换修改

  2. 问题:ld: attempted static link of dynamic object

解决:

  • 因为指定了链接参数-static,它的存在,要求链接的必须是静态库,而不能是共享库
  • 链接的应该为其他函数,误写成main函数的目标文件了
  1. 问题:undefined reference to异常

    解决:因为makefile写错了,把链接库的名字写成要调用它的文件名了,导致找不到文件

  2. 问题:使用文件时,找不到动态库

    解决:gcc编译时指明路径 ./

其他方法:来源于https://www.cnblogs.com/x_wukong/p/4722903.html

分析原因:ld提示找不到库文件,而库文件就在当前目录中。

链接器ld默认的目录是/lib和/usr/lib,如果放在其他路径也可以,需要让ld知道库文件在哪里。

  • 方法1:

    编辑/etc/ld.so.conf文件,在新的一行中加入库文件所在目录;

    运行ldconfig,以更新/etc/ld.so.cache文件;
  • 方法2:

    在/etc/ld.so.conf.d/目录下新建任何以.conf为后缀的文件,在该文件中加入库文件所在的目录;

    运行ldconfig,以更新/etc/ld.so.cache文件;

觉得第二种办法更为方便,对于原系统的改动最小。因为/etc/ld.so.conf文件的内容是include /etc/ld.so.conf.d/*.conf

所以,在/etc/ld.so.conf.d/目录下加入的任何以.conf为后缀的文件都能被识别到。

二、C程序反汇编

  1. 目的:分析汇编代码的工作过程中堆栈的变化
  2. 基本知识:

X86t体系结构栈地址向下增长(地址减小)

汇编指令:

mov寻址

  1. 1. 寄存器寻址
  2. `movl %eax, %edx`
  3. 2. 立即寻址
  4. `movl $0x123, %edx`
  5. 3. 直接寻址
  6. `movl 0x123, %edx`
  7. 4. 变址寻址
  8. `movl 4(%ebx), %edx`
  9. ### 进出栈
  10. 1. 进栈
  11. ```
  12. `pushl %eax`
  13. 等价伪指令
  14. ```
  15. sub $4 ,%esp
  16. mov %eax,%esp
  1. 2.出栈
  2. `popl %eax`
  3. 等价伪指令
  1. mov %esp,%eap
  2. add $4 ,%esp

  1. 函数命令
  2. 函数调用
  3. `call 0x12345`
  4. 等价伪指令
  5. `push %eip`
  6. `mov $OX???? ,%eip`
  7. 函数返回
  8. ```
  9. ret
  10. 等价伪指令
  11. pop %eip

建立函数堆栈enter

等价伪指令

  1. push1 %ebp
  2. movl %esp, %ebp

撤销函数堆栈leave

等价伪指令

movl %ebp, %esp

popl %ebp

  1. 步骤一 反汇编

// main.c

int g(int x)

{

return x + 5555;

}

int f(int x)

{

return g(x);

}

int main(void)

{

return f(6) + 6666;

}


  1. ![](https://img2020.cnblogs.com/blog/2175053/202010/2175053-20201018232126107-1250148043.png)
  2. ![](https://img2020.cnblogs.com/blog/2175053/202010/2175053-20201018232042662-
  3. 步骤二 分析汇编代码

g:

pushl %ebp

movl %esp, %ebp

movl 8(%ebp), %eax

addl $5555, %eax

popl %ebp

ret

f:

pushl %ebp

movl %esp, %ebp

subl $4, %esp

movl 8(%ebp), %eax

movl %eax, (%esp)

call g

leave

ret

main:

pushl %ebp

movl %esp, %ebp

subl $4, %esp

movl $6, (%esp)

call f

addl $6666, %eax

leave

ret


  1. (二)下面分析过程
  2. 首先进行main函数调用g:

main:

// 1、建立main的空栈 等价于enter

pushl %ebp

movl %esp, %ebp

// 2、等价于push $6

subl $4, %esp //栈顶地址-4,左移增加栈空间一个单元

movl $6, (%esp) //栈顶值设为6(设在内存中对应块号为0)

  1. //(设该立即数的存储位置在内存中对应块号为0)
  2. // 3、进入f函数调用
  3. call f //eip跳转到函数f的第一条命令
  4. f:
  5. // 1、压栈f所需参数(上一步的栈顶值即为参数,放在f的栈底)
  6. // 建立f的空栈 等价于enter
  7. pushl %ebp //基地址右移一个单元(在内存中对应块号为1),获取块号0的值,放在eax。
  8. movl %esp, %ebp //栈顶、栈底指向(在内存中对应块号为1),建立f的空栈
  9. // push f栈的-2单元
  10. subl $4, %esp //左移,增加栈空间一个单元(esp在内存中对应块号为2)
  11. movl 8(%ebp), %eax//获取(基地址块号1右移两个单元,在内存中对应块号为-1)即上级函数存储的立即数6,放到eax
  12. // 将值存入f的栈顶
  13. movl %eax, (%esp)//块号2存储块号0的存储值)
  14. // 2、 进入g函数调用
  15. call g //eip跳转到函数g的第一条命令
  16. g:
  17. //
  18. // 建立g的空栈 等价于enter
  19. pushl %ebp //(ebp存储的地址对应在内存中对应块号为2)
  20. movl %esp, %ebp//(esp存储的地址对应在内存中对应块号为2)
  21. // 上级函数所给的参数6 +5555存储到eax(存着main所给的参数值6)
  22. movl 8(%ebp), %eax//获取(在内存中对应块号为0)存储值.即上级函数存储的立即数6,放到eax
  23. addl $5555, %eax // eax寄存器值加5555
  24. popl %ebp //ebp指向块号为1,块号2的地址
  25. // 返回上级函数f,返回值为eax的值
  26. ret
  27. //撤销g的空堆栈
  28. leave
  29. // 返回上级函数main,返回值为eax的值
  30. ret
  31. addl $6666, %eax // eax寄存器值加56666
  32. leave //撤销空堆栈

// main函数结束,返回值为eax的值

ret

  1. # 三、其他
  2. ## 调试
  3. * b 设断点(要会设4种断点:行断点、函数断点、条件断点、临时断点)
  4. * run 开始运行程序
  5. * bt 打印函数调用堆栈
  6. * p 查看变量值
  7. * c 从当前断点继续运行到下一个断点
  8. * n 单步运行
  9. * s 单步运行
  10. * quit 退出CGDB
  11. ## 四种断点的设法
  12. 1.条件断点:b fxx(函数名)
  13. 2.条件断点:b 12 if i=5000
  14. 3.行断点:b 行号
  15. 4.临时断点:tb 行号
  16. # gcc编译
  17. ### 预处理
  18. `gcc -E hello.c -o hello.i`
  19. ### 编译
  20. `gcc –S hello.i –o hello.s`
  21. ### 汇编
  22. `gcc –c hello.s –o hello.o`
  23. ### 链接
  24. `gcc hello.o –o hello.exe`
  25. # gcc打包
  26. 1.把代码编译为目标文件形式(形如):
  27. `gcc -c liberr.c -o liberr.o`
  28. ## 静态库
  29. 2.使用工具ar创建一个存档文件:
  30. `ar rcs mymath9313.a otherfunc.o`
  31. 3.编译程序时把程序和myod9313.a链接起来:
  32. `gcc -static -o myod XXX myod9313.o mymath.a`
  33. ## 动态库
  34. 1.创建一个共享目标文件

gcc -shared -fpic -o mymath.so add5320.c sub5320.c mul.c div.c

gcc -shared -fpic -o myod9313.so myod9313.c

  1. 2.创建可执行目标文件
  2. `gcc -o myod XXX myod9313.c ./mymath.so`
  3. ## 运行+测试
  4. ## makefile

myod XXX:main.o otherfunc.o s

gcc main.o otherfunc.o s -o testmyod

main.o:main.c

gcc -c main.c -o main.o

otherfunc.o:otherfunc.c

gcc -c otherfunc.c -o otherfunc.o

clean:

rm -f *.o testmymath

2019-2020-1 20209313《Linux内核原理与分析》第二周作业的更多相关文章

  1. 2019-2020-1 20199303<Linux内核原理与分析>第二周作业

    2019-2020-1 20199303第二周作业 1.汇编与寄存器的学习 寄存器是中央处理器内的组成部份.寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令.数据和位址.在中央处理器的控制部件中 ...

  2. 20169219 linux内核原理与分析第二周作业

    "linux内核分析"的第一讲主要讲了计算机的体系结构,和各寄存器之间对数据的处理过程. 通用寄存器 AX:累加器 BX:基地址寄存器 CX:计数寄存器 DX:数据寄存器 BP:堆 ...

  3. 2019-2020-1 20199314 <Linux内核原理与分析>第二周作业

    1.基础学习内容 1.1 冯诺依曼体系结构 计算机由控制器.运算器.存储器.输入设备.输出设备五部分组成. 1.1.1 冯诺依曼计算机特点 (1)采用存储程序方式,指令和数据不加区别混合存储在同一个存 ...

  4. Linux内核原理与分析-第二周作业

    写之前回看了一遍秒速五厘米:如果

  5. Linux内核原理与分析-第一周作业

    本科期间,学校开设过linux相关的课程,当时的学习方式主要以课堂听授为主.虽然老师也提供了相关的学习教材跟参考材料,但是整体学下来感觉收获并不是太大,现在回想起来,主要还是由于自己课下没有及时动手实 ...

  6. 2019-2020-1 20199314 <Linux内核原理与分析>第一周作业

    前言 本周对实验楼的Linux基础入门进行了学习,目前学习到实验九完成到挑战二. 学习和实验内容 快速学习了Linux系统的发展历程及其简介,学习了下的变量.用户权限管理.文件打包及压缩.常用命令的和 ...

  7. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  8. 2020-2021-1 20209307 《Linux内核原理与分析》第九周作业

    这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第九周作业> 这个作业的目标 & ...

  9. 2019-2020-1 20199329《Linux内核原理与分析》第十三周作业

    <Linux内核原理与分析>第十三周作业 一.本周内容概述 通过重现缓冲区溢出攻击来理解漏洞 二.本周学习内容 1.实验简介 注意:实验中命令在 xfce 终端中输入,前面有 $ 的内容为 ...

随机推荐

  1. python之ddt模块使用

    一.DDT(数据驱动)简介 Data-Driven Tests(DDT)即数据驱动测试,可以实现不同数据运行同一个测试用例(通过数据的不同来驱动测试结果的不同). ddt本质其实就是装饰器,一组数据一 ...

  2. 小BUG大原理 | 第一篇:重写WebMvcConfigurationSupport后SpringBoot自动配置失效

    一.背景 公司的项目前段时间发版上线后,测试反馈用户的批量删除功能报错.正常情况下看起来应该是个小BUG,可怪就怪在上个版本正常,且此次发版未涉及用户功能的改动.因为这个看似小BUG我了解到不少未知的 ...

  3. hadoop和hbase高可用模式部署

    记录apache版本的hadoop和hbase的安装,并启用高可用模式. 1. 主机环境 我这里使用的操作系统是centos 6.5,安装在vmware上,共三台. 主机名 IP 操作系统 用户名 安 ...

  4. NX二次开发-NX访问MySQL数据库(增删改查)

    版本:NX11+VS2013+MySQL5.6(x64)+SQLyog 1.新建一个NX项目(多字节) 2.设置VC++目录(调用MySQL的头文件,dll和lib库文件) 3.设置番茄助手 然后重启 ...

  5. MATLAB 与 Excel 接口

    MATLAB 与 Excel 接口MATLAB 与 Excel 有两种接口方式:一种是通过 MATLAB 提供的 Excel 生成器,生成220 MATLAB 实用教程DLL 组件和 VBA 代码,实 ...

  6. hystrix(2) metrics

    上一节讲到了hystrix提供的五个功能,这一节我们首先来讲hystrix中提供实时执行metrics信息的实现.为什么先讲metrics,因为很多功能都是基于metrics的数据来实现的,它是很多功 ...

  7. VMware-workstation-full-安装教程

    网盘提取 图1中的包 链接:https://pan.baidu.com/s/11BnY2_v9cDfP1SXPoqOUWQ 提取码:jhfa (1) 点击Vware-workstation-full ...

  8. 利用python简单实现unittest

    python3的eval方法 eval() 函数用来执行一个字符串表达式,并返回表达式的值 # 例如 a = [1,2,3,4] b = "a" print(eval(b)) # ...

  9. @RequiresPermissions注解的作用,超级简单的权限验证

    是shiro里面权限验证的一个注解 @RequiresPermissions(value = {"engineeringPause:download", "workCon ...

  10. phpStudy8.1.0.1配置子域名多网站

    版本 这里phpStudy版本为8.1.0.1: 步骤 假设域名为:domain.com:公网IP地址为:42.33.33.33 首先云解析中配置,添加子域名A记录直接指向你的公网IP: ep.dom ...