X86-64 汇编学习1
Posted 不会写代码的丝丽
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了X86-64 汇编学习1相关的知识,希望对你有一定的参考价值。
前言
熟悉一些关键字可以更方便看懂官方的手册:
IA-32(Intel architecture -32)
: 指代因特尔32位处理器架构。
X86-64
:64位处理器架构
compatibility(兼容模式)
:在64位下运行IA-32程序或者模式
内存范围
我们知道我们的32位程序寻址范围为2^32=4G内存即 0000 0000-FFFF FFFF
。
具体内存寻址如下图所示:
64位处理器寻址范围为2^64但是实际上指令集架构设计和处理器都没有完全实现这么大的范围。
AMD在地址线实现了52根,但是实际往往只使用48位而已。因此64位系统往往实际只使用48位内存寻址范围,
前16位用于预留扩展。
我们利用x64Dbg调试相关用户程序,你会发现所有的地址前16位都是0,即16进制的四个0。
寄存器
这块建议参阅Intel手册卷1部分内容,这里贴出部分节选:
通用寄存器32位下有8位,64位有16个。
如果你需要访问特定大小的寄存器可以按照如下官方表格进行操作。比如 1字节R8可以使用R8B等
限制:
(1) 所有32位寄存器的修改,会将对应的64位寄存器的前32位用0填充(8,16位的赋值不会有影响)。
举例如下:
(1) 所有高8位寄存器访问不能与新的寄存器同时访问(r8-r15等)
Win64 调用约定
这可直接参阅官方文档:
调用约定文档
举例环节:
#include<stdio.h>
float subIntFloat(int i1, float i2, int i3, float i4)
printf("hello test %d %f %d %f \\r\\n", i1, i2, i3, i4);
return i1 + i2 + i3 + i4;
int addNumber4(int i1,int i2,int i3,int i4)
printf("hello test %d %d %d %d \\r\\n",i1,i2,i3,i4);
float fRet= subIntFloat(1,2.0,3,3.0);
printf("subIntFloat fRet %f \\r\\n", fRet);
return i1 + i2 + i3 + i4;
int main()
int ret= addNumber4(1, 2, 3, 4);
printf("addNumber4 ret %d \\r\\n", ret);
return 0;
我们首先关注addNumber4
传参和结果返还。
栈进行128位对齐
在64位系统下很多指令要求内存进行128对齐,比如MOVAPS指令。
因此很多函数在开头对RSP进行栈对齐(一般末尾补8h).
相对RIP进行寻址
x86-64额外多出一个寻址方式,
在x32我们想得到EIP的地址往往需要跳一个空函数得到,而在x86-64我们可以写出如下图汇编指令:
x32下相关操作是不被支持的:
参考
wikipedia 64-bit computing 内存说明
stackoverflow 中64-bit 内存讨论
微软文档关于64寄存器说明
intel 手册
以上是关于X86-64 汇编学习1的主要内容,如果未能解决你的问题,请参考以下文章