能力值:
( LV4,RANK:50 )
|
-
-
2 楼
这主要是这2个函数的参数定义不一样造成的
printf函数调用的堆栈是调用者负责平衡的,所以调用的时候必须在call后面add esp,4*参数数目,MessageBoxA函数是函数内部负责堆栈平衡 所以直接调用就可以了
在使用call的时候最好看看调用的函数定义的申明
|
能力值:
( LV8,RANK:130 )
|
-
-
3 楼
CALL printf //这种是直接调用函数
CALL DWORD PTR[MessageBox] //这种为什么是地址
我想要知道的是调用方式,两者的区别。。。
|
能力值:
( LV4,RANK:50 )
|
-
-
4 楼
由于使用了内联汇编,C编译器将MessageBox申明为一个指向dword地址的指针,这个地址用于存放MessageBoxA加载后的内存地址,所以需要call [MessageBox]
上面的例子不同 printf函数在c编译器里面 函数实体已经被编译到程序里面了,函数的地址明确不需要重定位,所以可以使用call addr
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
换种说法
printf是使用静态连接,直接把函数代码写到EXE中
MessageBox是动态连接,MessageBox在程序中只是一个指针,当EXE要使用的时候,只能根据这个指针去读取DLL中函数代码
|
能力值:
( LV8,RANK:130 )
|
-
-
6 楼
谢谢!!!
|
能力值:
( 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]
|
能力值:
( LV8,RANK:130 )
|
-
-
8 楼
到底那一个说的对啊???
|
能力值:
(RANK:20 )
|
-
-
9 楼
他们说的不矛盾,是因为__declspec(dllimport)关键字的原因。对于使用了__declspec(dllimport)关键字来声明的函数,VC会将对这些函数的调用翻译成一个间址的call,通过IAT来调用,如果你是用C/C++自然不用关心怎么调用,但用汇编就得按编译器的翻译规则来。MSDN里对__declspec(dllimport)有详细描述。
|
能力值:
( LV8,RANK:130 )
|
-
-
10 楼
终于明白了!!!!!!
|
能力值:
( LV8,RANK:130 )
|
-
-
11 楼
对了,谢谢!!!!!!!
呵呵~~~~~~~~~~~~
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
各位~~~~看图吧
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
|
能力值:
( LV2,RANK:10 )
|
-
-
14 楼
多了图
|
能力值:
(RANK:50 )
|
-
-
15 楼
最后贴的是静态联编的是吧?
把源代码也贴出来对比看看啊
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
晕,你别看错了啊,黑体就是源代码,编译出来的是灰体
|
能力值:
(RANK:50 )
|
-
-
17 楼
没注意,呵呵,真不好意思啊
|
能力值:
( LV6,RANK:90 )
|
-
-
18 楼
看了比较有收获,谁在说说在BCB中的吧
|
能力值:
(RANK:220 )
|
-
-
19 楼
关键是――MessageBoxA 是在DLL中引入的,而printf却不是。就是这点区别。
DLL 引入的函数,因为DLL的Base Address是不确定的,所以需要重定位,即载入DLL后才知道MessageBoxA的真正的地址。(理论上)
而 printf 是编译后就确定了的,所以没问题。
|
能力值:
( LV2,RANK:10 )
|
-
-
20 楼
收获不小呀!!支持..
|
|
|