首页
社区
课程
招聘
VC中使用内联汇编的一个问题~~~~~~~~~~~~~~~~~~~~~
发表于: 2005-1-17 10:27 16791

VC中使用内联汇编的一个问题~~~~~~~~~~~~~~~~~~~~~

lee 活跃值
3
2005-1-17 10:27
16791

char szFormat[]="%s %s\n";
char szHello[]="Hello";
char szWorld[]="World";

void main()
{
        __asm
        {
                LEA EAX,szWorld
                PUSH EAX
                LEA EAX,szHello
                PUSH EAX
                LEA EAX,szFormat
                PUSH EAX
                CALL printf //这个地方
                ADD ESP,12
        }
}

TCHAR appname[]=TEXT("API Test");

void main()
{
        TCHAR tszHello[]=TEXT("hello,word");
        __asm
        {
                PUSH MB_OK OR MB_ICONINFORMATION
                PUSH OFFSET appname
                LEA  EAX,tszHello
                PUSH EAX
                PUSH 0
                CALL DWORD PTR[MessageBox]//这个地方
     ;注意这里不是CALL MessageBox,而是重定位过的函数地址
        }
}

同样是调用函数,为什么方法不一样啊,虽然上面有句注释,但是我还是不懂

那位指点一下!!!

有《软件加密技术内幕》的可以看398页


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (19)
雪    币: 260
活跃值: (162)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
这主要是这2个函数的参数定义不一样造成的

printf函数调用的堆栈是调用者负责平衡的,所以调用的时候必须在call后面add esp,4*参数数目,MessageBoxA函数是函数内部负责堆栈平衡 所以直接调用就可以了

在使用call的时候最好看看调用的函数定义的申明
2005-1-17 10:53
0
雪    币: 255
活跃值: (175)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
CALL printf //这种是直接调用函数
CALL DWORD PTR[MessageBox] //这种为什么是地址

我想要知道的是调用方式,两者的区别。。。
2005-1-17 11:00
0
雪    币: 260
活跃值: (162)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
由于使用了内联汇编,C编译器将MessageBox申明为一个指向dword地址的指针,这个地址用于存放MessageBoxA加载后的内存地址,所以需要call [MessageBox]

上面的例子不同 printf函数在c编译器里面 函数实体已经被编译到程序里面了,函数的地址明确不需要重定位,所以可以使用call addr
2005-1-17 11:16
0
雪    币: 239
活跃值: (160)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
换种说法
printf是使用静态连接,直接把函数代码写到EXE中

MessageBox是动态连接,MessageBox在程序中只是一个指针,当EXE要使用的时候,只能根据这个指针去读取DLL中函数代码
2005-1-17 11:39
0
雪    币: 255
活跃值: (175)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
6
谢谢!!!
2005-1-17 12:04
0
雪    币: 216
活跃值: (370)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
7
最初由 vcasm 发布
由于使用了内联汇编,C编译器将MessageBox申明为一个指向dword地址的指针,这个地址用于存放MessageBoxA加载后的内存地址,所以需要call [MessageBox]

上面的例子不同 printf函数在c编译器里面 函数实体已经被编译到程序里面了,函数的地址明确不需要重定位,所以可以使用call addr

错了,真正的原因在于定义方式。

不要包含任何头文件:
这样写:
int __stdcall MessageBoxA(void* hWnd,
    const char * lpText,
    const char * lpCaption,
    unsigned int  uType
);
就要这样调用
call MessageBoxA

如果这样写:
__declspec(dllimport) int __stdcall MessageBoxA(void* hWnd,
    const char * lpText,
    const char * lpCaption,
    unsigned int  uType
);
就要这样调:
call dword ptr [MessageBoxA]

因为vc的头文件已经默认给写上了__declspec(dllimport)
所以就必须call dword ptr [MessageBox]
2005-1-17 13:42
0
雪    币: 255
活跃值: (175)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
8
到底那一个说的对啊???
2005-1-19 11:57
0
雪    币: 3246
活跃值: (374)
能力值: (RANK:20 )
在线值:
发帖
回帖
粉丝
9
他们说的不矛盾,是因为__declspec(dllimport)关键字的原因。对于使用了__declspec(dllimport)关键字来声明的函数,VC会将对这些函数的调用翻译成一个间址的call,通过IAT来调用,如果你是用C/C++自然不用关心怎么调用,但用汇编就得按编译器的翻译规则来。MSDN里对__declspec(dllimport)有详细描述。
2005-1-19 12:54
0
雪    币: 255
活跃值: (175)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
10
终于明白了!!!!!!
2005-1-19 17:03
0
雪    币: 255
活跃值: (175)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
11
对了,谢谢!!!!!!!

呵呵~~~~~~~~~~~~
2005-1-19 17:03
0
雪    币: 216
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
各位~~~~看图吧
2005-1-25 07:18
0
雪    币: 216
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
2005-1-25 07:22
0
雪    币: 216
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
多了图
2005-1-25 07:25
0
雪    币: 1829
活跃值: (1377)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
15
最后贴的是静态联编的是吧?
把源代码也贴出来对比看看啊
2005-1-26 23:36
0
雪    币: 216
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
晕,你别看错了啊,黑体就是源代码,编译出来的是灰体
2005-1-27 03:09
0
雪    币: 1829
活跃值: (1377)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
17
没注意,呵呵,真不好意思啊
2005-1-28 18:52
0
雪    币: 239
活跃值: (478)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
18
看了比较有收获,谁在说说在BCB中的吧
2005-6-27 09:24
0
雪    币: 81
活跃值: (41)
能力值: (RANK:220 )
在线值:
发帖
回帖
粉丝
19
关键是――MessageBoxA 是在DLL中引入的,而printf却不是。就是这点区别。

DLL 引入的函数,因为DLL的Base Address是不确定的,所以需要重定位,即载入DLL后才知道MessageBoxA的真正的地址。(理论上)

而 printf 是编译后就确定了的,所以没问题。
2005-9-30 14:44
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
收获不小呀!!支持..
2005-11-9 21:10
0
游客
登录 | 注册 方可回帖
返回
//