首页 > 解决方案 > 如何将 x86 和 x64 asm 文件包含到单个 Visual Studio 项目中?

问题描述

我正在使用 Visual Studio 2017 Community 构建测试控制台 C++ 应用程序。我需要在该项目中包含一个汇编功能:

extern "C" void* __fastcall getBaseFS(void);

要包含一个 asm 文件,我右键单击该项目并转到“构建依赖项”->“构建自定义”并在列表中选中“masm”。

然后我可以通过右键单击我的项目 -> 添加新项目 -> 添加一个 asm 文件,然后在我编写 x86-64 asm 代码的位置添加“asm_x64.asm”文件:

.code

getBaseFS PROC

mov ecx, 0C0000100H   ; IA32_FS_BASE
rdmsr

shl rdx, 32
or rax, rdx

ret

getBaseFS ENDP

END

这适用于 64 位项目。

问题是当我将解决方案平台从 x64 切换到 x86 时:

在此处输入图像描述

我的 asm 文件需要更改。所以从某种意义上说,我需要在编译中包含一个不同的“asm_x86.asm”文件,该文件仅用于 x86 构建与 x64 构建。

自动化此开关的最佳方法是什么?

标签: visual-studioassemblymasm

解决方案


好的,多亏了Michael Petch,我解决了。必须将两者x64x86代码放在一个.asm文件中。

(还有另一个建议的选项来处理构建配置,但我更喜欢我在这里展示的方法。当解决方案从计算机移动到计算机时,这些构建配置消失了,我运气不好。)

所以,我不确定为什么usingIFDEF RAX有效,而微软自己的提议 ifndef X64却没有。但是哦,好吧。如果有人知道,请发表评论。

asm_code.asm文件:

IFDEF RAX
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; x64 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; WinAPI to call
extrn Beep : proc


.data

align   8
beep_freq:
    dq  700 ; hz
beep_dur:
    dq  200 ; ms
str_from:
    db  "Hail from x64 asm", 0



.code

useless_sh_t_function__get_GS_a_string_and_beep PROC
    ; parameter = CHAR** for a string pointer
    ; return = value of GS register selector

    mov     rax, str_from
    mov     [rcx], rax

    mov     rdx, qword ptr [beep_dur]
    mov     rcx, qword ptr [beep_freq]
    call    Beep

    mov     rax, gs
    ret
useless_sh_t_function__get_GS_a_string_and_beep ENDP




ELSE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; x86 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.686p  
.XMM  
.model flat, C  


.data

align   4
beep_freq   dd  700 ; hz
beep_dur    dd  200 ; ms
str_from    db  "Hail from x86 asm", 0


.code

; WinAPI to call
extrn stdcall Beep@8 : proc


useless_sh_t_function__get_GS_a_string_and_beep PROC
    ; parameter = CHAR** for a string pointer
    ; return = value of GS register selector

    mov     eax, [esp + 4]
    mov     [eax], OFFSET str_from

    push    dword ptr [beep_dur]
    push    dword ptr [beep_freq]
    call    Beep@8

    mov     eax, gs
    ret
useless_sh_t_function__get_GS_a_string_and_beep ENDP


ENDIF

END

main.cpp文件:

#include "stdafx.h"
#include <Windows.h>

extern "C" {
    size_t useless_sh_t_function__get_GS_a_string_and_beep(const CHAR** ppString);
};

int main()
{
    const char* pString = NULL;
    size_t nGS = useless_sh_t_function__get_GS_a_string_and_beep(&pString);
    printf("gs=0x%Ix, %s\n", nGS, pString);

    return 0;
}

推荐阅读