IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> X86和X64运行环境下C++调用汇编函数源码和解释 -> 正文阅读

[C++知识库]X86和X64运行环境下C++调用汇编函数源码和解释

备注: 这里给出的代码是在Win10系统中VS2022开发环境下编译测试通过的。

X86环境下C++调用汇编函数

c++代码:

#include <iostream>

// 函数使用 C 风格命名规范
extern "C" int CalcSum_(int a, int b, int c);

int main(int argc, unsigned short* argv[])
{
    int a = 17, b = 11, c = 14;
    int sum = CalcSum_(a, b, c);

    std::cout << "  a:   " << a << std::endl;
    std::cout << "  b:   " << b << std::endl;
    std::cout << "  c:   " << c << std::endl;
    std::cout << "  (x86)sum: " << sum << std::endl;
    return 0;
}

x86汇编代码:

    .model flat,c
    .code

; extern "C" int CalcSum_(int a, int b, int c)
;
; Description:  This function demonstrates passing arguments between
;               a C++ function and an assembly language function.
;
; Returns:      a + b + c

CalcSum_ proc

; x86处理器环境下, 参数由堆栈传入(依旧是从右向左入栈)
; Initialize a stack frame pointer
        push ebp
        mov ebp,esp

; Load the argument values
        mov eax,[ebp+8]                     ; eax = 'a'
        mov ecx,[ebp+12]                    ; ecx = 'b'
        mov edx,[ebp+16]                    ; edx = 'c'

; Calculate the sum
        add eax,ecx                         ; eax = 'a' + 'b'
        add eax,edx                         ; eax = 'a' + 'b' + 'c'

; Restore the caller's stack frame pointer
        pop ebp
        ret

CalcSum_ endp
        end

运行结果:

X64环境下C++调用汇编函数

c++代码:

#include <iostream>

// 函数使用 C 风格命名规范
extern "C" int CalcSum3_(int a, int b, int c);
extern "C" int CalcSum6_(int a, int b, int c, int d, int e, int f);
extern "C" int CalcSum7_(int a, int b, int c, int d, int e, int f, int g);

int main(int argc, unsigned short* argv[])
{
    int a = 17, b = 11, c = 14;
    int sum3 = CalcSum3_(a, b, c);

    std::cout << "  a:   " << a << std::endl;
    std::cout << "  b:   " << b << std::endl;
    std::cout << "  c:   " << c << std::endl;
    std::cout << "  (x64)sum3(a+b+c)        ,result: " << sum3 << std::endl;

    std::cout << "" << std::endl;

    a = 17, b = 11, c = 14;
    int d = 3, e = 9, f = 5, g = 6;
    int sum6 = CalcSum6_(a, b, c, d, e, f);
    int sum7 = CalcSum7_(a, b, c, d, e, f, g);

    std::cout << "  a:   " << a << std::endl;
    std::cout << "  b:   " << b << std::endl;
    std::cout << "  c:   " << c << std::endl;
    std::cout << "  d:   " << d << std::endl;
    std::cout << "  e:   " << e << std::endl;
    std::cout << "  f:   " << f << std::endl;
    std::cout << "  g:   " << g << std::endl;
    std::cout << "  (x64)sum6(a+b+c+d+e+f)  ,result: " << sum6 << std::endl;
    std::cout << "  (x64)sum7(a+b+c+d+e+f+g),result: " << sum7 << std::endl;
    return 0;
}

x64汇编代码:

; x64 新增 r8, r9, r10, r11, r12, r13, r14, r15 这8个通用寄存器
    .code

; extern "C" int CalcSum3_(int a, int b, int c)
;
; Description:  This function demonstrates passing arguments between
;               a C++ function and an assembly language function.
;
; Returns:      a + b + c

CalcSum3_ proc

; x64, 默认前四个参数由 rcx,rdx,r8,r9 四个寄存器传参
; Initialize a stack frame pointer
        push rbp
        mov rbp,rsp

; Load the argument values
        mov rax,rcx                          ; eax = 'a'

; Calculate the sum
        add rax,rdx                         ; eax = 'a' + 'b'
        add rax,r8                          ; eax = 'a' + 'b' + 'c'
                                            ; 返回值存放在rax中

; Restore the caller's stack frame pointer
        pop rbp
        ret

CalcSum3_ endp


; extern "C" int CalcSum6_(int a, int b, int c, int d, int e, int f)
;
; Description:  This function demonstrates passing arguments between
;               a C++ function and an assembly language function.
;
; Returns:      a + b + c + d + e + f

CalcSum6_ proc

; x64处理器环境下, 默认前四个参数由 rcx,rdx,r8,r9 四个寄存器传参,更多参数由堆栈传入(依旧是从右向左入栈)(第五个参数e也存放在rax中)
; Initialize a stack frame pointer
        push rbp
        mov rbp,rsp

; Load the argument values
        ;mov r10d, dword ptr [rbp + 8 * (5 + 1)]    ; 第5个参数, 即参数e
                                                    ; 这里的5(即: 5 * 8 = 40个字节) 表示 4 * 8 = 32 字节的影子空间(home area 为rcx,rdx,r8,r9准备的预留空间)和8字节调用此函数的返回地址(push rbp)
        mov r10d, [rbp + 8 * (5 + 1)]               ; 第5个参数, 即参数e
        mov r11d, [rbp + 8 * (5 + 2)]               ; 第6个参数, 即参数f
        mov rax,rcx                                 ; eax = 'a'

; Calculate the sum
        add rax,rdx                                 ; eax = 'a' + 'b'
        add rax,r8                                  ; eax = 'a' + 'b' + 'c'
        add rax,r9                                  ; eax = 'a' + 'b' + 'c' + 'd'
        add rax,r10                                 ; eax = 'a' + 'b' + 'c' + 'd' + 'e'
        add rax,r11                                 ; eax = 'a' + 'b' + 'c' + 'd' + 'e' + 'f'
                                                    ; 返回值存放在rax中

; Restore the caller's stack frame pointer
        pop rbp
        ret

CalcSum6_ endp


; extern "C" int CalcSum7_(int a, int b, int c, int d, int e, int f, int g)
;
; Description:  This function demonstrates passing arguments between
;               a C++ function and an assembly language function.
;
; Returns:      a + b + c + d + e + f + g


CalcSum7_ proc

; x64处理器环境下, 默认前四个参数由 rcx,rdx,r8,r9 四个寄存器传参,更多参数由堆栈传入(依旧是从右向左入栈)(第五个参数e也存放在rax中)

; Load the argument values
        ;mov r10d, dword ptr [rsp + 8 * (4 + 1)]    ; 第5个参数, 即参数e
                                                    ; 这里的4, 即: 4 * 8 = 32 字节的影子空间(home area 为rcx,rdx,r8,r9准备的预留空间)。注意,这里直接使用了rsp
        mov r10d, [rsp + 8 * (4 + 1)]               ; 第5个参数, 即参数e
        mov r11d, [rsp + 8 * (4 + 2)]               ; 第6个参数, 即参数f
        mov r12d, [rsp + 8 * (4 + 3)]               ; 第7个参数, 即参数g

        mov rax,rcx                                 ; eax = 'a'

; Calculate the sum
        add rax,rdx                                 ; eax = 'a' + 'b'
        add rax,r8                                  ; eax = 'a' + 'b' + 'c'
        add rax,r9                                  ; eax = 'a' + 'b' + 'c' + 'd'
        add rax,r10                                 ; eax = 'a' + 'b' + 'c' + 'd' + 'e'
        add rax,r11                                 ; eax = 'a' + 'b' + 'c' + 'd' + 'e' + 'f'
        add rax,r12                                 ; eax = 'a' + 'b' + 'c' + 'd' + 'e' + 'f' + 'g'
                                                    ; 返回值存放在rax中

; Return
        ret

CalcSum7_ endp
        end

运行结果:

可以看得出来,x64比x86环境下调用机制要复杂一些。所以x64环境下示例代码用了三个函数来演示说明。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 20:30:29  更:2022-03-21 20:31:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:44:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码