ASM呼叫中的访问冲突 [英] Access violation in ASM call

查看:135
本文介绍了ASM呼叫中的访问冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作自己的Allegro类,因此比较容易,但是我在使用ESP时遇到了问题,我遇到了访问冲突.

I am making my own Allegro Class so is more easy but I am having problem with ESP, I am getting Access Violation.

void RBAllegro::AddText( FONT *f, int x, int y, int color, int bg, const char *format)
{
    //textprintf_ex( m_Buffer, f, x, y, color, bg, format );
    __asm
    {
        push format;
        push bg;
        push color;
        push y;
        push x;
        push f;
        push m_Buffer;
        call textprintf_ex;
        add esp, 28;
    }
}

推荐答案

首先,为什么要这么做?编译器将执行吸气剂工作,并具有使其正确处理的附加优势.

您没有提供足够的信息.什么是快板班"? textprintf_ex的调用约定是什么(例如__stdcall__cdecl或什么)?由于该呼叫看起来很适合__cdecl呼叫,因此我将其假定为__stdcall.在这种情况下,请尝试以下代码:
Firstly, why the hell are you doing this? The compiler will do a getter job with the added advantage that it gets it right.

You haven''t provided enough information. What''s an "Allegro Class"? What''s the calling convention of textprintf_ex (e.g. __stdcall, __cdecl or what)? Since the call looks right for a __cdecl call I''ll assume it''s __stdcall. In that case try this code:
__asm
{
    push format;
    push bg;
    push color;
    push y;
    push x;
    push f;
    push m_Buffer;
    call textprintf_ex;
}



__stdcall函数清理自己的堆栈.

另一方面,它可能是成员函数.在这种情况下,您将需要传递this指针.根据调用约定,执行此操作的方式将有所不同.

总结:



__stdcall function clean up their own stacks.

On the other hand it may be a member function. In this case you''ll need to pass the this pointer. Depending on the calling convention how you go about doing this will vary.

In summary:


    • 删除汇编代码.
  • 如果您必须使用汇编代码,那么更多信息会很好.


来自文档:

From the docs:

void textprintf_ex(BITMAP *bmp, const FONT *f, int x, int y, int color, int bg, const char *fmt, ...);


你不是想念什么吗? ...提示...

为什么要使用汇编程序?那太疯狂了.您将无法优化函数调用.

...也许毕竟还不那么疯狂.

如果您在格式字符串中不使用任何格式说明符,这可能对您有用:


Aren''t you missing something? ... hint ...

Why do you use assembler? That''s just crazy. You won''t be able to optimize a function call.

...or maybe not that crazy after all.

This should probably work for you if you don''t use any format specifiers in your format string:

__asm
{
    push format;
    push bg;
    push color;
    push y;
    push x;
    push f;
    push m_Buffer;
    call dword ptr[textprintf_ex];
    add esp, 28;
}



当涉及可变参数时,与尝试一次推送一个值相比,从堆栈中执行memcpy可能更好.因为在后一种情况下,您将必须解析格式字符串以了解所有参数的大小.

您可以将& f用作源开始,并使用函数中易失性变量的地址偏移量作为对存储块结尾的引用.您只需要像上面一样处理m_Buffer.



When it comes to the varadic arguments you might be better off doing a memcpy from the stack, than trying to push a value at a time. Because in the latter case you will have to parse the format string to know the size of all parameters.

You can use &f as the source start and use an offset to the address of a volatile variable located in your function as a reference to the end of the memory block. You will only have to deal with m_Buffer as you do above.


看看va_start,va_args和va_end宏.它们是专门为处理变量参数列表而设计的,包括将它们传递给带有变量参数列表的其他函数.

现在讲道...

当在流行的I/O模型中使用插入和提取运算符时,为什么在C ++中使用可变参数列表?有什么不对:

Look at the va_start, va_args and va_end macros. They''re designed explicitly for handling variable parameter lists, including passing them onto other functions taking variable parameter lists.

Now the sermon...

Why, in C++, are you using variable parameter lists when the prevailing model for I/O uses insertion and extraction operators? What''s wrong with having:

allegro_text_stream str( f, x, y, color, bg );

str << "The value of n is: " << n;



阅读Langer和Kreft撰写的"Standard C ++ IOStreams and Locales",它具有您需要的所有详细信息.

干杯,



Have a read of "Standard C++ IOStreams and Locales" by Langer and Kreft, it''s got all the gory details you''ll need.

Cheers,

Ash


这篇关于ASM呼叫中的访问冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆