X86-64寄存器,立即数与寻址,汇编常用指令整理

辣个 ”拆炸弹“ 的实验 要 来 力 ,提前准备一下,到时候要做汇编,提前搞懂那些寄存器啊,指令的意义,以及x86-64指令的栈帧结构,否则无头苍蝇,是找不出boom函数调用的点的

寄存器

  • %rsp 栈顶位置指针
  • %rax 函数的返回值
  • %rdi,%rsi,%rdx,%rcx,%r8,%r9 函数形参,对应第 1,2,3,4,5,6 个形参
  • %rbx, %rbp, %r12, %r13, %r14, %r15
    数据寄存器,即过程调用时,可以存放数据的临时寄存器,这些寄存器是被调用者保存
  • %r10, %r11 数据寄存器,调用者保存

被调用者保存

因为子函数调用时,必须用寄存器完成计算啊,而父函数调用子函数时,可能寄存器里面已经有值了,那么需要子函数来帮忙保存这些值(压入栈中保存)

调用者保存

类似的,因为父子都要用寄存器,所以要备份,值得注意的是,这【调用者保存】的备份,是父函数自己想办法做的

X86-64寄存器,立即数与寻址,汇编常用指令整理

图来自《深入理解计算机系统》第三版

立即数

类似php语言 ,如果是立即数的话,需要在数字前面加上$号,比如十六进制数0x8,如果要在汇编当中使用,那么应当是 $0x8

寻址

如果一个变量表示的是地址,要想获得对应地址的值,需要寻址,最常用的是基址+偏移的寻址方式,立即数做偏移,$立即数(基址),表示的格式是:$立即数(寄存器名),意义是将寄存器名对应的寄存器里面的值取出来,加上偏移,获得新地址,然后去内存里找新地址对应的数字

其他寻址方式:

  • R[寄存器名] 表示 寄存器名对应的寄存器中的数据
  • M[] 表示内存

X86-64寄存器,立即数与寻址,汇编常用指令整理

图来自《深入理解计算机系统》第三版

指令

数据移动指令mov_

最常用的指令之一,移动数据,而下划线的填空,代表数据的规模,比如 b,w,l,q 代表 1,2,4,8 字节

格式: mov_ source destination 即将源移到目的,值得注意的是源目不能同时为内存

栈的进出

压栈需要将栈指针寄存器 %rsp -8,然后再将数据写入栈指针寄存器对应的地址

出栈需取出栈指针寄存器对应的地址的数据,再将栈指针寄存器 %rsp +8

算数和逻辑操作

主要用的还是 ADD 和 SUB,格式也是 操作 源 目

值得注意的是,这些都是二元的,比如 ADD SRC DES,等价于 DES += SRC,第二个操作数即是源也是目的

lea不访问内存,只是将源操作数作为地址,赋值到目的操作数中,很多时候,lea也被用来做加法操作。。。

X86-64寄存器,立即数与寻址,汇编常用指令整理

流程控制

调用

call

返回

ret

CPU状态标志位

即条件码,这些条件码将被用来作为if判断,描述最近的一次运算的特征

常常使用test或者cmp语句来改变条件码

跳转

je 等于时跳转
jne 不等于时跳转
ja 大于跳转(无符号数)
jg 大于跳转(有符号数)
jle 小于等于跳转