20135308-信息安全系统设计基础第五周学习总结

第3章 程序的机器级表示

一、X86 寻址方式

1 DOS时代的平坦模式,不区分用户空间和内核空间,很不安全

2 8086的分段模式

3 IA32的带保护模式的平坦模式

二、程序编码

编译如下代码:

unix> gcc -01 -o p p1.c p2.c

  • 01 表示告诉编译器使用第一级优化。通常,提高优化级别会使最终程序运行的更快,但编译时间可能会变长,用调试工具对代码进行调试会更困难。
  • 从得到的程序性能方面考虑,第二级优化-02被认为是是较好的选择。

二、机器级代码

1、两种抽象

(1)ISA

ISA(Instruction set architecture)指令体系结构:机器级程序的格式和行为,定义了处理器状态、指令的格式、每条指令对状态的影响。

(2)机器级程序使用的存储器地址是虚拟地址

提供的存储器模型看上去是一个非常大的字节数组,实际实现是将多个硬件存储器和操作系统软件组合起来。

2、汇编代码特点

它用可读性更好的文本格式来表示。

3、状态可见的几种处理器

  • 程序计数器 (PC,用%eip表示)
  • 整数寄存器 (包含8个命名的位置,存储32位的值)
  • 条件码寄存器 (实现if和while语句)
  • 浮点寄存器 (存放浮点数)

机器代码简单地将存储器看成一个很大的、按字节寻址的数组。 汇编代码也不区分有符号或无符号整数,不区分各种类型的指针,甚至不区分指针和整数。

一条机器指令只执行一个非常基本的操作

三、获得汇编代码

(1)gcc -S xxx.c -o xxx.s 获得汇编代码

eg:unix> gcc -01 -S code.c

(2)objdump -d xxx 反汇编;

eg:unix> objdump -d code.o

注意: 64位机器上想要得到32代码:gcc -m32 -S xxx.c

MAC OS中没有objdump, 有个基本等价的命令otool

Ubuntu中 gcc -S code.c (不带-O1) 产生的代码更接近教材中代码(删除"."开头的语句)

四、查看二进制格式文件

二进制文件可以用od 命令查看,也可以用gdb的x命令查看。 有些输出内容过多,我们可以使用 more或less命令结合管道查看,也可以使用输出重定向来查看

        od code.o | more

        od code.o > code.txt

五、关于格式的注解

以“.”开头的行都是指导汇编器和链接器的命令,我们通常可以忽略这些行。

gcc -S 产生的汇编中可以把 以”.“开始的语句都删除了再阅读。

六、Linux和Windows的汇编格式

ATT格式的汇编代码

是GCC、OBJDUMP及其他我们使用的一些工具的默认格式。


Intel格式的汇编代码

包括Microsoft工具等编程工具。

1、C语言基本数据类型对应的IA32表示。



数据传送指令有三个变种:

movb(传送字节)

movw(传送字)

movl(传送双字)

后缀‘l‘用来表示双字

注:汇编代码也使用后缀‘l‘来表示4字节整数和8字节双精度浮点数。

七、访问信息

一个IA32中央处理单元(CPU)包含一组8个存储32位值的寄存器。这些寄存器用来存储整数数据和指针。

esi edi可以用来操纵数组,esp ebp用来操纵栈帧。


1、操作数指示符

操作数:指示出执行一个操作中要引用的源数据值,以及放置结果的目标位置。

(1)操作数的三种类型

  • 立即数
  • 寄存器
  • 存储器

(2)多种不同的寻址方式


2、数据传送指令


(1)MOV类指令

定义:将数据从一个位置复制到另一个位置,将源操作数的值复制到目的操作数。

(2)PUSH&POP指令

PUSH:将数据压入程序栈中

POP:从程序栈中弹出数据

注意:

1.后进先出:即弹出的值永远是最近被压入,仍然在栈内的值

2.栈指针指向栈顶元素

3.栈向下即低地址方向增长

4.栈顶元素的地址是所有栈中元素地址中最低的。

3、数据传送示例

(1)指针示例

eg:int x = *xp;

读出参数xp,放在寄存器%edx里,然后将x读到%eax中,实现了C程序中的操作 x=*xp,然后用寄存器%eax从该函数返回一个值x。

八、算术和逻辑操作

1、操作分类

  • 加载有效地址
  • 一元操作

    只有一个操作数,既是源又是目的。它可以是一个寄存器,或者存储器位置。

  • 二元操作

    有两个操作数,其中第二个操作数,又是源,又是目的。

  • 移位

    SAL 算术左移

    SHL 逻辑左移

    SAR 算术右移(补符号位)

    SHR 逻辑右移(补0)

先给出位移量,再给出要位移的位数,可进行算术和逻辑右移。

2、加载有效地址

加载有效地址(load effective address)指令leal是movl指令的变形。

将有效地址写入到目的操作数。


3、特殊算术操作

下图描述的指令支持产生两个32位数字的全64位乘积以及整数除法。 


(1)乘法

乘积截断:产生一个32位乘积

乘积不截断:

  • 无符号数乘法(mull)
  • 补码乘法(imull)

(2)除法

有符号除法指令:idivl

将寄存器%edx,%eax中的64位数作为被除数

将商存储在寄存器%eax中,余数存储在%edx中。

九、控制

1、条件码

条件码寄存器:他们描述了最近的算术或逻辑操作的属性。

常用的条件码:

CF:进位标志
ZF:零标志
SF:符号标志
OF:溢出标志

常见指令:

LEAL:不改变条件码寄存器
XOR:进位标志和溢出标志会设置成0
INC:设置溢出和零标志
DEC:设置溢出和零标志
CMP:根据操作数之差设置条件码
SUB:设置条件码,更新寄存器
TEST:改变目的寄存器的值

2、访问条件码

常用使用方法:

(1)根据条件码的某个组合,将一个字节设置成0或1

(2)可以条件跳转到某个其他部分

(3)可以有条件的传送数据

(1)SET指令

通过set与不同的条件码的组合,达到不同的跳转条件。


3、跳转指令及其编码

JUMP指令,导致执行切换到程序中一个全新的位置。

注意:jump分为直接跳转和间接跳转

  • 直接跳转:后面跟标号作为跳转目标
  • 间接跳转:*后面跟一个操作数指示符


十、翻译条件分支

将条件表达式和语句从c语言翻译成机器语言,最常用的方式就是结合有条件和无条件跳转。

使用goto通常认为是一种不太好的风格。

十一、循环

1、do-while循环

汇编中,根据do-while形式产生循环代码

do-while语句的通用形式:

do
body-statement
while(test-expr);

可翻译成如下:

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

2、while循环

while语句的通用形式:

while (test-expr)
body-statement

GCC采用的方法,是使用条件分支,需要时省略循环体的第一次执行::

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:

3、for循环

for循环的通用形式:

for(init-expr;test-expr;update-expr)
body-statement

汇编结构:

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

4、switch语句

根据一个整数索引值进行多重分支,执行switch语句的关键步骤是通过跳转表来访问代码位置,使结构变得更加高效。

十二、过程

过程调用

  • 进入时为过程的局部变量分配空间
  • 将数据(以过程参数和返回值的形式)和控制从代码的一部分传递到另一部分。
  • 退出时释放这些空间。

1、栈帧结构

  • IA32程序用程序栈来支持过程调用。
  • 机器用栈来传递过程参数、存储返回信息、保存寄存器,以及本地存储。

2、转译控制

(1)call指令

  • 目标是指明被调用过程起始的指令地址
  • 效果是将返回地址入栈,并跳转到被调用过程的起始处。

(2)ret指令

  • 从栈中弹出地址,并跳转到这个位置。
  • 函数返回值存在%eax中

3、寄存器使用惯例

注意:保证当一个过程调用另一个过程时,被调用者不会覆盖某个调用者稍后会用的寄存器的值。

十三、应用:使用GDB调试器

关于栈帧的gdb命令:

1、backtrace/bt

打印当前的函数调用栈的所有信息。

n是一个正整数,表示只打印栈顶上n层的栈信息。

-n表一个负整数,表示只打印栈底下n层的栈信息。

2、frame

n为栈中的层编号,是一个从0开始的整数

比如:frame 0,表示栈顶,frame 1,表示栈的第二层。

该指令是移动到n指定的栈帧中去,并打印选中的栈的信息。

如果没有n,则打印当前帧的信息。

3、up

表示向栈顶移动n层

可以不打n,表示向上移动一层。

4、down

表示向栈底移动n层

可以不打n,表示向下移动一层。
时间: 2024-10-24 17:57:13

20135308-信息安全系统设计基础第五周学习总结的相关文章

20135223何伟钦—信息安全系统设计基础第五周学习总结

第三章 程序的机器级表示 一.历史观点 Intel处理器(X86) 二.程序编码 gcc -01 -o p p1.c p2.c ①编译选项-01 表示编译器使用第一级优化 ②编译选项-02 表示编译器使用第二级优化(较好的选择) ③-o 表示分别将p1.c和p2.c编译后的可执行文件命名为p GCC将源代码转化为可执行代码的步骤: C预处理器:扩展源代码,插入所有#include命令指定的文件,并扩展生成.i文件 编译器:产生两个源代码的汇编代码,生成.s文件 汇编器:将汇编代码转化成二进制目标

信息安全系统设计基础第五周学习总结------20135334赵阳林

第四章 处理器体系结构 第一节 Y86指令集体系结构 一.程序员可见的状态 1.含义: 每条指令都会读取或修改处理器状态的某些部分 2.“程序员”: 可以是用汇编代码写程序的人,也可以是产生机器级代码的编译器. 3.具体的处理器状态:类似于IA32 有8个程序寄存器,%eax,%ecx,%edx,%ebx,%esi,%edi,%esp,%ebp 处理器的每个程序寄存器存储一个字 寄存器%esp被入栈.出栈.调用和返回指令作为栈指针.在其他情况下,寄存器没有固定的含义或固定值. 有三个一位的条件码

20135304刘世鹏——信息安全系统设计基础第五周学习总结

第四章 处理器体系结构 ISA:一个处理器支持的指令和指令的字节级编码——指令集体系结构 ISA在编译器编写者和处理器设计人员之间提供了一个概念抽象层 与IA32相比Y86指令集的数据类型.指令和寻址方式都要少一些,它的字节级编码比较简单,不过它仍然足够完整 4.1.Y86指令集结构 定义一个指令集体系结构,暴扣定义各种状态元素.指令集和它们的编码.一组编程规范和异常事件处理 1.程序员可见的状态 程序员可见状态:Y86程序中的每条指令都会读取或修改处理器状态的某些部分 Y86的处理器状态类似与

信息安全系统设计基础第五周学习总结—20135227黄晓妍

X86 寻址方式经历三代: 1 DOS时代的平坦模式,不区分用户空间和内核空间,很不安全 2 8086的分段模式 3 IA32的带保护模式的平坦模式 ISA 指令集体系结构,机器级程序的指令和格式.它定义了处理状态,指令的格式,以及每条指令对状态的影响. 获得汇编代码的两种方式: gcc -S xxx.c -o xxx.s 获得汇编代码,也可以用objdump -d xxx 反汇编 (反汇编不需要访问程序的源代码或者汇编代码) C语言数据类型在IA32中的大小: P111页表格. 8个寄存器(3

信息安全系统设计基础第五周学习总结

处理器的体系结构 ISA:一个处理器支持的指令和指令的字节级编码称为它的指令集体系结构ISA. Y86是一个指令体系结构(ISA)寄存器.存储器.条件码.PC.程序状态. halt:这个指令将会终止指令的执行. nop:这是一个占位指令,它不做任何事情,后续为了实现流水线,它有一定的作用. xxmovl:这是一系列的数据传送指令,其中r代表寄存器,m代表存储器,i代表立即数.比如rrmovl指令,则代表将一个寄存器的值,赋给另外一个寄存器. opl:操作指令,比如加法,减法等等. jxx:条件跳

20135234马启扬-——信息安全系统设计基础第五周学习总结

信息安全系统设计基础第五周学习总结-吕松鸿

第四章  处理器体系结构 4.1 Y86指令集体系结构 4.11程序员可见的状态 1.程序员可见状态: Y86程序中的每条指令都会读取或修改处理器状态的某些部分. 2.“程序员”: 既可以是用汇编代码写程序的人,也可以是产生机器级代码的编译器. 3.程序寄存器: (1)8个,%eax.%edx.%ebx.%esi.%edi.%esp和%ebp. (2)处理器的每个程序寄存器存储一个字. (3)寄存器%esp被入栈,出栈,调用和返回指令作为栈指针. (4)其他情况,有三个一位的条件码:ZF,SF和

20145216史婧瑶《信息安全系统设计基础》第九周学习总结

20145216史婧瑶<信息安全系统设计基础>第九周学习总结 教材内容总结 第十章 系统级I/O 输入/输出(I/O)是在主存和外部设备之间拷贝数据的过程. 第一节 Unix I/O 这一节涉及到操作系统的基本抽象之一--文件.也就是说,所有的I/O设备都被模型化为文件,而所有的输入输出都被当做对相应文件的读/写.相关的执行动作如下: 1.打开文件: 应用程序向内核发出请求→要求内核打开相应的文件→内核返回文件描述符 文件描述符:一个小的非负整数,用来在后续对此文件的所有操作中标识这个文件.有

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

2017-2018-1 20155228 <信息安全系统设计基础>第九周学习总结 教材学习内容总结 常见的存储技术 RAM 随机访问存储器(Random-Access Memory, RAM)分为两类:静态的和动态的.静态 RAM(SRAM)比动态RAM(DRAM)更快,但也贵得多.SRAM用来作为高速缓存存储 器,既可以在CPU芯片上,也可以在片下.DRAM用来作为主存以及图形系统的帧缓冲 区.典型地,一个桌面系统的SRAM不会超过几兆字节,但是DRAM却有几百或几千兆 字节. SRAM将每

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

2017-2018-1 20155227 <信息安全系统设计基础>第九周学习总结 教材学习内容总结 第六章 随机访问存储器 随机访问存储器分为:静态RAM(SRAM)和动态RAM(DRAM),静态RAM(SRAM)比动态RAM(DRAM)更快,但也贵很多. (1)静态RAM SRAM将每个位存储在一个双稳态的存储器单元里,每个单元是用一个六晶体管电路来实现的. 属性:它可以无限制地保持在两个不同的电压配置或状态之一.其他任何状态都是不稳定的. 特点:由于SRAM的双稳态特性,只要有电,它就会永