三.程序的机器级表示

1.两种抽象

指令集体系结构或指令集架构(ISA)来定义机器级程序的格式和行为

使用的内存地址是虚拟地址,看上去是一个非常大的字节数组

2.数据格式

byte、word、quad words

3.16个寄存器

4.三种操作数

立即数、寄存器、内存引用
AT&T:
第一个是源操作数,第二个是目的操作数
movzbq 将做了零拓展的字节传送到四字
movsbq 将做了符号拓展的字节传送到四字
cltq 总是以%eax为源,%rax为符号拓展的目的,编码更紧凑

5.数据传送示例

C的指针其实就是地址。间接引用指针,就是把指针放在寄存器中,然后在内存引用中使用这个寄存器
像x这样的局部变量通常保存在寄存器中,而不是内存中,访问更快。

6.压入和弹出栈数据

pushq %rbq等价于
subq $8,%rsp
movq %rbp,(%rsp)

popq %rax等价于
movq (%rsp),%rax
addq $8,%rsp

7.算术和逻辑操作

7.1 整数算术操作

subq %rax,%rdx 从%rdx中减去%rax
第一个是源操作数,第二个是目的操作数

7.2 加载有效地址leaq

(load effective address)
根本没有引用内存,不是从指定的位置读入数据,而是把有效地址写入到目的操作数

7.3 逻辑操作

7.4 乘除法

乘法
存储需要两个movq指令,一个存储帝8位字节(第4行),一个存储高8位字节(第5行)
针对小端法机器,高位字节存储在大地址,如8(%redi)
除法
除法需要用%rdx,因此需要先把qp保存到另一个寄存器中
准备被除数:复制并符号拓展x
寄存器%rax中的商保存在qp,寄存器%rdx中的余数保存在rp

8.控制

8.1 实现机制

两种基本的低级机制实现有条件的行为
测试数据值,根据测试的结果来改变控制流或者数据流

8.2 条件码

CF:进位标志。最近的操作使最高位产生进位,检查无符号操作的溢出
ZF:零标志。最近的操作得到的结果为0
SF:符号标志。最近的操作得到的结果是负数
OF:溢出标志。最近的操作导致一个补码溢出,检查有符号操作的溢出
只设置条件码,不更新目的寄存器
CMP~SUB TEST~AND

8.3 条件码的使用

根据条件码的组合,设置字节为0或1,即SET指令
条件跳转
条件数据传送
8.3.1 SET指令
示例
a-b
8.3.2 跳转指令
直接跳转
movq $0,%rax
jmp .L1
movq (%rax),%rdx
.L1:
popq %rdx

间接跳转
jmp *%rax 用%rax中的值作为跳转目标
jmp*(%rax) 以%rax中的值作为读地址,从内存中读出跳转目标
跳转指令的编码:
PC相对寻址:将目标指令的地址,和紧跟在跳转指令后的那条指令的地址的差,作为编码
给出绝对地址,直接指出目标
PC相对寻址 示例
第一条跳转指令的目标编码是0X03(第二个字节),加上下一个指令的编码0X5,得到跳转目标地址0X8(第4行指令的地址)
第二条跳转指令的目标编码是0Xf8(十进制为-8),加上下一个指令的编码0Xd,得到跳转目标地址0X5(第3行指令的地址)
8.3.3 条件数据传送
基于条件数据传送比基于条件控制转移的代码性能好
因为流水线,分支预测错误处罚主导这个函数的性能
条件数据传送,处理器无需预测测试的结果就可以执行

8.4 循环

用条件测试和跳转,组合实现循环
8.4.1 while循环
while循环的两种翻译方法
第一种:jump to middle
执行一个无条件跳转到循环结尾处的测试,以此来执行初始的测试
第二种:guarded-do
先条件分支,若初始条件不成立则跳出,变换为do-while
8.4.2 for循环
把for变成while
8.4.3 switch
跳转表:
一个数组,表项i是一个代码段的地址,这个代码段实现当开关索引值等于i时,程序应采取的动作
优点是执行开关语句的时间和开关情况的数量无关
当开关情况数量比较多,并且值的范围跨度比较小时,适合使用

9.过程

过程是一种抽象,提供一种封装代码的方式,用一组指定的参数和一个可选的返回值实现某种功能
包括:函数(function)、方法(method)、子例程(subroutine)、处理函数(handler)
共有的特性:传递控制、传递数据、分配和释放内存
运行时栈:
使用栈数据结构的LIFO内存管理原则
当过程需要的存储空间超出寄存器能存放的大小,就会在栈上分配空间,称为栈帧
转移控制:
将控制函数P转移到函数Q,只需要把PC设置为Q的代码的起始位置
数据传送:
x86-64中,可以通过寄存器最多传递6个整型参数,超出的部分用栈来传递
栈上的局部存储:
根据惯例,%rbx、%rbp和%r12~%r15被划分为 被调用者保存寄存器
所有其他的寄存器(除了栈指针%rsp)都被划分为 调用者保存寄存器
%rbxp作为基指针(base pointer),管理变长栈帧

10.数组的分配与访问

movl (%rdx,%rcx,4),%eax
对于E[i],E的地址存放在%rdx,i存放在%rcx

11.浮点代码

vcvtsi2sdq %rax,%xmm1,%xmm1
通常,第二个源的值只影响结果的高位字节,和目的操作数是相同的
vunpcklps %xmm0,%xmm0,%xmm0
交叉放置来自两个XMM寄存器的值,把它们存储到第三个寄存器中
浮点常数
对于LC2:
3435973837(0Xcccccccd)、1073532108(0X3ffccccc)
高位抽取指数字段0X3ff(1023),减去偏移1023,得到0
低位连接得到小数字段(0Xccccccccccccd),二进制小数为0.8,加上隐含的1得到1.8
浮点比较
三个条件码:
ZF:零标志位
CF:进位标志位
PF:奇偶标志位
对于整数操作,最近的一次算术或逻辑运算产生的值的最低位字节是偶校验的(有偶数个1)
对于浮点比较,当两个操作数中任一个是NaN
当任一个操作数为NaN时,会出现无序

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

B.D.S.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值