首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Visual Studio asm移植到g++ basic asm

将Visual Studio asm移植到g++ basic asm
EN

Stack Overflow用户
提问于 2020-12-27 20:50:28
回答 1查看 102关注 0票数 0

我有一个简单但令人沮丧的问题:我使用的是g++编译器,但我使用的示例代码是为Visual Studio编写的。通常不是问题,但它们的内联汇编程序的工作方式不同,因此需要更改代码。

问题所在的片段如下:

代码语言:javascript
复制
float someotherfuncname(inputvar)
{
    //For example purposes. Can be arbitrary amount of math.
    return 1;
}

void __declspec(naked)funcname(void)
{
    __asm
    {   
        push    ecx
        call    someotherfuncname
        pop     ecx
        retn
    }
}

我在这个话题上没有经验,基本上我是在小心翼翼地复制一个更有经验的程序员写的神秘公式,希望能重现结果(在其他部分取得成功,但这个部分得到了我的支持)。

据我所知,主要的问题是:

-g++ asm没有"retn“。

-"call“使用来自周围c++程序的东西。没有扩展的asm,g++ asm不能很容易地使用c++的东西。__declspec(裸体)阻止我使用扩展的asm。

-I不知道"retn“是做什么的,所以我不能用等价的代码来伪造它。

编辑:我正在使用Windows。

其目的是构建一个供OBSE用于TES遗忘的.dll。我正在用g++ (可能是MinGW)构建它。

一个(非)工作代码的最小草图是:在.h文件中(这不是问题,只是为了完整性):

代码语言:javascript
复制
#ifndef MSK_B
#define MSK_B

#ifdef __cplusplus
extern "C" {
#endif

#ifdef DLL_KOMP
#define SPECK __declspec(dllexport)
#else
#define SPECK __declspec(dllexport)
#endif

bool SPECK OBSEPlugin_Query(const OBSEInterface * obse, PluginInfo * info);

bool SPECK OBSEPlugin_Load(const OBSEInterface * obse);

#ifdef __cplusplus
}
#endif

#endif  // MMC_B_H

在.cpp文件中:注意,这里没有定义OBSEInterface和PluginInfo,但也不需要它们(只有一些框架定义可以让编译器满意,所以我省略了它们)。

代码语言:javascript
复制
include "[name of the .h file]"
include <fstream>
include "Windows.h"

typedef unsigned long UInt32

void SafeWrite8(UInt32 addr, UInt32 data)
{
    UInt32  oldProtect;

    VirtualProtect((void *)addr, 4, PAGE_EXECUTE_READWRITE, &oldProtect);
    *((UInt8 *)addr) = data;
    VirtualProtect((void *)addr, 4, oldProtect, &oldProtect);
}

void SafeWrite32(UInt32 addr, UInt32 data)
{
    UInt32  oldProtect;

    VirtualProtect((void *)addr, 4, PAGE_EXECUTE_READWRITE, &oldProtect);
    *((UInt32 *)addr) = data;
    VirtualProtect((void *)addr, 4, oldProtect, &oldProtect);
}

void WriteRelPaddedCall(UInt32 strtAddr, UInt32 retnAddr, UInt32 callbackAddr)
{
    for (UInt32 i = strtAddr; i < retnAddr; i++) SafeWrite8(i,0x90);
    WriteRelCall(strtAddr,callbackAddr);
}

extern "C" {
bool SPECK OBSEPlugin_Query(const OBSEInterface * obse, PluginInfo * info)
{
    return true;
}

bool SPECK OBSEPlugin_Load(const OBSEInterface * obse)
{
    UInt32 RuesDispAddrH = 0x005AB365;
    UInt32 RuesDispAddrR = 0x005AB36D;
    //RuestungECX is the function i posted above.
    //This line (as implemented here) causes the game to crash when loading a game (or starting a new game).
    WriteRelPaddedCall(RuesDispAddrH, RuesDispAddrR, (UInt32) &RuestungECX);
    return true;
}
};
EN

回答 1

Stack Overflow用户

发布于 2020-12-27 23:02:25

我不确定它是否适合你,但你可以用clang (-fasm-blocks开关)编译msvc stile程序集。

下面是一个成功编译的asm示例:https://godbolt.org/z/o57sbq

不确定这是不是一个很好的选择,因为轰隆不是一个gcc,但只是想提一下。也许这对你有帮助。请不要杀我。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65465946

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档