IA-32指令系统类型

IA-32中的传送指令

IA-32常用指令类型

(1)传送指令
    – 通用数据传送指令
        MOV:一般传送,包括movb、movw和movl等
        MOVS:符号扩展传送,如movsbw、movswl等
        MOVZ:零扩展传送,如movzwl、movzbl等
        XCHG:数据交换
        PUSH/POP:入栈/出栈,如pushl,pushw,popl,popw等
    –地址传送指令
        LEA:加载有效地址,如leal (%edx,%eax), %eax”的功能为
        R[eax]←R[edx]+R[eax],执行前,若R[edx]=i,
        R[eax]=j,则指令执行后,R[eax]=i+j – 输入输出指令
        IN和OUT:I/O端口与寄存器之间的交换
    – 标志传送指令
        PUSHF、POPF:将EFLAG压栈,或将栈顶内容送EFLAG   

“入栈”(pushw %ax)

“出栈” (popw %ax)

 程序由指令序列组成

功能:R[esp]← R[esp]-4,M[R[esp]] ←R[ebp]的实现原理

执行下一个指令 

扫描二维码关注公众号,回复: 3259833 查看本文章

 

IA-32中的定点算术运算指令

(2)定点算术运算指令
    – 加 / 减运算(影响标志、不区分无/带符号)
        ADD:加,包括addb、addw、addl等
        SUB:减,包括subb、subw、subl等
    – 增1 / 减1运算(影响除CF以外的标志、不区分无/带符号)
        INC:加,包括incb、incw、incl等
        DEC:减,包括decb、decw、decl等
    – 取负运算(影响标志、若对0取负,则结果为0且CF清0,否则CF置1)
        NEG:取负,包括negb、negw、negl等
    – 比较运算(做减法得到标志、不区分无/带符号)
        CMP:比较,包括cmpb、cmpw、cmpl等
    – 乘 / 除运算(不影响标志、区分无/带符号)
        MUL / IMUL:无符号乘 / 带符号乘
        DIV/ IDIV:带无符号除 / 带符号除

算数运算

 IA-32的寄存器组织

 

功能:R[eax]← R[edx]+R[eax]*1

 

功能:R[eax]← R[edx]+R[eax]*1 (执行后)

 

定点加法指令举例

假设 R[ax]=FFFAH,R[bx]=FFF0H,则执行以下指令后
    “addw %bx, %ax”
    AX、BX中的内容各是什么?标志CF、OF、ZF、SF各是什么?要求分别
    将操作数作为无符号数和带符号整数解释并验证指令执行结果。
    解:功能:R[ax]←R[ax]+R[bx],指令执行后的结果如下
        R[ax]=FFFAH+FFF0H=FFEAH ,BX中内容不变
        CF=1,OF=0,ZF=0,SF=1
        若是无符号整数运算,则CF=1说明结果溢出
    验证:FFFA的真值为65535-5=65530,FFF0的真值为65515
        FFEA的真值为65535-21=65514≠65530+65515,即溢出
        若是带符号整数运算,则OF=0说明结果没有溢出
    验证:FFFA的真值为-6,FFF0的真值为-16
        FFEA的真值为-22=-6+(-16),结果正确,无溢出

定点乘法指令举例

假设R[eax]=000000B4H,R[ebx]=00000011H,
    M[000000F8H]=000000A0H,请问:
(2) 执行指令“imull $-16, (%eax,%ebx,4), %eax”后哪些寄存器和存储单元发生
了变化?乘积的机器数和真值各是多少?
    解:“imull -16, (%eax,%ebx,4),%eax”
        功能为 R[eax]←(-16)×M[R[eax]+R[ebx]×4] ,执行结果如下
        R[eax]+R[ebx]×4=000000B4H+00000011H<<2=000000F8H
        R[eax]=(-16)×M[000000F8H]
        =(-16)× 000000A0H(带符号整数乘)
        =16 × (-000000A0H)
        =FFFFFF60H<<4
        =FFFFF600H
        EAX中的真值为-2560

x87浮点处理指令

 IA-32的浮点处理架构

IA-32的浮点处理架构有两种
    (1) x87FPU指令集(gcc默认)
    (2) SSE指令集(x86-64架构所用)
• IA-32中处理的浮点数有三种类型
    – float类型:32位 IEEE 754 单精度格式
    – double类型:64位 IEEE 754 双精度格式
    – long double类型:80位双精度扩展格式
1位符号位s、15位阶码e(偏置常数为16 383)、1位显式
首位有效位(explicit leading significant bit)j 和 63位
尾数f。它与IEEE 754单精度和双精度浮点格式的一个重要的
区别是:它没有隐藏位,有效位数共64位。

x87 FPU指令

x87 FPU 特指与x86处理器配套的浮点协处理器架构
    – 浮点寄存器采用栈结构
        • 深度为8,宽度为80位,即8个80位寄存器
        • 名称为 ST(0) ~ ST(7),栈顶为ST(0),编号分别为 0~7
    – 所有浮点运算都按80位扩展精度进行
    – 浮点数在浮点寄存器和内存之间传送
        • float、double、long double型变量在内存分别用IEEE 754单精度、双精度和扩展精            
            度表示,分别占32位(4B)、64位(8B)和96位(12B,其中高16位无意义)
        • float、double、long double类型变量在浮点寄存器中都用80位扩展精度表示
        • 从浮点寄存器到内存:80位扩展精度格式转换为32位或64位
        • 从内存到浮点寄存器: 32位或64位格式转换为80位扩展精度格式
数据传送类
(1) 装入 (转换为80位扩展精度)
    FLD:将数据从存储单元装入浮点寄存器栈顶 ST(0)
    FILD:将数据从int型转换为浮点格式后,装入浮点寄存器栈顶
(2) 存储(转换为IEEE 754单精度或双精度)
    FSTx:x为s/l时,将栈顶ST(0)转换为单/双精度格式,然后存入存储单元
    FSTPx:弹出栈顶元素,并完成与FSTx相同的功能
    FISTx:将栈顶数据从int型转换为浮点格式后,存入存储单元
    FISTP:弹出栈顶元素,并完成与FISTx相同的功能
    带P结尾指令表示操作数会出栈,也即ST(1)将变成ST(0)
数据传送类
(3) 交换
    FXCH:交换栈顶和次栈顶两元素
(4) 常数装载到栈顶
    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 
算术运算类
(3) 乘法
    FMUL/FMULP: 相乘/相乘后弹出栈
    FIMUL:按int型转换后相乘
(4) 除法
    FDIV/FDIVP : 相除/相除后弹出栈
    FIDIV:按int型转换后相除
    FDIVR/FDIVRP:调换次序相除/相减后弹出栈
    FIDIVR:按int型转换并调换次序相除

IA-32浮点操作举例

 

 

从这个例子可以看出
    – 编译器的设计和硬件结构紧密相关。
    – 对于编译器设计者来说,只有真正了解底层硬件结构和真正
理解指令集体系结构,才能够翻译出没有错误的目标代码,
并为程序员完全屏蔽掉硬件实现的细节,方便应用程序员开
发出可靠的程序。
    – 对于应用程序开发者来说,也只有真正了解底层硬件的结构
    ,才有能力编制出高效的程序,能够快速定位出错的地方,
    并对程序的行为作出正确的判断。

猜你喜欢

转载自www.cnblogs.com/chenxuming/p/9671417.html