X86-64 NASM calling extern c functions

…衆ロ難τιáo~ 提交于 2019-12-31 07:54:26

问题


Im very new to assembly but know a bit of c. Im playing around with extern function calls like

extern _printf
str db "Hello", 0
push str
call _printf

but cant find any tutorials using extern functions except scanf and printf. For example strcmp? How can i call strcmp in my case?


回答1:


Here is my answer. It is specific to x86-64 though. Please know that when pushing arguments to a function, you usually place the first 6 in registers rdi, rsi, rdx, rcx, r8, and r9. The rest get pushed to the stack. The specification for this is called the System V ABI (Note that Windows uses a different convention called the "Microsoft x64 Calling Convention").

    segment .data     ; or use .rodata for read-only data.
str1    db      "Hello", 0x0
str2    db      "Hellx", 0x0
fmt     db      "Comparison = %d", 0xa, 0x0

segment .text
    global main
    extern strcmp, printf
    default rel             ; RIP-relative addressing for [name] is what you want.

main:
    ; Create a stack-frame, re-aligning the stack to 16-byte alignment before calls
    push rbp
    mov rbp, rsp

    ; Prepare the arguments for strcmp.
    lea rdi, [str1]
    lea rsi, [str2]

    ; Call strcmp, return value is in rax.
    call strcmp

    ; Prepare arguments for printf.
    lea rdi, [fmt]
    mov esi, eax  ; int return value from strcmp -> 2nd arg for printf
    xor eax, eax  ; Indicate no floating point args to printf.

    ; Call printf
    call printf

    ; Return 0 (EXIT_SUCCESS), and destroy the stack frame.
    xor eax, eax
    leave            ; or just pop rbp because RSP is still pointing at the saved RBP
    ret



回答2:


Edit: I made a few mistakes here, see comments for details!

Here is a 32bit version (64bit below):

SECTION .data
    ; global functions in this file
    global main

    ; extern functions
    extern strcmp

hworld: ; our first string
    db "hello world", 0

hworld2: ; our second string
    db "hello world2", 0

SECTION .text

;=============================================================================
; The program entrypoint
;
main:

    ; int rv = strcmp("hello world", "hello world2");
    push    hworld2
    push    hworld
    call    strcmp

    ; _exit(rv);
    mov     ebx, eax
    mov     eax, 1
    int     0x80

Then you can compile it with:

nasm -f elf main.s -o main.o
cc -m32 main.o -o hello_world

And here is the 64bit version:

SECTION .data
    ; global functions in this file
    global main

    ; extern functions
    extern strcmp

hworld: ; our first string
    db "hello world", 0

hworld2: ; our second string
    db "hello world2", 0

SECTION .text

;=============================================================================
; The program entrypoint
;
main:

    ; int rv = strcmp("hello world", "hello world2");
    mov     rsi, hworld2
    mov     rdi, hworld
    call    strcmp

    ; _exit(rv);
    mov     rdi, rax
    mov     rax, 60
    syscall

Then you can compile the x64 version with:

nasm -f elf64 main.s -o main.o
cc main.o -o hello_world

And run it:

$ ./hello_world 
$ echo $?
206


来源:https://stackoverflow.com/questions/54657687/x86-64-nasm-calling-extern-c-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!