对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区别:

//假设 %dh =8D,%eax=98765432

movb %dh %al      %eax=9876548D                             

movsbl %dh %eax   %eax=FFFFFF8D

movzbl %dh %eax   %eax=0000008D

调用者保存与被调用者保存

栈帧

想要了解栈帧的结构?我们还是先来回顾(review)以下有哪些和函数栈相关的寄存器吧。(这儿并没有包含浮点寄存器)

  • 所谓调用者保存,就是可以让被调用者(自身不作为另一个调用者)随意使用,也是为了自己用到的数据不被覆盖。

  • 所谓被调用者保存,恰恰与调用者保存相反。

  • 函数调用一般参数传递(非浮点)前6个参数存于寄存器,剩下的参数按照函数定义从右向左压栈

  • 栈指针指向函数栈栈顶。

  • %rax 用于保存函数调用返回值。


    了解了这些寄存器,我们再来看看栈帧的结构


就拿函数P的栈帧来说,从栈底到栈顶的方向分别存储以下内容:

  • 被保存的寄存器

  • 局部变量(sub $0x18,%rsp )

  • 如果调用其他函数参数多于6,便有参数构造区

  • 调用其他函数时需要将返回地址压栈

用记录对抗遗忘