2010-08-26 51 views
1

我正在编写一个汇编函数,它将从C调用将调用带有传递给C函数的内存地址的sidt机器指令。从我的MSVC10生成的代码的分析,我构建了下面的代码(YASM语法):在ASM函数中访问栈中传递的参数

SECTION .data 
SECTION .text 
GLOBAL _sidtLoad 
_sidtLoad: 

push  ebp 
mov   ebp,esp 
sub   esp,0C0h 
push  ebx 
push  esi 
push  edi 
lea   edi,[ebp-0C0h] 
mov   ecx,30h 
mov   eax,0CCCCCCCCh 

sidt [ebp+8] 

pop   edi 
pop   esi 
pop   ebx 
add   esp,0C0h 
cmp   ebp,esp  
mov   esp,ebp 
pop   ebp 
ret 

这里是C函数签名:

void sidtLoad (void* mem); 

据我所看到的一切都应该工作,我甚至检查了传递给函数的内存地址,并且看到它与[ebp + 8]中存储的地址匹配(字节相反,我认为这是字节序的结果,应该由机器处理) 。我尝试了sidt指令的其他参数,例如[ebp + 12],[ebp + 4],[ebp-8]等,但没有运气。

P.S我在外部程序集模块中编写此代码以解决使用MSVC10定位x64时缺乏内联汇编的问题。但是,这个特定的汇编函数/程序正在以x86的方式运行,这样我就可以掌握整个过程。

P.P.S我没有使用__sidt内在因为Windows Driver Kit(WDK)似乎不支持它。或者至少我不能让它与它一起工作!

+0

你在用户模式或内核模式下运行?在Windows下绝对不支持对IDT的直接操作 - 你在做什么? – Michael 2010-08-26 00:38:05

+0

sidt指令只是将来自IDT的数据存储到指定的地址中。我已经初始化一个包含正确成员的结构,并将它的地址传递给sidtLoad()函数。我只是想用IDT信息填充结构并打印出来。如果我使用内联asm来调用sidt指令,它工作正常,所以我不认为这是一个安全访问问题。 – 2010-08-26 00:45:34

回答

2

你的代码会将IDT写入内存地址ebp+8,这不是你想要的。相反,你需要这样的东西:

mov eax, [ebp+8] 
sidt [eax] 
+0

工程就像一个魅力,感谢你。 – 2010-08-26 00:52:27

1

编译:

int sidLoad_fake(void * mem) { 
    return (int)mem; 
} 

到组装,然后看它就会从把在返回寄存器中的值。

我认为x86_64上的前几个参数在寄存器中传递。