一、32与64位数据类型宽度
- 可以看到除了long_ 和 指针两大类数据类型以外,其他的数据类型宽度都是相同的
二、x86-64的通用寄存器 (共16个)
- 可以看到,左边一列中,深蓝色方框中的是32位寄存器的写法,而蓝色方框左边是64位寄存器的写法。
- 为了向下兼容,还可以通过eax/edx/ecx...进行32位的存取
- 右侧是8个64位新扩展的8个寄存器,同时低32位同样可以被当做32位寄存器所使用。
- %ebp/%rbp寄存器不再是专用寄存器
三、 x86-32位下的swap
void swap(int *xp,int *yp){
int t0 = *xp;
int t1 = *yp;
*xp = t1;
*yp = t0;
}
- 64位下汇编代码
# 32位
movl 8(%esp), %edx
movl 12(%esp), %eax
movl (%edx), %ecx
movl (%eax), %ebx
movl %ebx, (%edx)
movl %ecx, (%eax)
popl %ebx
ret
- 64位下汇编代码
当被操作数据是32位时,我们能够观察出两者的几点不同:
参数通过寄存器来传递
- 当参数少于7个时,参数从左到右被放到寄存器rdi,rsi,rdx,rcx,r8,r9
- 当参数在七个以上时,前6个的存储方式不变,但后面的一次从右向左放入栈中
当被操作数据是64位:
如图,我们可以看到,大体上没有什么区别,只是:
- 使用的寄存器从
%edx,%eax
变为了%rdx,%rax
moveq
指令
三、小结
x86指令特点:
- 支持多种类型的指令操作数
立即数,寄存器,内存数据 - 算数逻辑指令可以以内存数据作为操作数
- 支持多种内存地址计算模式
Rb+S*Ri+D
,也可用于整数指令(leal指令) - 变长指令 (这是什么???)
- 支持多种类型的指令操作数
习题:
知识点:
- 当局部变量不多时,编译器偏好将局部变量储存在寄存器中,避免访存