之前的笔记搬运
零散笔记
64位汇编中, 调用API超过4个时, 才会使用push, 低于等于4个参数时,默认使用寄存器传参
1
2
3
4
5
6
7浮点型参数使用: XMM0, 1, 2, 3这四个寄存器进行传参
整数型参数使用: RCX, RDX, R8, R9, 这四个寄存器传参
这些寄存器传参可以根据类型混合使用
大于128字节传参, 会申请新空间浅拷贝, 再传其指针新增加的寄存器访问低位: R8D, R8W, R8B
因为64位CPU中其实只有48根线, 所以高4位不是0000就是ffff
1 | 用户空间 0000000000000000 - 00007FFF FFFFFFFF |
- 64位中只有一个调用约定: X64 调用约定
1 | X64 调用约定: |
调用函数之前要保证栈顶模16, 否则调用xmm指令会出错
x64不可以内联汇编
xmm类型
1
2
3
4
5
6
7
8
9
10
11__m64类型,大小64位, 可能会使用xmm的低64位
__m128类型,大小128位, 可能会使用一个xmm寄存器
使用时需要包含Xmm库的头文件
汇编中xmmword类型, 大小128位
xmm指令:
cvt: 类型转换
ss : float
sd: double
si: int
cvtss2sd: float转double
cvttsd2si: double转int
addsd: double加法
- 返回值
1 | x64返回值, 小于等于64位通过rax返回, 大于64小于等于128位通过xmm0返回 |
- switch case和x86的差异
1 | x64的case数量小于6个时, 不会做表 |
局部变量,参数,全局变量
1
2
3
4
5
6不管全局或局部变量在x64中都是先定义的在栈的低地址, 后定义的在高地址
在x64访问局部变量与参数, 是依靠rsp寄存器进行偏移寻址来完成的
进函数里抬了多少空间的栈, 其值+8就是第一个参数
进入函数rsp会有一个为局部变量申请空间, 进行抬栈的操作, 所以在访问参数时, 需要加上局部变量空间大小, 这时是指向返回地址, 再+8就是第一个参数
x64中nop指令是可以变长的, nop后可以加寻址公式, 但是没有意义, 只是为了占空, 为了对齐指令地址, 其二进制也不一定是90
在 X86 CPU 中,FS 段寄存器用于指向线程环境块( TEB), 在 X64 上, GS 段寄存器在用户态是指向 TEB