2017-2018-1 20155313 《信息安全系统设计基础》第五周学习总结

2017-2018-1 20155313 《信息安全系统设计基础》第五周学习总结

课堂笔记

宿主机(x86):linuxhello >gcc
目标机->实验箱:armhello   >arm-gcc
交叉编译
程序->进程。
操作系统:并发的系统。硬件:CPU,内存,IO设备
linux、unix操作系统:输入输出被放在操作文件中。
操作系统:虚拟内存、进程、文件
nfs 宿主机ip/d /d
>man -k
>grep -nr

教材学习

1.程序编码

一个C语言程序需要经过四个阶段才能变成一个可执行的二进制代码。

  • 预处理阶段:预处理器cpp根据编译文件以“#”开头的命令,读取系统头文件stdio.h(.h结尾的表示头文件,.c表示可执行文件)的内容,并把它插入到程序文本中,得到一个新的文件。
  • 编译阶段:编译器ccl将预处理后的文件翻译成.s结尾的文本文件,里面包含一个汇编程序。(linux命令:gcc -Og -s hello.c)
  • 汇编阶段:汇编器ss将汇编 程序翻译成二进制的机器语言,并把结果保存在以.o结尾的二进制文件中。(linux命令:gcc -Og -c hello.c)
  • 链接阶段:链接器ld将程序用到的C语言类库的函数汇编后的代码合并到hello.o,得到可执行的目标文件。(linux命令:gcc -o hello hello.c)
  • 对二进制文件进行反编译:objdump -d hello.o

2.数据格式

  • 由于是从16位体系结构扩展成32位,intel用术语字(word)表示16位数据类型,因此32位为双字(double words),64位数为4字(quad words)。
  • 以下是比较容易模糊的数据类型大小:

32位机上:float 4 long int 4 double 8 longlong 8 char* 4 unsigned long 4

64位机上:float 4 long int 8 double 8 longlong 8 char*8 unsigned long 8

另外,GCC 用long double表示扩展精度(10字节),出于存储器性能考虑,会被存储为12字节


3.访问信息

操作数指示符

大多数指令有一到多个操作数,操作数有三种:

  • 立即数:即常数值
  • 寄存器:表示某个寄存器内容
  • 存储器引用:根据计算出来的地址(通常称有效地址)访问某个存储器位置

因此寻址方式也有多种,如:立即数寻址、寄存器寻址、绝对寻址、间接寻址、变址寻址、伸缩化的变址寻址。


数据传送指令

几个重要数据传送指令:mov族(之所以称这为族是因为mov指令还有很多兄弟指令如movb、movw、movsb、movzb,这是我个人对它们的称呼,便于记忆mov其他几个比较低调的兄弟)、pop、push。

另外,对于mov族,movb、movw自不必做过多解释,movsb、movzb分别为符号扩展、零扩展,它们只拷贝一个字节,源操作数均为单字节,并设置目的操作数中其余的位,效果如下:

初始假设:%dh=8D %eax=98765432
- 1.movb %dh,%al;%eax=9876548D
- 2.movsbl %dh,%eax;%eax=FFFFFF8D(目的操作数高24位设为源字节最高位,在这里为很显然为1,所以前24位为全F)
- 3.movzbl %dh,%eax;%eax=0000008D(目的操作数高24位被设为0)
对于pushl指令等价于:
 subl $4,%esp
movl %ebp,(%esp) //注意这里的括号引起的差别
popl指令等价于:
 movl (%esp),%eax
 
 addl $4,%esp

4.控制

循环

C语言提供了多种循环结构,即do-while、while和for。汇编中用条件测试和跳转结合起来实现。大多数汇编器根据一个循环的do-while形式来产生循环代码,即使do-while的形式用得相对较少。其他的循环会首先转换成do-while形式,然后再编译成机器代码。首先从do-while开始。

do-while循环

do-while的通用形式可以翻译成如下所示的条件和goto语句:

loop:
    body-statement
    t=test-expr;
    if(t)
        goto loop;

每次循环,程序会执行循环体内的语句,然后执行测试表达式。如果测试为真,则回去再执行一次循环。

while循环

将while循环翻译成机器代码有很多种方法,常见的是使用条件分支,在需要时省略循环体的第一次执行,从而将代码转换成do-while循环,如下:

if(!test-expr)
    goto done;
do
    body-statement
    while (test-expr);
done:

接下来,这个代码可以直接翻译成goto代码,如下:

    t=test-expr;
    if(!t)
        goto done;
loop:
    body-statement
    t=test-expr;
    if(t)
        goto loop;
done:
for循环

for循环可以很容易转换成while循环,进而转换成do-while形式:

init-expr;
if(!test-expr)
    goto done;
do {
    body-statement
    update-expr;
} while (test-expr);
done:

然后,将它转换成goto代码:

    init-expr;
    t=test-expr;
    if(!t)
        goto done;
loop:
    body-statement
    update-expr;
    t=test-expr;
    if(t)
        goto loop;
done:

代码调试中的问题和解决过程

  • 问题1:

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 20篇 400小时
第一周 100/100 1/1 5/5
第二周 100/200 2/3 5/10
第三周 100/300 2/5 5/15
第四周 100/400 1/6 5/20

代码托管


参考资料

程序的机器级表示

posted @ 2017-10-22 20:25  BonsaiYoung  阅读(149)  评论(0编辑  收藏  举报