码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-10-13 20:43:25      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:

 

     Intel处理器(X86)

程序编码

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

      ①编译选项-01 表示编译器使用第一级优化

     ②编译选项-02 表示编译器使用第二级优化(较好的选择)

     ③-o 表示分别将p1.c和p2.c编译后的可执行文件命名为p

     GCC将源代码转化为可执行代码的步骤:

  C预处理器:扩展源代码,插入所有#include命令指定的文件,并扩展生成.i文件
  编译器:产生两个源代码的汇编代码,生成.s文件
  汇编器:将汇编代码转化成二进制目标代码——生成.o文件
  链接器:产生可执行代码文件p

回顾:gcc命令编译运行C语言
  1. 预处理阶段:将*.c文件转化为*.i预处理过的C程序。

  2. 编译阶段:将*.i文件编译为汇编代码*.s文件。

  3. 汇编阶段:将*.s文件转化为*.o的二进制目标代码文件。

  4. 链接阶段:将*.o文件转化为可执行文件。

  5. 生成可执行文件:将*.o转换为可执行文件。

  6. 执行可执行C语言文件。

(1)机器级代码

    两种抽象

(1)指令集体系结构ISA

   (2)机器级程序使用的存储器地址是虚拟地址(多个硬件存储器和操作系统软件组合起来)


 处理器状态:
  • 程序计数器(CS:IP)
  • 整数寄存器(AX,BX,CX,DX)
  • 条件码寄存器(OF,SF,ZF,AF,PF,CF)
  • 浮点寄存器
 (2)代码示例
C语言代码文件code.c:

int accum = 0;
int sum(int x, int y) 
{
   int t = x + y; 
   accum += t; 
   return t;
 }

产生汇编代码code.s:
gcc -01 -S code.c
编译并汇编该代码,产生目标代码code.o:gcc -01 -c code.c

反汇编器——查看目标代码文件
abjdump -d code.o


三、数据格式
数据类型:
字:16位
双字:32位
四位:64位

基本数据类型:

C 声明 Intel 汇编代码后缀 大小(字节)
char 字节 b 1
short 字 w 2
int 双字 l 4
long int 双字 l 4
long long int — — 4
char * 双字 l 4
float 单精度 s 4
double 双精度 l 8
long double 扩展精度 t 10/12
 

数据传送指令


movb 传送字节

movw 传送字

movl 传送双字


访问信息

 

(一)操作数指示符


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


操作数类型:

  1. 立即数 (常数值)  例:$0x1F
  2. 寄存器  例:%ax
  3. 存储器 有效地址

寻址方式:

(1)立即数寻址方式

(2)寄存器寻址方式

(3)存储器寻址方式

(4)直接寻址方式

(5)寄存器间接寻址方式

(6)寄存器相对寻址方式

(7)基址变址寻址方式

(8)相对基址变址寻址方式

 

 

(二)数据传送指令


1.mov指令: 把源操作数的值复制到目的操作数上

movb、movw、movl

技术分享

2.堆栈

  • 遵循“后进先出”的原则
  • 栈指针指向栈顶元素
  • 栈顶元素的地址在栈中元素地址是最低的

压栈push:将数据压入栈中
出栈pop:弹出数据

 

3.数据传送示例

c语言中的指针其实就是地址,间接引用指针就是将该指针放在一个寄存器中,然后在存储器引用中使用这个寄存器

局部变量通常保存在寄存器


算术和逻辑操作

字节加法:addb
字加法;addw
双字加法:addl

1、加载有效地址


加载有效地址指令——leal,是movl指令的变形,对比汇编中的LEA指令学习。


将有效地址写入到目的操作数,目的操作数必须是寄存器

技术分享


2、一元操作和二元操作


1.一元操作


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

例:加法运算符(++)和减1运算符


2.二元操作

第二个数既是源又是目的

  • 第一个操作数可以是立即数、寄存器或者存储器位置
  • 第二个操作数可以是寄存器或者存储器位置
  • 两个操作数但是不能同时是存储器位置。

三、移位操作


右边填0:SAL 算术左移
         SHL 逻辑左移
填上符号位:SAR 算术右移
填上0:SHR 逻辑右移

移位操作源操作数可以是立即数或CL

移位操作目的操作数可以是寄存器或存储器


4、特殊的算术操作

技术分享


 


(六) 控制


一、条件码

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

技术分享


注意:

  1. leal不改变条件码寄存器
  2. CMP与SUB的区别:CMP也是根据两个操作数之差设置条件码,但只设置条件码而不更新目标寄存器
  3. 有条件跳转的条件看状态寄存器(教材上叫条件码寄存器)

常用指令:
MOV 不影响标志位
PUSH POP 不影响标志位
XCHG 交换指令 不影响标志位
XLAT 换码指令 不影响标志位
LEA 有效地址送寄存器指令 不影响标志位
PUSHF 标志进栈指令 不影响标志位
POPF 标志出栈指令 标志位由装入值决定

2、访问条件码
  1. 根据条件码的某个组合,将一个字节设置成0或1;
  2. 跳转到程序某个其他的部分
  3. 有条件的传送数据。

    SET指令根据t=a-b的结果设置条件码


SET指令:

技术分享


3、跳转指令及其编码


JUMP指令会导致执行切换到程序一个全新的位置,通常用一个标号指明

jmp指令是无条件跳转,可分为直接跳转和间接跳转:

直接跳转:后面跟标号作为跳转目标

间接跳转:*后面跟一个操作数指示

区别:

jmp *%eax 用寄存器%eax中的值作为跳转目标

jmp *(%eax) 以%eax中的值作为读地址,从储存器中读取跳转目标

技术分享

控制中最核心的是跳转语句:

  • 有条件跳转(实现if,switch,while,for)

  • 无条件跳转jmp(实现goto)

当执行PC相关的寻址时,程序计数器的值是跳转指令后面那条指令的地址,而不是跳转指令本身的地址。

4、翻译条件分支

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

无条件跳转:例如goto。书上的例子就是把if-else语句翻译成了goto形式,然后再由这个形式翻译成汇编语言

C语言中if-else语句的通用形式:

if(test-expr)
	then-statement
else
	else-statement

汇编结构:

	t=test-expr;
	if!(t)
		goto false;
	then-statement
	goto done;
false:
	else-statement
done:

5、循环


汇编中可以用条件测试和跳转组合起来实现循环的效果,但是大多数汇编器中都要先将其他形式的循环转换成do-while格式。


1.do-while循环


通用形式:


do
	body-statement
	while(test-expr);

循环体body-statement至少执行一次。


可以翻译成如下所示的条件和goto语句:


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

即先执行循环体语句,再执行测试表达式。


2.while循环

C语言中while语句的通用形式:

while(test-expr)
	body-statement

汇编结构:

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

for循环

C语言中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:

3.for循环


for循环

C语言中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:

6、条件传送指令(详细看书本)


7、Switch语句


Switch语句是多重分支的典型(这个已经掌握的比较好,详细见书本)

技术分享



(七) 过程

栈帧结构
  • 为单个过程分配的栈叫做栈帧,寄存器%ebp为帧指针,而寄存器指针%esp为栈指针,程序执行时栈指针移动,大多数信息的访问都是相对于帧指针。

  • 栈向低地址方向增长,而栈指针%esp指向栈顶元素。

  转移控制

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

ret:从栈中弹出地址,并跳转到这个位置。

函数返回值存在%eax中

1.call

call指令和转移指令相似,同样分直接和间接,直接调用的目标是标号,间接调用的目标是*后面跟一个操作数指示符,和JMP一样。

CALL指令的效果是将返回地址入栈,并跳转到被调用过程的起始处。返回地址是还在程序中紧跟在call后面的那条指令的地址。

然后就会用到ret了。

2.ret

ret指从栈中弹出地址,并跳转到这个位置。

在上学期的汇编语言学习中,call和ret常被用来进行子函数、子模块的调用。

3.leave

这个指令可以使栈做好返回的准备,等价于:

movl %ebp,%esp
popl %ebp

查看函数调用栈信息的GDB命令

Ÿ   backtrace/bt n

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

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

Ÿ   frame n

n是一个从0开始的整数,是栈中的层编号。这个指令的意思是移动到n指定的栈帧中去,并打印选中的栈的信息。如果没有n,则打印当前帧的信息。

Ÿ   up n

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

Ÿ   down n

表示向栈的下面移动n层,可以不打n,表示向下移动一层。


 寄存器使用惯例


             寄存器%eax、%edx和%ecx被划分为调用者保存寄存器。


                 寄存器%ebx、%esi、%edi被划分为被调用者保存寄存器。


过程示例


          GCC坚持一个函数使用的所有栈空间必须是16字节的整数倍,包括保存%ebp值的4个字节和返回值的4个字节。


递归过程


          递归调用自身和调用其它函数是一样的。栈规则提供了一种机制,每次函数调用都有它自己私有的状态信息存储(保存的返回位置,栈指针和被调用者保存寄存器的值)


补充汇编语言命令:
算术指令
ADD 加法指令 影响标志位
ADC 带进位加法指令 影响标志位
INC 加一指令 不影响CF,影响别的标志位
SUB 减法指令 影响标志位
SBB 带借位减法指令 影响标志位
DEC 减一指令 不影响CF,影响其他标志位
NEG 求补指令 影响标志位 只有操作数为0,例如字运算对-128求补,OF=1,其他时候OF=0
CMP 比较指令 做减法运算但不存储结果,根据结果设置条件标志位
MUL 无符号数乘法指令
IMUL 有符号数乘法指令   均对CF和OF位以外的条件码位无定义(即状态不定)
DIV 无符号数除法指令
IDIV 带符号数除法指令 除法指令对所有条件码位均无定义
位操作指令:
AND 逻辑与
OR 逻辑或
NOT 逻辑非 不影响标志位
XOR 异或
TEST 测试指令   除NOT外的四种,置CF、OF为0,AF无定义,SF,ZF,PF根据运算结果设置
移位指令:
SHL 逻辑左移指令
SHR 逻辑右移指令 移位指令根据结果设置SF,ZF,PF位
ROL 循环左移指令
ROR 循环右移指令 循环移位指令不影响除CF,OF之外的其他条件位
串处理指令:
MOVS 串传送指令
STOS 存入串指令
LODS 从串取指令 均不影响条件位
CMPS 串比较指令
SCAS 串扫描指令 均不保存结果,只根据结果设置条件码
控制转移指令:
JMP 无条件转移指令 不影响条件码

参考资料:20135223何伟钦《第三章 程序的机器级表示》以及课本

 

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

标签:

原文地址:http://www.cnblogs.com/sunxiaobo/p/4875604.html

踩
(0)
赞
(0)
   
举报
评论 一句话评论(0)
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!