c - 程序集 x86 - 调用 C 函数

标签 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;
}

好的,所以我们需要推送格式的地址而不是格式本身,所以像这样的东西应该足够接近了吧?

#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;
}

你们碰巧有时间演示一个工作示例吗?在互联网上找不到任何相关信息。

最佳答案

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

涉及的字符转换为%=37, d=100, \n=10 in decimal.
但是使用十六进制要容易得多:%=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;
}

关于c - 程序集 x86 - 调用 C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33650174/

相关文章:

c - 用于简单固定(多)精度运算(add、div、mul、sub)的快速 C 代码?

字谜 C 程序如何(忽略大写字母)

c - 将 unsigned int 转换为 float 时出错

assembly - 在此 x86 指令中, %r11d 中的 d 指的是什么?

c - 在二进制数中找到第一个 "1"

c - 为什么像这样初始化二维数组会更糟​​?

C - 如何创建指向不同数据类型的数组?

c++ - 你能在#define 宏名称中使用 a.b 符号吗?

c - 提高 OpenMP 程序的性能

c++ - 现代如何使用汇编(例如,使用 C/C++)?