1

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

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 中,则 cmpfunc 将在 4(%ebx) 中找到。但我不知道如何从程序集中调用这个函数。我已经尝试通过以下方式直接从 4(%ebx) 运行:

call    *4(%ebx)

那行不通,所以我尝试了:

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

但无济于事。我似乎找不到任何方法来做到这一点,而且我尝试过的任何搜索都一无所获。我将如何在大会中做到这一点?

4

2 回答 2

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 演示一起编译。我懂了:

    .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)在优化打开的情况下优化了该功能。

于 2013-09-17T18:20:48.493 回答
0

我发现如何在汇编中用 C 语言编写一些东西的一种方法是查看编译器是如何做到的。AC 编译器将首先在内部将您的代码转换为汇编,然后运行汇编器以创建目标文件。

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

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

于 2013-09-17T18:19:51.290 回答