标签:
第三章 程序的机器级表示
3.1 历史观点
- Intel处理器系列俗称x86,开始时是第一代单芯片、16位微处理器之一。
- 每个后继处理器的设计都是后向兼容的——较早版本上编译的代码可以在较新的处理器上运行。
- X86 寻址方式经历三代:
1 DOS时代的平坦模式,不区分用户空间和内核空间,很不安全
2 8086的分段模式
3 IA32的带保护模式的平坦模式
3.2 程序编码
gcc -01 -o p p1.c
- -01 表示使用第一级优化。优化的级别与编译时间和最终产生代码的形式都有关系,一般认为第二级优化-02 是较好的选择。
- -o 表示将p1.c编译后的可执行文件命名为p
3.2.1机器级代码
- 计算机系统使用了多种不同形式的抽象,对于机器级编程来说,两种抽象尤为重要。第一种是机器级程序的格式和行为,定义为指令集体系结构(ISA),他定义了处理器状态、指令的格式,以及每条指令对状态的影响。
-
几个处理器:
- 程序计数器(CS:IP)
- 整数寄存器(AX,BX,CX,DX)
- 条件码寄存器(OF,SF,ZF,AF,PF,CF)
- 浮点寄存器
3.2.2代码示例
int accum = 0;
int sum(int x, int y)
{
int t = x + y;
accum += t;
return t;
}
在命令行上使用“-S”选项,就能得到C语言编译器产生的汇编代码:
unix> gcc -01 -S code.c
这会使GCC运行编译器产生一个汇编文件code.s,但不做其他进一步工作
如果在命令行上使用“-C”选项,GCC会编译并汇编该代码:
unix> gcc -01 -c code.c
这就会产生目标代码文件code.o,他是二进制格式,无法直接查看。
要查看目标代码文件的内容,这里需要注意的是反汇编器的使用:
unix> objdump -d code.o
机器代码和它的反汇编表示的一些特性需要注意:
- IA32指令长度从1到15个字节不等
- 设计指令格式的方式是,从某个给定位置开始,可以将字节唯一的解码成机器指令。
- 反汇编器只是基于机器代码文件中的字节序列来确定汇编代码,不需要访问程序的源代码或汇编代码。
- 反汇编器使用的指令命名规则与GCC生成的汇编代码使用的有些差别。
3.3 数据格式
1.Intel中:
8 位:字节
16位:字
32位:双字
64位:四字
2.c语言基本数据类型对应的IA32表示
char 字节 1字节
short 字 2字节
int 双字 4字节
long int 双字 4字节
long long int (不支持) 4字节
char * 双字 4字节
float 单精度 4字节
double 双精度 8字节
long double 扩展精度 10/12字节
3.数据传送指令的三个变种:
- movb 传送字节
- movw 传送字
- movl 传送双字
3.4 访问信息
3.4.1操作数指示符
大多数指令都有一个或多个操作数,指示出执行一个操作中要引用的源数据值,以及放置结果的目标位置。
操作数的三种类型
寻址方式
(1)立即数寻址方式
格式:$后加用标准c表示法表示的整数,如$0xAFF
(2)寄存器寻址方式
如%eax,与汇编中学过的AX寄存器类比。
(3)存储器寻址方式
- 直接寻址方式
- 寄存器间接寻址方式
- 寄存器相对寻址方式
- 基址变址寻址方式
- 相对基址变址寻址方式
3.4.2 数据传送指令
mov类指令:将源操作数的值复制到目的操作数中。源操作数指定的值是一个立即数,存储在寄存器中或存储器中。目的操作数制指定一个位置,要么是一个寄存器,要么是一个存储器。
- movb 传送字节
- movw 传送字
- movl 传送双字
- movs 符号位扩展
- movz 零扩展
push操作把数据压入栈中
pop操作删除数据
3.4.3 数据传送示例
- c语言中的指针其实就是地址,间接引用指针就是将该指针放在一个寄存器中,然后在存储器引用中使用这个寄存器
- 局部变量通常保存在寄存器中,而不是存储器
3.5 算术和逻辑操作
第三章程序的机器级表示 学习报告
标签:
原文地址:http://www.cnblogs.com/disturbia/p/4869229.html