x64汇编第三讲,64位调用约定与函数传参.

一丶复习X86传参

在x86下我们汇编的传参如下:


push eax
call xxx xxx fun proc push ebp 保存栈底
mov ebp,esp 设置ebp
sub esp,0C0h 开辟局部变量空间
push ebx 保存寄存器环境
push esi
push edi pop edi 恢复寄存器环境
pop esi
pop ebx
mov esp,ebp 释放局部变量空间
pop ebp 恢复栈底
ret 返回,平展, 如果是 C在外平展 add esp,xxx stdcall 则内部平展 ret 4

看到上面这段代码.我们就应该在脑海中有一个示意图.

我们可以根据上图可以看到.在调用函数的时候做了那些事情.

1.往栈中存放参数

2.将返回地址入栈

3.保存栈底

4.栈内部进行自己的 申请空间 保存环境 以及释放.

二丶x64汇编

2.1汇编详解

在x64下,万变不离其宗.大部分跟x86一样.

如汇编代码为:

sub rsp,0x28

mov r9,1
mov r8,2
mov rdx,3
mov rcx,4
call xxx
add rsp,0x28

1.传参方式

首先说明一下,在X64下,是寄存器传参. 前4个参数分别是 rcx rdx r8 r9进行传参.多余的通过栈传参.从右向左入栈.

2.申请参数预留空间

在x64下,在调用一个函数的时候,会申请一个参数预留空间.用来保存我们的参数.比如以前我们通过push压栈

参数的值.相应的栈就会抬高.其实x64下,一样会申请.只不过这个地方在进函数的时候并没有值.进入函数之后才会将寄存器的值在拷贝到这个栈中.其实就相当于你还是push了.只不过我是外边申请空间,内部进行赋值.

如下:


sub rsp,0x28 //申请的栈空间为0x28,就相当于我们push rcx rdx r8 r9.只不过只是申请.
call xxxx
add rsp,0x28 xxx //函数内部 mov [rsp - 8],rcx
mov [rsp - 0x10],rdx
mov [rsp - 0x18],r8
mov [rsp - 0x20],r9 xxx

如下图:

我们编写一个简单的x64程序.对其反汇编进行查看.

首先开辟我们的参数空间,以及返回地址空间.我们单步一下查看



可以看大开辟了 5*8个字节大小的空间.

然后下方的汇编对其寄存器赋值.进行传参.说明我们只有4个参数.

此时进入Call内部.看下栈.

3.栈按照16字节对齐

现在我们应该明白了.在调用一个函数的时候. 使用 *sub rsp,xxx**进行抬栈,函数内部则进行参数赋值.

其实也是相当于push了参数.只不过它不像x86一样.在里面进行平栈了.而是外面进行平栈了.

那么有个疑问.比如说我们就4个参数. 通过上面来说.我们应该申请 sub rsp,0x20个字节才对.在CALL的时候

x86 x64都是一样的会将返回地址入栈. 那为什么要rsp,0x28.这样的话会多申请一个参数的值哪.

原因是这样的.栈要按照16字节对齐进行申请.

那么还有人会说.按照16字节对齐,那么我们的参数已经是16字节对齐了.比如为我们4个寄存器申请预留空间. rsp,0x20. (4 * 8 = 32 = 16j进制的 0x20)

那为什么还是会申请 rsp,0x28个字节,并且不对齐.

其实是这样的.当我们在 Call函数的时候.返回地址会入栈.如果按照我们之前申请的rsp,0x20个字节的话.那么当

返回地址入栈之后,现在总共抬栈大小是 0x28个字节.并不是16进制对齐. 但是当我们一开始就申请0x28个字节.

当返回地址入栈.那么就是0x28+8 = 0x30个字节. 0x30个字节不是正好跟16字节对齐吗.

所以我们的疑问也就没有了.

所以申请了0x28个字节,其实多出了的8字节是要跟返回地址一样.进行栈对齐使用.

那么申请的这个8字节空间,是没有用的.只是为了对齐使用.

所以x64汇编其实也就搞明白了.

1.在调用函数之前,会申请参数预留空间.(rcx,rdx,r8,r9)

2.函数内部,会将寄存器传参的值(rcx,rdx,r8,r9)保存到我们申请的预留空间中.

上面这两步其实就相当于x86下的 push r9 push r8 push rdx,push rcx

3.调用约定是__fastcall.传参有rcx rdx,平栈是按照c调用约定平栈. 也就是调用者平栈.

x64汇编第三讲,64位调用约定与函数传参.的更多相关文章

  1. linux 64位调用

    linux系统中64位汇编和32位汇编的系统调用主要有以下不同:(1)系统调用号不同.比如x86中sys_write是4,sys_exit是1:而x86_64中sys_write是1, sys_exi ...

  2. VC与JavaScript交互(三) --- CWebPage类调用javascript函数(给js函数传参,并取得返回值)

    ①需要一个别人写好的类CWebPage,将其对于的两个文件WebPage.h和WebPage.cpp添加到工程中. ②添加WebBrowser控件,在视图/对话框类的头文件中#include &quo ...

  3. VC/MFC中通过CWebPage类调用javascript函数(给js函数传参,并取得返回值)

    转自:http://www.cnblogs.com/javaexam2/archive/2012/07/14/2632959.html ①需要一个别人写好的类CWebPage,将其对于的两个文件Web ...

  4. x86 x64下调用约定浅析

    x86平台下调用约定 我们都知道x86平台下常用的有三种调用约定,__cdecl.__stdcall.__fastcall.我们分别对这三种调用约定进行分析. __cdecl __cdecl是C/C+ ...

  5. 【转载】64 位 Windows 内核虚拟地址空间布局(基于 X64 CPU)

    原文链接:http://shayi1983.blog.51cto.com/4681835/1734822 本文为原创翻译,原文出处为 http://www.codemachine.com/articl ...

  6. 64位gcc编译32位汇编

    由于使用as和ld来编译链接汇编程序,在使用C库的时候比较麻烦,需要输入比较多的指令,所以使用gcc进行编译链接.由于书中内容是32位汇编程序,但是机器使用的是64位操作系统,自带的gcc也是64位的 ...

  7. Jarvis OJ- [XMAN]level2/3_x64-Writeup——64位简单栈溢出

    两道64位栈溢出,思路和之前的32位溢出基本一致,所以放在一起 在这两道中体现的32位和64位的主要区别在于函数参数传递的方式 在32位程序运行中,函数参数直接压入栈中 调用函数时栈的结构为:调用函数 ...

  8. java——JNI(例子控制台(64位)清屏

    因为java的最底层是jvm,所以单纯的控制台java程序不能感知jvm再下面的操作系统的情况, 可以通过JNI(Java Native Interface)技术实现java后台调用C++/C的dll ...

  9. vs2010中配置OpenGL以及针对64位系统所遇问题的解决办法

    一.下面将对VS2010中配置OpenGL进行简单介绍. 学习OpenGL前的准备工作 第一步,选择一个编译环境 现在Windows系统的主流编译环境有Visual Studio,Broland C+ ...

随机推荐

  1. VHDL之concurrent之generate

    GENERATE It is another concurrent statement (along with operators and WHEN). It is equivalent to the ...

  2. Android读写文件

    1.从resource中的raw文件夹中获取文件并读取数据(资源文件只能读不能写) String res = ""; try{ InputStream in = getResour ...

  3. js 请求单个文件 并验证扩展名

    function suffix(file_name) { var three=file_name.split("."); ]; return last; } $('#btnSear ...

  4. https证书安装无效的主要原因

    https证书的作用是为了确认服务端身份,但网络上充满了无效的证书,浏览器对使用无效证书的访问,给出危险.不安全警告,将是否选择继续访问由用户选择,而大多数用户是无法区分这是配置还是真的存在安全问题. ...

  5. Vue.js大总结

    最近回顾了一下Vue.js的基础知识,把认为重要的几个点简单的罗列了出来 vue渐进式的理解 vue可以开发很多插件,可以把很多插件组合到一起,渐进的增加vue的功能 update beforeUpd ...

  6. 递归、作用域、生命周期(day09)

    数组可以作为形式参数使用 数组做形式参数的时候真正的形式参数并 不是数组而是一个可以作为数组使用的 变量 数组形式参数里包含的存储区都不是被调用 函数提供的 声明数组形式参数的时候可以省略中括号 里的 ...

  7. MySQL7.5.15数据库配置主从服务器实现双机热备实例教程

    环境说明 程序在:Web服务器192.168.0.57上面 数据库在:MySQL服务器192.168.0.67上面 实现目的:增加一台MySQL备份服务器(192.168.0.68),做为MySQL服 ...

  8. 1、dubbo的概念

    Dubbo是什么? Dubbo是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000+次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点. Dubbo[]是 ...

  9. 5G的前景以及意义

    首先来介绍一下5G:5G网络是第五代移动通信网络,其峰值理论传输速度可达每8秒1GB,比4G网络的传输速度快数百倍.举例来说,一部1G的电影可在8秒之内下载完成. 5G的技术原理是:三星电子通过研究和 ...

  10. vue采坑一:全局API

    Vue.set Vue.set( target, key, value ),target不能是 Vue 实例,或者 Vue 实例的根数据对象,因为源码中做了如下判断: var ob = (target ...