程序集x86-调用C函数

程序集x86-调用C函数,c,assembly,C,Assembly,我想知道是否可以调用printf,例如不在数据段中声明格式数组。这个问题是关于x86的 #include <stdio.h> int main() { __asm { push 1 ; number to print push 3710092110 ; format in ascii for %d\n call printf add esp, 8 } return 0; } #包括

我想知道是否可以调用printf,例如不在数据段中声明格式数组。这个问题是关于x86的

#include <stdio.h>

int main()
{
    __asm
    {
        push 1 ; number to print
        push 3710092110 ; format in ascii for %d\n
        call printf
        add esp, 8
    }

    return 0;
}
#包括
int main()
{
__asm
{
按1;数字进行打印
为%d推送3710092110;ascii格式\n
调用printf
添加esp,8
}
返回0;
}
好的,我们需要推送格式的地址,而不是格式本身,所以像这样的东西应该足够接近,对吗

#include <stdio.h>

int main()
{
    __asm
    {
        push 3710092110 ; 3710092110 = format in ascii for %d\n
        push 1; argument to print
        lea edx, dword ptr[esp + 4]; get address of the format on stack
        push edx ; push the address of the format
        call printf
        add esp, 12
    }

    return 0;
}
#包括
int main()
{
__asm
{
为%d按3710092110;3710092110=ascii格式\n
按1;参数打印
lea edx,dword ptr[esp+4];获取堆栈上格式的地址
推送edx;推送格式的地址
调用printf
添加esp,12
}
返回0;
}

你们有时间演示一个有效的例子吗?在internet上找不到与此相关的任何内容。

通过在堆栈上按其地址传递格式字符串。因此,您可以将字符串放在任意位置,但仍然需要传递其地址。

您的第二个代码段很接近,但它仍然需要为格式字符串的内容使用不同的值%d\n

所涉及的字符转换为十进制的%=37、d=100、\n=10。
但使用十六进制要容易得多:%=25h,d=64h,\n=0Ah 由于没有什么特殊性,我们必须将第一个字符放在dword的最低字节,才能推送到堆栈上。我们将最高字节保留为零,以进行必要的空终止

%d\n  -->  000A6425h
您的代码:

#include <stdio.h>

int main()
{
    __asm
    {
        push 000A6425h ;= format in ascii for %d\n
        push 1; argument to print
        lea edx, dword ptr[esp + 4]; get address of the format on stack
        push edx ; push the address of the format
        call printf
        add esp, 12
    }

    return 0;
}
#包括
int main()
{
__asm
{
push 000A6425h;=用于%d的ascii格式\n
按1;参数打印
lea edx,dword ptr[esp+4];获取堆栈上格式的地址
推送edx;推送格式的地址
调用printf
添加esp,12
}
返回0;
}

是的,但是(我想你知道),不使用该代码。这是可能的,但你需要将指针推到格式字符串,而不是格式字符串本身。你认为
3710092110
%d\n
有什么关系?@Ville ValtteriTiittanen:嗯,妈妈:如果你认为
%d\n
等于字节
37
100
92
110
,那么你需要学习转义码和空终止符。