QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1286|回复: 10

请问这段汇编是什么意思啊……

[复制链接]
发表于 2005-10-4 21:37:14 | 显示全部楼层 |阅读模式
[code:1]
DWORD Call_stdcall( const void* args, size_t sz, DWORD func )
{
    DWORD rc;//这是我们的返回值...
    __asm
    {
        mov  ecx, sz//获得缓冲区大小
        mov  esi, args//获得缓冲区
        sub  esp, ecx//分配栈空间
        mov  edi, esp//目标栈帧的起始地址
        shr  ecx, 2//以双字节为单位操作
        rep movsd//复制参数到真正的栈中
        call [func]//调用函数
        mov rc, eax//恢复栈指针
    }
}  
[/code:1]
这是我从一本书上看来的
是在x86,windows环境下,以通用的方式调用函数的代码
第三行、第四行还有第六行汇编是什么意思啊
书上的意思好像是说这个只适用于windows,不知道怎么移至到linux下
发表于 2005-10-4 23:28:25 | 显示全部楼层
为什么只适合windows?

大概就是
在栈顶分配一段空间,把你的参数拷贝进取,然后调用(函数清栈),然后返回值

印象中cdecl和stdcall的区别就是cdecl是调用者清栈
回复

使用道具 举报

发表于 2005-10-5 12:06:52 | 显示全部楼层
intel手册上有

rep重复执行指令,一直到ecx为0为止
回复

使用道具 举报

 楼主| 发表于 2005-10-5 14:09:13 | 显示全部楼层
恩,今天看了汇编的简明教程,大致理解了这段代码,现在我还有个疑问,就是这段代码是不是操作系统无关的呢,这段代码在linux下也能实现调用任何原型的函数这一功能吗?
回复

使用道具 举报

发表于 2005-10-5 17:50:41 | 显示全部楼层
linux里面大多数函数都是cdecl吧?这个是调用stdcall的,windows API大多都是stdcall的
回复

使用道具 举报

 楼主| 发表于 2005-10-5 20:11:14 | 显示全部楼层
那么这个呢,在linux下可以用吗:
[code:1]
DWORD Call_cdecl( const void* args, size_t sz, DWORD func )
{
    DWORD rc;//这是我们的返回值……
    __asm
    {
        mov  ecx, sz//获得缓冲区大小
        mov  esi, args//获得缓冲区
        sub  esp, ecx//分配栈空间
        mov  edi, esp//目标栈帧的起始地址
        shr  ecx, 2//以双字为单位操作
        rep  movsd//复制参数到真正的栈中
        call  [func]//调用函数
        mov  rc, eax//保存返回值
        add  esp, sz//恢复栈指针
    }
    return ( rc );
}
[/code:1]
这个在linux下可以用吗?
回复

使用道具 举报

发表于 2005-10-6 09:14:11 | 显示全部楼层
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_core___cdecl.asp
回复

使用道具 举报

 楼主| 发表于 2005-10-6 12:00:19 | 显示全部楼层
kakuyou, 我问的是在linux下该怎么做啊……或者在linux下是和在win下一样的?
回复

使用道具 举报

发表于 2005-10-6 13:36:50 | 显示全部楼层
如ShiChao所说,我记得linux是调用方恢复栈顶指针,也就是cdecl方法,自己写个程序然后
objdump -d反汇编以下就知道了。

不过,我觉得这段代码除了学习用外,真正要用它的只有编译器
回复

使用道具 举报

 楼主| 发表于 2005-10-6 17:51:13 | 显示全部楼层
[quote:0ca1faa924="sjinny"]那么这个呢,在linux下可以用吗:
[code:1]
DWORD Call_cdecl( const void* args, size_t sz, DWORD func )
{
    DWORD rc;//这是我们的返回值……
    __asm
    {
        mov  ecx, sz//获得缓冲区大小
        mov  esi, args//获得缓冲区
        sub  esp, ecx//分配栈空间
        mov  edi, esp//目标栈帧的起始地址
        shr  ecx, 2//以双字为单位操作
        rep  movsd//复制参数到真正的栈中
        call  [func]//调用函数
        mov  rc, eax//保存返回值
        add  esp, sz//恢复栈指针
    }
    return ( rc );
}
[/code:1]
这个在linux下可以用吗? [/quote]

这个呢
回复

使用道具 举报

发表于 2005-10-6 17:51:35 | 显示全部楼层
楼主想做什么用?

改成cdecl风格的,最后加一行

add esp, sz;
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-5 02:14 , Processed in 0.069196 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表