visual-studio - 如何将 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 构建。
自动化此开关的最佳方法是什么?
解决方案
好的,多亏了Michael Petch,我解决了。必须将两者x64
和x86
代码放在一个.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;
}
推荐阅读
- java - Android Studio 在警报对话框中显示图像
- amazon-web-services - AWS SDK 中内置的 SES 事件解析
- c# - 使用 C# 打开/保存 excel 文件时的问题
- database - 蜂巢 - 如何每天自动将数据附加到蜂巢表?
- node.js - 尝试使用加密在nodejs中解密使用AES 256(AES / ECB / PKCS7Padding)算法生成的加密密钥
- python - OSMNX:街道边缘的长度
- react-native - API GET 请求 URL 适用于 Brave/Chrome,但不适用于 fetch()
- android - 响应是动态的:需要一个字符串,但在第 1 行第 149 列是 BEGIN_OBJECT
- axios - axios'then()调用外部函数无法获取数据
- docker - docker-compose kafka - 本地机器客户端无法向 kafka 生成消息