从结构调用函数(C / Assembly)

时间:2013-09-17 17:58:42

标签: c assembly struct

我正在尝试将一些代码从C移植到汇编但我在这里遇到了一些麻烦。在c函数中,我传递了一个struct。在这个结构中,保存了两个这样的函数:

typedef struct sort sort_t;
struct sort {
    void *data;
    cmpfunc_t cmpfunc;
    cpyfunc_t cpyfunc;
};

在C代码中,这些函数被调用(m是指向结构的指针):

m->cpyfunc(m->data, j, k);

现在我正在尝试在装配中这样做。我意识到结构在内存中按顺序保存。因此,如果m存储在%ebx中,那么将在4(%ebx)中找到cmpfunc。但我无法弄清楚如何从汇编中调用此函数。我试过直接从4(%ebx)直接运行:

call    *4(%ebx)

那不行,所以我试过了:

movl    4(%ebx),%edx
call    *%edx

但无济于事。我似乎无法找到任何方法来做到这一点,任何我尝试过的搜索都没有发现。我将如何在大会中这样做?

2 个答案:

答案 0 :(得分:1)

我制作了一个小测试程序:

typedef void (*cpyfunc_t)(void *, int, int);
typedef void (*cmpfunc_t)(void);
struct sort {
    void *data;
    cmpfunc_t cmpfunc;
    cpyfunc_t cpyfunc;
};


int main()
{
    struct sort *m;
    int k,j;

    m->cpyfunc(m->data, j, k);
}

并使用ELLCC demo进行编译。我明白了:

    .file   "/tmp/webcompile/_31142_0.c"
    .text
    .globl  main
    .align  16, 0x90
    .type   main,@function
main:                                   # @main
# BB#0:                                 # %entry
    pushl   %ebp
    movl    %esp, %ebp
    pushl   %edi
    pushl   %esi
    subl    $32, %esp
    movl    $0, %eax
    movl    -12(%ebp), %ecx
    movl    8(%ecx), %ecx
    movl    -12(%ebp), %edx
    movl    (%edx), %edx
    movl    -20(%ebp), %esi
    movl    -16(%ebp), %edi
    movl    %edx, (%esp)
    movl    %esi, 4(%esp)
    movl    %edi, 8(%esp)
    movl    %eax, -24(%ebp)         # 4-byte Spill
    calll   *%ecx
    movl    -24(%ebp), %eax         # 4-byte Reload
    addl    $32, %esp
    popl    %esi
    popl    %edi
    popl    %ebp
    ret
.Ltmp0:
    .size   main, .Ltmp0-main


    .section    ".note.GNU-stack","",@progbits

请注意,cpyfunc元素在结构中位于偏移量8处。

编辑:我确实必须关闭优化,因为ELLCC编译器(基于clang)在启用优化的情况下将函数优化为零。

答案 1 :(得分:0)

我发现如何在汇编中找到如何从C编写内容的一种方法是看看编译器是如何做到的。 C编译器将首先在内部将代码转换为Assembly,然后运行Assembler以创建目标文件。

您通常可以将标志传递给编译器以创建中间汇编代码。这样做,然后看看C编译器如何调用函数指针。

您还可以在由编译器创建的目标文件上运行objdump反汇编。这会产生类似的结果。