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 数据寄存器,调用者保存的
被调用者保存
因为子函数调用时,必须用寄存器完成计算啊,而父函数调用子函数时,可能寄存器里面已经有值了,那么需要子函数来帮忙保存这些值(压入栈中保存)
调用者保存
类似的,因为父子都要用寄存器,所以要备份,值得注意的是,这【调用者保存】的备份,是父函数自己想办法做的
图来自《深入理解计算机系统》第三版
立即数
类似php语言 ,如果是立即数的话,需要在数字前面加上$号,比如十六进制数0x8,如果要在汇编当中使用,那么应当是 $0x8
寻址
如果一个变量表示的是地址,要想获得对应地址的值,需要寻址,最常用的是基址+偏移的寻址方式,立即数做偏移,$立即数(基址)
,表示的格式是:$立即数(寄存器名)
,意义是将寄存器名对应的寄存器里面的值取出来,加上偏移,获得新地址,然后去内存里找新地址对应的数字
其他寻址方式:
- R[寄存器名] 表示 寄存器名对应的寄存器中的数据
- M[] 表示内存
图来自《深入理解计算机系统》第三版
指令
数据移动指令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也被用来做加法操作。。。
流程控制
调用
call
返回
ret
CPU状态标志位
即条件码,这些条件码将被用来作为if判断,描述最近的一次运算的特征
常常使用test或者cmp语句来改变条件码
跳转
je 等于时跳转
jne 不等于时跳转
ja 大于跳转(无符号数)
jg 大于跳转(有符号数)
jle 小于等于跳转