文章目录
记录至循环
3.1 历史发展
ISA:指令集架构
IA32,x86-64的32位前身
处理器发展趋势:从32到64位,核数越来越多
大部分32位代码可以在64位机器上跑,但是需要在编译时显式说明。
3.2 程序编码
linux> gcc -Og -o p p1.c p2.c
通过命令gcc使用gcc编译器(Og是优化等级选项),将p1.c和p2.c(源文件)编译为可执行文件p。(-o即翻译成机器语言)
类似地,在命令行上使用"-S"选项,就能得到源文件对应的汇编代码。
objdum -d sum
对sum文件进行反汇编,得到的代码可能跟源文件有一定出入。
3.3 数据格式
Inter用“字”表示16位数据类型,32位为“双字”,64位为“四字”
3.4 访问信息
寄存器:
如果移动1字节或2字节到一个寄存器中,寄存器原来高字节中的内容不变;如果移动4个字节,则原来的高位会被清零。
3.4.1 操作数指示符
操作数有三种:立即数,寄存器(%rsp被特殊保留),内存引用
3.4.2 数据传送指令
move指令:
规则:
- 内存里的数据不可以直接传送到数据中,只能通过寄存器传送。
- movabsq:传送64位立即数,常规的movq指令只能将32位补码数字的立即数作为源操作数,移动后进行符号扩展。movabsq能以64位立即数作为源操作数,并且只能以寄存器作为目标。
- 目标和源的字节数都要和指令匹配
cltq:只用于把%rax的一半扩展到全部,因为这个寄存器用的比较多所以专门设置了一个指令
3.4.3 数据传送示例
%rax中保存返回值
压入和弹出栈数据
*栈从上往下增长,类似于钟乳石。“
3.5 算术和逻辑操作
3.5.1 加载有效地址
实际上并没有引用内存,而是将有效地址写到目的操作数(必须是寄存器),常用于描述普通的算数计算,效率较高。
3.5.4 讨论
xorq %rax,%rax//即把%rax的值设为0
3.5.5 特殊的算数操作*
3.6 控制
3.6.1 条件码
会设置条件码的操作:
- 除了leaq之外的算术运算指令
- 比较和测试指令(如下)
test和cmp指令仅设置条件码而不改变寄存器的值
set指令:
set指令的目的操作数是寄存器的低位单字节,指令将这个字节设置为0或1。
3.6.3 跳转
3.6.4 跳转指令的编码:pc相对寻址
用下一行指令的地址+本行最后一个字节的补码值=将要跳转到的指令,这种方式称为相对寻址,便于移植。
3.6.5 用条件控制实现条件分支
有两种方式:条件控制和条件传送
- 条件控制:通过判定条件码来决定是否跳转到另外的指令
3.6.6 用条件传送实现条件分支
在现有的流水线指令集中,条件传送能够达到比条件控制更好的性能。但并不是所有的条件控制都能用条件传送实现