在C中调用NASM功能

时间:2016-04-26 17:15:48

标签: c gcc assembly segmentation-fault nasm

我正在尝试学习x86汇编程序,我想在 C 中调用 NASM 函数。当我运行我的程序时,我收到此错误:

  

分段错误(核心转储)

我已经尝试过几十种简单测试功能,但每次都停在同一位置。

以下是我的asmc个文件:

div.asm:

global _test

_test:
    push    ebp
    mov     ebp, esp
    push    ebx
    mov     eax, [ebp+8]
    mov     ebx, [ebp+12]
    div     ebx
    pop     ebp
    ret

main.c中:

#include <stdio.h>

extern unsigned int test (unsigned int, unsigned int);

int main(void)
{
    printf("%d\n", div(85,5));
    return 0;
}

我编译&amp;将文件链接到:

nasm -f elf -o div.o div.asm
gcc -m32 -c -o main.o main.c
gcc -m32 -o run div.o main.o

我在64 Bit Linux中使用Virtual Machine

我的错误是什么,我该如何解决?

2 个答案:

答案 0 :(得分:4)

你忘记弹出ebx(或者至少按顺序排列堆栈):

push    ebp
mov     ebp, esp
push    ebx         ; you push it here
mov     eax, [ebp+8]
mov     ebx, [ebp+12]
xor     edx,edx     ; ..and you must zero edx
div     ebx
pop     ebx         ; forgot to pop it here
pop     ebp
ret

答案 1 :(得分:2)

目前还不清楚你是否解决了问题。除了其他问题之外,您还需要在main.c中调用函数调用div.asm中的调用。例如,如果您已创建汇编函数_test,则需要将其声明为extern并实际使用main中的函数。 e.g:

#include <stdio.h>

extern unsigned int _test (unsigned int, unsigned int);

int main(void)
{
    printf("%d\n", _test (85,5));    /* you are calling div here, not _test */
    return 0;
}

(您的函数名称不是汇编对象文件div.o的名称 - 并且正如评论中所指出的,div是在{中声明的无符号分区{1}}以及stdlib.hldiv

汇编函数文件中的lldiv声明必须与global中声明的名称相匹配。 e.g:

main

现在,您可以编译,链接和运行您的测试文件:

    global _test

_test:
    push    ebp
    mov     ebp, esp
    mov     eax, [ebp+8]
    xor     edx, edx
    div     dword [ebp+12]
    mov     esp, ebp
    pop     ebp
    ret

或编译/链接,只需:

$ nasm -f elf -o div.o div.asm
$ gcc -m32 -c -o main.o main.c
$ gcc -m32 -o run div.o main.o
$./run
17