6.4 IA-32中的控制转移指令
1. 常用控制转移指令
2. 类别
- 根据单个标志的值转移
- 按无符号整数比较转移
- 按带符号整数比较转移
3. 例子:程序的机器级表示与执行
问题描述:
(1) subl $1, %edx指令的执行结果
(2) cpml %edx,%eax指令的执行结果
(3) jbe .L3指令的执行结果
总结
正确的做法是将参数len声明 为int型。Why?
4. C表达式类型转换顺序
6.5 x87浮点处理指令
1. IA-32的浮点处理架构
(1) IA-32的浮点处理架构有两种
- x87FPU指令集(gcc默认)
- SSE指令集(x86-64架构所用)
(2)IA-32中处理的浮点数有三种类型
- float类型:32位IEEE 754 单精度格式
- double类型:64位IEEE 754 双精度格式
- long double类型:80位双精度扩展格式
long double类型: 1位符号位s、15位阶码e(偏置常数为16 383)、1位显式 首位有效位(explicit leading significant bit)j 和63位 尾数f。它与IEEE 754单精度和双精度浮点格式的一个重要的区别是:
它没有隐藏位,有效位数共64位
。
2. x87 FPU指令
(1)概述
2. 指令类型
数据传送类 |
---|
装入 | (转换为80位扩展精度) |
---|---|
FLD: | 将数据从存储单元装入浮点寄存器栈顶ST(0) |
FI LD: | 将数据从int型转换为浮点格式后,装入浮点寄存器栈顶 |
存储 | (转换为IEEE 754单精度或双精度) |
FSTx: | x为s/l 时,将栈顶ST(0)转换为单/双精度 格式,然后存 入存储单元 |
FSTPx: | 弹出栈顶元素,并完成与FSTx相同的功能 |
FI STx: | 将栈顶数据从int型转换为浮点格式后,存入存储单元 |
FI STP: | 弹出栈顶元素,并完成与FISTx相同的功能 |
带P结尾指令表示操作数会出栈,也即ST(1)将变成ST(0) | |
交换 | |
FXCH: | 交换栈顶和次栈顶两元素 |
常数装载到栈顶 | |
FLD1 : | 装入常数1.0 |
FLDZ : | 装入常数0.0 |
FLDPI : | 装入常数pi (=3.1415926…) |
FLDL2E : | 装入常数log(2)e |
FLDL2T : | 装入常数log(2)10 FLDLG2 :装入常数log(10)2 |
FLDLN2 : | 装入常数Log(e)2 |
算术运算类 |
---|
加法 | |
---|---|
FADD/FADDP: | 相加/相加后弹出栈 |
FI ADD: | 按int型转换后相加 |
减法 | |
FSUB/FSUBP : | 相减/相减后弹出栈 |
FSUBR/FSUBRP: | 调换次序相减/相减后弹出栈 |
FI SUB: | 按int型转换后相减 |
FISUBR: | 按int型转换并调换次序相减 |
若指令未带操作数,则默认操作数为ST(0)、ST(1) 带R后缀指令是指操作数顺序变反,例如: fsub执行的是x-y,fsubr执行的就是y-x | |
乘法 | |
FMUL/FMULP: | 相乘/相乘后弹出栈 |
FI MUL: | 按int型转换后相乘 |
除法 | |
FDIV/FDIVP : | 相除/相除后弹出栈 |
FI DIV: | 按int型转换后相除 |
FDIVR/FDIVRP: | 调换次序相除/相减后弹出栈 |
FI DIVR: | 按int型转换并调换次序相除 |
3. IA-32浮点操作举例
(1)例一
Q:使用老版本gcc –O2编译时,程序一输出0,程序二输 出是1,是什么原因造成的? f(10)的值是多少?机器数是多少?
分析
程序一执行
程序二执行
总结:编译器的设计和硬件结构紧密相关。
(2)例二
问题
分析
6.6 MMX及SSE指令
由MMX发展而来的SSE架构
- MMX指令使用8个64位寄存器
MM0~MM7
,借用8个80位寄存 ST(0)~ST(7)中64位尾数所占的位,可同时处理8个字节,或4 个字,或2个双字,或一个64位的数据- MMX指令并没带来3D游戏性能的显著提升,故推出SSE指令, 并陆续推出SSE2、SSE3、SSSE3和SSE4等采用SIMD技术的指 令集,这些统称为SSE指令集
- SSE指令集将80位浮点寄存器扩充到
128位多媒体扩展通用寄存器XMM0~XMM7
,可同时处理16个字节,或8个字,或4个双 字(32位整数或单精度浮点数)
,或两个四字的数据- 从SSE2开始,还支持128位整数运算,或同时并行处理两个64位 双精度浮点数
1. IA-32中通用寄存器中的编号
反映了体系结构发展的轨迹,字长不断扩充,指令保持兼容 ST(0)~ ST(7)是80位,MM0 ~MM7使用其低64位
3. SSE指令(SIMD操作)
(1)例子
(3)常用指令
paddb 指令 | (操作数在两个xmm寄存器中) |
---|---|
①一条指令同时完成6个单字节 数据相加 ② 类似指令padd w 同时完成8个单字 数据相加③类似指令psub l 同时完成4个双字 数据相减 | |
movdq a指令 | |
①将双四字(128位)从源操作数处移到目标操作数处 ②用于在XMM 寄存器与128 位存储单元之间移入/移出双四字,或在两个XMM 寄存器之间移动 ③源操作数或目标操作数是存储器操作数时,操作数必须是 16 字节边界对齐,否则将发生一般保护性异常(#GP) | |
movdqu指令 | |
①在未对齐的存储单元 中移入/移出双四字 |