IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    在 MSYS2 上开发 GNU 汇编程序

    Easior Lars发表于 2023-09-22 17:20:29
    love 0

    汇编语言是最贴近机器硬件、运行效率很高的一种低级编译型语言。由于它与硬件紧密相关,因此它的开发完全受平台限制,所开发的程序基本上不具有移植性。当然,只要硬件(主要是中央处理器)相近,那就有可能采用同一套汇编语言编程工具进行程序开发。MSYS2 是 GCC 工具链在 MS Windows 上极为成功的移植!利用 MSYS2 提供的编程工具,就可以通过 C/C++/Python 等编程语言进行 MS Windows 上的原生程序开发。这既可以借鉴 GNU Linux 上优秀开源软件的成功开发经验,还可以将这些优秀的软件移植到 MS Windows 平台。不过,这里要介绍的是如何利用 MSYS2 中基于 MinGW x64 工具链提供的 GNU as 与 ld 工具进行 GNU 汇编程序的开发。

    先来看一个示例,它主要通过指令 call 调用了标准 C 函数:

        /* test.s */
        .section .data
    msg: .asciz "Hello, MSVC Library!"
        .section .text
        .global main
    main:
        pushq %rbp
        movq %rsp, %rbp
        subq $8, %rsp
    
        leaq msg(%rip), %rcx
        call printf
    
        xor %eax, %eax
        call exit

    上述汇编源代码在 MSYS2 环境下的编译以及运行过程是这样的:

    $ as -o test.o test.s
    $ ld -o test.exe test.o -lmsvcrt
    $ ./test.exe

    为了正确编写 GNU 汇编源代码,除了熟悉 AT&T 汇编语法与 Amd64 指令集之外,特别需要了解 MS Windows x64 的调用协定(FASTCALL 的一种变体)、MS Windows C/C++ 运行库,请参看 https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions?view=msvc-170、https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170。

    再来看如何调用 MS Windows 的应用程序编程接口?

        .section .rodata
    mba_msg:
        .asciz "Hello ASM world!"
    mba_title:
        .asciz "Simple Message Box"
        .section .text
        .globl  _start
    _start:
        # align RSP
        pushq %rbp
        movq %rsp, %rbp
        subq $0x20, %rsp 
    
        # https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messageboxa
        # display a message box
        xorl %ecx, %ecx   # hWnd = NULL
        leaq mba_msg(%rip), %rdx
        leaq mba_title(%rip), %r8
        movl $0x40, %r9d  # MB_ICONINFORMATION
        call MessageBoxA
     
        # exit with zero
        xorl %ecx, %ecx
        call ExitProcess

    上述源代码在 MSYS2 环境下的编译以及运行过程是这样的:

    $ as -o test.o test.s
    $ ld test.o -lkernel32 -luser32 -o test.exe
    $ ./test.exe

    Linux 与 MS Windows API 对照表 https://www.cnblogs.com/UnGeek/p/2981439.html。如果 GNU 汇编代码中还调用了 Nt/Zw 开头的 MS Windows API,那么只需在使用 GNU 链接器时增加 NTDLL 选项。



沪ICP备19023445号-2号
友情链接