X86-64 NASM calling extern c functions

前端 未结 2 1784
伪装坚强ぢ
伪装坚强ぢ 2021-01-29 06:19

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


        
相关标签:
2条回答
  • 2021-01-29 06:44

    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
    
    0 讨论(0)
  • 2021-01-29 06:56

    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
    
    0 讨论(0)
提交回复
热议问题