简体   繁体   中英

Calling NASM function in C

I'm trying to learn x86 assembler, and I want to call a NASM function in C . When i run my program I get this error:

Segmentation fault (Core dumped)

I've tried dozens of variations of my simple test function but it stops every time at the same position.

Here are my asm and c files:

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

I compile & link the files with:

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

I use a 64 Bit Linux in a Virtual Machine .

What is my mistake here, and how can I fix it?

You forget to pop ebx (or at least make the stack in order):

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

It is unclear if you ever got your problem solved. In addition to the other issues, you would need to make your function call in your main.c match the call in div.asm . For example if you have created an assembly function _test , you need to declare it as extern and actually use the function in main . eg:

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

(your function name is not the name for your assembly object file div.o -- and as pointed out in the comments, div is an unsigned division declared in stdlib.h along with ldiv , and lldiv )

Your global declaration in your assembly function file must match the name you declared in main . eg:

    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

Now, you can compile, link and run your test file:

$ 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

or for the compilation/link, simply:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM