MASM代码转换到AT&T

老邓 2009-02-25 03:59:43
想用MinGW实现thunk,看到这个文章:http://www.vckbase.com/document/viewdoc/?id=1817
文章利用编译器,避免了写机器码来实现thunk,但汇编部分是MASM。
我移植到MinGW下运行。
这是汇编部分的关键代码:
void ThunkTemplate(DWORD& addr1,DWORD& addr2,int calltype=0)
{
int flag = 0;
DWORD x1,x2;

if(flag)
{
__asm //__thiscall
{
thiscall_1: mov ecx,-1; //-1占位符,运行时将被替换为this指针.
mov eax,-2; //-2占位符,运行时将被替换为CTimer::CallBcak的地址.
jmp eax;
thiscall_2: ;
}

__asm //__stdcall
{
stdcall_1: push dword ptr [esp] ; //保存(复制)返回地址到当前栈中
mov dword ptr [esp+4], -1 ; //将this指针送入栈中,即原来的返回地址处
mov eax, -2;
jmp eax ; //跳转至目标消息处理函数(类成员函数)
stdcall_2: ;
}
}

if(calltype==0)//this_call
{
__asm
{
mov x1,offset thiscall_1; //取 Thunk代码段 的地址范围.
mov x2,offset thiscall_2 ;
}
}
else
{
__asm
{
mov x1,offset stdcall_1;
mov x2,offset stdcall_2 ;
}
}

addr1 = x1;
addr2 = x2;
}


能否帮忙转换成AT&T汇编代码?希望能在MinGW下调试通过!
我尝试改写,但失败。如果调试通过,请将调试后源码发送到:loaden (@) gmail dot com (烦请替换一下)
多谢!只懂C/C++,只懂一点8086汇编的新手恳请帮助...
...全文
273 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
老邓 2009-02-27
  • 打赏
  • 举报
回复
解决了:汇编的条件判断有问题,不要判断flag了。
老邓 2009-02-27
  • 打赏
  • 举报
回复
hopy,你好!stdcall还是有问题,能否帮忙再看看转换后的AT&T代码?
__stdcall由主调函数负责参数压栈,由函数本身负责栈的恢复:是否是因为没有进行栈的恢复呢?
如果是stdcall的话,代码长度应该是16,而现在的汇编:thiscall和stdcall的代码长度都是12,是一样的。
killbug2004 2009-02-26
  • 打赏
  • 举报
回复
movl -2, %eax不能这样写吧
老邓 2009-02-26
  • 打赏
  • 举报
回复
通过查阅资料,慢慢尝试:虽然通过编译,但并不正确。能否在指出此转换的错误?
void ThunkTemplate(DWORD& addr1,DWORD& addr2,int calltype=0)
{
long x1 = 0, x2 = 0;
bool flag = false;
if (flag)
{
asm volatile
(
"thiscall_1:\n\t" // 这里我感觉有问题!
"movl -1, %ecx\n\t"
"movl -2, %eax\n\t"
"jmp * %eax\n\t"
"thiscall_2:" // 这里我感觉有问题!
);

asm volatile
(
"stdcall_1:\n\t"
"pushl (%esp)\n\t"
"movl -1, %esp\n\t" // 这里我感觉有问题!
"movl -2, %eax\n\t"
"jmp * %eax\n\t"
"stdcall_2:"
);
}

if (calltype==0)
{
asm volatile("movl $thiscall_1, %0;" : "=r"(x1)); // 这里我感觉有问题!
asm volatile("movl $thiscall_2, %0;" : "=r"(x2));
}
else
{
asm volatile("movl $stdcall_1, %0;" : "=r"(x1));
asm volatile("movl $stdcall_2, %0;" : "=r"(x1));
}

addr1 = x1;
addr2 = x2;
}
老邓 2009-02-26
  • 打赏
  • 举报
回复
C++:Debug下测试成功。Release下不优化成功。
C:Debug下成功,Release下-O2成功。
大熊猫侯佩 2009-02-26
  • 打赏
  • 举报
回复
你在debug下测试成功的?
老邓 2009-02-26
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 mydo 的回复:]
改了一下,现在用C++编译连接(debug和release)都可以无错通过。

C/C++ code
static void ThunkTemplate(DWORD &addr1,DWORD &addr2,int calltype=0)
{
int flag = 0;
DWORD x1,x2;

__asm__ __volatile__("testl $0,%3;jz 0f;thiscall_1:movl $-1,%…
[/Quote]

加上static,我在MinGW 4.3.2下还是无法在Release下编译链接。还是内联了。
不过,找到调试通不过的原因了。竟然是因为:
printf("\n CTimer::CallBcak,ID=%d, Elapse=%d\n",m_TimerID,m_uElapse);

将其改为printf("OK\n"),发现thunk已经成功了!!

非常感谢mydo援手!!解决了一个长期以来压抑在心中的问题。
也坚定了我坚决转向MinGW的决心!!
老邓 2009-02-26
  • 打赏
  • 举报
回复
还是有问题:虽然编译链接成功,但所产生的代码段长度不对。不管是thiscall,还是stdcall,代码长度都是12。而从原理上,stdcall的代码长度应该是16.
不过原因可能正如你所说:指令布局不同。
恳请调试一下,但能否thunk成功,非常感谢!
搜遍整个网络,都没有gcc下thunk的例子或成功的消息。真的很无奈。
请多费费心。
实在不行的话,也只能放弃GCC了...
工程的设计都建立在thunk的基础上,如果没有thunk,改动太大,而且效率上、面向对象设计上都不能让人满意。
  • 打赏
  • 举报
回复
确实如此。我才知道有这样的语法要求。:)
大熊猫侯佩 2009-02-26
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 DelphiGuy 的回复:]
直接jmp %%eax就好了,为什么要jmp *%%eax?

[/Quote]
我在gcc下直接写jmp %%eax 编译连接时提示 :
Compiling source file(s)...
cppcon.cpp
{standard input}: Assembler messages:
{standard input}:81: Warning: indirect jmp without `*'

cppcon.exe - 1 error(s), 0 warning(s)
大熊猫侯佩 2009-02-26
  • 打赏
  • 举报
回复
改了一下,现在用C++编译连接(debug和release)都可以无错通过。
你再试试。感觉这样可能有问题。因为
虽然逻辑上和你原先的相同,但因为你这个是Thunk,不是用来
实际执行的,所以指令布局可能会略有差异。


static void ThunkTemplate(DWORD &addr1,DWORD &addr2,int calltype=0)
{
int flag = 0;
DWORD x1,x2;

__asm__ __volatile__("testl $0,%3;jz 0f;thiscall_1:movl $-1,%%ecx;"
"movl $-2,%%eax;jmp *%%eax;thiscall_2:;"
"stdcall_1:pushl (%%esp);movl $-1,4(%%esp);"
"movl $-2,%%eax;jmp *%%eax;stdcall_2:;"
"0:testl $0,%2;jnz 1f;movl $thiscall_1,%0;"
"movl $thiscall_2,%1;jmp 2f;1:mov $stdcall_1,%0;"
"mov $stdcall_2,%1;2:;"
:"=r"(x1)/*%0*/,"=r"(x2)/*%1*/:"r"(calltype)/*%2*/,\
"r"(flag)/*%3*/);

addr1 = x1;
addr2 = x2;
}
  • 打赏
  • 举报
回复
直接jmp %%eax就好了,为什么要jmp *%%eax?
killbug2004 2009-02-26
  • 打赏
  • 举报
回复
mydo来了就可以搞定了 呵呵
老邓 2009-02-26
  • 打赏
  • 举报
回复
1090833
大熊猫侯佩 2009-02-26
  • 打赏
  • 举报
回复
你QQ或msn多少?
老邓 2009-02-26
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 killbug2004 的回复:]
movl -2, %eax不能这样写吧
[/Quote]这应该没问题,我调试时看生成的汇编,这一行是正确的。
老邓 2009-02-26
  • 打赏
  • 举报
回复
多谢mydo出手相助!
MinGW TDM 4.3.2 Debug版编译链接成功,但无法实现thunk;而改成release版,则编译错误:
C:\DOCUME~1\qpsoft\LOCALS~1\Temp\cclUXWhF.s|172|Error: symbol `thiscall_1' is already defined|
C:\DOCUME~1\qpsoft\LOCALS~1\Temp\cclUXWhF.s|172|Error: symbol `thiscall_2' is already defined|
C:\DOCUME~1\qpsoft\LOCALS~1\Temp\cclUXWhF.s|172|Error: symbol `stdcall_1' is already defined|
C:\DOCUME~1\qpsoft\LOCALS~1\Temp\cclUXWhF.s|172|Error: symbol `stdcall_2' is already defined|
C:\DOCUME~1\qpsoft\LOCALS~1\Temp\cclUXWhF.s|318|Error: symbol `thiscall_1' is already defined|
C:\DOCUME~1\qpsoft\LOCALS~1\Temp\cclUXWhF.s|318|Error: symbol `thiscall_2' is already defined|
C:\DOCUME~1\qpsoft\LOCALS~1\Temp\cclUXWhF.s|318|Error: symbol `stdcall_1' is already defined|
C:\DOCUME~1\qpsoft\LOCALS~1\Temp\cclUXWhF.s|318|Error: symbol `stdcall_2' is already defined|
恳请帮忙调试一下。
现在被迫使用VC编译器的唯一理由就是GCC还无法支持thunk,无法将当前工程移植MinGW。
多谢了!
大熊猫侯佩 2009-02-26
  • 打赏
  • 举报
回复
你先试一下,有问题再说。(MinGW gcc 3.4.5编译连接OK!)


void ThunkTemplate(DWORD *addr1,DWORD *addr2,int calltype)
{
int flag = 0;
DWORD x1,x2;

__asm__ __volatile__("testl $0,%3;jz 0f;thiscall_1:movl $-1,%%ecx;"
"movl $-2,%%eax;jmp *%%eax;thiscall_2:;"
"stdcall_1:pushl (%%esp);movl $-1,4(%%esp);"
"movl $-2,%%eax;jmp *%%eax;stdcall_2:;"
"0:testl $0,%2;jnz 1f;movl $thiscall_1,%0;"
"movl $thiscall_2,%1;jmp 2f;1:mov $stdcall_1,%0;"
"mov $stdcall_2,%1;2:;"
:"=r"(x1)/*%0*/,"=r"(x2)/*%1*/:"r"(calltype)/*%2*/,\
"r"(flag)/*%3*/);

*addr1 = x1;
*addr2 = x2;
}

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧