x86笔记
Last Update:
对X86寄存器、概念和常见指令做一个笔记。
笔记来源自各大网站、博客。
常见寄存器作用:
x86-64 架构的寄存器有一些使用习惯,比如:
用来传参数的寄存器:%rdi, %rsi, %rdx, %rcx, %r8, %r9
保存返回值的寄存器:%rax
被调用者保存状态:%rbx, %r12, %r13, %r14, %rbp, %rsp
调用者保存状态:%rdi, %rsi, %rdx, %rcx, %r8, %r9, %rax, %r10, %r11
栈指针:%rsp
指令指针:%rip
函数调用约定:
%rdi
:第一个参数%rsi
:第二个参数%rdx
:第三个参数%rcx
:第四个参数%r8
:第五个参数%r9
:第六个参数%rax
:返回值
数据传输指令:
源目的地址:立即数,寄存器,存储器
目的地址:寄存器,存储器
(存储器不能到存储器)
mov指令的五种形式:
movl 传送双字
movb 传送一个字节
movw 传送两个字节
这里注意:
==movsbl== ==movzbl==指令负责拷贝一个字节,并设置目的操作数其余的位
区别在于:
movsbl源操作数是单字节,move后将24位设置为源字节的最高位(在下列例子中为F),然后拷贝到32位中。
movzbl 源操作数单字节,前面加24个0扩展到32位.然后拷贝到32位中.
mov movsbl movzbl区别:
1 |
|
调用者保存与被调用者保存
栈帧
想要了解栈帧的结构?我们还是先来回顾(review)以下有哪些和函数栈相关的寄存器吧。(这儿并没有包含浮点寄存器)
所谓调用者保存,就是可以让被调用者(自身不作为另一个调用者)随意使用,也是为了自己用到的数据不被覆盖。
所谓被调用者保存,恰恰与调用者保存相反。
函数调用一般参数传递(非浮点)前6个参数存于寄存器,剩下的参数按照函数定义从右向左压栈。
栈指针指向函数栈栈顶。
%rax 用于保存函数调用返回值。
了解了这些寄存器,我们再来看看栈帧的结构
就拿函数P的栈帧来说,从栈底到栈顶的方向分别存储以下内容:
被保存的寄存器
局部变量(sub $0x18,%rsp )
如果调用其他函数参数多于6,便有参数构造区
调用其他函数时需要将返回地址压栈