我正在尝试将一些代码从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
但无济于事。我似乎无法找到任何方法来做到这一点,任何我尝试过的搜索都没有发现。我将如何在大会中这样做?
答案 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反汇编。这会产生类似的结果。