2009-06-10 90 views
2

我正在分析我在程序集中编写的一个程序,并且正在考虑在程序集中移动一些代码。我有一个程序需要一个参数,但我不确定它是否通过堆栈或寄存器。将函数的参数传递给堆栈还是寄存器?

当我在IDA打开我的程序临,在程序的第一行是:

ThreadID= dword ptr -4 

如果我将鼠标悬停我的光标在声明中,下面还显示:

ThreadID dd ? 
r db 4 dup(?) 

这我会假设会指向一个堆栈变量?

然而,当我在OllyDbg中打开相同的程序时,在栈上的这个位置存在一个很大的值,这与任何可能已经传递的参数都不一致,导致我相信它被传入一个寄存器。

任何人都可以指向正确的方向吗?

回答

0

参数传递给函数的方式取决于函数的calling convention。默认调用约定取决于语言,编译器和体系结构。

对于您提供的信息我无法确定,但您不应该忘记像OllyDbg这样的汇编级调试器和像IDA这样的反汇编程序经常使用启发式方法对程序进行反向工程。研究编译器生成的代码的最好方法是指示它编写汇编列表。大多数编译器都可以选择这样做。

+0

调用约定是__fastcall – samoz 2009-06-10 16:22:44

0

这是一个肯定的局部变量。要检出参数,请查找[esp + XXX]值。 IDA自动命名这些[esp + arg_XXX]。

.text:0100346A sub_100346A  proc near    ; CODE XREF: sub_100347C+44p 
.text:0100346A           ; sub_100367A+C6p ... 
.text:0100346A 
.text:0100346A arg_0   = dword ptr 4 
.text:0100346A 
.text:0100346A     mov  eax, [esp+arg_0] 
.text:0100346E     add  dword_1005194, eax 
.text:01003474     call sub_1002801 
.text:01003474 
.text:01003479     retn 4 
.text:01003479 
.text:01003479 sub_100346A  endp 

以上注释中概述的fastcall约定使用寄存器来传递参数。我敢打赌微软或GCC编译器,因为它们被广泛使用。所以先看看ECX和EDX寄存器。

微软或GCC [2] __fastcall [3] 约定(又名__msfastcall)穿过 前两个参数(评价 从左到右)配合到ECX和 EDX。剩余的参数从右到左推送到堆栈上。 http://en.wikipedia.org/wiki/X86_calling_conventions#fastcall